Thread: Display Dialog Box Then Execute

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    193

    Display Dialog Box Then Execute

    I want to know how to get a dialog box to display itself before I execute a function. This is what I have for the dialog box procedure:

    Code:
    LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam) {
         switch(Message) {
              case WM_INITDIALOG:
                   hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE, 5,35,76,20, hWndDlg, 0, hInst, NULL);
                   SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100));
                   SendMessage(hProgress, PBM_SETSTEP, (WPARAM)5, 0);
                   return true;
              case WM_COMMAND:
                   myFunction(hWndDlg); // This calls a function which updates the progress bar
                   EndDialog(hWndDlg,0);
                   return true;
              default:
                   return DefWindowProc(hWndDlg, Message, wParam, lParam);
         }
    }
    The problem with that code is the dialog box isnt displayed UNTIL AFTER myFunction has completed its execution (and then the next line of code closes the dialog box, so you actually dont get to see the dialog box at all). I just want a simple progress bar that I can set the current status in myFunction (which this works properly if I could only get it to display the dialog box).

    Any help is greatly appreciated. THANKS!!!

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    This should have been posted on the windows board (maybe a mod will move it). If you don't actually see the dialog box, how do you know that it gets displayed? Is it created with the WS_VISIBLE style?
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    If I comment out the EndDialog() line, the dialog box is displayed after myFunction() executes.

    I'm sorry for putting this in the wrong forum...

  4. #4
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I don't think there's anything in the code you posted that should cause that to happen. I see two errors: your dialog procedure should return FALSE as default, and the return type should be INT_PTR. But I don't think either of those should cause the behavior you've described.

    Could you post the code that creates the dialog and the dialog template resource?
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  5. #5
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    Here is the code I use to create the dialog (and I call this function from another dialog box):

    Code:
    DialogBox(hInst, "PROGRESSDLG", GetParent(hWndDlg), reinterpret_cast<DLGPROC>(DlgProc));
    // GetParent(...) gets the main window...I want the parent dialog to be the main window for this dialog and not a dialog to be the parent
    Here is my updated procedure code. There is no default parameter this time because if I put the DefWinowProc(...) function there, the WM_LBUTTONDOWN message never gets called (which is needed if someone wants to reposition the progress bar)

    Code:
    LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam) {
         switch(Message) {
              case WM_INITDIALOG:
                   hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE, 5,35,76,20, hWndDlg, 0, hInst, NULL);
                   SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100));
                   SendMessage(hProgress, PBM_SETSTEP, (WPARAM)5, 0);
                   SendMessage(hWndDlg, WM_COMMAND, 0, 0);
                   break;
              case WM_COMMAND:
                   myFunction(hWndDlg); // This calls a function which updates the progress bar
                   SendMessage(hWndDlg, WM_DESTROY, 0, 0);
                   break;
              case WM_DESTROY:
                   EndDialog(hWndDlg, 0);
                   break;
              case WM_LBUTTONDOWN:
                   SendMessage(hWndDlg, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
                   break;
         }
         return 0;
    }
    And lastly, here is my resource code...

    Code:
    PROGRESSDLG DIALOGEX 75,82,50,41
    STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_BORDER
    FONT 9, "Times New Roman"
    BEGIN
         LTEXT             "Please wait...",IDC_STATIC,5,5,40,12
    END

  6. #6
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Quote Originally Posted by Win32 API
    (dialog boxes) must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure.
    What are you processing the WM_COMMAND message in return to? There are any number of things and controls (buttons, menu items, etc) that _all_ spawn WM_COMMAND messages, usually there is some filtering done to determine who sent that message. You're responding to all of them the same - probably bad practice. What are you trying to accomplish, in English?

    Edit in response to your code:
    1) You're not returning the correct values from your callback. Return nonzero if you process the message, zero if you don't. (Except on WM_INITDIALOG, look it up.)
    2) You shouldn't need the cast in DialogBox();.
    3) Again, the WM_COMMAND parts are mysterious. The way your code is setup, you will never see the box, because:
    DialogBox() sends a WM_INITDIALOG to your box.
    Your box does a SendMessage() to itself with WM_COMMAND.
    Your box (processing WM_COMMAND) sends itself a WM_DESTROY.
    WM_DESTROY calls EndDialog(), which says:
    If your application calls the function while WM_INITDIALOG is being processed, the dialog box is destroyed before it is shown and before the input focus is set.
    And your dialog is gone. (After WM_INITDIALOG is finished then will DialogBox() display your dialog. Your WM_INITDIALOG essentially kills the dialog before it is shown.)
    Last edited by Cactus_Hugger; 05-08-2006 at 10:24 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  7. #7
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    1.) Could you tell me what to return? I believe that you and JaWiB disagree on the type thats returned. Bascially, JaWiB said INT and your saying BOOL. So, bascially, which one do I return, INT or BOOL?

    3.) I understand what you are saying, but my question basically is, how can the WM_COMMAND message be sent automatically after the dialog box is created. If I move my WM_COMMAND send message from WM_INITDIALOG to WM_KEYDOWN, everything works as I want it to, but it doesnt start myFunction(...) until I hit Enter (which is KEYDOWN). My basic question is how can I send a message AUTOMATICALLY after the dialog box is created.

    EDIT:

    For question 1.), how big of a difference does it make by returning different values? For me, everything works no matter what I return. Maybe I'm missing something, but I dont see the significance in what is returned.

    EDIT EDIT:

    2.) When I removed the cast, I got quite a few compiler errors. Invalid conversions between LRESULT and BOOL. I think the cast is necessary.
    Last edited by stickman; 05-09-2006 at 03:13 PM.

  8. #8
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I said the return type should be INT_PTR, but if you don't handle any messages (default case) you should return FALSE.

    If you change the prototype to:
    Code:
    INT_PTR CALLBACK DlgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
    You shouldn't need the cast.

    There might be a message sent to the dialog immediately after it is displayed, but I'm not sure (possibly WM_ENTERIDLE would work). What you could do is create the dialog with the CreateDialog function, then immediately after that send a custom message to the dialog, eg:
    Code:
    #define UM_MYMESSAGE WM_USER + 10
    
    HWND hDialog = CreateDialog(/*...*/);
    if (hDialog)
      SendMessage(hDialog,UM_MYMESSAGE,0,0);
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  9. #9
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    I changed the prototype to INT_PTR and removed the cast and it worked. Thanks for your help.

    Ok, for the default case, return false, and for all the other cases, return true? Is that correct or should it be 0 (zero) or what should be returned, literally.

    I also just realized that myFunction(...) doesnt need to be in the WM_COMMAND case because I'm sending a message (WM_COMMAND message), so instead of sending a message, I can just put myFunction(...) in there instead....This doesnt really help me, but it somewhat allows me to be more flexible with my code.

    WM_ENTERIDLE didnt work. I'm sure it would work as soon as the dialog box entered the idle state, but I dont want to wait that long.

    Using CreateDialog, I was able to get it to work properly...Just only one problem...It doesnt display my LTEXT. I tried creating a STATIC class window, but that didnt work either. Any suggestions. EDIT: Maybe it doesnt work entirely properly. Only the WM_INITDIALOG message is sent. It never sends the WM_LBUTTONDOWN message (which is needed if someone wants to move the progress bar around).

    Thanks for your help.
    Last edited by stickman; 05-09-2006 at 04:12 PM.

  10. #10
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Let's see your updated code.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  11. #11
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    My resource code hasnt changed...I think theres a problem with DIALOGEX, it should be DIALOG. Could that be causing any of my problems? (I would prefer to have DIALOGEX because it makes the dialog box look much nicer)

    Here is one way that I'm calling the dialog box. The only problem with this one is that I dont know how to initialize myFunction(...) after the dialog box has been created and displayed.

    Code:
    DialogBox(hInst, "PROGRESSDLG", hWndDlg, DlgProc);
    Here is the other way that I'm calling the dialog box. Two problems with this one. 1 - WM_LBUTTONDOWN message never gets called resulting in a dialog box that cant be repositioned. 2 - The LTEXT control isnt displayed, but the progress bar is.

    Code:
    HWND hDialog = CreateDialog(hInst, "PROGRESSDLG", hWndDlg, DlgProc);
    ShowWindow(hDialog, SW_SHOWNORMAL);
    if(hDialog) {
         myFunction(hDialog);
         DestroyWindow(hDialog);
    }
    Here is my procedure function:

    Code:
    INT_PTR CALLBACK DlgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam) {
         switch(Message) {
              case WM_INITDIALOG:
                   //CreateWindowEx(0,"Static","Please wait...",WS_CHILD | WS_VISIBLE,5,5,40,12,hWndDlg,0,hInst,NULL);
                   hProgress = CreateWindowEx(0,PROGRESS_CLASS,NULL,WS_CHILD | WS_VISIBLE,5,35,76,20,hWndDlg,0,hInst,NULL);
                   SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100));
                   SendMessage(hProgress, PBM_SETSTEP, (WPARAM)5, 0);
                   return true;
              case WM_COMMAND:
                   myFunction(hWndDlg);
                   EndDialog(hWndDlg,0);
                   return true;
              case WM_LBUTTONDOWN:
                   SendMessage(hWndDlg, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
                   // The next line allows me to initiate myFunction(...) after I click and release the left mouse button within the progress bar dialog box
                   SendMessage(hWndDlg, WM_COMMAND, 0, 0);
                   return true;
              default:
                   return false;
         }
    }
    I comment out the case WM_COMMAND portion and the Send WM_COMMAND portion when I try the second way of creating the dialog box.

    EDIT:

    If I wanted to, I could replace the WM_COMMAND SendMessage (which is located in the WM_LBUTTONDOWN message) with myFunction(...); EndDialog(...); and it would do the same thing. Thats kinda what I meant in my previous post.

    EDIT EDIT:

    One thing I tried to do for automatically initializing the myFunction() function was to put it in the default case. I assumed WM_INITDIALOG is the very first message that gets sent and the second message, no matter what, would initialize myFunction() and close the dialog box. However, that never displays the dialog box. I then attempted to put myFunction() within the WM_PAINT message (since WM_PAINT is another message that is automatically sent), but then the LTEXT control is not displayed, but it works.

    Also, I just realized that if I'm in the middle of executing myFunction, there isnt going to be any messages sent and since I want myFunction to execute automatically and when its done, I want it to close the dialog box, the user will have no possible way of moving the dialog box so I can remove that message.
    Last edited by stickman; 05-09-2006 at 07:43 PM.

  12. #12
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    Finally...Me fergets I made meself simple text output function...Here is my procedure function using the first method of calling a dialog box:

    Code:
    INT_PTR CALLBACK DlgProg(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam) {
         switch(Message) {
              case WM_INITDIALOG:
                   hProgress = CreateWindowEx(0,PROGRESS_CLASS,NULL,WS_CHILD | WS_VISIBLE,5,35,76,20,hWndDlg,0,hInst,NULL);
                   SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100));
                   SendMessage(hProgress, PBM_SETSTEP, (WPARAM)5, 0);
                   return true;
              case WM_PAINT: {
                   PAINTSTRUCT ps;
                   HDC hdc = BeginPaint(hWndDlg, &ps);
                   RECT rc;
                   GetClientRect(hWndDlg,&rc);
                   //Parameter of textout():
                   // (HDC,RECT,Const Char* output,INT fontsize,INT mode, UINT);
                   // Mode - 1=bold,2=bold/italic,3=italic,4=normal
                   textout(hdc, rc, "\r\nPlease wait...", 14, 4, DT_CENTER | DT_WORDBREAK);
                   EndPaint(hWndDlg, &ps);
                   myFunction(hWndDlg);
                   EndDialog(hWndDlg,0);
                   return true;
              }
              default:
                   return false;
         }
    }
    That works perfectly...Thanks for your help.
    Last edited by stickman; 05-09-2006 at 07:53 PM.

  13. #13
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Code:
    HWND hDialog = CreateDialog(hInst, "PROGRESSDLG", hWndDlg, DlgProc);
    I think that should be
    Code:
    HWND hDialog = CreateDialog(hInst, MAKEINTRESOURCE(PROGRESSDLG), hWndDlg, DlgProc);
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  14. #14
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    MAKEINTRESOURCE(PROGRESSDLG) and "PROGRESSDLG" are the same thing except you have to predefine PROGRESSDLG if you use MAKEINTRESOURCE. I forget where I read that, but I'll post a link if I'm able to find.

  15. #15
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Ah! I wasn't quite understanding what you wanted to occur. Grats on getting it fixed.

    As a last note, MAKEINTRESOURCE(PROGRESSDLG) and "PROGRESSDLG" are not the same thing, and which one you want depends on how you built your resource file. Since your program is working, there is no need for change. The difference is that one is a string ("ID") and one a number (MAKEINTRESOURCE(ID), where ID is usually #define'd as some number.) But otherwise both are perfectly valid - but not the same.
    Quote Originally Posted by Win32 API
    If the high-order word of the [name] is zero, the low-order word specifies the integer identifier of the name or type of the given resource. Otherwise, those parameters are long pointers to null-terminated strings. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource's name or type. For example, the string "#258" represents the integer identifier 258.
    See MAKEINTRESOURCE() and FindResource().

    (100th post! Yay...)
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. make Child Dialog not Popup?
    By Zeusbwr in forum Windows Programming
    Replies: 5
    Last Post: 04-08-2005, 02:42 PM
  2. Get a string from a modal dialog box
    By axr0284 in forum Windows Programming
    Replies: 1
    Last Post: 03-03-2005, 01:39 PM
  3. Dialog Box Resources
    By Mecnels in forum Windows Programming
    Replies: 2
    Last Post: 04-28-2003, 05:57 AM
  4. edit control in dialog box problems
    By Bajanine in forum Windows Programming
    Replies: 11
    Last Post: 11-11-2002, 06:55 PM
  5. Resize Dialog Box via Code :: MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 10-27-2002, 11:00 PM