Announcement

Collapse
No announcement yet.

Close dialog via Windows taskbar

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Close dialog via Windows taskbar

    Which event is triggered when a dialog is closed via the Windows taskbar menu?

  • #2
    No specific event for that way of closing. The normal WM_CLOSE message is sent, but it doesn't provide any information about where it came from.

    Comment


    • #3
      If a window opens a second window and I then click Close in the task bar, then %WM_CLOSE is carried out. But only in the first window. The event %WM_CLOSE does not occur in the second window.

      Click image for larger version

Name:	Untitled.png
Views:	89
Size:	34.3 KB
ID:	797104

      Code:
      #COMPILE EXE
      #DIM ALL
      #INCLUDE ONCE "WIN32API.INC"
      
      
      %IDC_BUTTON1 = 1001
      %IDC_BUTTON2 = 2001
      
      
      CALLBACK FUNCTION ShowDIALOG2Proc()
      SELECT CASE AS LONG CB.MSG CASE %WM_COMMAND SELECT CASE AS LONG CB.CTL
      CASE %IDC_BUTTON2
      IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
      MSGBOX "OK"
      END IF
      END SELECT CASE %WM_CLOSE
      MSGBOX "%WM_CLOSE 2"
      CASE %WM_SYSCOMMAND
      IF ((CBWPARAM AND &HFFF0) AND %SC_CLOSE) = %SC_CLOSE THEN
      MSGBOX "%WM_SYSCOMMAND 2"
      END IF
      END SELECT
      END FUNCTION FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG LOCAL hDlg AS DWORD
      DIALOG NEW hParent, "Dialog2", 89, 83, 201, 121, %WS_POPUP OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR _ %DS_SETFOREGROUND OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _ %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _ %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Button2 >> OK", 55, 45, 80, 25 DIALOG SHOW MODAL hDlg, CALL ShowDIALOG2Proc TO lRslt FUNCTION = lRslt
      END FUNCTION CALLBACK FUNCTION ShowDIALOG1Proc()
      SELECT CASE AS LONG CB.MSG CASE %WM_COMMAND SELECT CASE AS LONG CB.CTL
      CASE %IDC_BUTTON1
      IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
      ShowDIALOG2 CBHNDL
      END IF
      END SELECT CASE %WM_CLOSE
      MSGBOX "%WM_CLOSE 1"
      CASE %WM_SYSCOMMAND
      IF ((CBWPARAM AND &HFFF0) AND %SC_CLOSE) = %SC_CLOSE THEN
      MSGBOX "%WM_SYSCOMMAND 1"
      END IF
      END SELECT
      END FUNCTION FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG LOCAL hDlg AS DWORD
      DIALOG NEW hParent, "Dialog1", 89, 83, 201, 121, %WS_POPUP OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR _ %DS_SETFOREGROUND OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _ %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _ %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Button1 >> Dialog2", 55, 45, 80, 25 DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
      FUNCTION = lRslt
      END FUNCTION FUNCTION PBMAIN()
      ShowDIALOG1 %HWND_DESKTOP
      END FUNCTION

      Comment


      • #4
        Code in post 3 works here.
        Start program, button on dlg1 to open dlg2, right click taskbar and close. Get 3 message boxes and both windows close.
        PBWin 10, Windows 64 v10.
        cheers,

        (note - you used cbhndl vs cb.hndl in your code. I did not change it for test run.)
        Dale

        Comment


        • #5
          Try adding WM_DESTROY message boxes to the Callbacks.

          Sequence is:

          WM_SYSCOMMAND
          window receives this message when the user chooses the close button (eg via the Taskbar).

          The DefWindowProc function carries out the command request (eg SC_CLOSE).

          WM_CLOSE
          sent as a signal that a window or an application should terminate.

          By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.

          DestroyWindow Function
          If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

          DestroyWindow does not send WM_CLOSE to the 'owned window' but does send WM_DESTROY.
          Rgds, Dave

          Comment


          • #6
            Originally posted by Dale Yarker View Post
            Code in post 3 works here.
            Start program, button on dlg1 to open dlg2, right click taskbar and close. Get 3 message boxes and both windows close.
            PBWin 10, Windows 64 v10.
            cheers,

            (note - you used cbhndl vs cb.hndl in your code. I did not change it for test run.)
            Here: Start program >> Button on dlg1 to open dlg2 >> right click taskbar >> close

            Result: Only 2 message boxes >> %WM_SYSCOMMAND 1 and %WM_CLOSE 1

            PBWin10, Windows 32 v7 and Windows 64 v10

            Comment


            • #7
              Since adding CASE %WM_DESTROY : MSGBOX "%WM_DESTROY 1" I get four message boxes, on either WIn7 or Win10, as expected.
              Rgds, Dave

              Comment


              • #8
                I get stacked icons (one for every instance).
                Windows then asks if you want to close all instances ("close all windows") or just one if one icon is clicked ("close window")...
                Regards,
                Peter

                Comment


                • #9
                  Unable to duplicate the second dialog not closing problem.
                  Did you copy/paste that code or retype?

                  BTW I noticed
                  '
                  Code:
                  in two places -
                  IF ((CB.WPARAM AND &HFFF0) AND %SC_CLOSE) = %SC_CLOSE THEN
                    'should be -
                  IF (CB.WPARAM AND &HFFF0) = %SC_CLOSE THEN '
                  The way you have it allows %SC_DEFAULT (and a couple others) to be
                  equal to %SC_CLOSE. While not a problem in this demo code, it could
                  cause problems in other code.

                  Cheers,

                  ((change word "allows" in above to "modifies"))
                  Dale

                  Comment


                  • #10
                    Originally posted by Peter Lameijn View Post
                    I get stacked icons (one for every instance).
                    Windows then asks if you want to close all instances ("close all windows") or just one if one icon is clicked ("close window")...
                    Maybe 2nd dialog is getting hParent = 0 (desktop). Is why I asked about retyping in my previous.

                    Cheers,
                    Dale

                    Comment


                    • #11
                      Originally posted by Dave Biggs View Post
                      Try adding WM_DESTROY message boxes to the Callbacks.

                      Sequence is:

                      WM_SYSCOMMAND
                      window receives this message when the user chooses the close button (eg via the Taskbar).

                      The DefWindowProc function carries out the command request (eg SC_CLOSE).

                      WM_CLOSE
                      sent as a signal that a window or an application should terminate.

                      By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.

                      DestroyWindow Function
                      If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

                      DestroyWindow does not send WM_CLOSE to the 'owned window' but does send WM_DESTROY.
                      I already knew, but forgot. Thank you!

                      Comment


                      • #12
                        Re Mr. Biggs' summary of messages and default actions...

                        I believe those are the Microsoft Windows' actions. I THINK PowerBASIC DDT dialogs use the Windows default actions but I would either test that or maybe I would just use the WinAPI methods to manage this screen if you need to rely on a particular set of notification messages. .
                        Michael Mattias
                        Tal Systems Inc. (retired)
                        Racine WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          CASE %WM_QUERYENDSESSION

                          If the Windows user is logged out, "%WM_QUERYENDSESSION" is triggered.

                          Do you still have the option to stop an ongoing process properly?

                          CASE %WM_QUERYENDSESSION
                          ProcessCancel = %TRUE
                          while isfalse ProcessStopped
                          sleep 10
                          wend

                          Comment


                          • #14
                            Do you still have the option to stop an ongoing process properly?
                            You need to read the doc for the message:



                            ....

                            Return Values

                            If an application can terminate conveniently, it should return TRUE; otherwise, it should return FALSE.
                            Remarks

                            By default, the DefWindowProc function returns TRUE for this message.

                            Windows NT/2000/XP: When an application returns TRUE for this message, it receives the WM_ENDSESSION message and it is terminated, regardless of how the other applications respond to the WM_QUERYENDSESSION message.

                            Windows 95/98/Me: After all applications return TRUE for this message, they receive the WM_ENDSESSION and they are terminated.
                            And in any event, until you complete processing of the WM_QUERYENDSESSION message your program is in control amd you may do whatever you want... which may be to "smoothly" terminate the program. .

                            Needless to say... you need to make sure your program can handle this message and will at that time be able to do what it must.

                            FWIW, you really need to check the doc for operating systems after Windows/XP, which is what was current when I got my doc-on-disk.

                            MCM
                            Michael Mattias
                            Tal Systems Inc. (retired)
                            Racine WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              in all programs of mine with more than on dialog i have to have a callback for each

                              Comment


                              • #16
                                in all programs of mine with more than one dialog i have to have a callback for each

                                Comment


                                • #17
                                  Originally posted by James C Morgan View Post
                                  in all programs of mine with more than one dialog i have to have a callback for each
                                  ???
                                  Bernhard does in code above, I usually use one per dialog; but cb.hndl specifies the dialog if you service more than one in a callback.

                                  So why do you "have to"? Relevance to this thread?

                                  Cheers,
                                  Last edited by Dale Yarker; 24 Jul 2020, 08:33 PM.
                                  Dale

                                  Comment


                                  • #18
                                    Originally posted by James C Morgan View Post
                                    in all programs of mine with more than one dialog i have to have a callback for each
                                    You don't have to
                                    You can do the same thing with one Callback function if you include "SELECT CASE CB.HNDL" with a separate CASE block for each dialog.

                                    Comment


                                    • #19
                                      if you include "SELECT CASE CB.HNDL" with a separate CASE block for each dialog.
                                      What I have done when I have had multiple windows or dialogs sharing a callback function (or even a primary window procedure) is

                                      1. After the window has been created, assign it an ID:
                                      Code:
                                         SetWindowLong hWnd, %GWL_ID,  %MEANINGFUL_WINDOW_EQUATE
                                      And when the callback is entered....

                                      Code:
                                           WhichWindow& =  GetWindowLong  ( hWnd. %GWL_ID)
                                           SELECT CASE WhichWindow&
                                             CASE %BLUE_WINDOW
                                               do something
                                            CASE %RED_WINDOW
                                              do something else
                                        .....
                                      Sure it's the same thing as simply querying 'Hwnd' (or CB.HNDL) but A) you don't have to save a handle or use a GLOBAL variable to compare against and B) it's far more self-documenting.

                                      (And IMO using GLOBAL variables with a shared callback can be kind of tricky).

                                      IIRC, you can set and get a unique value for a window with PB 'DDT' dialogs using DIALOG SET/GET USER; same principle

                                      MCM
                                      .




                                      Michael Mattias
                                      Tal Systems Inc. (retired)
                                      Racine WI USA
                                      [email protected]
                                      http://www.talsystems.com

                                      Comment

                                      Working...
                                      X