Announcement

Collapse
No announcement yet.

Button, thread

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

  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    Also.... what's left works, don't it?
    It certainly seems to. I shall no doubt borrow it when I need to go GLOBAL-free, and include you in my prayers.

    Think I'll start another thread about DDT and threads.

    Leave a comment:


  • Michael Mattias
    replied
    Um, self-explanatory?

    Well, Ok, not really all that self-evident... but it does mean that DDT must be doing something to implement CONTROL GET TEXT which results in a WM_GETTEXT message or something else which must execute in the context of the thread in which the window (dialog) was created... but whatever that is cannot get done because that thead is currently suspended on a WFSO.

    Meaning... CONTROL GET TEXT cannot be used when the thread in which the dialog was created is in a wait state.

    Like I said... this is not documented where it should be, under the CONTROL GET TEXT statement.


    Also.... what's left works, don't it?

    MCM

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    AFAIK - and I am NOT a 'DDT' guy - there are no restrictions vis-a-vis 'DDT in Multithreaded applications' than there are in general on 'DDT in any application' or on 'multi-threaded applications using the PB compilers.'
    I was thinking about your comment in the source code of the last example quoyted, where you say

    ' I had to use a string ptr here instead of CONTROL GET TEXT because the calling thread was in a wait
    ' state (WaitForSingleObject) and apparently (undocumented but not reasonably) CONTROL GET TEXT does
    ' "something" which must execute in the context of the same thread (suspended) as the dialog.
    ' Apparently (that means also not documented), DIALOG GET USER does not need to execute anything in the
    ' context of the thread in which the dialog was created.

    Leave a comment:


  • Michael Mattias
    replied
    I don't like GLOBALs because it makes code less re-useable; and more difficult to port to a separate module (DLL) within the same application. I also tend to forget the names of GLOBAL variables, but that's probably not a real good excuse.

    DIALOG DOEVENTS is not ugly; looping on a variable's value is ugly: it's inefficient. But since you brought it up, I also consider it ugly to use additional "inline" message loops at multiple points within a program.

    AFAIK - and I am NOT a 'DDT' guy - there are no restrictions vis-a-vis 'DDT in Multithreaded applications' than there are in general on 'DDT in any application' or on 'multi-threaded applications using the PB compilers.'

    MCM

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    I truly do not believe it gets any simpler than that.. at least to do it without timing and/or "check the value of a GLOBAL variable" loops.
    Questions:
    • why not use a global variable?
    • why do you consider DIALOG DOEVENTS ugly?
    • It would be useful to know which bits of DDT work with multithreading and which don't - any ideas?

    Leave a comment:


  • Michael Mattias
    replied
    I truly do not believe it gets any simpler than that.. at least to do it without timing and/or "check the value of a GLOBAL variable" loops.

    And for sure I believe you'll not find a better-commented demo explaining what's happening.

    Maybe that would be a really good program to compile and attach an 'EXE' for people to run?

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    I forgot the most recent demo.... the 'simplified basic using DDT '
    Simplified - I like the sound of that - yes, that's the one!

    Leave a comment:


  • Michael Mattias
    replied
    I forgot the most recent demo.... the 'simplified basic using DDT '....the one I should have done years ago...

    GUI + Worker Thread + Abort Demo 11-24-07

    MCM

    Leave a comment:


  • Chris Holbrook
    replied
    Thread eg

    Same application stopping a long running process in a seperate thread.

    Just to show how simple your threads can be in an extreme case!

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    %IDD_DIALOG1             =  101
    %IDC_BUTTON1             = 1001
    %IDC_BUTTON2             = 1002 '
    %IDC_PROG1 = 1006
    
    GLOBAL gflag AS LONG
    '-------------------------------------------------------------------------------
    SUB long_runner ( hD AS DWORD, t AS DOUBLE)
        LOCAL n, untilnow, tstart AS DOUBLE
    
        tstart = TIMER
        WHILE untilnow < t
            CONTROL SEND hD, %IDC_PROG1, %PBM_SETPOS, untilnow*100/t, 0
            IF gflag = 1 THEN
                ? "interrupted!"
                EXIT SUB
            END IF
            INCR n
            untilnow = TIMER - tstart
            SLEEP 50
        WEND
        ? "finished long runner"
    END SUB
    '-------------------------------------------------------------------------------
    FUNCTION wThread ( BYVAL hD AS DWORD) AS LONG
        long_runner ( hD, 20)
    END FUNCTION
    '-------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
        LOCAL lresult, n AS LONG
        STATIC hwthread AS LONG
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
            CASE %WM_COMMAND
                SELECT CASE AS LONG CBCTL
                    CASE %IDC_BUTTON1
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            THREAD CREATE wthread(CBHNDL) TO hwthread
                            THREAD CLOSE hwThread TO lresult
                            gflag = 0
                        END IF
                    CASE %IDC_BUTTON2
                        gflag = 1
                END SELECT
            CASE %WM_DESTROY
        END SELECT
    END FUNCTION
    '-----------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Interrupt a long-running process", 175, 118, 170, 58, %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, "Start", 5, 35, 30, 15
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Stop",  55, 35, 30, 15
        CONTROL ADD "msctls_progress32", hDlg, %IDC_PROG1, "msctls_progress32_1", 5, 10, 140, 15, %WS_CHILD OR _
            %WS_VISIBLE
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
        FUNCTION = lRslt
    END FUNCTION
    '============================================================================
    FUNCTION PBMAIN()
        InitCommonControls
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION

    Leave a comment:


  • Michael Mattias
    replied
    Well, you know what they say: Ugly is in the eye of the beholder.

    Leave a comment:


  • Chris Holbrook
    replied
    DIALOG DOEVENTS eg

    Using Dialog DoEvents to allow message processing so that a control can be used to interrupt a long running process:

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    %IDD_DIALOG1             =  101
    %IDC_BUTTON1             = 1001
    %IDC_BUTTON2             = 1002 '*
    %IDC_TEXTBOX1            = 1003 '*
    %IDC_RESULTS_LB          = 1004 '*
    %IDC_STATS_LAB           = 1005 '*
    %IDC_PROG1 = 1006
    
    GLOBAL gflag AS LONG
    '-------------------------------------------------------------------------------
    SUB long_runner ( hD AS DWORD, t AS DOUBLE)
        LOCAL i, j, k AS LONG
        LOCAL n, untilnow, tstart AS DOUBLE
        
        tstart = TIMER
        WHILE untilnow < t
            CONTROL SEND hD, %IDC_PROG1, %PBM_SETPOS, untilnow*100/t, 0
            IF gflag = 1 THEN
                ? "interrupted!"
                EXIT SUB
            END IF
            INCR n
            untilnow = TIMER - tstart
            DIALOG DOEVENTS 1
            SLEEP 50
        WEND
        ? "finished long runner"
    END SUB
    '-------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
    
        LOCAL lresult, n AS LONG
       
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
            CASE %WM_COMMAND
                SELECT CASE AS LONG CBCTL
                    CASE %IDC_BUTTON1
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            long_runner(CBHNDL, 20)
                            gflag = 0
                        END IF
                    CASE %IDC_BUTTON2
                        gflag = 1
                END SELECT
            CASE %WM_DESTROY
        END SELECT
    END FUNCTION
    '-----------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Interrupt a long-running process", 175, 118, 170, 58, %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, "Start", 5, 35, 30, 15
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Stop",  55, 35, 30, 15
        CONTROL ADD "msctls_progress32", hDlg, %IDC_PROG1, "msctls_progress32_1", 5, 10, 140, 15, %WS_CHILD OR _
            %WS_VISIBLE
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
        FUNCTION = lRslt
    END FUNCTION
    '============================================================================
    FUNCTION PBMAIN()
        InitCommonControls
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    Last edited by Chris Holbrook; 27 May 2008, 11:22 AM. Reason: removed spurious statemenst

    Leave a comment:


  • Chris Holbrook
    replied
    MCM, thanks for your reply, it lead me indirectly to this thread and Chris Boss's suggestion, which so far works 100% in my test context, no need for threads at all, just put a DIALOG DOEVENTS in the slow running part.

    Unfortunately, it would not work if the slow running bit was an external call - as mine is in the "real world" so it's back to threads again!

    Leave a comment:


  • Michael Mattias
    replied
    Thread objects do not receive messages; windows receive messages. Threads do not set flags; procedures set flags.

    However, these demos may be of use to you.....

    Terminate Worker Threads Using Windows Events (and Using Thread Local Storage) Demo Dec 23 2005

    And/or

    Progress Bar Dialog for PB/CC programs October 24, 2002
    (Ignore the "PB/CC" in the thread title. This will work in a GUI program exactly the same way).

    Leave a comment:


  • Chris Holbrook
    started a topic Button, thread

    Button, thread

    I have very little experience of threads, just what I've read in the help and read here. I don't have any conceptual problems with concurrent stuff, just never dabbled with it in Windows or PB.

    The application runs a long running process which can be interrupted by setting a flag. In my first attempt, the thread which sets the flag puts up a MSGBOX, sets the flag and clears the msgbox when the MSGBOX button is clicked. This works, but if the button is NOT clicked, how to get rid of the MSGBOX? CLOSE THREAD doesn't do it.

    Is there a way in which the new thread can get messages from a button in the dialog created by the main process, rather than starting a new (MSGBOX) window? This would look better.
    Last edited by Chris Holbrook; 27 May 2008, 07:20 AM.
Working...
X