Window not receiving all its messages
-
Hello - I have a CWnd derived class which I am creating in a MFC SDI app. I create it hidden, and its job is to handle some messages generated by the back end of my app. If I fire up the app and don't touch it, everything runs fine, and all messages are received by this class. However, as soon as I start doing anything in the GUI (i.e. more messages are generated), then some of messages generated by my back end are posted but not received. Here is how I create the class:
m_pMyWnd->CreateEx(0, _T("STATIC"), _T(""), 0, CRect(0,0, 100, 100), NULL, 0);
and another chunk of code does a postmessage to this window, but it doesnt receive the message, even though PostMessage() succeeds. Is there a different way I should create this window to ensure that my messages will make it through? Thanks! Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer -
Hello - I have a CWnd derived class which I am creating in a MFC SDI app. I create it hidden, and its job is to handle some messages generated by the back end of my app. If I fire up the app and don't touch it, everything runs fine, and all messages are received by this class. However, as soon as I start doing anything in the GUI (i.e. more messages are generated), then some of messages generated by my back end are posted but not received. Here is how I create the class:
m_pMyWnd->CreateEx(0, _T("STATIC"), _T(""), 0, CRect(0,0, 100, 100), NULL, 0);
and another chunk of code does a postmessage to this window, but it doesnt receive the message, even though PostMessage() succeeds. Is there a different way I should create this window to ensure that my messages will make it through? Thanks! Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer -
It sounds like you really want a multi-threaded application. Cathy Life's uncertain, have dessert first!
Care to explain? This app is quite multi-threaded already, and the section posting the messages is in its own thread... Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer
-
Hello - I have a CWnd derived class which I am creating in a MFC SDI app. I create it hidden, and its job is to handle some messages generated by the back end of my app. If I fire up the app and don't touch it, everything runs fine, and all messages are received by this class. However, as soon as I start doing anything in the GUI (i.e. more messages are generated), then some of messages generated by my back end are posted but not received. Here is how I create the class:
m_pMyWnd->CreateEx(0, _T("STATIC"), _T(""), 0, CRect(0,0, 100, 100), NULL, 0);
and another chunk of code does a postmessage to this window, but it doesnt receive the message, even though PostMessage() succeeds. Is there a different way I should create this window to ensure that my messages will make it through? Thanks! Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - HomerFirst, messages sent though PostMessage are not guaranteed to make it through. In practice, however, only in very extreme circumstances (slow machine, fast input) do they not get through. Also note that PostMessage() will only fail if the window handle is incorrect or some other critical problem. Whether or not the message will be received has no bearing on the success of the call. (See SDK documentation.) I question the use of a hidden window. I suspect the messages are being reflected somewhere. Why not just use the main window and use USER messages?
-
First, messages sent though PostMessage are not guaranteed to make it through. In practice, however, only in very extreme circumstances (slow machine, fast input) do they not get through. Also note that PostMessage() will only fail if the window handle is incorrect or some other critical problem. Whether or not the message will be received has no bearing on the success of the call. (See SDK documentation.) I question the use of a hidden window. I suspect the messages are being reflected somewhere. Why not just use the main window and use USER messages?
Joe, Thanks for the info. I suppose I should've mentioned that the messages I'm referring to come from the WaveOut API, so they cannot be user messages. In particular, I'm handling the MM_WOM_DONE message. (See waveOutProc in the SDK doc, if you are interested.) The reason I chose to not use the main window was for code maintainability. I am able to keep all of the waveOut code in one or two classes that I can move around as needed, this way. I'm not sure that handling it in the main window will do it either, see below... You are correct about the messages being reflected, I think. I've noticed that the MM_WOM_DONE message comes through my main message loop and is then dispatched to this hidden class, most of them anyway. (Hence my problem - I'm not seeing all of them here, either.) Based on the way I'm creating the window (see the code in the prior post, parentwnd = NULL), I figured that the messages would come straight to this window,but I guess not. So assuming that this is the nonUSER message I'm working with, is there a way to get it to post to the queue in my hidden window directly, instead of routing through the main message loop? Thanks! Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer
-
Care to explain? This app is quite multi-threaded already, and the section posting the messages is in its own thread... Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer
I thought maybe that was the problem, that you were doing it in the same thread. I had to do something like this to get my messages through:
while (theApp.m_pMainWnd && PeekMessage(&msg, theApp.m_pMainWnd->m_hWnd, 0, 0, PM_NOREMOVE)) { if (!theApp.PumpMessage()) { PostQuitMessage(0); return TRUE; } }
Cathy Life's uncertain, have dessert first! -
Joe, Thanks for the info. I suppose I should've mentioned that the messages I'm referring to come from the WaveOut API, so they cannot be user messages. In particular, I'm handling the MM_WOM_DONE message. (See waveOutProc in the SDK doc, if you are interested.) The reason I chose to not use the main window was for code maintainability. I am able to keep all of the waveOut code in one or two classes that I can move around as needed, this way. I'm not sure that handling it in the main window will do it either, see below... You are correct about the messages being reflected, I think. I've noticed that the MM_WOM_DONE message comes through my main message loop and is then dispatched to this hidden class, most of them anyway. (Hence my problem - I'm not seeing all of them here, either.) Based on the way I'm creating the window (see the code in the prior post, parentwnd = NULL), I figured that the messages would come straight to this window,but I guess not. So assuming that this is the nonUSER message I'm working with, is there a way to get it to post to the queue in my hidden window directly, instead of routing through the main message loop? Thanks! Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer
I have a wave in/out class that doesn't have a problem. First, due to where the code is used, I don't use MFC when I create the callback window. I also create it with CreateWindowEx with WS_EX_NOPARENTNOTIFY. Here's a snippet from my code:
LRESULT CALLBACK CBWaveCallback(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
CBWave *pWave = (CBWave *)::GetWindowLong(hwnd, 0);
if (pWave)
{
switch(msg)
{
case MM_WOM_DONE:
pWave->OnDataOut((HWAVEOUT) wParam, (WAVEHDR *) lParam);
return 0L;case MM\_WIM\_DATA: pWave->OnDataIn((HWAVEIN) wParam, (WAVEHDR \*) lParam); return 0L; } } return (DefWindowProc(hwnd, msg, wParam, lParam));
}
static TCHAR nameBase[] = _T("CBWaveCallback");
HWND CBCreateWaveWindow(
HINSTANCE hInst,
HWND hWndParent,
LONG waveClassThisPtr)
{
TCHAR className[32];
_tcscpy(className, nameBase);
_tcscat(className, _T("Class"));WNDCLASS wndClass; if (!::GetClassInfo(hInst, className, &wndClass)) { wndClass.style = 0; wndClass.lpfnWndProc = CBWaveCallback; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 4; wndClass.hInstance = hInst; wndClass.hIcon = NULL; wndClass.hCursor = NULL; wndClass.hbrBackground = NULL; wndClass.lpszMenuName = NULL; wndClass.lpszClassName = className; if (!::RegisterClass(&wndClass)) return (HWND) 0; } TCHAR windowName\[32\]; \_tcscpy(windowName, nameBase); \_tcscat(windowName, \_T("Window")); HWND hWnd = ::CreateWindowEx(WS\_EX\_NOPARENTNOTIFY, className, windowName, hWndParent ? WS\_CHILD : WS\_POPUP, 0, 0, 0, 0, hWndParent, NULL, hInst, NULL); ::SetWindowLong(hWnd, 0, waveClassThisPtr); return hWnd;
}
-
I have a wave in/out class that doesn't have a problem. First, due to where the code is used, I don't use MFC when I create the callback window. I also create it with CreateWindowEx with WS_EX_NOPARENTNOTIFY. Here's a snippet from my code:
LRESULT CALLBACK CBWaveCallback(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
CBWave *pWave = (CBWave *)::GetWindowLong(hwnd, 0);
if (pWave)
{
switch(msg)
{
case MM_WOM_DONE:
pWave->OnDataOut((HWAVEOUT) wParam, (WAVEHDR *) lParam);
return 0L;case MM\_WIM\_DATA: pWave->OnDataIn((HWAVEIN) wParam, (WAVEHDR \*) lParam); return 0L; } } return (DefWindowProc(hwnd, msg, wParam, lParam));
}
static TCHAR nameBase[] = _T("CBWaveCallback");
HWND CBCreateWaveWindow(
HINSTANCE hInst,
HWND hWndParent,
LONG waveClassThisPtr)
{
TCHAR className[32];
_tcscpy(className, nameBase);
_tcscat(className, _T("Class"));WNDCLASS wndClass; if (!::GetClassInfo(hInst, className, &wndClass)) { wndClass.style = 0; wndClass.lpfnWndProc = CBWaveCallback; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 4; wndClass.hInstance = hInst; wndClass.hIcon = NULL; wndClass.hCursor = NULL; wndClass.hbrBackground = NULL; wndClass.lpszMenuName = NULL; wndClass.lpszClassName = className; if (!::RegisterClass(&wndClass)) return (HWND) 0; } TCHAR windowName\[32\]; \_tcscpy(windowName, nameBase); \_tcscat(windowName, \_T("Window")); HWND hWnd = ::CreateWindowEx(WS\_EX\_NOPARENTNOTIFY, className, windowName, hWndParent ? WS\_CHILD : WS\_POPUP, 0, 0, 0, 0, hWndParent, NULL, hInst, NULL); ::SetWindowLong(hWnd, 0, waveClassThisPtr); return hWnd;
}
Thanks for the help! I'll give that a try. Marcus Spitzmiller "Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer