Thread: Dialog Box Callback Functions

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    204

    Smile Dialog Box Callback Functions

    Hi,

    I posted this on another forum but haven't really understood some of the replies I received, I was wondwering if you guys could take a look at these questions for me, thanks.

    So on with the questions! Callback functions for DB's (Dialog Boxes). As I understand it there's no such thing as a DB without a callback function, otherwise you can't 'do' anything with the user input the DB is intended to capture. Now I don't want to get into the guts of a DB callback function just yet - most of it from what I can see revolves around lengthly switch/case statements each one bound to the ID designated for each box/menu/button.

    I have some more general questions about them. Looking at a DB creation function below:
    Code:
    int DialogBox(HINSTANCE hInstance, LPCSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc);
    for those of you who have forgotten or aren't familiar with what it looks like.

    I'm ok with most of the parameters. In fact I'm *fairly* ok with them all. The first parameter wants a windows handle to the module where the resource files are. IN my case it's a DLL I'm working with. Fine. THe lpTemplate part is the template for the DB defined in the .rc file. This is where all the data regarding how the box should look, and where its buttons are - is contained. Ok, this is the part where you need that MAKEINTRESOURCE() thing to use with your defines inside the resource.h file. Ok with that too. hWndParent is the parent window - ok with that. However:

    1)What is a DLGPROC variable? I've seen some strange stuff used here. In the source I've got which compiles ok I have the following:
    Code:
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLGFIRST),
    	          hWnd, reinterpret_cast<DLGPROC>(DlgProc));
    which uses the re-interpret cast thing. In my book I've seen just simply the name of a function used for this parameter with no casting:
    Code:
    nResult = DialogBox(m_hDll, "dlgChangeDevice", hWnd, DlgProc);
    The difference is, the source I have has the DlgProc function defined as:
    Code:
    LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
    , whereas in my book I've got:
    Code:
    BOOL CALLBACK DlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
    The only real difference being one has a return variable of LRESULT and the other a return variable of BOOL. What I'm really wondering is, does the return variable type of a callback function have any bearing on how that function can be passed as an argument to the DialogBox function? Also what is it we are actually passing here? By simply passing a function's name is it somehow decaying to a function pointer and thus satisfying the requirements of the DLGPROC variable? Is that what a DLGPROC variable is, a pointer/function pointer? Proper confused here - you can probably tell! ;o)

    2)One rather interesting query pops up in my book. He states that a class member function can be used as the callback function. Ok sounds great, so I can use the member callback function to fill out a load of private data in the class. Super. Only problem is it appears that the compiler is not happy unless there's a guaranteed instance of said class at run-time. In my book he basically states that without an existing declared instance of a class which contains the member callback function at compile time, the code will not compile. Is this to prevent a Dialog Box from ever being run without a callback function to use - this preventing it from being high and dry?

    Thanks for any help anyone can offer - cheers!

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by shrink_tubing View Post
    1)What is a DLGPROC variable? I've seen some strange stuff used here. In the source I've got which compiles ok I have the following:
    Code:
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLGFIRST),
    	          hWnd, reinterpret_cast<DLGPROC>(DlgProc));
    which uses the re-interpret cast thing. In my book I've seen just simply the name of a function used for this parameter with no casting:
    Code:
    nResult = DialogBox(m_hDll, "dlgChangeDevice", hWnd, DlgProc);
    The code from your book is correct. Never cast a function pointer (unless you really know what you are doing).
    If you see anyone casting a function pointer like that, yell at them.
    It should work fine without the cast. If you get a compile error, it simply means that your function signature which you're passing a pointer to is incorrect.

    Can also be written in a IMO better way:
    Code:
    nResult = DialogBox(m_hDll, "dlgChangeDevice", hWnd, &DlgProc);
    This way it's clear that it's taking the address of the function.

    The difference is, the source I have has the DlgProc function defined as:
    Code:
    LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
    , whereas in my book I've got:
    Code:
    BOOL CALLBACK DlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
    The only real difference being one has a return variable of LRESULT and the other a return variable of BOOL. What I'm really wondering is, does the return variable type of a callback function have any bearing on how that function can be passed as an argument to the DialogBox function?
    Yes, it does matter, and neither of those declarations are correct. The correct one is:
    Code:
    INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
    If you don't return the correct type, the code will not compile and will cause undefined behavior. Windows expects the function to return an INT_PTR, and if you don't, who knows what will happen?

    Also what is it we are actually passing here? By simply passing a function's name is it somehow decaying to a function pointer and thus satisfying the requirements of the DLGPROC variable?
    You are passing the address of the DlgProc function. That is, a pointer to the DlgProc function. Windows requires this to notify you of event occurring in the dialog box. It will call this function to notify you that something happened.

    Is that what a DLGPROC variable is, a pointer/function pointer? Proper confused here - you can probably tell! ;o)
    Function pointer.

    2)One rather interesting query pops up in my book. He states that a class member function can be used as the callback function. Ok sounds great, so I can use the member callback function to fill out a load of private data in the class. Super. Only problem is it appears that the compiler is not happy unless there's a guaranteed instance of said class at run-time. In my book he basically states that without an existing declared instance of a class which contains the member callback function at compile time, the code will not compile. Is this to prevent a Dialog Box from ever being run without a callback function to use - this preventing it from being high and dry?
    Not sure what you're asking, but a class member function cannot be used as a callback method to Windows (though it can be used in C++).
    The reason is that all member functions are tied to a specific instance. All functions would access member data specific to that instance. But when you pass a pointer to such a function, it is impossible to know which instance's member function you are calling.
    That is why it won't work properly if you pass it to a API function that expects a function pointer (and that is why the compiler barfs).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    204
    That's a great reply thanks for taking the time to write it it has helped me alot

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by shrink_tubing View Post
    1)What is a DLGPROC variable? I've seen some strange stuff used here. In the source I've got which compiles ok I have the following:
    The DLGPROC is a pointer to a windows message tosser function that you have to provide for each dialog box you create.

    According to the Windows API the correct definition for this is:
    Code:
    INT_PTR CALLBACK DialogProc(         
       HWND hwndDlg,            // contains the handle of the dialog box
       UINT uMsg,               // contains message from a control
       WPARAM wParam,           // message data 
       LPARAM lParam            // message data
    );
    Windows UI is all about messages. You click a button, it sends a message to it's owner window, open a drop list... another message... close it... more messages... change selection on a treeview... yet another message... everything you do either causes or handles messages.

    The normal way of handling these messages is in switch{case...} chains that can be rather complex depending what you are doing.

    When you create a dialogbox with any of the various calls available CreateDialog(), DialogBox(), etc. you have to give it the address of a message "tosser" procedure which accepts and handles the messages controls in the dialog box are going to create.

    For example Here is a complete dialog to get "Yes or No" from the user...
    When the user clicks the Yes button a WM_COMMAND message is sent to ConfTosser, with IDOK in it's WPARAM... the switch case sorts this out and will exit the dialog with a return value of 1 (TRUE). If he presses "No" the same sequence happens with IDCANCEL and a return value of 0 (FALSE)...

    confirm.c
    Code:
    // message handler
    INT_PTR CALLBACK ConfTosser(HWND Dlg, UINT Msg, WPARAM wParm, LPARAM lParm)
      { switch (Msg)
          { case WM_COMMAND :
              switch (LOWORD (wParm))
                { case IDOK :
                    EndDialog(Dlg,1);
                    break;
                  case IDCANCEL :
                    EndDialog(Dlg,0);
                    break; } } 
        return 0; }
    
    // confirmation dialog, return 1 = yes, 0 = no
    BOOL ConfirmAction(HWND Parent)
      { return DialogBox(PgmInst,L"CONFIRM",Parent,&ConfTosser); }
    confirm.rc ...
    Code:
    CONFIRM DIALOGEX DISCARDABLE 6, 18, 117, 41
    STYLE DS_SHELLFONT|WS_POPUP|DS_MODALFRAME|DS_3DLOOK|WS_CAPTION|WS_VISIBLE
    CAPTION "Please Confirm..."
    FONT 8, "MS Shell Dlg", 0, 0, 1
    {
      CONTROL "Yes", IDOK, "Button", BS_DEFPUSHBUTTON|BS_FLAT|WS_TABSTOP, 27, 25, 40, 12
      CONTROL "No", IDCANCEL, "Button", BS_FLAT|WS_TABSTOP, 71, 25, 40, 12
      CONTROL "This action cannot be undone...\r\nAre you sure\?\r\n", 4003, "Static", 0x00000000, 5, 3, 106, 18
    }

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    204
    This is a great reply!!! I've only just seen it. I understood it exactly you put it just in words I can really understand. I also got it to compile and run too

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by shrink_tubing View Post
    This is a great reply!!! I've only just seen it. I understood it exactly you put it just in words I can really understand. I also got it to compile and run too
    Glad I could help...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. validate data in a dialog box
    By COBOL2C++ in forum Windows Programming
    Replies: 4
    Last Post: 09-22-2003, 01:55 PM
  2. Dialog Box Resources
    By Mecnels in forum Windows Programming
    Replies: 2
    Last Post: 04-28-2003, 05:57 AM
  3. edit control in dialog box problems
    By Bajanine in forum Windows Programming
    Replies: 11
    Last Post: 11-11-2002, 06:55 PM
  4. Resize Dialog Box via Code :: MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 10-27-2002, 11:00 PM
  5. Context Menu & Dialog Box :: MFC
    By kuphryn in forum Windows Programming
    Replies: 4
    Last Post: 08-11-2002, 10:01 AM