Thread: PeekMessage function

  1. #1
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715

    PeekMessage function

    Hi, I've been reading Programming Windows by Charles Petzold and I've found an interesting example of drawing random rectangles. Here's the code:

    Code:
    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    void DrawRectangle(HWND);
    static int cxClient,cyClient;
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
    {
    	static LPSTR szClsName="RandRect";
    	HWND hwnd;
    	MSG msg;
    	WNDCLASS wndclass;
    
    	ZeroMemory(&wndclass,sizeof(WNDCLASS));
    	wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    	wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    	wndclass.hInstance=hInstance;
    	wndclass.lpfnWndProc=WndProc;
    	wndclass.lpszClassName=szClsName;
    	wndclass.lpszMenuName=NULL;
    	wndclass.style=CS_HREDRAW | CS_VREDRAW;
    
    	RegisterClass(&wndclass);
    
    	hwnd=CreateWindow(szClsName,"Random Rectangles",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
    		CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    	if(!hwnd)
    	{
    		MessageBox(hwnd,"KIvla",NULL,MB_OK);
    		return 0;
    	}
    
    	ShowWindow(hwnd,nCmdShow);
    	UpdateWindow(hwnd);
    
    	while(TRUE)
    	{
    		 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
              {
                   if (msg.message == WM_QUIT)
                        break ;
                   TranslateMessage (&msg) ;
                   DispatchMessage (&msg) ;
              }
              else
                   DrawRectangle (hwnd) ;
    	}
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
    	switch(uMsg)
    	{
    	case WM_SIZE:
    		cxClient=LOWORD(lParam);
    		cyClient=HIWORD(lParam);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(WM_QUIT);
    		return 0;
    	}
    	return DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    
    void DrawRectangle(HWND hwnd)
    {
    	HBRUSH hBrush;
    	HDC hdc;
    	RECT rect;
    
    	if(cxClient==0 || cyClient==0)
    		return;
    	SetRect(&rect, rand () % cxClient, rand () % cyClient,
                         rand () % cxClient, rand () % cyClient) ;
    	hBrush=CreateSolidBrush(RGB(rand()%256,rand()%256,rand()%256));
    	hdc=GetDC(hwnd);
    	FillRect(hdc,&rect,hBrush);
    	ReleaseDC(hwnd,hdc);
    	DeleteObject(hBrush);
    
    }
    I have question regarding this program.
    1. While compiling geting warning message at line:
    Code:
    return msg.wParam;
    possible loss of data
    Why this warning and if is OK juct to cast it with (int)?
    2. I've read in the book that PeekMessage() function is used because of "There must be plenty of "dead time" in Windows—time during which all the message queues are empty and Windows is just sitting around waiting for keyboard or mouse input.". I noticed that there is a small delay between mouse click on close button (x) and actual closing window and suspect this is because of PeekMessage. i'd like to know why this is happening, is there any time quantum that is used in Windows or what?
    Thanks for help!

  2. #2
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Micko,

    1. Yes, just cast it to an int. Microsoft says to pass the message's wParam, so it should be ok. Since DOS, no one really cares about the return value anymore, anyway.

    2. This program is Petzold's attempt at, sort of, hacking out an old style DOS program, that continually just does stuff, as fast as it can, to the screen. This is NOT an example of good programming. This is not how Windows programs work. Also, PeekMessage should, basically, never be used. If you find yourself using it, think about creating a new thread. Until you get involved into multi-threading, forget the function even exists. That's the best advice I can give you at the moment.

    As far as the delay between clicking the close button, and seeing the application close, I noticed this, as well, and it bothered me just as much, because it just did not make sense. Windows sometimes does strange things, because different messages have different priorities. For example, WM_PAINT is low priority, so this is why when some application is taking up all of the CPU, the rest of the screen is slow to refresh. Even in your own application, if you allow a scrollbar to scroll data in your window, you may find that the data isn't being refreshed, because Windows is handling all of the scroll messages, and not WM_PAINT (the solution is to force a painting with UpdateWindow). So, I think the odd behaviour has something to do with all of this. It hasn't bothered me since, because I know that the way this application runs is NOT the proper way to create a windows program, so look at it as an improperly programmed application. Don't attempt to recreate DOS graphics with Windows in this manner.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Since DOS, no one really cares about the return value anymore, anyway.
    Plenty of folks use and care about process return codes. Just not from a process that generates random rectangles

    >> 2. ....
    Good advice.

    gg

  4. #4
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    I don't know that I agree PeekMessage should never be used. GetMessage pauses until something comes in. You may need to know information about your message queue immediately without waiting for a message. Could you back up this "should never be used" statement further?
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  5. #5
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    for example, if you have a window with an absurd number of child windows or an excessive amount of drawing to be done, you may want to use PeekMessage skip to the last WM_SIZE message in the queue so that you don't process all of them.

    also, games tend to use PeekMessage so that they don't have to animate by using a SetTimer.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  6. #6
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Ok, I jumped the gun by saying that no one uses return codes. I should say that most people do not use them, as most normal applications do not require their use. I still pass back different values for different exits in my programs, but I doubt that I will ever use them.

    PeekMessage can be used in certain situations, but most people throw them in when they should use another worker thread. This is wrong.

    Keep in mind that I am answering the questions of someone who is a beginner to Windows, who is only on Chapter 5 of Petzold's book.

  7. #7
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Quote Originally Posted by FillYourBrain
    also, games tend to use PeekMessage so that they don't have to animate by using a SetTimer.
    Yes, games are quite different from other Windows programs. This is sort of the point I was touching upon earlier. The program Petzold wrote is similar to an old graphics DOS program, and games are similar to this, as well. This is NOT a good thing to get into when someone is trying to learn Windows programming...

  8. #8
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    that's cool. I just saw "never" and got worried. Every time I see a criticism of a method that I have used for years I wonder if there is a better way. Thanks for clearing it up though chief.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  9. #9
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Oh, ok. No problem.

    It's hard to answer questions like the above because it really gets into deeper issues that shouldn't concern a beginner. I really believe that rectangle program should have been left out of the book. I understand why it is there - there's a ton of us old DOS graphics people wondering how we can do this stuff in Windows (which is so EASY in DOS), and he shows us a quick way.

    The proper answer (I think) is that you CAN'T do the DOS stuff in Windows without complicating things. All answers (GDI or DirectX) lie on top of Windows, so you gotta learn Windows by itself first.

  10. #10
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Yeah, yeah guys, as JasonD said I'm still on chapter 5 and all this discussion about PeekMesssage is pretty much confusing. I don't know will I ever be able to think about things you're talking now.
    I'm very satisfied to JasonD's answer and hope I'll be getting help from him and from you in future. Thank you all.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  4. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM