Announcement

Collapse
No announcement yet.

Advise on Dialog Box Move/Drag

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

  • Advise on Dialog Box Move/Drag

    Hi to all
    I have PUT together a rough example showing a problem when I drag a Dialog Box.
    When you run the program and press Start Button you will see a bunch of colored numbers count.
    When you Drag the Dialog Box you will notice the numbers stop counting, once released the counting
    starts again. I was wondering if there is a way to return back to the application so it can continue
    counting when dragged?. To give you some background info on the application, I Read Data from a
    High Speed CAN Bus, this data has to be read, processed and sometimes logged. To keep up with this
    High Speed traffic I have to talk to a DLL which talks to a device which passes the Data to me.
    I originally Read the Data using Threads but it was a touch slow and could not keep up, I then tried
    Timer and it worked well but was a touch slow not keeping up with the high flow of data. In the Example Code
    shown seems to work the fastest and can keep up with the Data, the only drawback is when
    the Window is dragged the program stops reading the Data which can cause the buffer to overflow and
    not process the Data. Maybe with Timer or Threads there are tricks to make it work faster but
    I am limited with Windows experience.

    Code:
     
    #PBFORMS CREATED V1.51
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other
    ' PB/Forms metastatements are placed at the beginning and
    ' end of "Named Blocks" of code that should be edited
    ' with PBForms only. Do not manually edit or delete these
    ' metastatements or PB/Forms will not be able to reread
    ' the file correctly. See the PB/Forms documentation for
    ' more information.
    ' Named blocks begin like this: #PBFORMS BEGIN ...
    ' Named blocks end like this: #PBFORMS END ...
    ' Other PB/Forms metastatements such as:
    ' #PBFORMS DECLARATIONS
    ' are used by PB/Forms to insert additional code.
    ' Feel free to make changes anywhere else in the file.
    '------------------------------------------------------------------------------
    #COMPILE EXE
    #DIM ALL
    '------------------------------------------------------------------------------
    ' ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    %USEMACROS = 1
    #IF NOT %DEF(%WINAPI)
    #INCLUDE "WIN32API.INC"
    #ENDIF
    #IF NOT %DEF(%COMMCTRL_INC)
    #INCLUDE "COMMCTRL.INC"
    #ENDIF
    #INCLUDE "PBForms.INC"
    #PBFORMS END INCLUDES
    '------------------------------------------------------------------------------
    ' ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1 = 101
    %IDC_GRAPHIC1 = 102
    %IDC_GRAPHIC2 = 103
    %IDC_GRAPHIC3 = 104
    %IDC_FRAME1 = 138
    %IDC_StartComms = 139
    %IDC_StopComms = 140
    #PBFORMS END CONSTANTS
    '---------------------------------------------------------------------------
    ' ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    DECLARE CALLBACK FUNCTION ShowDIALOG2Proc()
    DECLARE FUNCTION ShowDIALOG2(BYVAL hDlg AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
     
    GLOBAL hFont AS LONG
    GLOBAL Abort AS LONG
    GLOBAL C() AS LONG
    '------------------------------------------------------------------------------
    ' ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
    PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
    ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    '------------------------------------------------------------------------------
    ' ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
    DIM C(10) AS GLOBAL LONG
    SELECT CASE AS LONG CBMSG
    CASE %WM_INITDIALOG
    FONT NEW "FIXEDSYS", 10 TO hFont
    C(0) = %BLACK
    C(1) = %BLUE
    C(2) = %GREEN
    C(3) = %CYAN
    C(4) = %RED
    C(5) = %MAGENTA
    C(6) = %YELLOW
    C(7) = %WHITE
    C(8) = %GRAY
    C(9) = %LTGRAY
    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_DESTROY
    Abort = -1
    CASE %WM_MOVE
    CASE %WM_COMMAND
    ' Process control notifications
    SELECT CASE AS LONG CBCTL
    CASE %IDC_StartComms
    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
    Abort = 0
    Showpacket (CB.HNDL)
    END IF
    CASE %IDC_StopComms
    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
    Abort = -1
    END IF
    END SELECT
    END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    ' ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    LOCAL lRslt AS LONG,w AS LONG, h AS LONG
     
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
    LOCAL hDlg AS DWORD
    LOCAL hFont1 AS DWORD
    DIALOG NEW PIXELS, hParent, "Test", 260, 143, 400, 315, %WS_POPUP OR _
    %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
    %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
    %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
    CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 30, 41, 322, 24, %WS_CHILD _
    OR %WS_VISIBLE OR %WS_BORDER
    CONTROL ADD BUTTON, hDlg, %IDC_StartComms, "Start", 68, 244, 90, 48, _
    %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER _
    OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
    CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC2, "", 30, 89, 322, 25, %WS_CHILD _
    OR %WS_VISIBLE OR %WS_BORDER
    CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC3, "", 30, 138, 322, 24, %WS_CHILD _
    OR %WS_VISIBLE OR %WS_BORDER
    CONTROL ADD FRAME, hDlg, %IDC_FRAME1, "PID's", 8, 8, 382, 203
    CONTROL ADD BUTTON, hDlg, %IDC_StopComms, "Stop", 225, 244, 90, 48
    hFont1 = PBFormsMakeFont("MS Sans Serif", 10, 400, %FALSE, %FALSE, _
    %FALSE, %ANSI_CHARSET)
    CONTROL SEND hDlg, %IDC_StartComms, %WM_SETFONT, hFont1, 0
    CONTROL SEND hDlg, %IDC_FRAME1, %WM_SETFONT, hFont1, 0
    CONTROL SEND hDlg, %IDC_StopComms, %WM_SETFONT, hFont1, 0
    #PBFORMS END DIALOG
    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    DeleteObject hFont1
    #PBFORMS END CLEANUP
    FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    SUB PrintBox (BYVAL hDlg AS DWORD, _
    BYVAL ID AS LONG, _
    BYVAL sText AS STRING, _
    BYVAL X AS LONG, _
    BYVAL FontClr AS LONG)
    LOCAL Xpos AS LONG
    DECR X
    XPos = X * 8 + 5
    GRAPHIC ATTACH hDlg, ID, REDRAW
    GRAPHIC SET FONT hFont
    GRAPHIC COLOR FontClr, -1
    GRAPHIC SET POS (Xpos, 2)
    GRAPHIC PRINT sText
    END SUB
    '------------------------------------------------------------------------------
    FUNCTION ShowPacket (BYVAL CTLHandle AS DWORD) AS LONG
    LOCAL A AS LONG
    LOCAL X AS LONG
    LOCAL Z AS LONG
    DO
    PrintBox CTLHandle, %IDC_GRAPHIC1+X, USING$("####";A), 15, C(Z)
    GRAPHIC REDRAW
    DIALOG DOEVENTS 50
    IF Abort THEN EXIT DO
    INCR A: IF A > 1000 THEN A = 0
    INCR X: IF X > 2 THEN X = 0
    INCR Z: IF Z > 9 THEN Z = 0
    LOOP
     
    END FUNCTION
    '------------------------------------------------------------------------------
    Last edited by Peter Maroudas; 2 May 2009, 03:44 AM.
    Peter Maroudas

  • #2
    I guess you tried it all and in several cases the processing was to slow.
    I would look for a better computer since a thread should be enough.
    You can optimize some parts i suspect but it appears to me you have reached the computer's limit.

    Even if you succeed it may produce a problem in some scenario's.
    Like when you start another app or a virusscanner doing something.
    Windows s***s
    hellobasic

    Comment


    • #3
      Edwin

      In my case its possibly very true about the PC processing power being a contribiting cause when I tested Threads at the time.

      But I am curious to know, when you Drag/Move the Dialog Box across the screen is the Message Loop so busy processing messages that it stays in a constant Loop and not able to return to the Callback Function until the mouse button is released?

      Is that what I am seeing when the numbers stop updating/counting on the Dialog Box when Moved.
      Peter Maroudas

      Comment


      • #4
        Hi Peter,

        Try this mod to your code - changes ShowPacket() to a
        threaded function operating separately from the main GUI (callback) function.
        Code:
              SELECT CASE AS LONG CBCTL
                CASE %IDC_StartComms
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 Then
                 Local hThread, Res As Long
                  Abort = 0
                  Thread Create Showpacket (CB.HNDL) To hThread
                  Thread Close hThread To Res
                END IF
                CASE %IDC_StopComms
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                Abort = -1
                END IF
              END SELECT
        Rgds, Dave

        Comment


        • #5
          Originally posted by Peter Maroudas View Post
          Edwin

          In my case its possibly very true about the PC processing power being a contribiting cause when I tested Threads at the time.

          But I am curious to know, when you Drag/Move the Dialog Box across the screen is the Message Loop so busy processing messages that it stays in a constant Loop and not able to return to the Callback Function until the mouse button is released?

          Is that what I am seeing when the numbers stop updating/counting on the Dialog Box when Moved.
          From what i know..
          During the *first* attempt to drag a window, everything freezes, the next time it seems to behave different.
          I believe i have tested this with a timer updating a static and i had trouble with MSIE breaking up transmision into several parts (uploading)

          You can not rely on the GUI stuff and you'll need to find a different way like threads.

          Often the question is "i can not drag the form during my process".
          I suspect this is not the case here, your process is influenced by the GUI.
          hellobasic

          Comment


          • #6
            You could try thread priority?
            hellobasic

            Comment


            • #7
              Dave

              I originaly did that as you have shown using a Thread, but for some reason I did not keep up. I could have tried a few things like only update
              the screen so often to help it in the background to process incoming
              data but if its on the limit now, it won't keep up with more traffice later.

              Although I am not showing the original code for the CAN Bus routines
              it runs like a Rocket Ship using PBCC Console Compiler . I thought I practice converting the program to GUI.
              Peter Maroudas

              Comment


              • #8
                Edwin

                I did try all the Thread Priorities using THREAD SET PRIORITY and I did not
                notice any difference. I even checked them with THREAD GET PRIORITY
                to be sure.
                Peter Maroudas

                Comment


                • #9
                  Peter,

                  How much data are you dealing with? I mean what what sort of baud rate?
                  Rgds, Dave

                  Comment


                  • #10
                    Dave

                    The Data is anywhere up to 1mbit

                    Here is the device I am using, been using it for a few years now.
                    http://www.drewtech.com/products/Mon...ngooseiso.html
                    Peter Maroudas

                    Comment


                    • #11
                      Since nobody can read that fast anyway, you could show the numbers only every 'X' increments ..

                      Code:
                      incr count 
                      if count mod 10 =1 then 
                          show 'em
                      ....
                      Or, only go to this when you are dragging, eg,,
                      Code:
                      incr count 
                      if  ISTRUE (Dragging) IMP ISTRUE (count mod 10 =1) then 
                          show 'em
                      ....
                      Last edited by Michael Mattias; 2 May 2009, 08:25 AM.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Peter,

                        Thanks for the link - that looks pretty interesting.

                        As you have no problem keeping up with the data when using PBCC ("runs like a Rocket Ship") it would seem that your processor and the PBCC receive functions are more than adequate.
                        Those same receive functions should translate to threaded functions for your PBWin version with few changes.

                        Once the data is being received in it's own thread(s) in the PBWin program, the challenge is to update the GUI without interupting the program flow within the receive thread.
                        One way to do that is to set the data values to common (global) variables in the receive thread then read that data (periodically) in the main thread to update the GUI and/or in another thread to be written to a log file.

                        That's the approach that PB's Comms.bas example illustrates. I've used it in serial data programs of mine, sometimes running on pretty limited hardware, with good results.
                        Rgds, Dave

                        Comment


                        • #13
                          The separate thread thing does no good as shown, because all GDI operations (e.g the "GRAPHIC REDRAW" ) must execute in the thread context in which the window was created. That means Windows forces a thread switch at that time.

                          (Aside: PB/Forms does not INDENT the code it creates? That code is nearly impossible to read).

                          You have to get ONLY GUI operations in one thread, and ONLY your I-O operations in another, and when you need the two to communicate, you have to use something which is not going to force thread context switches.

                          Take a look at this demo: GUI + Worker Thread + Abort Demo 11-24-07

                          You can base your application on this.

                          Basically you want to do something like...
                          Code:
                             DIALOG NEW ....
                          
                             THREAD CREATE IOFunction   SUSPEND  (now that the suspend option is fixed) 
                             Set thread priority down on current thread (the GUI thread) 
                             DIALOG SHOW  MODELESS    
                             MESSAGE LOOP 
                          
                          CALBACK FUNCTION  whatever
                          
                                   CASE WM_INITDIALOG 
                                       whatever 
                                       POST message to self to resume the thread  function
                                    
                                   CASE private message to resume thread function 
                                        THREAD RESUME ...
                          
                          
                          THREAD FUNCTION IOFUNCTION (param) 
                          
                              DO 
                                 GetInput 
                                 Post a message to GUI to update when it gets around to it 
                             LOOP UNTIL told_to_stop
                          
                          END FUNCTION
                          MCM
                          Last edited by Michael Mattias; 2 May 2009, 10:42 AM.
                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            The separate thread thing does no good as shown, because all GDI operations (e.g the "GRAPHIC REDRAW" ) must execute in the thread context in which the window was created.
                            Yet strangely this does make a difference?
                            Code:
                             
                            #PBFORMS CREATED V1.51
                            '------------------------------------------------------------------------------
                            ' The first line in this file is a PB/Forms metastatement.
                            ' It should ALWAYS be the first line of the file. Other
                            ' PB/Forms metastatements are placed at the beginning and
                            ' end of "Named Blocks" of code that should be edited
                            ' with PBForms only. Do not manually edit or delete these
                            ' metastatements or PB/Forms will not be able to reread
                            ' the file correctly. See the PB/Forms documentation for
                            ' more information.
                            ' Named blocks begin like this: #PBFORMS BEGIN ...
                            ' Named blocks end like this: #PBFORMS END ...
                            ' Other PB/Forms metastatements such as:
                            ' #PBFORMS DECLARATIONS
                            ' are used by PB/Forms to insert additional code.
                            ' Feel free to make changes anywhere else in the file.
                            '------------------------------------------------------------------------------
                            #COMPILE EXE
                            #DIM ALL
                            '------------------------------------------------------------------------------
                            ' ** Includes **
                            '------------------------------------------------------------------------------
                            #PBFORMS BEGIN INCLUDES
                            %USEMACROS = 1
                            #IF NOT %DEF(%WINAPI)
                              #INCLUDE "WIN32API.INC"
                            #ENDIF
                            #IF NOT %DEF(%COMMCTRL_INC)
                              #INCLUDE "COMMCTRL.INC"
                            #ENDIF
                            #INCLUDE "PBForms.INC"
                            #PBFORMS END INCLUDES
                            '------------------------------------------------------------------------------
                            ' ** Constants **
                            '------------------------------------------------------------------------------
                            #PBFORMS BEGIN CONSTANTS
                            %IDD_DIALOG1  = 101
                            %IDC_GRAPHIC1 = 102
                            %IDC_GRAPHIC2 = 103
                            %IDC_GRAPHIC3 = 104
                            %IDC_FRAME1   = 138
                            %IDC_StartComms = 139
                            %IDC_StopComms  = 140
                            #PBFORMS END CONSTANTS
                            '---------------------------------------------------------------------------
                            ' ** Declarations **
                            '------------------------------------------------------------------------------
                            DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                            DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                            DECLARE CALLBACK FUNCTION ShowDIALOG2Proc()
                            DECLARE FUNCTION ShowDIALOG2(BYVAL hDlg AS DWORD) AS LONG
                            #PBFORMS DECLARATIONS
                             
                            GLOBAL hFont AS LONG
                            GLOBAL Abort AS LONG
                            GLOBAL C() AS LONG
                            '------------------------------------------------------------------------------
                            ' ** Main Application Entry Point **
                            '------------------------------------------------------------------------------
                            FUNCTION PBMAIN()
                              PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
                              ShowDIALOG1 %HWND_DESKTOP
                            END FUNCTION
                            '------------------------------------------------------------------------------
                            ' ** CallBacks **
                            '------------------------------------------------------------------------------
                            CALLBACK FUNCTION ShowDIALOG1Proc()
                             DIM C(10) AS GLOBAL LONG
                              SELECT CASE AS LONG CBMSG
                                CASE %WM_INITDIALOG
                                  FONT NEW "FIXEDSYS", 10 TO hFont
                                  C(0) = %BLACK
                                  C(1) = %BLUE
                                  C(2) = %GREEN
                                  C(3) = %CYAN
                                  C(4) = %RED
                                  C(5) = %MAGENTA
                                  C(6) = %YELLOW
                                  C(7) = %WHITE
                                  C(8) = %GRAY
                                  C(9) = %LTGRAY
                             
                                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_DESTROY
                                  Abort = -1
                             
                                CASE %WM_MOVE
                             
                                CASE %WM_COMMAND
                                ' Process control notifications
                                   SELECT CASE AS LONG CBCTL
                                     CASE %IDC_StartComms
                                       IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                             
                            '            Abort = 0
                             '            Showpacket (CB.HNDL)
                             '          END IF
                             '        CASE %IDC_StopComms
                             '          IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                             '            Abort = -1
                             '          END IF
                             '      END SELECT
                             
                                     Local hThread, Res As Long
                                      Abort = 0
                                      Thread Create Showpacket (CB.HNDL) To hThread
                                      Thread Close hThread To Res
                                    END IF
                                    CASE %IDC_StopComms
                                    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                    Abort = -1
                                    END IF
                                  END SELECT
                             
                              END SELECT
                            END FUNCTION
                            '------------------------------------------------------------------------------
                            ' ** Dialogs **
                            '------------------------------------------------------------------------------
                            FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                              LOCAL lRslt AS LONG,w AS LONG, h AS LONG
                             
                            #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                             LOCAL hDlg AS DWORD
                             LOCAL hFont1 AS DWORD
                              DIALOG NEW PIXELS, hParent, "Test", 260, 143, 400, 315, %WS_POPUP OR _
                                %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
                                %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                                %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                              CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 30, 41, 322, 24, %WS_CHILD _
                                OR %WS_VISIBLE OR %WS_BORDER
                              CONTROL ADD BUTTON, hDlg, %IDC_StartComms, "Start", 68, 244, 90, 48, _
                                %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER _
                                OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
                              CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC2, "", 30, 89, 322, 25, %WS_CHILD _
                                OR %WS_VISIBLE OR %WS_BORDER
                              CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC3, "", 30, 138, 322, 24, %WS_CHILD _
                                OR %WS_VISIBLE OR %WS_BORDER
                              CONTROL ADD FRAME, hDlg, %IDC_FRAME1, "PID's", 8, 8, 382, 203
                              CONTROL ADD BUTTON, hDlg, %IDC_StopComms, "Stop", 225, 244, 90, 48
                              hFont1 = PBFormsMakeFont("MS Sans Serif", 10, 400, %FALSE, %FALSE, _
                                %FALSE, %ANSI_CHARSET)
                              CONTROL SEND hDlg, %IDC_StartComms, %WM_SETFONT, hFont1, 0
                              CONTROL SEND hDlg, %IDC_FRAME1, %WM_SETFONT, hFont1, 0
                              CONTROL SEND hDlg, %IDC_StopComms, %WM_SETFONT, hFont1, 0
                             
                            #PBFORMS END DIALOG
                             
                              DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                             
                            #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
                              DeleteObject hFont1
                            #PBFORMS END CLEANUP
                             FUNCTION = lRslt
                            END FUNCTION
                            '------------------------------------------------------------------------------
                            SUB PrintBox (BYVAL hDlg AS DWORD, _
                                          BYVAL ID AS LONG, _
                                          BYVAL sText AS STRING, _
                                          BYVAL X AS LONG, _
                                          BYVAL FontClr AS LONG)
                             LOCAL Xpos AS LONG
                              DECR X
                              XPos = X * 8 + 5
                              GRAPHIC ATTACH hDlg, ID, REDRAW
                              GRAPHIC SET FONT hFont
                              GRAPHIC COLOR FontClr, -1
                              GRAPHIC SET POS (Xpos, 2)
                              GRAPHIC PRINT sText
                            END SUB
                            '------------------------------------------------------------------------------
                            FUNCTION ShowPacket (BYVAL CTLHandle AS DWORD) AS LONG
                             LOCAL A AS LONG
                             LOCAL X AS LONG
                             LOCAL Z AS LONG
                            DO
                              PrintBox CTLHandle, %IDC_GRAPHIC1+X, USING$("####";A), 15, C(Z)
                              GRAPHIC REDRAW
                              DIALOG DOEVENTS 50
                              IF Abort THEN EXIT DO
                              INCR A: IF A > 1000 THEN A = 0
                              INCR X: IF X > 2 THEN X = 0
                              INCR Z: IF Z > 9 THEN Z = 0
                            LOOP
                             
                            END FUNCTION
                            '------------------------------------------------------------------------------
                            Rgds, Dave

                            Comment


                            • #15
                              The proper way to use a Thread which needs to change the GUI.
                              The thread itself should not make any GUI calls. It should send a message to the dialog, which will force a context switch to the main GUI thread. Then in response to the message, the GUI can be updated.

                              You can pass data to the main GUI thread, via a pointer to a structure so you don't need global variables.

                              It can do about 500 iterations per second.

                              Code:
                              #PBFORMS CREATED V1.51
                              '------------------------------------------------------------------------------
                              ' The first line in this file is a PB/Forms metastatement.
                              ' It should ALWAYS be the first line of the file. Other
                              ' PB/Forms metastatements are placed at the beginning and
                              ' end of "Named Blocks" of code that should be edited
                              ' with PBForms only. Do not manually edit or delete these
                              ' metastatements or PB/Forms will not be able to reread
                              ' the file correctly. See the PB/Forms documentation for
                              ' more information.
                              ' Named blocks begin like this: #PBFORMS BEGIN ...
                              ' Named blocks end like this: #PBFORMS END ...
                              ' Other PB/Forms metastatements such as:
                              ' #PBFORMS DECLARATIONS
                              ' are used by PB/Forms to insert additional code.
                              ' Feel free to make changes anywhere else in the file.
                              '------------------------------------------------------------------------------
                              #COMPILE EXE
                              #DIM ALL
                              '------------------------------------------------------------------------------
                              ' ** Includes **
                              '------------------------------------------------------------------------------
                              #PBFORMS BEGIN INCLUDES
                              %USEMACROS = 1
                              #IF NOT %DEF(%WINAPI)
                              #INCLUDE "WIN32API.INC"
                              #ENDIF
                              #IF NOT %DEF(%COMMCTRL_INC)
                              #INCLUDE "COMMCTRL.INC"
                              #ENDIF
                              #INCLUDE "PBForms.INC"
                              #PBFORMS END INCLUDES
                              '------------------------------------------------------------------------------
                              ' ** Constants **
                              '------------------------------------------------------------------------------
                              #PBFORMS BEGIN CONSTANTS
                              %IDD_DIALOG1 = 101
                              %IDC_GRAPHIC1 = 102
                              %IDC_GRAPHIC2 = 103
                              %IDC_GRAPHIC3 = 104
                              %IDC_FRAME1 = 138
                              %IDC_StartComms = 139
                              %IDC_StopComms = 140
                              #PBFORMS END CONSTANTS
                              '---------------------------------------------------------------------------
                              ' ** Declarations **
                              '------------------------------------------------------------------------------
                              DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                              DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                              DECLARE CALLBACK FUNCTION ShowDIALOG2Proc()
                              DECLARE FUNCTION ShowDIALOG2(BYVAL hDlg AS DWORD) AS LONG
                              #PBFORMS DECLARATIONS
                              GLOBAL hFont AS LONG
                              GLOBAL Abort AS LONG
                              GLOBAL C() AS LONG
                              '------------------------------------------------------------------------------
                              ' ** Main Application Entry Point **
                              '------------------------------------------------------------------------------
                              FUNCTION PBMAIN()
                                   PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
                                   ShowDIALOG1 %HWND_DESKTOP
                              END FUNCTION
                              '------------------------------------------------------------------------------
                              ' ** CallBacks **
                              '------------------------------------------------------------------------------
                              '
                              GLOBAL hThread&
                              %MY_ThreadMessage   =    %WM_USER+400
                              TYPE ThreadData
                                   ThDlg AS DWORD
                                   TID AS LONG
                                   TsText AS ASCIIZ*255
                                   TX AS LONG
                                   TFontClr AS LONG
                              END TYPE
                              '
                              CALLBACK FUNCTION ShowDIALOG1Proc()
                                   DIM C(10) AS GLOBAL LONG
                                   SELECT CASE AS LONG CBMSG
                                        CASE %MY_ThreadMessage
                                             LOCAL T AS ThreadData PTR
                                             T=CBWPARAM
                                             PrintBox @T.ThDlg, @T.TID, @T.TsText, @T.TX, @T.TFontClr
                                             FUNCTION=1
                                             EXIT FUNCTION
                                        CASE %WM_INITDIALOG
                                             FONT NEW "FIXEDSYS", 10 TO hFont
                                             C(0) = %BLACK
                                             C(1) = %BLUE
                                             C(2) = %GREEN
                                             C(3) = %CYAN
                                             C(4) = %RED
                                             C(5) = %MAGENTA
                                             C(6) = %YELLOW
                                             C(7) = %WHITE
                                             C(8) = %GRAY
                                             C(9) = %LTGRAY
                                        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_DESTROY
                                             Abort = -1
                                        CASE %WM_MOVE
                                        CASE %WM_COMMAND
                                        ' Process control notifications
                                        SELECT CASE AS LONG CBCTL
                                             CASE %IDC_StartComms
                                                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                                       Abort = 0
                                                       THREAD CREATE Showpacket (CB.HNDL) TO hThread&
                                                  END IF
                                             CASE %IDC_StopComms
                                                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                                       Abort = -1
                                                  END IF
                                             END SELECT
                                        END SELECT
                              END FUNCTION
                              '------------------------------------------------------------------------------
                              ' ** Dialogs **
                              '------------------------------------------------------------------------------
                              FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                   LOCAL lRslt AS LONG,w AS LONG, h AS LONG
                                   #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                                   LOCAL hDlg AS DWORD
                                   LOCAL hFont1 AS DWORD
                                   DIALOG NEW PIXELS, hParent, "Test", 260, 143, 400, 315, %WS_POPUP OR _
                                   %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
                                   %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                                   %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                   CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 30, 41, 322, 24, %WS_CHILD _
                                   OR %WS_VISIBLE OR %WS_BORDER
                                   CONTROL ADD BUTTON, hDlg, %IDC_StartComms, "Start", 68, 244, 90, 48, _
                                   %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER _
                                   OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
                                   CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC2, "", 30, 89, 322, 25, %WS_CHILD _
                                   OR %WS_VISIBLE OR %WS_BORDER
                                   CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC3, "", 30, 138, 322, 24, %WS_CHILD _
                                   OR %WS_VISIBLE OR %WS_BORDER
                                   CONTROL ADD FRAME, hDlg, %IDC_FRAME1, "PID's", 8, 8, 382, 203
                                   CONTROL ADD BUTTON, hDlg, %IDC_StopComms, "Stop", 225, 244, 90, 48
                                   hFont1 = PBFormsMakeFont("MS Sans Serif", 10, 400, %FALSE, %FALSE, _
                                   %FALSE, %ANSI_CHARSET)
                                   CONTROL SEND hDlg, %IDC_StartComms, %WM_SETFONT, hFont1, 0
                                   CONTROL SEND hDlg, %IDC_FRAME1, %WM_SETFONT, hFont1, 0
                                   CONTROL SEND hDlg, %IDC_StopComms, %WM_SETFONT, hFont1, 0
                                   #PBFORMS END DIALOG
                                   DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                                   #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
                                   DeleteObject hFont1
                                   #PBFORMS END CLEANUP
                                   FUNCTION = lRslt
                              END FUNCTION
                              '------------------------------------------------------------------------------
                              SUB PrintBox (BYVAL hDlg AS DWORD, _
                                   BYVAL ID AS LONG, _
                                   BYVAL sText AS STRING, _
                                   BYVAL X AS LONG, _
                                   BYVAL FontClr AS LONG)
                                   LOCAL Xpos AS LONG
                                   DECR X
                                   XPos = X * 8 + 5
                                   GRAPHIC ATTACH hDlg, ID, REDRAW
                                   GRAPHIC SET FONT hFont
                                   GRAPHIC COLOR FontClr, -1
                                   GRAPHIC SET POS (Xpos, 2)
                                   GRAPHIC PRINT sText
                                   GRAPHIC REDRAW
                              END SUB
                              '------------------------------------------------------------------------------
                              THREAD FUNCTION ShowPacket (BYVAL CTLHandle AS DWORD) AS LONG
                                   LOCAL A AS LONG
                                   LOCAL X AS LONG
                                   LOCAL Z AS LONG
                                   LOCAL T AS ThreadData
                                   DO
                                        T.ThDlg   = CTLHandle
                                        T.TID     = %IDC_GRAPHIC1+X
                                        T.TsText  = USING$("####";A)
                                        T.TX      = 15
                                        T.TFontClr= C(Z)
                                        SendMessage CTLHandle, %MY_ThreadMessage, VARPTR(T),0
                                        IF Abort THEN EXIT DO
                                        INCR A: IF A > 32000 THEN A = 0
                                        INCR X: IF X > 2 THEN X = 0
                                        INCR Z: IF Z > 9 THEN Z = 0
                                   LOOP
                              END FUNCTION
                              '------------------------------------------------------------------------------
                              Chris Boss
                              Computer Workshop
                              Developer of "EZGUI"
                              http://cwsof.com
                              http://twitter.com/EZGUIProGuy

                              Comment


                              • #16
                                It should send a message to the dialog, which will force a context switch to the main GUI thread.
                                Well, that makes two opinions.

                                I think it should POST a message to the dialog... which will get the message processed the next time Windows was going to make a thread switch anyway, rather than forcing a thread switch at that time.

                                (Application-specific, of course).

                                In this case, I'll bet simply disabling updates whilst dragging will make all the difference in the world.

                                Computers are fast, but not infinitely so. Using clocks to constantly update the screen while dragging seems like overkill if those clocks would be better spent processing input.

                                When you are not dragging, you don't have to use clocks updating the entire screen as it moves, so the computer CAN keep up under tose conditions.
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                • #17
                                  (Previously posted as response to a thread in another forum. It belongs here)

                                  See also:
                                  WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE.

                                  Disable repainting (WM_SETREDRAW) while the user is moving the window. When he's done moving, re-enable painting (WM_SETREDRAW) and only the last WM_PAINT will be processed.
                                  Michael Mattias
                                  Tal Systems (retired)
                                  Port Washington WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                  • #18
                                    Posting a message from a thread is not possible here.

                                    First, you can't pass a pointer to structure when posting a message, since the structure may be gone by time the message is processed.

                                    Second, SendMessage does not return until the message is processed, so you know the code in the message has been executed before continuing another iteration in the thread.

                                    Sendmessage forces an immediate context switch (which is what is wanted) so you know all the GUI code is already in the proper thread when executed, otherwise the GUI code (if called from the thread) could cause multiple context switches, rather than just one (by sendmessage).

                                    Lastly, PostMessage is dangerous in such situations since the posted messages can end up piling up in the message que. The thread can execute faster than the message que can process the messages, so they pile up. Trust me, I know. I have done a lot of experiments with threads calling the main GUI thread and PostMessage can crash the app, because of too many messages pilling up in the message que.

                                    SendMessage is the proper way to communicate between a worker thread and the main GUI thread. It works flawlessly.
                                    Chris Boss
                                    Computer Workshop
                                    Developer of "EZGUI"
                                    http://cwsof.com
                                    http://twitter.com/EZGUIProGuy

                                    Comment


                                    • #19
                                      SendMessage would not be suitable from within a data receive thread.
                                      The idea is not to cause any delays in the data aquisition loop.
                                      Rgds, Dave

                                      Comment


                                      • #20
                                        Dave,

                                        You have no choice.

                                        If you plan to use any PB GUI commands, you will force a context switch from the worker thread to the main GUI thread (primary thread of the process). SendMessage will not slow your thread down, but will force a single context switch, so the primary thread can do the necessary drawing.

                                        The only way to avoid this, would be to not continously update the dialogs controls.

                                        The best way to update the dialog visually via a thread, is to calculate how many iterations can be done in say 1/10 a second and then only update the dialog everytime the iteration reach that point.

                                        Previously the thread was iterating 500 times per second and updating the dialog every iteration.

                                        By adding code to count until 50 (1/10 of the 500 iterations or 1/10 second), the thread only calls sendmessage to update the dialog about every 1/10 a second, fast enough to appear continuous.

                                        This code executed the thread about 24,000 times per second:

                                        Code:
                                         
                                        #PBFORMS CREATED V1.51
                                        '------------------------------------------------------------------------------
                                        ' The first line in this file is a PB/Forms metastatement.
                                        ' It should ALWAYS be the first line of the file. Other
                                        ' PB/Forms metastatements are placed at the beginning and
                                        ' end of "Named Blocks" of code that should be edited
                                        ' with PBForms only. Do not manually edit or delete these
                                        ' metastatements or PB/Forms will not be able to reread
                                        ' the file correctly. See the PB/Forms documentation for
                                        ' more information.
                                        ' Named blocks begin like this: #PBFORMS BEGIN ...
                                        ' Named blocks end like this: #PBFORMS END ...
                                        ' Other PB/Forms metastatements such as:
                                        ' #PBFORMS DECLARATIONS
                                        ' are used by PB/Forms to insert additional code.
                                        ' Feel free to make changes anywhere else in the file.
                                        '------------------------------------------------------------------------------
                                        #COMPILE EXE
                                        #DIM ALL
                                        '------------------------------------------------------------------------------
                                        ' ** Includes **
                                        '------------------------------------------------------------------------------
                                        #PBFORMS BEGIN INCLUDES
                                        %USEMACROS = 1
                                        #IF NOT %DEF(%WINAPI)
                                        #INCLUDE "WIN32API.INC"
                                        #ENDIF
                                        #IF NOT %DEF(%COMMCTRL_INC)
                                        #INCLUDE "COMMCTRL.INC"
                                        #ENDIF
                                        #INCLUDE "PBForms.INC"
                                        #PBFORMS END INCLUDES
                                        '------------------------------------------------------------------------------
                                        ' ** Constants **
                                        '------------------------------------------------------------------------------
                                        #PBFORMS BEGIN CONSTANTS
                                        %IDD_DIALOG1 = 101
                                        %IDC_GRAPHIC1 = 102
                                        %IDC_GRAPHIC2 = 103
                                        %IDC_GRAPHIC3 = 104
                                        %IDC_FRAME1 = 138
                                        %IDC_StartComms = 139
                                        %IDC_StopComms = 140
                                        #PBFORMS END CONSTANTS
                                        '---------------------------------------------------------------------------
                                        ' ** Declarations **
                                        '------------------------------------------------------------------------------
                                        DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                                        DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                        DECLARE CALLBACK FUNCTION ShowDIALOG2Proc()
                                        DECLARE FUNCTION ShowDIALOG2(BYVAL hDlg AS DWORD) AS LONG
                                        #PBFORMS DECLARATIONS
                                        GLOBAL hFont AS LONG
                                        GLOBAL Abort AS LONG
                                        GLOBAL C() AS LONG
                                        '------------------------------------------------------------------------------
                                        ' ** Main Application Entry Point **
                                        '------------------------------------------------------------------------------
                                        FUNCTION PBMAIN()
                                             PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
                                             ShowDIALOG1 %HWND_DESKTOP
                                        END FUNCTION
                                        '------------------------------------------------------------------------------
                                        ' ** CallBacks **
                                        '------------------------------------------------------------------------------
                                        '
                                        GLOBAL hThread&
                                        %MY_ThreadMessage   =    %WM_USER+400
                                        TYPE ThreadData
                                             ThDlg AS DWORD
                                             TID AS LONG
                                             TsText AS ASCIIZ*255
                                             TX AS LONG
                                             TFontClr AS LONG
                                        END TYPE
                                        '
                                        CALLBACK FUNCTION ShowDIALOG1Proc()
                                             DIM C(10) AS GLOBAL LONG
                                             SELECT CASE AS LONG CBMSG
                                                  CASE %MY_ThreadMessage
                                                       LOCAL T AS ThreadData PTR
                                                       T=CBWPARAM
                                                       PrintBox @T.ThDlg, @T.TID, @T.TsText, @T.TX, @T.TFontClr
                                                       FUNCTION=1
                                                       EXIT FUNCTION
                                                  CASE %WM_INITDIALOG
                                                       FONT NEW "FIXEDSYS", 10 TO hFont
                                                       C(0) = %BLACK
                                                       C(1) = %BLUE
                                                       C(2) = %GREEN
                                                       C(3) = %CYAN
                                                       C(4) = %RED
                                                       C(5) = %MAGENTA
                                                       C(6) = %YELLOW
                                                       C(7) = %WHITE
                                                       C(8) = %GRAY
                                                       C(9) = %LTGRAY
                                                  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_DESTROY
                                                       Abort = -1
                                                  CASE %WM_MOVE
                                                  CASE %WM_COMMAND
                                                  ' Process control notifications
                                                  SELECT CASE AS LONG CBCTL
                                                       CASE %IDC_StartComms
                                                            IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                                                 Abort = 0
                                                                 THREAD CREATE Showpacket (CB.HNDL) TO hThread&
                                                            END IF
                                                       CASE %IDC_StopComms
                                                            IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                                                 Abort = -1
                                                            END IF
                                                       END SELECT
                                                  END SELECT
                                        END FUNCTION
                                        '------------------------------------------------------------------------------
                                        ' ** Dialogs **
                                        '------------------------------------------------------------------------------
                                        FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                             LOCAL lRslt AS LONG,w AS LONG, h AS LONG
                                             #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                                             LOCAL hDlg AS DWORD
                                             LOCAL hFont1 AS DWORD
                                             DIALOG NEW PIXELS, hParent, "Test", 260, 143, 400, 315, %WS_POPUP OR _
                                             %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
                                             %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                                             %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                             CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 30, 41, 322, 24, %WS_CHILD _
                                             OR %WS_VISIBLE OR %WS_BORDER
                                             CONTROL ADD BUTTON, hDlg, %IDC_StartComms, "Start", 68, 244, 90, 48, _
                                             %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER _
                                             OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
                                             CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC2, "", 30, 89, 322, 25, %WS_CHILD _
                                             OR %WS_VISIBLE OR %WS_BORDER
                                             CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC3, "", 30, 138, 322, 24, %WS_CHILD _
                                             OR %WS_VISIBLE OR %WS_BORDER
                                             CONTROL ADD FRAME, hDlg, %IDC_FRAME1, "PID's", 8, 8, 382, 203
                                             CONTROL ADD BUTTON, hDlg, %IDC_StopComms, "Stop", 225, 244, 90, 48
                                             hFont1 = PBFormsMakeFont("MS Sans Serif", 10, 400, %FALSE, %FALSE, _
                                             %FALSE, %ANSI_CHARSET)
                                             CONTROL SEND hDlg, %IDC_StartComms, %WM_SETFONT, hFont1, 0
                                             CONTROL SEND hDlg, %IDC_FRAME1, %WM_SETFONT, hFont1, 0
                                             CONTROL SEND hDlg, %IDC_StopComms, %WM_SETFONT, hFont1, 0
                                             #PBFORMS END DIALOG
                                             DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                                             #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
                                             DeleteObject hFont1
                                             #PBFORMS END CLEANUP
                                             FUNCTION = lRslt
                                        END FUNCTION
                                        '------------------------------------------------------------------------------
                                        SUB PrintBox (BYVAL hDlg AS DWORD, _
                                             BYVAL ID AS LONG, _
                                             BYVAL sText AS STRING, _
                                             BYVAL X AS LONG, _
                                             BYVAL FontClr AS LONG)
                                             LOCAL Xpos AS LONG
                                             DECR X
                                             XPos = X * 8 + 5
                                             GRAPHIC ATTACH hDlg, ID, REDRAW
                                             GRAPHIC SET FONT hFont
                                             GRAPHIC COLOR FontClr, -1
                                             GRAPHIC SET POS (Xpos, 2)
                                             GRAPHIC PRINT sText
                                             GRAPHIC REDRAW
                                        END SUB
                                        '------------------------------------------------------------------------------
                                        THREAD FUNCTION ShowPacket (BYVAL CTLHandle AS DWORD) AS LONG
                                             LOCAL A AS LONG
                                             LOCAL X AS LONG
                                             LOCAL Z AS LONG
                                             LOCAL T AS ThreadData
                                             LOCAL UCount&
                                             DO
                                                  UCount&=UCount&+1
                                                  IF UCount&>=50 THEN     ' update approximately every 1/10 second, rather than every iteration
                                                       T.ThDlg   = CTLHandle
                                                       T.TID     = %IDC_GRAPHIC1+X
                                                       T.TsText  = USING$("####";A)
                                                       T.TX      = 15
                                                       T.TFontClr= C(Z)
                                                       SendMessage CTLHandle, %MY_ThreadMessage, VARPTR(T),0
                                                       UCount&=0
                                                  END IF
                                                  IF Abort THEN EXIT DO
                                                  INCR A: IF A > 32000000 THEN A = 0
                                                  INCR X: IF X > 2 THEN X = 0
                                                  INCR Z: IF Z > 9 THEN Z = 0
                                             LOOP
                                        END FUNCTION
                                        '------------------------------------------------------------------------------
                                        Since the dialog updates abourt every 1/10 second it will appear continous to the eye.

                                        This is the best approach for continuous updates (visually), but the fastest thread speed.
                                        Chris Boss
                                        Computer Workshop
                                        Developer of "EZGUI"
                                        http://cwsof.com
                                        http://twitter.com/EZGUIProGuy

                                        Comment

                                        Working...
                                        X