I have a strange issue I've been unable to diagnose and am hoping someone can at least point me in the right direction. I have a C++ MFC application that collects data from various sources and displays it on the screen. After a random interval (typically around 5-10 minutes), however, the display gets "corrupted" in a way I've never seen or have been able to track down as shown in the image below (left is normal, right is corrupt):
The basic symptoms are:
Up/down arrow images turn into "5"s and "6"s.
Opening a combo box list results in just the item text displayed (list border and scroll bar is not shown).
Background colours on some controls don't update or display correctly.
Z-order is broken and the app controls "leak" through other windows placed on top.
Pressing Print-Screen with the app in focus no longer captures the window to the clipboard.
Closing and reopening the window does nothing.
Restarting the application gets things back to normal.
Things I've tried to eliminate as a possible cause include:
Operating System & Computer: The same issue is present on a variety of systems from Windows 7-64 bit to Windows Xp-32 bit.
Multi-threading: I added a mutex to prevent the display updates from occurring at the same time but it had no effect (as expected).
Memory Corruption: This has been my assumption all along but there are no signs of memory corruption at all. The base display code has been used for years with no similar issue as well as the base networking message library.
Specific Code: I have narrowed down the issue to one specific dialog among a variety of others that show no issue. They all use the same base code which would seem to indicate the issue lies in the specific display code for the dialog. Exactly how or why the issue occurs has eluded me so far.
Any ideas on what the cause might be or how to narrow it down would be great.
Update 1:
Doing some more timing/repeatable tests and it looks like leaving this one dialog running for a short while causes the issue. The amount time is consistently between 300-400 seconds before the issue shows up.
It sounds like your application could be leaking GDI objects. To check if that is the case, open your task manager and enable the GDI Objects column. Observe the number for your process and see if it's increasing continuously.
If that is actually the case, you should read Detect and Plug GDI Leaks in Your Code with Two Powerful Tools for Windows XP. That MSDN article also offers a tool named GDILeaks.exe that should help you identify your GDI Leaks.
In the case where these symptoms surface within a short time, it should be something that is drawn repeatedly that isn't freeing GDI resources properly. Possibly in (or called within) the windows procedure (OnPaint for example).
If I'm not mistaken Windows' GUI uses a ttf(?) font for those little icons, and it looks like the font gets destroyed somehow (DeleteObject being called with font's handle?)
Related
I have some legacy code made with Borland C++ Builder 6 that I have to port from Windows XP embedded to Windows 10 IoT.
It all seems to run properly, except dialog forms which aren't drawn properly. When I call ShowModal on the forms to show them, they flash quickly and then seems to disappear. However they are not gone, instead they are just not drawn and the form behind the dialog is seen. The dialog form buttons can still be pressed (if we know where they are).
I have tried all possible redrawing, refresh, repaint and update functions I could find, but nothing seems to work.
To make matters worse, dialogs containing actual control elements (like one containing a set of TSpeedButton elements) the controls are redrawn when moving the mouse over them, but anything else are not redrawn.
I have tried to search for similar issues but can't find anything for this.
Could this be solved? Or do we have to update to a newer Embarcadero version of the IDE to be able to solve it (which is a lot or work and not really something we can do at the moment)?
The problem was the use of a Billenium Software (now defunct) package for "fancy" transitions.
The transition in question "zooms" a dialog open, and it just doesn't seem to work. Disabling this transition will solve the problem of the disappearing dialogs.
I still don't know if it's a problem with the components Windows 10 compatibility, or with its 64-bit system compatibility.
I found a bug yesterday in one of my Windows applications, which is built in a high level framework, which in the end, calls Windows APIs like CreateWindow, and ShowWindow, in order to display its user interface.
One one machine so far, and only one, which happened to be a customer machine, I observed the following behaviour:
For only one window in my entire application, when I first call ShowWindow(Handle,SW_SHOW ) for this window, the size which it previously had received by SetWindowPos is overridden.
Reading the MSDN Win32 API documentation, on ShowWindow(Handle,SW_SHOW) I can not see any reference it it moving the window bounds. I can work around this surprising result by having my window-show routine get the bounds before it calls the Win32 ShowWindow routine.
My question is, has anyone ever seen behaviour like this? I think it must be one of the following:
An obscure bug in Windows 7 Service Pack 1 that does not reproduce on all systems, and only reproduces perhaps for a particular version of a particular video card driver. (This affected system has dual AMD/ATI FireGL video cards)
An obscure problem caused by a side effect of some other software running on the system, which may be hooking window handles, installing trampolined code hooks somewhere (perhaps even inside my own process, thanks to some DLL or something that I am not aware of).
Something my 4 million line application is doing to me, through some weird code somewhere I have not yet identified.
I am hitting an application compatibility shim within the Win32 API layer.
If anyone who has worked in C++, C, or Delphi, or any other language, has ever seen anything like this and can think of a reason why ShowWindow would have this amazing and unexpected side effect, of moving the bounds of the window, back to a certain original position, in my case, x=175, y=175, width=320, height=240, which appears to be have been the window bounds right after the initial CreateWindow call, I'd like to know what it is.
Here is a sequence of events:
Application starts up, and creates a few top level windows parented to the desktop.
The first window created is the main application window and the second is a tool window, both have full window grabber bars and are conventional top level Win32 windows, Forms which are sizeable, draggable, and parented to the desktop.
The second window's position is loaded from disk, and the form is shown.
During the form show process, its bounds are set so that the window is at some x and y top/left position, and some height/width is given.
If I query the Win32 window handle immediately before I call ShowWindow, its bounds are where I expect.
If I query the Win32 window handle immediately after I call ShowWindow, its bounds have been reset.
According to MSDN help SW_SHOW means Activates the window and displays it in its current size and position.
This is indeed what occurs on over 100 client PCs I have observed. Only on a single customer-owned Windows 7 PC is this behaviour different.
This affected system has dual AMD/ATI FireGL video cards
I ain't sure about FireGL, but for consumers videocards, made upon the same chip lineage, video-drivers exactly have add-on to reposition windows as they think is easier for operator.
it is called HydraVision Package for Catalyst Software Suite
The MSDN page on DXGI gives instructions on how to handle fullscreen resolutions different from the desktop resolution. It says to call IDXGISwapChain::ResizeTargets() before calling IDXGISwapChain::SetFullscreenState() to prevent flickering, among other things.
It does not say how to handle Alt-Enter, which calls IDXGISwapChain::SetFullscreenState() before the program is given a chance to make its own call to IDXGISwapChain::ResizeTargets(). If the latter method is called upon a WM_SIZE message, another WM_SIZE message will be sent, possibly causing an infinite loop. How can I ensure that the latter will be called before the former when alt-enter or alt-tab are pressed, and that mode switching occurs painlessly in general?
This is going to be really tricky ... the right way how this is supposed to be handled is IDXGIFactory::MakeWindowAssociation, which, as far as I know, nobody has managed to use successfully. You may want to try it anyway.
The "right" answer is to manually handle Alt+Enter. So, disable Alt+Enter using MakeWindowAssociation and get your hands dirty. First, there is no need to capture WM_SIZE. Instead, listen on WM_ENTERSIZEMOVE, WM_CAPTURECHANGED, WM_WINDOWPOSCHANGED and WM_EXITSIZEMOVE. This will prevent you from having to deal with WM_SIZE and still get all relevant window resizing events. (When doing this, read this question as well: WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE - when using menu, not always paired)
Ok, so assuming everything went fine, for Alt+Enter, you have to do the following: You set your swap chain to full screen using IDXGISwapChain::SetFullscreenState and then resize your swap chain (IDXGISwapChain::ResizeBuffers). By default, you'll get a swap chain which is as close as possible to the current resolution of your window before resizing. The way you do this properly is to enumerate the full screen resolutions first, and upon going fullscreen, forcing the resolution you want to have. This sounds ugly, but it seems to be the most robust way to solve the problem.
In general, real, exclusive fullscreen mode is not worth the trouble, as you will always get flickering when someone goes Alt+Tab (you can't avoid it if a mode switch happens, as the screen itself will have to readjust.) A much better solution is to use a fullscreen borderless window. You simply create a window class without any decoration, make it full-screen, place it such that it covers the whole screen and be done with it. Then you don't have to worry about Alt+Enter and Alt+Tab at all. It also allows people to continue working on a second screen without flickering. Performance wise, this is pretty ok'ish (most new games support this as "borderless fullscreen".)
There might be a silver bullet which solves all of this correctly, but I haven't seen it yet. If there is a cleaner/nicer solution, I'd be really curious to hear it. "Borderless fullscreen" seems to be the current standard though, IIRC, Unity 5 will only allow "borderless fullscreen" for Direct3D 11.
I just want to add an update on this issue - I've written a small windowing library that I believe handles DXGI pretty well - no debug messages, no error messages, and everything behaves as intended, at least on my Windows environment. The full solution to this problem is much too complex to explain in a single answer, since it requires a lot of precisely placed method calls (DXGI is really, really rigid as it turns out), but I have my code up on github if anyone wants to take a look at it. Specifically, this file and this file are the ones you want to look at - the latter being an aggregate object of the former.
Note that I have disabled ALT+ENTER in favor of F11, but the functionality is exactly the same.
If you want to use that library, by the way, I am releasing it as free software and will provide documentation soon.
EDIT:
This question isn't about briging a window to the front of EVERYTHING, just for my specifc application. I'd like the frame they were interacting with to be behind the new frame. Much like a dialog, except that it is not a dialog. I don't think this is bad practice, something was summoned (in this case via a menu) I expect it to be infront of the window I used to summon it.
I just read How can I ensure that a wxFrame is brought to the foreground? and that didn't work either.
SetFocus(); makes the window want my attention (it flashes in my task bar in the case of my platform, GTK and MATE task bar if that matters)
Raise(); does.... nothing
Show(); shows it, obviously, but despite it's newly created status nothing happens.
Weirdly clicking the window doesn't bring it to the front until after I have done something in the parent despite showing as the thing I am interacting with in the task bar. I am using all the 3 of the above (Show, SetFocus then Raise).
I've read Raise's documentation ( http://docs.wxwidgets.org/trunk/classwx_window.html#a54808c933f22a891c5db646f6209fa4d ) Raise and Lower are "z-order functions" - this suggests that it's supposed to do this. I have never really had much success with it though. I'd be really really nice if the starting frame came to the foreground whenever I run for example, but given the amount of times I press run and the project is built compared to the amount of time spent writing code and the fact creating a new folder even is more frequent, I've put up with it.
It'd be nice to get it fixed!
Addendum
Using Lower on the parent hasn't worked. There will be 64 less a few obvious ways to try this, I really want to avoid stumbling about.
I believe ravenspoint, and this is not a good user interface trick, but, if you don't mind a little bit of flashing... and stealing of focus, regardless of where you may be typing, etc, etc, just kinda bad...
ParentWindow->Iconize(false); // restore the window if minimized
ParentWindow->SetFocus(); // focus on my window
ParentWindow->Raise(); // bring window to front
ParentWindow->Show(true); // show the window
And before you do, think about another critical application running with
"Enter the counter measure launch code, impact in 12 seconds: "
and half way through typing, your window decides to pop to the top.
I am developing an application for PocketPC. When the application starts the custom function SetScreenOrientation(270) is called which rotates the screen. When the application closes the function SetScreenOrientation(0) is called which restores the screen orientation.
This way the screen orientation isn't restored if the user minimizes the application and this is not acceptable.
Does anyone know where (in which event handlers) should SetScreenOrientation(int angle) be called to set the screen orientation on application start, restore orientation on minimize, set the orientation on maximize and restore the orientation on close?
Actually I don't know which event handler handles the Minimize and Maximize event.
The correct message is WM_SIZE, but Daemin's answer points to the wrong WM_SIZE help topic. Check the wParam. Be careful as your window may be maximized but hidden.
Going from my Windows CE experience you should handle either the WM_SIZE or WM_WINDOWPOSCHANGED messages. If you're working on PocketPC I would suggest you take a look at the WM_WINDOWPOSCHANGED message first because I'm not sure the WM_SIZE has the right parameters that you need.
From the WM_WINDOWPOSCHANGED message's WINDOWPOS structure take a look at the flags member, specifically SWP_SHOWWINDOW and SWP_HIDEWINDOW.
The specific version of the messages that you need to look at vary with what operating system you're using. The Pocket PC OS is built on Windows CE 3.0 (and lower), while Windows Mobile is now built on Windows CE 5.0 (even Windows Mobile 6), but was also built on Windows CE 4. (Source)
So just look under the relevant section in MSDN for the OS that you're writing for.
I don't know what these are called in the C++ world, but in .NET Compact Framework your application form's Resize event would be called when you minimize/maximize a window, and then in the event code you would check the WindowState property of the form to see if its minimized or mazimized.
Altering the state of your PDA from within your application is risky (although there are lots of good reasons to do it), because if your app crashes it will leave the PDA in whatever state it was in. I've done a lot of kiosk-type (full-screen) apps in Windows Mobile, and one of the tricks to doing this effectively is to hide the WM title bar (the top row with the Windows start button) to keep it from flashing up for a split second every time you open a new form. If the app crashes, the windows bar remains invisible until you reset the device, which isn't good. At least with screen rotation the user can restore it manually.
It really depends on the platform, but I'd go with WM_WINDOWPOSCHANGED or the OnShow. It's not wm_size.. That one is not always thrown on all platforms. Casio's don't throw the size event when you'd expect them to. TDS and Symbol's do.
Even though the MSDN is a great sourse for info, remember not all OS's are created equal. In the PPC world the hardware provider gets to create their own OS and sometimes the miss things, or purposfully ignore things.
I've got a platform here (name withheld to protect... well me) that has left and right buttons.. When you press them, you'd expect to be able to catch VK_LEFT, VK_RIGHT.. You'd be wrong. You actually get ';' or ':'. How's that for a kick in the pants.