Announcement

Collapse
No announcement yet.

MOUSEPTR 11 and DIALOG DOEVENTS

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

  • #21
    There is an easier way of doing this:

    Code:
    Select Case As Long CbMsg
      Case %WM_INITDIALOG
        ' Initialization handler
        Static IAmBusy As Long
    Code:
    Case %WM_SETCURSOR
      WinBeep 1800, 100  ' Beep to announce when WM_SETCURSOR is fired - it's busy!!
      If IAmBusy  Then
        MousePtr IAmBusy                       ' ** because we are taking control of the cursor
        Function = 1                        '    - let DefWindowProc know it's been handled
      End If
     
    Case %WM_COMMAND
      ' Process control notifications
      Select Case As Long CbCtl
        Case %IDC_BUTTON1
          If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
            MousePtr 11
            Sleep 2000
            IAmBusy = 11
            Dialog DoEvents
            IAmBusy = 0
            Sleep 2000
            MousePtr 1        ' add MousePtr else curor doesn't reset until mouse move
          End If
      End Select

    Comment


    • #22
      (did I miss something; wouldn't this work (and be even simpler)? IN RED BELOW)

      Code:
      #PBFORMS CREATED V2.01
      #PBFORMS BEGIN INCLUDES
      %USEMACROS = 1
      #INCLUDE "WIN32API.INC"
      #INCLUDE "COMMCTRL.INC"
      #INCLUDE "PBForms.INC"
      #PBFORMS END INCLUDES
      
      #PBFORMS BEGIN CONSTANTS
      %IDD_DIALOG1  =  101
      %IDC_BUTTON1  = 1001
      %IDC_TEXTBOX1 = 1002
      #PBFORMS END CONSTANTS
      
      DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
      DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
      #PBFORMS DECLARATIONS
      
      SUB MyTest()
          WinBeep 2800,250
          SLEEP 5000
          WinBeep 1800,250
      END SUB
      
      FUNCTION PBMAIN()
          PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _
              %ICC_INTERNET_CLASSES)
          ShowDIALOG1 %HWND_DESKTOP
      END FUNCTION
      
      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_SETCURSOR
                  MOUSEPTR 1
                  FUNCTION = 1
                              
              CASE %WM_COMMAND
                  ' Process control notifications
                  SELECT CASE AS LONG CBCTL
                      CASE %IDC_BUTTON1
                          IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                              MOUSEPTR 11
                              MyTest
                          END IF
                  END SELECT
          END SELECT
      END FUNCTION
      '------------------------------------------------------------------------------
      
      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", 349, 84, 274, 200, %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, %IDC_BUTTON1, "BUSY", 110, 75, 50, 15
          CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "", 110, 175, 50, 15
      #PBFORMS END DIALOG
          DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
      #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
      #PBFORMS END CLEANUP
          FUNCTION = lRslt
      END FUNCTION
      Last edited by Jim Dunn; 19 May 2010, 01:07 PM.
      3.14159265358979323846264338327950
      "Ok, yes... I like pie... um, I meant, pi."

      Comment


      • #23
        Jim, if you have a look at the previous posts it was found that the MyTest 'problem' wasn't a problem but the default behaviour - the arrow is returned on completion of the Callback.

        Dialog DoEvents is a different matter. During its execution the pointer is made to be the arrow. Dave Biggs and I have kicked around some code to catch 'Dialog DoEvents' changing the pointer and then to put it back to the 'busy' pointer - its state before entering 'Dialog DoEvents'.

        If you run my last effort and click the BUSY button, Dave's audio enhancement will kick in with the left mouse button going down. In the middle of the two sleeps you will also hear WM_SETCURSOR firing. This is where the pointer is put back to 'busy' after 'Dialog DoEvents' set it to the arrow.

        Comment


        • #24
          Just out of interest I tried this:

          Code:
          Case %WM_SETCURSOR
            zTrace(Hex$(Hi(Word, CB.lParam)) + $Nul)
          where zTrace is Patrice Terriers little trace utility.

          and

          Code:
          Case %WM_COMMAND
            Select Case As Long CbCtl
              Case %IDC_BUTTON1
                If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                  Sleep 2000
                  Dialog DoEvents
                End If
            End Select
          To check, just moving around we get &H200. A left click and we get &H201/&H202. A right click and we get &H204/&H205.

          So far, so good. On clicking the BUSY button we get &H201 followed by &H200 a couple of seconds later.

          Well, it isn't moving, is it? We don't get a message with MOUSEPTR and we don't get one at the end of the Callback. So, why does 'Dialog DoEvents' send a movement message? So we can trap it.

          Comment


          • #25
            So, why does 'Dialog DoEvents' send a movement message?
            It doesn't.

            If we remove the 'Dialog DoEvents' we still get "&H201 followed by &H200 a couple of seconds later". Interestingly, we get the same combination, ie &H201/&H200, when left clicking in a text box.

            With
            Code:
            Case %WM_COMMAND
              Select Case As Long CbCtl
                Case %IDC_BUTTON1
                  If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                    Sleep 2000
                    zTrace("Before" + $Nul)
                    Dialog DoEvents
                    zTrace("After" + $Nul)
                  End If
              End Select
            I get
            201
            Before
            200
            After
            Remming the 'Dialog DoEvents' I get
            201
            Before
            After
            200
            If it isn't 'Dialog DoEvents' sending that 200, who is?

            Answers on a postcard to ....

            Comment


            • #26
              Remming the 'Dialog DoEvents' I get
              Code:
              201
              Before
              After
              200
              I can't tell from posted code what you are printing when you get "200" or "201".

              Is that CB.MSG? HI(WORD, CB.Wparam)?

              Note that you can get notification messages even if that application is not the active application, is not visible, or is minimized.

              While what DIALOG DOEVENTS actually does is proprietary, I cannot think of any way to implement it such that it would ever generate a WM_MOUSEMOVE (&h200) notification. That notification means - BION - "the mouse has moved."

              Maybe you bumped your desk.

              Comment


              • #27
                I'm using Hex$(Hi(Word, CB.lParam) as in the previous post according to the SDK WM_SETCURSOR notification
                wParam
                Handle to the window that contains the cursor.
                lParam
                The low-order word of lParam specifies the hit-test code.
                The high-order word of lParam specifies the identifier of the mouse message.
                In the previous post I experiment with clicking in the client area.

                Comment


                • #28
                  >If it isn't 'Dialog DoEvents' sending that 200, who is?

                  To paraphrase the SDK docs:
                  The system typically sends nonqueued messages (like WM_SETCURSOR) to notify a window of events that affect it.
                  For example, when the user activates a new application window, the system sends the window a series
                  of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR.

                  Looks like &H200 comes along (passed by GefWindowProc) pretty much whenever it's possible that you might need to reset the cursor. e.g. if your app regains focus (try Alt-Tabbing away from, then back to your test app to demonstrate).
                  Code:
                          CASE %WM_SETCURSOR
                              WinBeep 1800,100                      ' Beep to announce when WM_SETCURSOR is fired - it's busy!!
                              DIALOG SET TEXT CBHNDL, HEX$(HI(WORD, CBLPARAM)) : Sleep 100 : DIALOG SET TEXT CBHNDL, " "
                              IF (GetDlgCtrlID(CBWPARAM) = %IDC_TARGET) THEN 'OR (ISTRUE ConditionFlag) THEN  
                                MousePtr Mptr                       ' ** because we are taking control of the cursor
                                FUNCTION = 1                        '    - let DefWindowProc know it's been handled
                              END IF
                  Rgds, Dave

                  Comment


                  • #29
                    pretty much whenever it's possible that you might need to reset the cursor
                    With
                    Code:
                    Sleep 2000
                    zTrace("Before" + $Nul)
                    Dialog DoEvents
                    Sleep 100
                    Dialog DoEvents
                    zTrace("After" + $Nul)
                    I still get

                    201
                    Before
                    200
                    After

                    and not a couple off 200s so DefWindowProc thinks that the arrow is still in force, set by the first instance of 'Dialog DoEvents', but then it would because we used 'Function = 1' in 'CASE %WM_SETCURSOR'. At the end of the Callback DefWindowProc still thinks the arrow is in force, necessitating the 'MousePtr 1' that Dave made sure of.

                    Wow!

                    Comment


                    • #30
                      WM_SETCURSOR occurs every time the cursor is to be shown... which means every time the mouse moves or is clicked or the keyboard is used.

                      If the programmer does not "do something" in response to WM_SETCURSOR, DefWindowProc or DefDlgProc will use the default cursor for the window class.

                      While the PB 'MOUSEPTR' function is inadequately documented, I seriously doubt it resets the class default cursor, so it must be called on every WM_SETCURSOR notification for which the (current) default cursor is not wanted. (and you have to return TRUE for it to have effect).

                      Here is what the "do something" should be...
                      If an application processes this message, it should return TRUE to halt further processing or FALSE to continue.




                      Remarks

                      The high-order word of lParam is zero when the window enters menu mode.

                      The DefWindowProc function passes the WM_SETCURSOR message to a parent window before processing. If the parent window returns TRUE, further processing is halted. Passing the message to a window's parent window gives the parent window control over the cursor's setting in a child window. The DefWindowProc function also uses this message to set the cursor to an arrow if it is not in the client area, or to the registered class cursor if it is in the client area. If the low-order word of the lParam parameter is HTERROR and the high-order word of lParam specifies that one of the mouse buttons is pressed, DefWindowProc calls the MessageBeep function.
                      MCM

                      Comment


                      • #31
                        I seriously doubt it resets the class default cursor
                        I think it does

                        Code:
                        If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                          MousePtr 11
                          Sleep 2000
                        End If
                        will see the busy icon for a couple of seconds and then the arrow.

                        Added: Actually, that proves it doesn't.

                        Without Dave's 'MousePtr 1' the busy icon persists because DefWindowProc was kept out of the loop by 'Function = 1'.
                        Last edited by David Roberts; 20 May 2010, 10:32 AM.

                        Comment


                        • #32
                          Removed.

                          I thought I could dispense with 'Function = 1' but not so.
                          Last edited by David Roberts; 20 May 2010, 11:53 AM.

                          Comment


                          • #33
                            Code:
                            #DIM ALL    'MOUSEPTR.BAS
                            
                            #INCLUDE "win32api.inc"
                            GLOBAL gCursor AS LONG
                            %Button1          = 1001
                            %Sleep            = 250
                            
                            FUNCTION Dialog1(BYVAL hParent AS DWORD) AS LONG
                              gCursor = 4 'initial cursor
                              LOCAL hDlg AS LONG
                              DIALOG NEW hParent, "MOUSEPTR DEMO",,, 200, 170,%WS_SYSMENU TO hDlg
                              CONTROL ADD BUTTON, hDlg, %Button1, "Click", 10,10,50,15
                              DIALOG SHOW MODAL hDlg, CALL MyCB
                            END FUNCTION
                            
                            FUNCTION PBMAIN()
                              Dialog1 %HWND_DESKTOP
                            END FUNCTION
                            
                            CALLBACK FUNCTION MyCB()
                              SELECT CASE AS LONG CB.MSG
                                CASE  %WM_SetCursor
                                  MOUSEPTR gCursor
                                  FUNCTION = 1
                                CASE %WM_COMMAND
                                  SELECT CASE AS LONG CB.CTL
                                    CASE %Button1
                                      IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                                        Test
                                      END IF
                                  END SELECT
                              END SELECT
                            END FUNCTION
                            
                            SUB PBSetCursor(NewCursor AS LONG)
                              gCursor = NewCursor
                              MOUSEPTR NewCursor
                            END SUB
                            
                            SUB Test
                              LOCAL cursor AS LONG
                              FOR cursor = 0 TO 13
                                PBSetCursor cursor
                                SLEEP %sleep
                              NEXT
                            END SUB
                            https://www.tesla.com/roadster

                            Comment


                            • #34
                              Hi Mike,

                              And if you want to let the CPU breathe a little more then
                              you don't need to load the cursor on every WM_SETCURSOR mouse move.
                              You can load it once and have WM_SETCURSOR to only return %TRUE.

                              Pierre

                              Code:
                              #COMPILE EXE '#Win 8.04#
                              #DIM ALL
                              #INCLUDE "Win32api.inc"
                               
                              GLOBAL hDlg AS DWORD
                               
                              %ButtonCursorNormal  = 201
                              %ButtonCursorWait    = 202
                              %ButtonCursorSizeAll = 203
                              %ButtonCursorNo      = 204
                              '______________________________________________________________________________
                               
                              CALLBACK FUNCTION DlgProc
                               STATIC KeepCursor AS LONG
                               
                               SELECT CASE CBMSG
                               
                                 CASE %WM_SETCURSOR      'This message is received from Windows on mouse move/click
                                   FUNCTION = KeepCursor 'This will stop Windows resetting mouse cursor to default, usually an arrow
                               
                                 CASE %WM_COMMAND
                                   SELECT CASE LOWRD(CBWPARAM)
                               
                                     CASE %ButtonCursorSizeAll
                                       IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN
                                         SetCursor(LoadCursor(%NULL, BYVAL %IDC_SIZEALL))
                                         KeepCursor = %TRUE
                                       END IF
                               
                                     CASE %ButtonCursorNo
                                       IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN
                                         SetCursor(LoadCursor(%NULL, BYVAL %IDC_NO))
                                         KeepCursor = %TRUE
                                       END IF
                               
                                     CASE %ButtonCursorWait
                                       IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN
                                         SetCursor(LoadCursor(%NULL, BYVAL %IDC_WAIT))
                                         KeepCursor = %TRUE
                                       END IF
                               
                                     CASE %ButtonCursorNormal
                                       IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN
                                         KeepCursor = %FALSE
                                       END IF
                               
                                   END SELECT
                               
                                END SELECT
                               
                              END FUNCTION
                              '______________________________________________________________________________
                               
                              FUNCTION PBMAIN()
                               LOCAL hIconBig   AS DWORD
                               LOCAL hIconSmall AS DWORD
                               
                               DIALOG NEW %HWND_DESKTOP, "WM_SETCURSOR", , , 230,  115, _
                               %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
                               
                               ExtractIconEx("AccessibilityCpl.dll", 4, BYVAL VARPTR(hIconBig), BYVAL VARPTR(hIconSmall), 1)
                               SetClassLong(hDlg, %GCL_HICONSM, hIconSmall)
                               SetClassLong(hDlg, %GCL_HICON, hIconBig)
                               SendMessage(hDlg, %WM_SETICON, %ICON_SMALL, hIconSmall)
                               SendMessage(hDlg, %WM_SETICON, %ICON_BIG, hIconBig)
                               
                               CONTROL ADD BUTTON, hDlg, %ButtonCursorSizeAll, "Set size &all",  25, 25, 80, 25
                               CONTROL ADD BUTTON, hDlg, %ButtonCursorNo,      "Set &no",       125, 25, 80, 25
                               CONTROL ADD BUTTON, hDlg, %ButtonCursorWait,    "Set &hourglass", 25, 65, 80, 25
                               CONTROL ADD BUTTON, hDlg, %ButtonCursorNormal,  "&Set normal",   125, 65, 80, 25
                               
                               DIALOG SHOW MODAL hDlg CALL DlgProc
                               
                               DestroyIcon(hIconSmall)
                               DestroyIcon(hIconBig)
                               
                              END FUNCTION
                              '______________________________________________________________________________
                              '
                              Last edited by Pierre Bellisle; 30 May 2016, 07:32 PM.

                              Comment


                              • #35
                                Let CPU breathe with a flag comments?
                                Code:
                                #DIM ALL    'MOUSEPTR.BAS
                                TYPE MyGlobals
                                  hDlg        AS DWORD
                                  Cursor      AS LONG
                                  CursorFlag  AS LONG
                                  TestCounter AS LONG
                                END TYPE
                                GLOBAL g AS MyGlobals
                                
                                #INCLUDE "win32api.inc"
                                %Button1 = 1001
                                
                                FUNCTION Dialog1(BYVAL hParent AS DWORD) AS LONG
                                  PbSetCursor 4 'set startup cursor
                                  DIALOG NEW hParent, "MOUSEPTR DEMO",,, 200, 170,%WS_SYSMENU TO g.hDlg
                                  CONTROL ADD BUTTON, g.hDlg, %Button1, "Click", 10,10,50,15
                                  DIALOG SHOW MODAL g.hDlg, CALL MyCB
                                END FUNCTION
                                '
                                FUNCTION PBMAIN()
                                  Dialog1 %HWND_DESKTOP
                                END FUNCTION
                                '
                                CALLBACK FUNCTION MyCB()
                                  SELECT CASE AS LONG CB.MSG
                                
                                    CASE  %WM_SetCursor
                                      FUNCTION = 1
                                      IF g.CursorFlag THEN
                                        INCR g.TestCounter
                                        DIALOG SET TEXT g.hDlg,STR$(g.TestCounter)
                                        MOUSEPTR g.Cursor
                                        'FUNCTION = 1 'not needed 5/31/16 7:04AM CST
                                        g.CursorFlag = %FALSE
                                      END IF
                                
                                    CASE %WM_COMMAND
                                      SELECT CASE AS LONG CB.CTL
                                        CASE %Button1
                                          IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                                            CONTROL DISABLE g.hDlg,%BUTTON1
                                            Test
                                            CONTROL ENABLE g.hDlg,%BUTTON1
                                          END IF
                                      END SELECT
                                  END SELECT
                                END FUNCTION
                                
                                SUB PBSetCursor(NewCursor AS LONG)
                                  g.Cursor = NewCursor
                                  MOUSEPTR NewCursor
                                  g.CursorFlag = %True
                                END SUB
                                
                                SUB Test
                                  PbSetCursor 11
                                  WaitInSeconds 1
                                  PbSetCursor 4
                                END SUB
                                
                                SUB WaitInSeconds(Seconds AS LONG)
                                  LOCAL counter AS LONG
                                  FOR counter = 1 TO Seconds *4
                                    SLEEP 250
                                    DIALOG DOEVENTS
                                  NEXT
                                END SUB
                                Last edited by Mike Doty; 31 May 2016, 07:08 AM.
                                https://www.tesla.com/roadster

                                Comment


                                • #36
                                  Yep, a little, in the sense that the cursor do not have to be
                                  reloaded on every mouse move, keeping the chosen one via KeepCursor is enough.

                                  Pierre

                                  Comment


                                  • #37
                                    Your method is definitely the under the hood method.
                                    Thank you for showing the errors of my ways.

                                    This just shows the basics:
                                    Code:
                                    GLOBAL gCursor,gCursorFlag AS LONG
                                    
                                    FUNCTION PBMAIN () AS LONG
                                      PbSetCursor 4
                                    END FUNCTION
                                    
                                    CASE  %WM_SetCursor
                                      FUNCTION = 1
                                      IF gCursorFlag THEN
                                        MOUSEPTR gCursor
                                        gCursorFlag = 0
                                      END IF
                                    
                                    SUB PBSetCursor(NewCursor AS LONG)
                                      gCursor = NewCursor
                                      MOUSEPTR NewCursor
                                      gCursorFlag = 1
                                    END SUB
                                    With dialog (compressed for easier studying)
                                    Code:
                                    #INCLUDE "win32api.inc"
                                    
                                    GLOBAL gCursor,gCursorFlag AS LONG
                                    
                                    SUB Test
                                      PBSetCursor 11:SLEEP 500:PbSetCursor 4
                                    END SUB
                                    
                                    FUNCTION PBMAIN () AS LONG
                                      Dialog1 %HWND_DESKTOP
                                    END FUNCTION
                                    
                                    FUNCTION Dialog1(BYVAL hParent AS DWORD) AS LONG
                                      LOCAL hDlg AS DWORD
                                      PbSetCursor 4
                                      DIALOG NEW hParent, "MOUSEPTR DEMO",,, 200, 170,%WS_SYSMENU TO hDlg
                                      CONTROL ADD BUTTON, hDlg, 1001, "Test", 10,10,50,15
                                      DIALOG SHOW MODAL   hDlg, CALL MyCallBack
                                    END FUNCTION
                                    
                                    CALLBACK FUNCTION MyCallBack()
                                      SELECT CASE AS LONG CB.MSG
                                        CASE  %WM_SetCursor:FUNCTION=1:IF gCursorFlag THEN MOUSEPTR gCursor:gCursorFlag=0
                                        CASE %WM_COMMAND
                                          SELECT CASE AS LONG CB.CTL
                                            CASE 1001:IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN Test
                                          END SELECT
                                      END SELECT
                                    END FUNCTION
                                    
                                    SUB PBSetCursor(NewCursor AS LONG)
                                      gCursor=NewCursor:MOUSEPTR NewCursor:gCursorFlag=1
                                    END SUB













                                    Last edited by Mike Doty; 31 May 2016, 07:35 PM.
                                    https://www.tesla.com/roadster

                                    Comment


                                    • #38
                                      Here is an example of Cursor Wait control within a thread...

                                      Code:
                                      #INCLUDE "win32api.inc"
                                      
                                      GLOBAL gMousePointerControl  AS LONG
                                      GLOBAL ghDlg                 AS DWORD
                                      
                                      %ID_StartWait = 1002
                                      %ID_StopWait  = 1003
                                      
                                      DECLARE THREAD FUNCTION DoTestThread(BYVAL yyy AS DWORD) AS LONG    'temporary
                                      
                                      SUB Test
                                        SendMessage ghDlg, %WM_COMMAND, %ID_StartWait, 0
                                        SLEEP 500
                                        SendMessage ghDlg, %WM_COMMAND, %ID_StopWait, 0
                                      END SUB
                                      
                                      FUNCTION PBMAIN () AS LONG
                                        Dialog1 %HWND_DESKTOP
                                      END FUNCTION
                                      
                                      FUNCTION Dialog1(BYVAL hParent AS DWORD) AS LONG
                                        MOUSEPTR 4
                                        DIALOG NEW hParent, "MOUSEPTR DEMO",,, 200, 170,%WS_SYSMENU TO ghDlg
                                        CONTROL ADD BUTTON, ghDlg, 1001, "Test", 10,10,50,15
                                        DIALOG SHOW MODAL   ghDlg, CALL MyCallBack
                                      END FUNCTION
                                      
                                      CALLBACK FUNCTION MyCallBack()
                                        SELECT CASE AS LONG CB.MSG
                                          CASE %WM_SetCursor
                                              IF gMousePointerControl = 1 THEN
                                                  MOUSEPTR 11
                                              ELSE
                                                  MOUSEPTR 4
                                              END IF
                                              FUNCTION = 1
                                      
                                          CASE %WM_COMMAND
                                            SELECT CASE AS LONG CB.CTL
                                              CASE 1001
                                                  IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                                                      LOCAL idThreadDoTest    AS LONG
                                      
                                                      THREAD CREATE DoTestThread(1) TO idThreadDoTest
                                                      THREAD CLOSE idThreadDoTest TO idThreadDoTest
                                      
                                                  END IF
                                      
                                              CASE %ID_StartWait
                                                 gMousePointerControl = 1
                                                 MOUSEPTR 11
                                                 FUNCTION = 1
                                                 EXIT FUNCTION
                                      
                                              CASE %ID_StopWait
                                                 gMousePointerControl = 0
                                                 MOUSEPTR 4
                                                 FUNCTION = 1
                                                 EXIT FUNCTION
                                      
                                            END SELECT
                                        END SELECT
                                      END FUNCTION
                                      
                                      
                                      '_________________________________________________________________
                                      '
                                      '   FUNCTION  DoTestThread
                                      '_________________________________________________________________
                                      
                                      THREAD FUNCTION DoTestThread(BYVAL yyy AS DWORD) AS LONG
                                      
                                          CALL Test
                                      
                                          FUNCTION = 1
                                      END FUNCTION

                                      Comment

                                      Working...
                                      X