I am designing a Windows Form app. I have an MDIParent form that loads in a maximized state, and loads its child forms in a maximized state as well. However, when I open an OpenFileDialog, or any datareader object, the MDIParent shrinks to a smaller size with all its forms and controls.
This solution Opening child form is causing mdiform to change size and shrink does not apply/work in my situation.
Also this solution https://support.microsoft.com/en-nz/help/967173/restoring-a-maximized-or-minimized-mdi-parent-form-causes-its-height-t did not work for me.
Some background: I have seen this behaviour in almost all my WinForm applications but I have never been keen to sort it out. I was able to narrow down to the causes as highlighted above when I started investigate it. Some posts are describing it as a windows bug, but it has existed for as long as the screen resolutions started going above 1024 (VS 2010) for my case. I hoped it is not just a windows bug...
I hoped it is not just a windows bug...
Feature, not a bug, but it is not one that Winforms programmers like very much. Notable is that there have been several questions about mystifying window shrinkage in the past few months. I think it is associated with the release of Win10 Fall Creators edition. It has deep changes to the legacy Win32 api layer and they've caused plenty of upheaval.
In your specific case, the "feature" is enabled by a shell extension. They get injected into your process when you use OpenFileDialog. The one that does this is very, very evil and does something that a shell extension must absolutely never do. It calls SetProcessDPIAware(). Notable is that it might have been written in WPF, it has a very sneaky backdoor to declare itself dpiAware. Just loading the PresentationCore assembly is enough. But not otherwise limited to WPF code, any code can do this and that might have been undetected for a long time.
One way to chase down this evil extension is by using SysInternals' AutoRuns utility. It lets you selectively disable extensions. But there is also a programmer's way, you can debug this in VS.
Use Project > Properties > Debug tab > tick the "Enable native code debugging" checkbox. Named slightly different in old VS versions btw. Then Debug > New Breakpoint > Function Breakpoint. Function name = user32!SetProcessDPIAware, Language = C. You can exercise this in a do-nothing WPF app to ensure that everything is set correctly. For completeness you can also add the breakpoint for SetProcessDPIAwareness, the new flavor.
Press F5 to start debugging and trigger the OpenFileDialog.ShowDialog() call. The breakpoint should now hit, use Debug > Windows > Call Stack to look at the stack trace. You typically will not see anything very recognizable in your case since the evil code lives in a DLL that you don't have a PDB for. But the DLL name and location (visible in Debug > Windows > Modules) ought to be helpful to identify the person you need to file a bug with. Uninstall it if you can live without it.
Last but not least, it is getting pretty important to start creating Winforms apps that are dpiAware so such a bug can never byte. You kick this off by declaring your app to be dpiAware so DPI virtualization is disabled. Plus whatever you need to do in your code to ensure the UI design scales properly.
Related
Observed behaviour (everything here is on Windows 10):
I run Visual Studio (tried 13 and 15, both behave the same) logged into user A
After starting up, VS takes virtually no CPU time (<1%)
I log into user B, without signing out of A
VS imediately starts using A LOT of CPU time (~25% on my 4 cores with hyper threading)
I can go back and forth between A and B, and it goes back and forth between low and high CPU usage
This is all without any projects or files opened, though it also happens in that case.
I noticed this because I was originally investigating similar behaviour of a WPF application (after a user reported this issue).
While trying to isolate the problem, I found that even a completely new WPF project, with just a single empty window, behaves exactly the same (whether or not run through Visual Studio).
Through profiling and debugging I found that the app seems to spend a huge amount of time handling windows messages.
Specifically I found that it seems to be almost exclusively WM_PAINT messages (we are talking easily hundreds or thousands of messages per second - as many as the CPU can handle it seems).
No other programs I have running (chrome, skype, sublime text, ..) behaves this way.
Has anybody else seen this kind of behaviour?
And/or any ideas what could cause this, or how I could investigate this further?
Naturally, I cannot fix Visual Studio (unless the problem is with my setup somehow) but I hope there is something I can do about my WPF application.
As per Hans Passant's suggestion in the comments, I reported this problem to Microsoft here:
http://connect.microsoft.com/VisualStudio/feedback/details/2390593/wpf-apps-use-a-lot-of-cpu-time-when-logged-into-different-user
As it turns out this indeed seems to have been a bug in WPF, which is fixed in the current version of Windows 10 (probably specifically since the Anniversary Update (version 1607)).
Hence the solution: Make sure to update your OS.
Try putting the following code inside Load event handler for WinForms or Loaded for WPF.
Dim doc As New XmlDocument
Dim nsmgr As New XmlNamespaceManager(Nothing) 'this line throws an exception
Problem is that exception is not thrown, and stack corruption happens. It may have different side effects, depending on the IDE - see below.
Affected IDEs are: 2008, 2010 and 2012 (those I could test). 2010 resets stack state, and returns from sub/handler, like nothing happened (but without proceeding with other statements there). 2012 may warn a user about a failed application and an attempt to run in compatibility mode. Next time after that it runs the same as 2010. 2008 properly throws an exception, but only on default configuration (AnyCPU). Switching platform target to x86 makes the problem reappear in 2008 as well.
Affected frameworks are WinForms and WPF. Console apps and ASP.NET
seem to work fine. .NET v2.0-4.5.
Affected scope is only Load event so far.
Putting this code into a button makes it work.
Affected build
configuration = any. Tried on default Debug and Release.
Why I consider it a bug is because it can leave objects in an unstable state - they did not finish initializing, which is not an expected behavior. What's critical about it is that nobody will know it happened, as it does not throw an exception. Depending on your design, you may end up with incorrect data in your database, which in the worst case may lead to severe consequences.
Does anyone have a good explanation to why this may be happening and if there is a workaround?
The problem is caused by the wow64 emulation layer that comes into play when you target x86 platform on a x64 OS.
It swallows exceptions in the code that is responsible to fire the Load event.
Thus the debugger doesn't see the exception and cannot step in to handle the situation.
This article seems to document well what's happening there,
This previous answer from Hans Passant (to which goes all the credits and upvotes) explains possible workarounds.
My preferite one is to move everything out of Form_Load event and put the problematic code in the form constructor. (Of course I don't know if it is applicable in your case)
I need to create a small notification in the right-bottom corner of the screen. It should provide the following functionality:
Should NOT change the current focus.
Should allow me to put some text in it.
Should appear (and stay if possible) on top of all windows.
Can you suggest using something? The less installing required the better.
Well, there are a few ways to do it.
Roll your own
Use the infrastructure of the desktop environment
Naturally, #2 is going to be more reliable — if you know what the desktop environment you're targeting is.
You mention Linux, so let's look at Gnome. The two most popular (?) Linux-based operating systems are the Red Hat/Fedora/CentOS family and Ubuntu, both of which are based on Gnome 3.
Gnome 3's Notifications;
Do not change the keyboard focus
Allow text (and more)
Appear for a moment above other windows, but then tuck away at the bottom of the screen after a bit; but, can be called back up by mousing over their icons.
Plus, there's nothing to “install” — unless you're running an unusual build, the stock distributions all include the Notification support you want already.
The documentation is found on the Developer.GNOME.org web site, here.
If you are not running on a “normal” Linux distribution, you still have options.
Install libnotify, and enough Gnome infrastructure to let it work.
Re-inventing the wheel…
In the latter case, you'll want to:
Create a top-level X Window;
Set flags on it to ask the Window Manager to please* keep it on top, not decorate it
with the usual resize and title decorations, and so forth;
and set up its contents on your own.
Some documentation on providing hints to the window manager can be found on FreeDesktop.org.
*- the window manager, however, is free to ignore your hints, if it chooses.
First I'd like to head off the "wait a minute" questions.
Yes, I've read every thread with similar titles and subjects on SO and beyond.
Yes, I'm using the very latest version of SP1 and any potential hotfixes that might be related to this problem.
So, with specificity, here is my problem:
When I'm debugging Silverlight applications and it hits a breakpoint, everything works just fine as long as I use the mouse. I can continue, step, stop debugging, disable and enable breakpoints all just fine -- as long as I do so with the mouse.
But when I use the keyboard, Visual Studio freezes for a number of seconds, sometimes over a minute. This is any use of the keyboard. But after a short time, it starts to work just fine until that debugging session is over. But the next debugging session (regardless of whether I use the same instance of Casini or not) it will do exactly the same thing.
When I say any keyboard use, I mean it. F5 (Continue), Shift-F5 (Stop Debugging), F10 (Step Over), as well as typing in the Immediate window or even hitting the ALT key to highlight the menu.
For instance, if I try to type something in the Immediate window, it freezes for about 15 seconds and then shows the first key and repeats the pattern about 5 times until it releases and everything is just fine.
When I say "freezes" I'm not talking just Visual Studio but it hangs the entire operating system except for my ability to move the mouse. Even so, the mouse cursor remains what it was when it froze regardless of the program it's over, such as the text selector.
It only happens with Silverlight and it doesn't matter which version I use.
Here's what I'm running:
Windows 7 Professional 64-bit, all of the latest updates included, 12 GB RAM & 1.5 TB HD.
Visual Studio 2010 Ultimate with all of the latest updates.
All software is legit and I've already tried removing and/or disabling just about everything that can be removed or disabled, including extensions. I've used Process Explorer from Sysinternals to kill or stop everything I can. I've also tried it on a very simple Silverlight application with nothing more than one line of code that doesn't access anything.
EDIT: Forgot to mention that I also don't have it loading symbols beyond the "Just My Code" that it normally would and I've tried every debug setting that I can think of as well. And Intellitrace is also turned off (since I do have Ultimate), but that makes no difference either.
UPDATE (11/18): It gets more and more odd. I determined that the temporary freeze doesn't occur only when Visual Studio has focus. When VS (during the super-simple Silverlight app) goes into debug mode, any keyboard access AT ALL causes the same effect. SO, it appears that it has to (in some way) be related (at least in part) to my Windows setup, contrary to my assertion in the comments, but I cannot possibly fathom how. And if other programs are doing something when it freezes, the delay is longer (which makes a certain amount of sense with the symptoms). I'm still at a complete loss.
Anyone have any ideas or see this before? It's really frustrating.
I solved the problem.
It turned out to be the LastPass toolbar. It's a very handy thing and I've used it for years without issue. Yeah, yeah, toolbars are evil, I get it. :)
Disabling it in IE fixed the problem completely. I can still use it in FF (which is my main browser anyway except for working for which I use IE) and everything works fine.
Even so, it's bizarre to me that the toolbar would only have an effect when SL debugs. I didn't have an issue with ASP.Net debugging and I didn't any issues when the SL app was actually running, only when I hit a breakpoint AND hit a key within the first 15 seconds or so.
In any case, problem solved and thanks for your suggestions.
Try changing registry setting LowLevelHooksTimeout from 5000 to something low, like 300.
It can be at
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\Control Panel\Desktop
or
HKEY_CURRENT_USER\Control Panel\Desktop
(first setting at Policy key seems to globally override user setting).
Here is the situation. The company I work for builds this piece of software in c that can make a Windows computer act a bit like a TV. Essentially, our piece of software is meant to be played full screen and content is displayed from the internet without the user having to ever touch the computer again.
The problem is that once in a while, the system brings up pop-ups like "Your Windows system is ready for an upgrade." or "Please renew your Norton subscription" etc. which the user has to periodically and manually remove.
Is there a way to display content full screen without being bothered by those warnings?
Yah, whether or not the development community agrees, Microsoft has several standards for when and why it might be acceptable to have exclusive use of the monitor.
The most official strategy is to use DirectX in exclusive mode. This is what games do, what windows media player does in full screen video with hardware acceleration enabled, etc... If your application is multimedia intensive (as suggested by TV like functionality), you should probably be using DirectX too. Besides giving you the exclusive display access it will also increase your applications performance while lowering the CPU load (as it will overload graphics work to the video card when possible).
If DirectX is not an option, there are a great number of hacks available that seem to all behave differently between various generations of windows operating systems. So you might have to be prepared to implement several techniques to cover each OS you plan to support.
One technique is to set your application as the currently running screensaver. A screensaver if really just an EXE renamed to SCR with certain command line switches it should support. But you can write your own application to be such a screensaver and a little launcher stub that sets it as the screensaver and launches it. Upon exit the application should return the original screensaver settings (perhaps the launcher waits for the process to exit so that it returns the settings in both graceful exits and any unplanned process terminations ie: app crash). I'm not sure if this behavior is consistent across platforms though, you'll have to test it.
Preventing other applications from creating window handles is truly a hack in my opinion and pretty bad one that I wouldn't appreciate as a customer of such software.
A constant BringWindowToTop() call to keep you in front is better (it doesn't break other software) but still a little hack-ish.
Catch window creation messages with a global hook. This way you can close or hide unwanted windows before they become visible.
EDIT: If you definitely want to avoid hooks, then you can call a function periodically, which puts your window to the top of the z-stack.
You could disable system updates http://support.microsoft.com/kb/901037 and remove the norton malware.
You could also connect a second screen so that the bubbles appear in the the first monitor.
Or you rewrite it for linux or windows ce.
One final option is to install software that reconfigures your os into a kiosk http://shop.inteset.com/Products/9-securelockdown.aspx
If you don't need keyboard or mouse input, how about running your application as a screensaver?
A lot of thoses messages are trigged/managed by Windows Explorer.
Just replace it with your dummy c#/winform.
By changing the registry value
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"Shell"="Explorer.exe"
You can specify virtually any exe as an alternative to explorer.exe
That's the way all windows based (embedded) system (ATM & co) do.
There's still few adjustment (disable services you dont need / dr watson & others), and of course, you'll want to keep a "restart explorer.exe" backdoor.
But that's a good start