First call is WM_PAINT or WM_CREATE ?

This is a discussion on First call is WM_PAINT or WM_CREATE ? within the Windows Programming forums, part of the Platform Specific Boards category; ! NOT; true if its argument is false 1 fFlipFlop is declared FALSE 2 then its changed to TRUE 3 ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749

    First call is WM_PAINT or WM_CREATE ?

    ! NOT; true if its argument is false

    1 fFlipFlop is declared FALSE
    2 then its changed to TRUE
    3 so it should call the first argument (black) but it calls FALSE (white) for the first time.

    Is it because Windows first calls WM_PAINT and then WM_CREATE ?
    Code:
    /*-----------------------------------------
       BEEPER1.C  -- Timer Demo Program No. 1
                     (c) Charles Petzold, 1998
    
      -----------------------------------------*/
    
    #include <windows.h>
    
    #define ID_TIMER    1
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT ("Beeper1") ;
         HWND         hwnd ;
         MSG          msg ;
         WNDCLASS     wndclass ;
         
         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
         wndclass.lpfnWndProc   = WndProc ;
         wndclass.cbClsExtra    = 0 ;
         wndclass.cbWndExtra    = 0 ;
         wndclass.hInstance     = hInstance ;
         wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
         wndclass.lpszMenuName  = NULL ;
         wndclass.lpszClassName = szAppName ;
         
         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }
         
         hwnd = CreateWindow (szAppName, TEXT ("Beeper1 Timer Demo"),
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
              
         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ;
              
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
         return msg.wParam ;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         static BOOL fFlipFlop = FALSE ; //declared FALSE
         HBRUSH      hBrush ;
         HDC         hdc ;
         PAINTSTRUCT ps ;
         RECT        rc ;
         
         switch (message)
         {
         case WM_CREATE:
              SetTimer (hwnd, ID_TIMER, 1000, NULL) ;
              return 0 ;
    
         case WM_TIMER :
              MessageBeep (-1) ;  
              fFlipFlop = !fFlipFlop ;    // changed to TRUE
              InvalidateRect (hwnd, NULL, FALSE) ;
              return 0 ;
              
         case WM_PAINT :
              hdc = BeginPaint (hwnd, &ps) ;
              
              GetClientRect (hwnd, &rc) ;
    
              hBrush = CreateSolidBrush (fFlipFlop ? RGB(0,0,0) : RGB(255,255,255)) ;
              // so here its being true, it should call RGB(0,0,0) (black) but it calls (white)
    
              FillRect (hdc, &rc, hBrush) ;
    
              EndPaint (hwnd, &ps) ;
              DeleteObject (hBrush) ;
              return 0 ;
              
         case WM_DESTROY :
              KillTimer (hwnd, ID_TIMER) ;
              PostQuitMessage (0) ;
              return 0 ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    Compiler MSVC++ 2010 with Code::Blocks.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    When I run it, I get white before the first beep happens -- so for the first second, until WM_TIMER happens, fFlipFlop is still false. Is this not what you expected?

  3. #3
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    I get white too so it means that it calls WM_PAINT first and then WM_CREATE.

    I thought Windows calls WM_CREATE first as the CreateWindow() function in WinMain causes WM_CREATE message.

    PS i dont get bip cause i dont know how to make it work in VC++ 2008.
    Compiler MSVC++ 2010 with Code::Blocks.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    I think you're still missing the point: neither WM_PAINT nor WM_CREATE changes the value of your boolean -- only WM_TIMER does. Regardless of which one happens first, they're both going to get called before WM_TIMER (since that takes an entire second).

    PS: To make the beep work in Visual C++, you ... don't do anything. (I mean, I didn't do anything, and there it is.) It is in gdi32.lib, but if it wasn't linking with the library you'd get linking errors. Maybe take your speakers off mute?

  5. #5
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    I know that it is changed in WM_TIMER but WM_TIMER is called by SetTimer (hwnd, ID_TIMER, 1000, NULL) which is in WM_CREATE. So it must be called after WM_PAINT.

    WM_PAINT --> WM_CREATE --> WM_TIMER

    PS ok i found reason. I chose "no sound" in Control Panel/ Sounds and Audio Devices.
    Thanks for making me think of it.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But the timer is set to start 1000ms after the creation of it, so flipflop isn't being changed until 1 second after WM_PAINT being called.

    Perhaps you would be better off opening a file and then logging the relevant stuff. Something along these lines:
    Code:
    // At beginning of file somewhere
    #include <time.h> 
    #include <stdio.h>
    FILE *logfile;  // Make this a global variable. 
    ...
    // In winMain:
         WNDCLASS     wndclass ;
    
        logfile = fopen("c:\\logging.txt", "w");
         
         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    ...
    // at end of winMain:
        fclose(logfile);
    // Then add something like this in relevant places:
         fprintf(logfile, "%6.2f Recieved VM_xxxx\n", clock() / (double)CLOCKS_PER_SEC);
    The time will be printed in seconds (with hundreds of a second precision), which should make it perfectly clear what is going on and in which order. I find it very unlikely that a WM_PAINT would precede the WM_CREATE, since before the window is create, there is nothing sensible that can be painted and it serves no purpose to do so - it's like filling the forecourt of a petrol station with petrol, because you didn't have a car, but you thought it was a good idea to fill up anyways... ;-)

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    Thanks Mats, it makes perfect sense.

    I'll try to create this logfile, it indeed will help me to see it better too.
    Compiler MSVC++ 2010 with Code::Blocks.

  8. #8
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,856
    Test using a MessageBox or break point in the event handlers .

    Part of creating a window is painting it to the screen (ie generating a WM_PAINT)

    So

    WM_CREATE (or WM_INITDIALOG)
    WM_PAINT (and WM_SIZE, WM_NCPAINT, WM_ERASEBKGND etc)
    ... appox 1 sec later (and lots of msgs)
    WM_TIMER
    WM_PAINT

    EDIT: WM_TIMER are the lowest priority msg in the apps queue (of default 8 msgs). They will be ignored in favour of other msgs (which is why timers have a min accuracy of +/- 50ms).
    Last edited by novacain; 09-02-2008 at 03:40 AM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. minix system call pls help for project
    By porvas in forum Linux Programming
    Replies: 2
    Last Post: 06-14-2009, 02:40 AM
  2. Error C2664 - Trying to call an external Dll
    By jamez05 in forum C++ Programming
    Replies: 3
    Last Post: 08-08-2006, 06:07 AM
  3. Class won't call
    By Aalmaron in forum C++ Programming
    Replies: 3
    Last Post: 04-13-2006, 04:57 PM
  4. Iterative Tree Traversal using a stack
    By BigDaddyDrew in forum C++ Programming
    Replies: 7
    Last Post: 03-10-2003, 04:44 PM
  5. call by reference and a call by value
    By IceCold in forum C Programming
    Replies: 4
    Last Post: 09-08-2001, 05:06 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21