Announcement

Collapse
No announcement yet.

User Messages

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

  • User Messages

    The scenario
    A Button on a Dialog starts a thread, some time later it sends a message to the Button to determine if it needs to do more work or end
    The Button can receive this message from the thread
    CONTROL SEND DlgH, %Bstart, %BM_CLICK, 0, 0
    but not this one
    CONTROL SEND DlgH, %Bstart, %WM_USER + 600, 0, 0
    Does the buton need to be sub classed or the message registered?

  • #2
    You need to tell it what control, that it's directed to (which you do) as well as what the message is and the control ID.

    Try using DIALOG POST instead. The Low Word of the wParam contains the control message (ie. %BN_CLICK), lParam the control id, and umsg contains the windows message. So it should look like;

    DIALOG POST hDlg, %WM_COMMAND, %BN_CLICK, %MyControlID

    This Any Message you post should show up in under %WM_COMMAND for that control ID.
    Scott Slater
    Summit Computer Networks, Inc.
    www.summitcn.com

    Comment


    • #3
      Couple of options:
      Code:
       'DIALOG SEND DlgH, %WM_COMMAND, MAKDWD(%Bstart, %BN_CLICKED), GetDlgItem(DlgH, %Bstart)
       'or
        DIALOG SEND DlgH, &WM_USER + 600, MAKDWD(%Bstart, %BN_CLICKED), 0
       ...
          CASE %WM_USER + 600
            ' CB.CTL is the control ID (equivalent to LO(WORD, CBWPARAM) )
            ' CB.CTLMSG is the notification message (equivalent to HI(WORD, CBWPARAM))
            IF CB.CTL = %Bstart THEN 
              IF CB.CTLMSG = %BN_CLICKED THEN..
      Rgds, Dave

      Comment


      • #4
        Sorry should have said 8.03. The control is %Bstart, sending the message %BM_CLICK works perfectly as it should. What doesn't work is sending the message %WM_USER + 600.

        Comment


        • #5
          Hmm, this test code works ok with PBWin804..
          Code:
          #DIM ALL
          #COMPILE EXE
          #INCLUDE "WIN32API.INC"
           
          %Bstart = 1001
          '------------------/
           
          FUNCTION TestThread(BYVAL DlgH AS DWORD) AS LONG
            SLEEP 2000    ' 1. Simulate click notification to parent window 
              DIALOG SEND DlgH, %WM_COMMAND, MAKLNG(%Bstart, %BN_CLICKED), 0
           
            SLEEP 2000    ' 2. Send user message to parent msg proc.
              DIALOG SEND DlgH, %WM_USER + 600, MAKDWD(%Bstart, %BN_CLICKED), 0
           
            SLEEP 2000    ' 3. Send user message to control (catch in subclass msg proc)
              DIALOG SEND GetDlgItem(DlgH, %Bstart), %WM_USER + 600, 0, 0
          END FUNCTION
          '------------------/TestThread
           
          FUNCTION Bstart_SubClassProc(BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
           LOCAL OldProc AS DWORD
            OldProc = GetProp(GetParent(hWnd), "OldProc")
           
            SELECT CASE wMsg
              CASE %WM_USER + 600     ' Msg 3. from thread
                WinBeep 400, 100
                Dialog Set Text GetParent(hWnd), "Msg received in sbclass proc"
           
              CASE %WM_DESTROY
                RemoveProp GetParent(hWnd), "OldProc"
                SetWindowLong hWnd, %GWL_WNDPROC, OldProc
           
            END SELECT
           
           Function = CallWindowProc(OldProc, hWnd, wMsg, wParam, lParam)
          END FUNCTION
          '------------------/SubClassProc
           
          CALLBACK FUNCTION DlgProc() AS LONG
           LOCAL hThread AS DWORD
           STATIC Res AS LONG, Second AS LONG
           
            SELECT CASE CBMSG
              CASE %WM_InitDialog
                THREAD CREATE TestThread(CBHNDL) TO hThread
                THREAD CLOSE hThread TO Res
           
              CASE %WM_USER + 600     ' Msg from thread
                ' CbCtl is the control ID (equivalent to LO(WORD, CBWPARAM) )
                ' CbCtlMsg is the notification message (equivalent to HI(WORD, CBWPARAM))
                IF CBCTL = %Bstart THEN
                  IF CBCTLMSG = %BN_CLICKED THEN
                    Second = %True
                    CONTROL SEND CBHNDL, %Bstart, %BM_CLICK, 0, 0     ' simulate user clicking button;
                    ' button receives WM_LBUTTONDOWN, WM_LBUTTONUP and parent window receives a BN_CLICKED notification
                  END IF
                END IF
           
              CASE %WM_Command
                SELECT CASE CBCTL
                  CASE %Bstart
                    IF CBCTLMSG = %BN_Clicked OR CBCTLMSG = 1 THEN
                      WinBeep 800,1
                      DIALOG SET TEXT CBHNDL, IIF$(Second, "'clicked' via %WM_USER + 600", "'clicked'")
                      Second = %False
                    END IF
                END SELECT
           
            END SELECT
          END FUNCTION
          '------------------/DlgProc
           
          FUNCTION PBMAIN() AS LONG
           LOCAL DlgH, OldProc AS DWORD
           
            DIALOG NEW 0, "Button click test", , , 240, 150, %WS_Caption OR %WS_SysMenu, 0 TO DlgH
              CONTROL ADD BUTTON, DlgH, %Bstart, "Bstart", 185, 132, 50, 14
           
                OldProc = SetWindowLong(GetDlgItem(DlgH, %Bstart), %GWL_WNDPROC, CODEPTR(Bstart_SubClassProc))
                SetProp DlgH, "OldProc", OldProc
           
            DIALOG SHOW MODAL DlgH, CALL DlgProc
           
          END FUNCTION
          '------------------/PBMain
          Last edited by Dave Biggs; 5 Jul 2009, 07:40 AM. Reason: Sample code modified to include subclass proc for button
          Rgds, Dave

          Comment


          • #6
            ...Unless you really do want to send the %WM_USER + 600 message TO the button instead of via it's parent for some reason?

            That's why you mentioned subclassing in the original question I'll bet

            LATER: Code sample above modified to include subclass proc. for button.
            Last edited by Dave Biggs; 5 Jul 2009, 07:38 AM. Reason: Update
            Rgds, Dave

            Comment


            • #7
              These are the valid button messages.
              %BM_GETCHECK = &HF0
              '%BM_SETCHECK = &HF1
              '%BM_GETSTATE = &HF2
              '%BM_SETSTATE = &HF3
              '%BM_SETSTYLE = &HF4
              '%BM_CLICK = &HF5
              '%BM_GETIMAGE = &HF6
              '%BM_SETIMAGE = &HF7

              Not sure why only %BM_CLICK gets through to the control?

              Correction: These are the wrong set of messages. Should be %BN messages.

              These are the correct ones:

              ' User Button Notification Codes
              %BN_CLICKED = 0
              %BN_PAINT = 1
              %BN_HILITE = 2
              %BN_UNHILITE = 3
              %BN_DISABLE = 4
              %BN_DOUBLECLICKED = 5
              %BN_SETFOCUS = 6
              %BN_KILLFOCUS = 7
              %BN_DBLCLK = %BN_DOUBLECLICKED


              Just saw Dave's solution, very informative.
              Last edited by Mike Doty; 6 Jul 2009, 09:39 AM. Reason: Showed wrong set of notification codes

              Comment


              • #8
                Thanks Dave
                Yes the question was more of a learning experience, I already had a simple work around. The object was to be able to distinguishe between a message coming from the thread and a user clicking on the button. Actually the Dialog Send is a better solution as it means I can disable the Start button once clicked.
                I got trapped by not carefully reading the manual documention for CONTROL SEND which says "To send a custom message to a dialog, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF)," (bolding mine) which has nothing to do with CONTROL SEND as it would appear most standard controls only accept specific messages and even then they have been translated i.e. as Mike says %BM_CLICK has a vaue of &HF5 but is received by the button with a value of 0.
                John

                Comment


                • #9
                  The button receives %BN_CLICKED in CBCTLMSG
                  Code:
                  SELECT CASE AS LONG CBCTL
                                CASE %bStart
                                  ? "CBCTLMSG" + STR$(CBCTLMSG)
                                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN

                  Comment


                  • #10
                    I see what you mean.
                    Is CBCTLMSG = changed to 0 after the click?

                    Code:
                    #PBFORMS CREATED V1.51
                    '------------------------------------------------------------------------------
                    #COMPILE EXE
                    #DIM ALL
                    '------------------------------------------------------------------------------
                    '   ** Includes **
                    '------------------------------------------------------------------------------
                    #PBFORMS BEGIN INCLUDES
                    #IF NOT %DEF(%WINAPI)
                        #INCLUDE "WIN32API.INC"
                    #ENDIF
                    #PBFORMS END INCLUDES
                    '------------------------------------------------------------------------------
                    '------------------------------------------------------------------------------
                    '   ** Constants **
                    '------------------------------------------------------------------------------
                    #PBFORMS BEGIN CONSTANTS
                    %IDD_DIALOG1 =  101
                    %bStart      = 1001
                    #PBFORMS END CONSTANTS
                    '------------------------------------------------------------------------------
                    '------------------------------------------------------------------------------
                    '   ** Declarations **
                    '------------------------------------------------------------------------------
                    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                    #PBFORMS DECLARATIONS
                    '------------------------------------------------------------------------------
                    '------------------------------------------------------------------------------
                    '   ** Main Application Entry Point **
                    '------------------------------------------------------------------------------
                    FUNCTION PBMAIN()
                        ShowDIALOG1 %HWND_DESKTOP
                    END FUNCTION
                    '------------------------------------------------------------------------------
                    '------------------------------------------------------------------------------
                    '   ** CallBacks **
                    '------------------------------------------------------------------------------
                    CALLBACK FUNCTION ShowDIALOG1Proc()
                        SELECT CASE AS LONG CBMSG
                            CASE %WM_INITDIALOG
                                ' Initialization handler
                            CASE %WM_NCACTIVATE
                                STATIC hWndSaveFocus AS DWORD
                                IF ISFALSE CBWPARAM THEN
                                    ' Save control focus
                                    hWndSaveFocus = GetFocus()
                                ELSEIF hWndSaveFocus THEN
                                    ' Restore control focus
                                    SetFocus(hWndSaveFocus)
                                    hWndSaveFocus = 0
                                END IF
                            CASE %WM_COMMAND
                                ' Process control notifications
                                GLOBAL gThread AS DWORD
                                LOCAL  temp    AS DWORD
                                SELECT CASE AS LONG CBCTL
                                  CASE %bStart
                                    ? "CBCTLMSG BEFORE IF LOGIC" + STR$(CBCTLMSG)
                                    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                      ?"CBCTLMSG IN CLICK" + STR$(CBCTLMSG)
                                      THREAD CREATE MyThread(CBHNDL) TO gThread     'create thread while passing handle of dialog
                                      SLEEP 50                                      'good idea
                                      THREAD CLOSE gThread TO temp                  'don't need handle
                                    END IF
                                END SELECT
                        END SELECT
                    END FUNCTION
                    '------------------------------------------------------------------------------
                    '------------------------------------------------------------------------------
                    '   ** Dialogs **
                    '------------------------------------------------------------------------------
                    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                        LOCAL lRslt AS LONG
                    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                        LOCAL hDlg  AS DWORD
                        DIALOG NEW hParent, "Dialog1", 355, 169, 201, 121, %WS_POPUP OR _
                            %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
                            %WS_VISIBLE OR %DS_MODALFRAME 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, %bStart, "Threads", 5, 5, 75, 15
                    #PBFORMS END DIALOG
                        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
                    #PBFORMS END CLEANUP
                        FUNCTION = lRslt
                    END FUNCTION
                    '------------------------------------------------------------------------------
                    THREAD FUNCTION MyThread(BYVAL DlgH AS DWORD) AS DWORD
                     LOCAL counter AS LONG
                     FOR counter = 1 TO 3
                       CONTROL SET TEXT DlgH, %Bstart, "Threads" + STR$(THREADCOUNT)
                       BEEP
                       SLEEP 1000
                     NEXT
                     CONTROL SEND DlgH, %Bstart, %BM_CLICK, 0, 0 'click again, works
                     'CONTROL SEND DlgH, %Bstart, %WM_USER + 600, 0, 0
                     'CONTROL SEND DlgH, %Bstart, %BM_SETSTYLE, 0,0
                     '%BM_GETCHECK = &HF0
                     '%BM_SETCHECK = &HF1
                     '%BM_GETSTATE = &HF2
                     '%BM_SETSTATE = &HF3
                     '%BM_SETSTYLE = &HF4
                     '%BM_CLICK    = &HF5
                     '%BM_GETIMAGE = &HF6
                     '%BM_SETIMAGE = &HF7
                     ? "Done"
                    END FUNCTION
                    Last edited by Mike Doty; 6 Jul 2009, 07:59 AM.

                    Comment


                    • #11
                      >Not sure why only %BM_CLICK gets through to the control?

                      Let's say YOU wrote a window procedure for a control you designed. Would IT know what to do with "WM_USER + 600?"

                      Same with the "button" class. Whomever at Microsoft wrote the window procedure for the button control must have forgotten to accomodate "WM_USER+600".

                      Fortunately, subclassing allows you to see EVERY message sent to ANY window.. and 'do something' at that time.

                      In your situation, I think maybe you could post/send WM_USER + 600 to the owner window, (DIALOG POST/DIALOG SEND), using the available "wParam" and "lparam" parameters to indicate which button you mean; those params will then be available in that owner window procedure as CB.WPARAM and CB.LPARAM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        My mistake!
                        Showed the wrong set of messages above

                        ' User Button Notification Codes
                        %BN_CLICKED = 0
                        %BN_PAINT = 1
                        %BN_HILITE = 2
                        %BN_UNHILITE = 3
                        %BN_DISABLE = 4
                        %BN_DOUBLECLICKED = 5
                        %BN_SETFOCUS = 6
                        %BN_KILLFOCUS = 7
                        %BN_DBLCLK = %BN_DOUBLECLICKED

                        Comment


                        • #13
                          >The button receives %BN_CLICKED in CBCTLMSG

                          This may seem semantic, but in context it's an important disctinction....

                          When "BN_CLICKED" comes via "CBCTLMSG" that's actually not the BUTTON receiving a notification... it's the owner window, receiving that notification thru the WM_COMMAND message.
                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            The object was to be able to distinguishe between a message coming from the thread and a user clicking on the button
                            To differentiate an actual click notification (or the result of a BM_CLICK message), from a simulated BN_CLICKED
                            generated by your code, Send (/Post) %WM_COMMAND, MAKLNG(%IDC_Button, %BN_CLICKED), 0 and then in your Callback..
                            Code:
                            CASE %WM_Command
                              IF CBCTL = %IDC_Button THEN
                                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                    IF CBLPARAM <> GetDlgItem(CbHndl, %IDC_Button) THEN
                                      DIALOG SET TEXT CbHndl, "Simulated WM_Command notification recieved!"
                                    END IF..
                            Re: BM_CLICK vs BN_CLICKED

                            An application sends a BM_CLICK (&HF5) message to simulate the user clicking a button.
                            This message causes the button to receive the WM_LBUTTONDOWN and WM_LBUTTONUP messages,
                            and the button's parent window to receive a BN_CLICKED (&H0) notification message.
                            The BM_CLICK message is sent to the control ( CONTROL SEND hDlg, %IDC_Button, %BM_CLICK, 0, 0 ).

                            The BN_CLICKED (&H0) notification code is sent when the user clicks a button.
                            The parent window of the button receives the BN_CLICKED notification code through the WM_COMMAND message, wherein..
                            CBWPARAM
                            The low-order word contains the button's control identifier. ( = CBCTL)
                            The high-order word specifies the notification message. ( = CBCTLMSG)
                            CBLPARAM
                            Contains the Handle to the button. ( = 'CONTROL HANDLE CBHNDL, %IDC_Button' / 'GetDlgItem(CbHndl, %IDC_Button' )
                            Rgds, Dave

                            Comment


                            • #15
                              Thanks all, I am a novice at windows GUI. Here is the crux of what I now understand. The message is actually sent to the control and interpreted or discarded before being passed to the Callback of the Dialog or Control. Whilst Michael's explanation is very logical it would superfically appear whether the control passed on or discarded unidentified messages would be irrelevant.
                              So does subclassing change the order i.e. do the messages go to the callback before the control? This would be of more importance for other controls like the Text Box. Lets say I didn't want the letter "F" ever be shown in a text box, then my understanding is I would need to sub-class the text box and identify the KewDown and KeyUp messages for the scan code representing the "F" and somehow cancel them, but without sub-classing I would only get %EN_CHANGE after it has displayed the unwanted character or %EN_UPDATE after it has formatted but not displayed it and then somehow remove it.
                              I guess my confusion arises that for most of my Windows programming life I have used VB for the GUI and PB (from DLL 1.1) for all the important work. It appears that VB has a low opinion of the usefullness of the standard controls and sub-classes every one of them so has always provided MouseDown, MouseUp, KeyDown, KeyUp etc events.
                              One of the most important of these events was QueryUnload which allowed for such simple thing as asking the user if they wished to save changes before unloading the form (ending dialog) and thus the ability to cancel the unload.

                              Comment


                              • #16
                                Lets say I didn't want the letter "F" ever be shown in a text box, then my understanding is I would need to sub-class the text box
                                That's more or less correct, but you don't have to do the 'key' messages, you can just intercept WM_CHAR.

                                Here's a demo of a subclass procedure used to limit characters to valid hex digits:
                                Code:
                                FUNCTION DelimiterHexEditProc (BYVAL hWnd AS LONG, BYVAL wMSG AS LONG, BYVAL wPAram AS LONG, BYVAL lParam AS LONG) AS LONG
                                
                                  STATIC dwProc AS DWORD, BeenHere AS LONG
                                  LOCAL szProp AS ASCIIZ * 64
                                  LOCAL  idCtrl AS LONG
                                  LOCAL  szText AS ASCIIZ * %MAX_PATH, lText AS LONG
                                  LOCAL  ichar  AS LONG
                                
                                
                                  IF ISFALSE beenHere THEN
                                      BeenHere = %TRUE
                                      szProp   = $PROP_OLD_WNDPROC
                                      dwProc   = getProp (hWnd, szProp)
                                  END IF
                                
                                  SELECT CASE AS LONG wMSg
                                
                                         CASE %WM_GETDLGCODE
                                             'FUNCTION =  %DLGC_WANTALLKEYS     ' With DLCG_WANTCHARS all regular keys work but no WM-CHAR message
                                             FUNCTION = %DLGC_WANTCHARS         ' doc says "WM_CHAR messages"
                                             'FUNCTION   = %DLGC_WANTMESSAGE
                                             EXIT FUNCTION
                                
                                         CASE  %WM_CHAR                      '"An application should return zero if it processes this message. "
                                            ' LOWRD wparam = "the character code of the key"
                                             IF wparam = %VK_TAB THEN
                                                 ' standard TAB behavior
                                                   SetFocus       GetnextDlgTabItem(GetParent(hWnd), hWnd, (GetKeyState(%VK_SHIFT) < 0))
                                                   FUNCTION = 0
                                                   EXIT FUNCTION
                                
                                             ELSE  ' not tab
                                                iChar  = LOWRD(WParam)
                                                SELECT CASE AS LONG iChar
                                                    CASE &h30 TO &h39, &h41 TO &h46, _    ' OK characters 0-9 and A-F
                                                         &h61 TO &h66, _                  ' lower case a-f, will be uppercased when they get in
                                                         %VK_TAB, %VK_HOME, %VK_END, %VK_BACK, _      ' expected control characters
                                                         %VK_RIGHT, %VK_LEFT, %VK_INSERT, %VK_DELETE, _
                                                         %vK_ESCAPE
                                                        EXIT SELECT                      ' allow normal processing
                                                    CASE ELSE
                                                        MessageBeep  %MB_ICONHAND
                                                        FUNCTION = 0
                                                        EXIT FUNCTION    ' bypass normal processing
                                                END SELECT
                                             END IF
                                
                                       END SELECT
                                       ' if message not handled (if handled proc was exited), call default handler
                                       FUNCTION = CallWindowProc (dwProc, hWnd, wMsg, wParam,lparam)
                                
                                END FUNCTION
                                MCM
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                • #17
                                  Query Unload

                                  query unload = wm_syscommand (wparam = sc_close)

                                  if you return 1 your window will not be destroyed!

                                  doesn´t work with DDT "Dialog End", use
                                  "postmessage hwnd, %wm_syscommand, %sc_close, 0" instead.

                                  Comment


                                  • #18
                                    Thanks Elisabeth for letting me know the message. The problem I have is if the Dialog is created with a %WS_SYSMENU style and the user ends the program by clicking on the close X of the Sysmenu (a very common occurence). If they click on an Exit/Finished/End button I have provided then obviously the program can do the appropriate checks or steps before doing a DIALOG END.
                                    Unfortunately I can't find any documentation that a DDT Dialog will get the sc_close message if the sysmenu X is used so I can do the same tests/checks. I guess I have to do some testing.
                                    John

                                    Comment


                                    • #19
                                      I have no trouble with something like this for all my DDT dialogs (all my dialogs are DDT dialogs).

                                      Code:
                                              CASE %WM_SYSCOMMAND
                                                  IF (CB.WPARAM AND &HFFF0) = %SC_CLOSE THEN          'trap the "X" to exit the program and clean up
                                                      OBJECT CALL MotorFunc.Disconnect()
                                                      MotorFunc = NOTHING                             'release the activex interface
                                                      COMM CLOSE SFunc.hComm                          'close stepper motor comm port
                                                      'TRACE CLOSE
                                                      DIALOG END CB.HNDL, 0                           'Applikation beenden!
                                                  END IF

                                      Comment


                                      • #20
                                        Some notes re: SC_CLOSE
                                        Code:
                                        #Compile Exe
                                        #Dim All
                                        #Include "WIN32API.INC"
                                         
                                        %BTN_Test      = 102
                                        %LBL_LABEL1    = 101
                                        '------------------
                                         
                                        CallBack Function DlgProc()
                                         Local Res, hDlg2 As Long 
                                         Local sTemp As String
                                          Select Case As Long CbMsg
                                            Case %WM_INITDIALOG
                                         
                                            Case %WM_COMMAND
                                              Select Case As Long CbCtl
                                                Case %BTN_Test
                                                  If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                                                    Dialog End CbHndl, 0
                                         '            Dialog Post CbHndl, %WM_SYSCOMMAND, %SC_CLOSE, 0
                                                  End If
                                              End Select
                                         
                                            Case %WM_SYSCOMMAND
                                              If (CbWParam AND &HFFF0) = %SC_CLOSE Then
                                                ' Either: 1. The System Menu "Close" option has been selected (via program icon on caption bar) or..
                                                '         2. The caption bar [X] button has been clicked or..
                                                '         3. The keyboard shortcut 'Alt-F4' has been used.
                                                '         4. The application has 'posted' a %WM_SYSCOMMAND, %SC_CLOSE message.
                                                Res = MsgBox ("Really quit?", %MB_YESNO Or %MB_ICONQUESTION, "SC_CLOSE")
                                                If Res = %IDNO Then
                                                  Function = 1  ' Signals that sc_close command has been 'dealt with' - no further action rqd,
                                                  Exit Function ' otherwise WM_CLOSE comes next.
                                                End If
                                              End If
                                         
                                            Case %WM_CLOSE
                                              ' NOTE: WM_CLOSE HAS DIFFERENT BEHAVIOUR IF USING SDK. 
                                              Res = MsgBox ("Really no choice for DDT :)", %MB_YESNO Or %MB_ICONQUESTION, "DDT WM_CLOSE")
                                              If Res = %IDNO Then
                                                Function = 1  ' Too late - WM_DESTROY comes next anyway.
                                                Exit Function
                                              End If
                                         
                                             Case %WM_DESTROY
                                               MsgBox "WM_DESTROY - window has gone"
                                               ' Hasta La Vista, Ma'a Salama !
                                         
                                          End Select
                                        End Function
                                        '------------------/DlgProc
                                         
                                        Function PBMain()
                                         Local hDlg  As Dword
                                         
                                          Dialog New 0, "Dialog End Test", , , 200, 120, %WS_CAPTION Or %WS_SYSMENU, To hDlg
                                          Control Add Label,  hDlg, %LBL_LABEL1, "Quit Dialog w/ [ X ] etc. or click btn.", 40, 25, 120, 20
                                          Control Add Button,  hDlg, %BTN_Test, "Exit", 75, 60, 50, 15
                                         
                                          Dialog Show Modal hDlg, Call DlgProc
                                         
                                        End Function
                                        '------------------/PbMain
                                         
                                        #IF 0
                                         'SDK..
                                                Case %WM_SYSCOMMAND
                                                  If (WParam AND &HFFF0) = %SC_CLOSE Then 
                                                    ' %WM_CLOSE comes next unless..
                                                    Select Case MessageBox(hWnd, "Do you wish to Exit ?", "SDK Sample SC_CLOSE", %MB_YESNO)
                                                      Case %IDNO
                                                        Function=0
                                                        Exit Function
                                                    End Select
                                                  End If
                                         
                                                Case %WM_CLOSE
                                                  ' WM_DESTROY comes next unless..
                                                  Select Case MessageBox(hWnd, "Do you wish to Exit ?", "SDK Sample WM_CLOSE", %MB_YESNO)
                                                    Case %IDNO
                                                      Function=0
                                                      Exit Function
                                                  End Select
                                         
                                                CASE %WM_DESTROY
                                                  PostQuitMessage 0       ' Window already gone - Exit message loop
                                        #ENDIF
                                        Last edited by Dave Biggs; 9 Jul 2009, 11:21 AM.
                                        Rgds, Dave

                                        Comment

                                        Working...
                                        X