I don't usually do much coding for Windows even though my development environment is in Windows. However I'm doing some work on an app. I am experiencing something rather unusual:
A second window is opened when the user clicks a particular button. The class is registered, window created and a few other things initialized. Everything seems to go without error except that after creation the window receives a WM_KEYDOWN for RWIN followed by WM_KEYDOWN/WM_KEYUP for VK_ESCAPE.
The VK_ESCAPE is tied to functionality to hide the window, so it appears and then hides because of these messages coming through after it is created.
I never touch the keyboard. The application is launched and interacted with the entire time using a mouse.
I have searched the codebase and inspected every SendMessage, PostMessage and related call. None of them are sending anything of the sort.
Furthermore the lParam for the WM_KEYUP message looks reasonable. So its highly unlikely to be an errant message that is completely different in nature. It is very much looking like an authentic keypress message.
So I have essentially two questions:
Am I able to track where the message is being sent from?
Is there some known mechanism by which keypress messages might be inserted into the message queue (other than the app itself calling SendMessage)?
EDIT:
For the WM_KEYUP message the values are:
lParam: 3221291009 or 1100 0000 0000 001 0000 0000 0000 001
wParam: 27
Which translates to:
repeat count: 1
scan code: 1
context code: 0
previous keystate: 1
transition state: 1
Related
Recently we are getting random crashes, which are rather hard to reproduce. There's no common action being done in our app, sometimes they just happen when you leave the app idling for a longer while. They have one thing in common though: The top of the stacktrace is always in mshtml!CDoc and looks like this:
[0x0] mshtml!CDoc::ReadOptionSettingsFromRegistry + 0xed
[0x1] mshtml!CDoc::UpdateFromRegistry + 0x123
[0x2] mshtml!CDoc::OnSettingsChange + 0xd0
[0x3] mshtml!OnSettingsChangeAllDocs + 0x8f
[0x4] mshtml!GlobalWndProc_SEH + 0x13b
[0x5] mshtml!GlobalWndProc + 0x2d
[0x6] user32!_InternalCallWinProc + 0x2b
[0x7] user32!UserCallWinProcCheckWow + 0x33a
[0x8] user32!DispatchClientMessage + 0xea
[0x9] user32!__fnINSTRINGNULL + 0x40
[0xa] ntdll!KiUserCallbackDispatcher + 0x4d
[0xb] user32!GetMessageW + 0x2e
The crashes are caused by access violations (c0000005, invalid pointer read) in mshtml!CDoc::ReadOptionSettingsFromRegistry.
There's no particular Windows message being processed at that time, it might be anything. The message loop is just a regular
MSG msg;
while (::GetMessage(&msg, 0 ,0, 0)) { ... }
I couldn't find any documentation for those CDoc functions. Does anyone have any idea what might cause these crashes or how to tackle this problem?
Two hints: 1) It might have something to do with copying/pasting HTML with the system clipboard. 2) We have both hosted IE browsers (legacy) and WebView2 browsers (already converted from IE) in our app. Perhaps they interfere with each other?
Mystery solved!
I was finally able to reproduce the crash sometimes on a VM with a debugger installed. Digging into the disassembly, I found out that mshtml!GlobalWndProc tried to handle WM_SETTINGCHANGE every time it crashed (as indicated by the OnSettingsChange... functions in the call stack). This in turn enabled me to reproduce the crash consistently by first pasting anything from the clipboard into one of our HTML editors and then by either broadcasting this message myself or by changing any system setting (like selecting a different system sound scheme). Narrowing it further down from there, it turned out that the culprit was a missing virtual destructor in a clipboard handler class. This left an mshtml::IHTMLDocument2Ptr unreleased, which somehow lead to the crash in MSHTML later while handling that Windows message.
In summary, the crash was caused by an unreleased smart pointer in our code, but was triggered by random system settings changes (probably scheduled by IT departments).
I was experimenting on a simple window to gain insights into the creation process. And I noticed some strange messages. Some was received by WinProc exclusively, others only appeared in message loop (GetMessage), DispatchMessage probably filtered them (0x60)? Some was passed to DefWindowProc by the loop (like 0x31F).
I suspect that Unique WMs you can see in the bottom might be from some random processes or Windows. And WM_TIMER is not passed to DefWindowProc because Dispatch calls it's callback, instead.
But what are this strange undocumented Windows-area messages? It's hightly unlikely that it can be from some random process, as I didn't disable UIPI for them via filters. I still get them in Admin mode, so it's either some rouge Admin program, or more likely OS itself.
I know that Registered WMs are from 4t Tray Minimiser program I use, but when I unload it, the undocumented ones still come in.
As you can see, 0x60 is very often repeated on window focus changes... Also, what could that WM_TIMER be?
I would like to understand how Turbo Debugger works. So, for example, I have a message and I moved it to the DX register.
(I show you how it looks in the debugger):
MOV DX,009E ;This is a version which debugger shows me in debugger mode;
;It takes all information from this code: MOV DX,OFFSET MSG.
In fact, the message's first element address is at 9E (this is how the debugger understands). But actually, in the debugger screen, I can see that in the DS register, MSG address is at A0. How can it be?
I know that code is more preferable, but this time a screenshot is more suitable:
As you can see, I marked 2 addresses, but they are not the same. Actually, I can see that my MSG begins in the above-marked address A0, but that the debugger understands it like 9E and moves it to DX. Can someone explain to me how this can be?
By the way, the program works and prints everything fine, the purpose is to understand how the debugger understands addresses.
MSG code is simply:
MSG db 'Hello, how do you do!!!!,'$'
I believe that if you will single step your code, instruction by instruction, you will see that
You are correct that that your message starts at DS:00A0
Turbo Debugger is also correct that it starts two bytes before that
Look carefully at what is located at DS:009E.
What do you see there ? Two bytes: 0A and 0D
That's an ascii "Line Feed" and an Ascii "Carriage Return".
Your confusion can be reduced by understanding the historical perspective...
Way back when printers used ink and paper, and telephones carried modem signals at 1200 BPS, and you paid something like ten hours of minimum wage pay for one hour of that connection to a city only three states away, there really was an economic imperative in choosing between running the little print head back to the left, or just jacking the platen down a line while the print head stayed in the same position.
I mean, you really saw it in your phone bill.
No joke, this one change, using the 0A byte without the 0D byte, could mean a 10 or 20 dollar difference in your phone bill; and remember to factor in inflation back then.
The reason that you see the message properly is because your machine is first placing a "line feed" (i.e., the cursor is probably dropping to the next line) and a "carriage return" (i.e., the cursor jumps back to the left edge) before putting your message on the screen. This happens much faster than your eye can see.
With the miracle of Turbo Debugger, you can single step this and watch it happen.
So, you are correct when you write that your message "starts" at 00A0, but Turbo Debugger is also right when it's telling you that the message starts two bytes ahead of that.
I have a general question about Rs232 Software Flowcontrol (aka XOn/XOff)
The .Net implementation (and the nativ win32 api) bothe define a property called WriteTimeout / ReadTimeout, which is a time in ms after which a communication is considered to be overdue.
No my problem is this: If I send, lets say a 5 Byte string to the device I don't see any WriteTimeout, as expected. How is this implemented? Everything I find about Software flow control is that XOFF is to be set, when the recieve buffer is full; XOn when it is ready to recieve again.
But from the behavior I see, I would suspect, hat the device sends XON, after it has processed the 5-Byte information that I send, thus creating the information for windows to generate the corresponding events.
So when to send XON on a two-wire only RS232 implementation? Only if the buffer was full and to restart recieving; Or to signal, that we are "still ready" to receive after every chunk we processed?
How to implement?
Cheers & thx in advance!
Corelgott
Send an XON any time you are ready to receive data (your receive buffer is empty or nearly so). Send an XOFF any time you cannot accept more incoming data (your receive buffer is full or nearly so). The process is documented on the Wikipedia software flow control page.
I have a Windows WinMain() window in which I write simple graphics -- merely LineTo() and FillRect(). The rectangles move around. After about an hour, the output that used o go to the main window, all of a sudden goes to the upper left corner of my screen -- as if client coordinates were being interpreted as screen coordinates. My GetDC()'s and ReleaseDC()'s seem to be balanced, and I even checked the return value from ReleaseDC(), make sure it is not 0 (per MSDN). Sometimes the output moves back to my main window. When I got to the debugger (VS 2010), my coordinates do not seem amiss--but output is going to the wrong place. I handle WM_PAINT, WM_CREATE, WM_TIMER, and a few others. I do not know how to debug this. Any help would be appreciated.
This has 'not checking return values' written all over it. Pretty crucial in raw Win32 programming, most every API function returns a boolean or a handle where FALSE or NULL indicates failure. GetLastError() provides the error code.
A cheap way to check for this without modifying code is by using the debugger to look at the EAX register value after the API call. A 0 indicates failure. In Visual Studio you can do so by using the #eax and #err pseudo variables in the Watch window, respectively the function return value and the GetLastError value.
This goes bad once Windows starts failing API calls, probably because of a resource leak. You can see it with TaskMgr.exe, Processes tab. View + Select Columns and tick Handles, USER objects and GDI objects. It is usually the latter, restoring the device context and releasing drawing objects is very easy to fumble. You don't have to wait until it fails, a steadily climbing number in one of those columns is the giveaway. It goes belly-up when the value hits 10,000
You must be calling GetDC(NULL) somewhere by mistake, which would get the DC for the entire desktop.
You could make all your GetDC calls call a wrapper function which asserts if the argument is NULL to help track this down:
#include <assert.h>
HDC GetDCAssert(HWND hWnd)
{
assert(hWnd);
return ::GetDC(hWnd);
}