Thread: The return value from WndProc

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    596

    The return value from WndProc

    What should WndProc return if a message is not procesed? Many should return zero if
    processed, but isn't zero is also normally returned if no message is processed?

    How does the caller to WndProc know if message was processed if the return value is
    zero either way?

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Mostly you return 0 to signal "I have handled this message" and 1 to indicate that the default windows process should handle the message (further).

    If you are not processing a message, you need to pass it along by calling DefWindowProc() which will take the appropriate action, which is most often to simply delete the message from the queue, but not always.

    However; you need to check the documentation for each message to know what the return value means... Sometimes it's nothing, sometimes it's a constant, a brush or a struct.

    Here's a snippet of code...
    Keep in mind this is a very simple MsgProc....
    Code:
    // Message Loop
    LRESULT CALLBACK MsgProc(HWND wnd,UINT msg,WPARAM wparm,LPARAM lparm)
      { switch (msg)
          { // main window buttons
            case WM_COMMAND :
              switch(LOWORD(wparm))
                { case 100 :    // pick a start path
                    SelectFolder();
                    return 0;
                  case 110 :    // toggle recursion
                    SetRecurse();
                    return 0;
                  case 120 :    // kill a scan
                    StopScan();
                    return 0;
                  case 130 :    // launch a scan
                    DoScan();
                    return 0;
                  case 140 :    // write report file
                    SaveReport();
                    return 0;
                  case 150 :     // show the help file 
                    ShowHelp();
                    return 0;
                  case 160 :    // give up and go home
                    SendMessage(WHandle[0],WM_CLOSE,0,0);
                    return 0; 
                  case 170 :    // Launch from pulldown
                    HandlePulldown( HIWORD(wparm) );
                    return 0;
                  default :
                    return DefWindowProc(wnd,msg,wparm,lparm); }
            // User messages           
            case UM_FINISH :
              CompleteTest();
              return 0;
            case UM_ADDERR :
              AddError(wparm,(PCHAR)lparm);
              return 0;
            case WM_TIMER :
            case UM_UPDATE :
              UpdateStatusBar(wparm);
              return 0;
            // misc. messages 
            case WM_CTLCOLORSTATIC :
               return SetColors((HDC)wparm,(HWND)lparm);
            case WM_SIZE :
              ResizeWindow();
              return 0; 
            case WM_GETMINMAXINFO :
              SetWindowMin((PMINMAXINFO) lparm); 
              return 0;
            case WM_CLOSE :
              StopScan();
              SaveSettings(); 
              DestroyWindow(WHandle[0]);
              return 0;
            case WM_DESTROY :
              PostQuitMessage(0);
              return 0; 
            default :
              return DefWindowProc(wnd,msg,wparm,lparm); } }
    Last edited by CommonTater; 09-10-2011 at 09:13 PM.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Thanks.

    I missed that somehow, the DefWindowProc.

    Big problem with example programs in tutorials.

    I had a combination of a default case with DefWindowProc and a return 0; at the end.
    Mixed together two different examples.
    Last edited by megafiddle; 09-10-2011 at 09:31 PM.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    So multiple returns are ok? Rather than setting a return value in each case and then
    using one return statement at end?

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by megafiddle View Post
    So multiple returns are ok? Rather than setting a return value in each case and then
    using one return statement at end?
    Yes, multiple returns are common and sometimes required as the return type varies (ie WM_COLORSTATIC requires a handle to a brush IIRC).

    [picky]
    No professional software house I have worked at would allow the code in Common tater's example.

    I would not accept it from any of my team (but we create mission critical asset protection software to ISO standards).

    Clearly the 'return' negates the need for 'break' but it is not something I would show to, let alone teach, any novice coder. I think that a novice should be taught 'perfect' syntax, not short-cuts (even if they are functionally correct).

    I also do not like the use of ID numbers instead of names (because the IDE sets the names not the coder and names are more descriptive than numbers). Also 2 windows can have the same control name/functionality, but with different ID numbers generated byt the IDE (causing confusion and cut and paste errors).

    But these are my personal coding standards, not hard coding rules.
    [/picky]
    Last edited by novacain; 09-10-2011 at 10:46 PM.
    "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

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    That's interesting about how standards can differ.
    I guess there's rules and then there's rules.

    I think I see why the sample code I was looking at simply put a "return 0;" at the end.
    All the messages just happened to return zero.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by megafiddle View Post
    That's interesting about how standards can differ.
    I guess there's rules and then there's rules.
    The only hard and fast rules here are the syntax rules of the language. While I agree with novacain about having standards and team based methodology... I do things as I do them because 1) I find it far easier to debug my code when it's all nicely compartmentalized in separate functions and 2) using breaks is not always going to take you completely out of the switch... My way guarantees the function exits. For the use of numbers instead of constants... I don't use any pansy arsed gui designers, I code the whole thing myself, so I have full control over what does what... thus, not an issue.

    I think I see why the sample code I was looking at simply put a "return 0;" at the end.
    All the messages just happened to return zero.
    Also don't forget that dialogs use a different switch() setup than top level windows... Dialogs do not call DefWindowProc()...

  8. #8
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by CommonTater View Post
    I do things as I do them because 1) I find it far easier to debug my code when it's all nicely compartmentalized in separate functions
    Agree on the functions. Callbacks are complicated enough with out msg processing code in them.

    Quote Originally Posted by CommonTater View Post
    and 2) using breaks is not always going to take you completely out of the switch... My way guarantees the function exits.
    I was commenting on the missing 'break's (even though the return makes them redundant) the lack of breaks makes the code syntactically incorrect.

    I would just add a 'break' under each of your returns (when using the code as an example).

    Quote Originally Posted by CommonTater View Post
    For the use of numbers instead of constants... I don't use any pansy arsed gui designers, I code the whole thing myself, so I have full control over what does what... thus, not an issue.
    Unless your target audience uses a GUI / resource editor and they have an issue....
    "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

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by novacain View Post
    Agree on the functions. Callbacks are complicated enough with out msg processing code in them.
    Exactly...

    I was commenting on the missing 'break's (even though the return makes them redundant) the lack of breaks makes the code syntactically incorrect.
    Not syntactically incorrect... just not how most people think about switch statements... Using return instead of break gives you a very fast and direct exit from the callback whereas breaks require code to find the end of each switch and path uplevel until the function exits at it's natural end... I know they teach that a function should have only one exit point (part of the reason C still has that stupid goto keyword) but if you want a windows message proc that runs blazing fast, that rule goes out the window....

    I would just add a 'break' under each of your returns (when using the code as an example).
    And when I do that I get a gazillion warnings about unreachable code.

    Unless your target audience uses a GUI / resource editor and they have an issue....
    Trust me... except for small snippets I post here, nobody else on this planet will ever see the complete source code for any of my projects... ever.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CommonTater
    Trust me... except for small snippets I post here, nobody else on this planet will ever see the complete source code for any of my projects... ever.
    Next year, you might be a different person from who you are this year
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by laserlight View Post
    Next year, you might be a different person from who you are this year
    And I promise you... THAT person isn't going to share source code either!

    I've had people I work for demand my source code:
    "What if you get hit by a bus and we find a bug in your program?"
    "Stop using it."

    I've been through that debacle before... Back in my Pascal days I wrote an inter-office messaging program (lan based, childsplay by modern standards) that the customer then used in a way I hadn't expected. Part of the contract was that I was to provide source code, which I obediently did... They started monkeying with it and eventually screwed it up to the point of failure... and then came after me, nearly 3 years later, for providing faulty software... I ended up providing them a refund, they still had the programs, and I've never shared source code again.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CommonTater
    And I promise you... THAT person isn't going to share source code either!
    You don't share source code with your future self? Time to make some backups
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by CommonTater View Post
    Not syntactically incorrect... just not how most people think about switch statements....
    Technically a 'switch' consists of 'case break' pairs and 'return' can not be subsituted for the 'break'.

    If a novice forgets one of the returns their code will not act as aexpected and they will not know why.

    To be super picky....you have hard coded your returns. So your msg handlers can not decide if the msg has been processed.

    I use some thing more like;
    Code:
    case WM_SOMEMSG:
         return SomeMsgHandler(params); //allow the handler decide if the msg requires further processing by setting the return value.
    break;
    case .....
    "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

  14. #14
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by novacain View Post
    Technically a 'switch' consists of 'case break' pairs and 'return' can not be subsituted for the 'break'.

    If a novice forgets one of the returns their code will not act as aexpected and they will not know why.
    Technically a switch consists of a number of cases... what else goes on is not specified. For example this is perfectly legal...
    Code:
    int somfunc(int x)
     {
        switch (x)
         { case 12 :
              x += 1;
           case 13 :
             x = 11; 
             break;
           case 14 :
           default :
              return 0; }
      return 42; }
    Don't mistake long time habits for standards... C is a LOT more flexible than that.

    To be super picky....you have hard coded your returns. So your msg handlers can not decide if the msg has been processed.
    I use some thing more like;
    Code:
    case WM_SOMEMSG:
         return SomeMsgHandler(params); //allow the handler decide if the msg requires further processing by setting the return value.
    break;
    case .....
    I do that too... it's just that in the example I posted, most of the handlers didn't need to return anything and THAT is a lot easier to see in the switch itself ... Note the WM_COLORSTATIC message...

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by laserlight View Post
    You don't share source code with your future self? Time to make some backups
    Technically... it would be that I'm not sharing source code with my PAST self...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WNDPROC conversion
    By kidburla in forum Windows Programming
    Replies: 5
    Last Post: 09-18-2006, 01:06 PM
  2. WndProc Hook - Help
    By Mastadex in forum Windows Programming
    Replies: 0
    Last Post: 05-15-2006, 03:13 PM
  3. my wndProc is out of scope
    By Raison in forum Windows Programming
    Replies: 35
    Last Post: 06-25-2004, 07:23 AM
  4. Wndproc
    By Unregistered in forum Windows Programming
    Replies: 6
    Last Post: 08-12-2002, 04:33 PM
  5. Getting WndProc
    By DutchStud in forum Windows Programming
    Replies: 3
    Last Post: 11-02-2001, 07:17 AM