|
Someone said that PostQuitMessage function does not really send a WM_QUIT message to the message queue of the calling thread. I wonder what does this function exactly do.
//Here is a simple test code
/*If PostQuitMessage function sends a WM_QUIT message to the message queue of the calling thread, GetMessage(..., hwnd, ..., ...) can't get the WM_QUIT message, the application won't leave the message loop.
But in this example:
1.compile the source ;
2.Ctrl+F5 to run it;
3.D&D to move the window;
4.press the corss to close window;
5.found that the application process disappear from the "task manager "
It seems that GetMessage(..., hwnd, ..., ...) got the WM_QUIT message.
Someone said it's because of that PostQuitMessage is called before DestroyWindow.
But I can't get the same result when debugging by F5.
Sorry for my poor English......thanks for your attention.
*/
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
BOOL bRet = FALSE;
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinSunProc;
wndcls.lpszClassName="Weixin2003";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd;
hwnd=CreateWindow("Weixin2003","CreateWindow",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while((bRet = GetMessage(&msg,hwnd,0,0)) != FALSE)
{
/*if(bRet == -1)
{
break;
}*/
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
DWORD dwCurThreadID = GetCurrentThreadId();
switch(uMsg)
{
case WM_CHAR:
break;
case WM_LBUTTONDOWN:
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"WM_PAINT",strlen("WM_PAINT"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
PostQuitMessage(0);
//DestroyWindow(hwnd);
break;
case WM_DESTROY:
//PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
|
|
|
|
|
|
Steve, thanks a lot for your answer.
More questions:
1.Where can I get more information about how the PostQuitMessage virtually sends a message?
2.Why Microsoft made such a difference between PostQuitMessage and PostThreadMessage(..., WM_QUIT, ..., ...)? How can we take advantage of this difference?
|
|
|
|
|
There is a queue status flag assigned per queue. When the thread is running it can request (GetQueueStatus) the status of its queue and observe its value (QS_PAINT, QS_QUIT, ...). This request happens when the thread calls GetMessage or PeekMessage APIs. Based in the status returned, this APIs process the appropriete message from the queue and return the control.
Now PostQuitMessage doesn't post a WM_QUIT message into the queue but only set QS_QUIT flag on queue status. Then if GetMessage [or PeekMessage] meet QS_QUIT flag, they return WM_QUIT message as if it were in the queue itself.
In contrast, PostThreadMessage posts the WM_QUIT message into the queue without settiong the QS_QUIT flag. So the GetMessage [or PeekMessage] gets the WM_QUIT message from the queue really.
Why so? Actually there are two reasons.
*) Security. It might be possible that the system will fail to reserve memory for another queue entry and thus the WM_QUIT message will not enter the queue. The point is that if the app wants to quit, it should quit surely.
*) Low level priority. WM_QUIT should be processed after all the messages from the queue are processed. This is important because it will allow the application finish its job and then [when no posted messages waiting] to exit. The idea is that when GetMessage detects QS_QUIT flag, it returns WM_QUIT [this is virtual message] only when the queue becomes empty and thus ensuring that the WM_QUIT is processed the last.
--
=====
Arman
|
|
|
|
|
Arman Z. Sahakyan wrote: Low level priority. WM_QUIT should be processed after all the messages from the queue are processed. This is important because it will allow the application finish its job and then [when no posted messages waiting] to exit. The idea is that when GetMessage detects QS_QUIT flag, it returns WM_QUIT [this is virtual message] only when the queue becomes empty and thus ensuring that the WM_QUIT is processed the last.
I have a question to that, this means that you violate event order? When someone posts a quit message, why would you want to move up later messages (in the queue) and process them before the WM_QUIT?
|
|
|
|
|
... this means that you violate event order?
Actually not me.
Ok, the rule violates, though partially. From the following code, it is guarranted that the application will exit after it's been processed the user defined message [generally, any posted [not sent] messages].
PostQuitMessage(0);
PostMessage(hwnd, WM_SOME_USER_DEFINED, 0, 0);
It is partial violation because the queue, as it is, bares no vialoation. Why? Simply because the WM_QUIT has not been there.
When someone posts a quit message, why would you want to move up later messages (in the queue) and process them before the WM_QUIT?
To keep the integrity of the messages posted. It is possible that the application may be in a job whose integrity is defined by multiple posted messages [IOW a group of messages may be doing a single job]. Rephrased, This is a guard against possible harm inside the application logic.
--
=====
Arman
|
|
|
|
|
Thanks all.
I think I have to learn something about Windows Message from the most basic level...
|
|
|
|
|
Thanks for the feedback. Good to learn something new about Window's event handling!
I can understand that paint and mouse messages have a special handling (low priority generation) as MS has a GUI centric design... however I am surprised that MS hasn't stopped the special cases here. For example asynchronous network events (FD_ACCEPT, FD_READ) are posted to the queue and recurring is enabled by calling the matching network function, but on the other hand recurring timer events have again a special handling... kinda inconsistent. WM_QUIT came really as a surprise for me, I see your point, just not sure if it really is necessary to guard application logic at this late shut-down stage.
/Moak (Event violator le Grande)
|
|
|
|
|
background: I have an application that will call functions in a Win32 DLL, I wish to have a single function in the DLL that accepts two strings(webservice name, text to be passed to the webservice) and then calls the webservice passed in passing it the text.
This is to allow for the addition of new web services without the need to recompile the DLL, just to add a config to the calling app with the name of the new web service and the text to be passed in. The Dll only needs to pass back a success or fail to the calling app. can some help with how Can someone give me some guidance on this. I am not very strong with C++ so your patiance is much appriciated.
|
|
|
|
|
rluckwell wrote: This is to allow for the addition of new web services without the need to recompile the DLL, just to add a config to the calling app with the name of the new web service and the text to be passed in.
You need more that a "name" to use a web service.
led mike
|
|
|
|
|
I wrote an application which creates a hidden registry key using the embedded null technique. The key is created fine. However, when I try to open the key with NtOpenKey, I am unable to. If I try to open the key using NtCreateKey, it opens without error. I see this abnormal behavior on Windows x64 OS only - on Windows XP 32-bit OS it runs fine.
The error NtOpenKey returns (using LsaNtStatusToWinError()) is 2 ('File/path not found').
Has anyone run into this and is there a workaround for it?
Thanks!
|
|
|
|
|
Hello!
I want my desktop to be clean (without shortcuts), but I want fast access to programs too.
So I want to make a program that behave like a Windows toolbar (with autohide):
when I point the mouse to the top-left corner of the screen I want my toolbar to appear.
I know that with Windows XP I can make a custom autohide toolbar (with what ever I want, where ever I want),
but I want some some menus entry (like: games, apps...), transparency, sounds and others.
I think this will eat some memory (with all that transparency and sounds), so here's my idea:
I will write a simple MFC program, that run in the background, without any controls and place it on top-left corner of the screen.
When the mouse (OnMouseMove) is over the window (which is a little square) it will call the actual program (ShellExecute).
This little "call program" eat around 2,700k.
* Is there a way to optimize this program to consume less memory?
* Is there another way to make what I want with less memory?
(some Windows shell programming, but this is some advanced stuff and I'm a beginner).
Here's some others questions not related with above (I hope you don't mind that I will post them here):
1. I found on the web some classes derived from the CBitmapButton and from all of them I get an error like this:
error LNK2001: unresolved external symbol "public: __thiscall MCBitmapButton::MCBitmapButton(void)" (??0MCBitmapButton@@QAE@XZ)
where MCBitmapButton is the derived class. What is the problem?
2. How can I make the background of MFC window dialog 50% transparent, without making the controls (like buttons) transparent.
If I use SetLayeredWindowAttributes: with LWA_COLORKEY the buttons are opaque, but the background is completly tranparent.
with LWA_ALPHA the buttons and the background share the same level of transparency.
3. Is there a way to make a MFC window dialog to have gradient-transparency: from opaque to completly transparent?
|
|
|
|
|
I'm new member please help me.
i need code in Visual c++ using while loop and allow one enter number between 1 and 100 and error trap if some one goes between the boundaries but stays in the loop until the correct number is inputed my email is jbusienei0235@stud.unva.edu
|
|
|
|
|
|
We don't do people's homework. What you're asking for is trivial, and working it out will teach you valuable lessons in doing your own research. Of course, if you've tried and you're genuinely stuck, we'd love to help, just post your code and explain what's not working for you.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Joseph_B wrote: i need code in Visual c++ using while loop and allow one enter number between 1 and 100 and error trap if some one goes between the boundaries but stays in the loop until the correct number is inputed
Oh No, Another request by someone to do his homework.
Regards,
Vijay.
God may not give us what we 'want', but he surely gives us what we 'need'.
|
|
|
|
|
There are two types of questions that do not get answered here: Homework and those that are too difficult.
Guess which one you are asking.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
John R. Shaw wrote: do not get answered here: Homework
I agree.
John R. Shaw wrote: too difficult.
But where we can get my answers?
|
|
|
|
|
WhiteSky wrote: But where we can get my answers?
Your own head usually (research),
I rarely ask a question and when I do, I rarely get an answer; because I do not ask it unless my research is giving none. But I continue researching to find the answer while I wait for some one to answer my question.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
|
Arris7 wrote: Could you please tell me how to create a CImageList for 4 Bitmaps...
Use the Add() method.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Arris7 wrote: All my bitmaps parameters are the same except their height
Images in an image list need to be the same size...
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Why delete your question?
|
|
|
|
|
Hi all,
I am making one pure win32 windows application by selecting “Win32 Project” template in Visual C++ project type 2005 version. This is my first win32 application but I can’t understand how can I add more controls and use it in the main form created by CreateWindow() function. Or can I get some help or place where I can get tutorial about win32 applications.
Thanks in advance,
Priyank
|
|
|
|
|
Programming Windows 5th Edition by Charles Petzold is THE book on Win32.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|