Author | Topic: XbpDialog in thread not refreshing | |
---|---|---|
JUAN GONZALEZ | XbpDialog in thread not refreshing on Sat, 23 Dec 2017 17:23:47 +0100 Hello friends. I tried to modify the ProgressBar sample of Alaska, and wrote a UDF that creates a thread object in which a basic dialog is shown: an XbpStatic with a text according to the record being processed, another XbpStatic with the progress bar and a button to abort the process. The dialog is a child of SetAppWindow():drawingArea. And I use the oThread:cargo variable to exchange information between the main thread and the thread of the progress bar. The dialog with the progress bar works fine and is perfectly updated only when the mouse pointer is over it, but when it is outside that area, the update stops. Moving again inside the dialog, the update is done immediately. I can not figure out why. I put a Tone() in the event loop of the secondary thread, and I hear them, so the lines of the event loop are executed (and they contain the steps to update the dialog). I read Clayton Jones great tutorials about threads and windows and Roger Donnay's one about multithreading, but I can not find an answer. So, as I use :cargo variable as an array, I put in the fourth element the dialog itself, and it works fine when I do oThread:cargo[4]:invalidateRect() in the main thread. But when I tried the invalidateRect() in the thread, it did not work. Any suggestion about texts or tutorials about event loops in threads, paint and draw events would be appreciated. Thank you all. With kind regards, Juampa | |
James Loughner | Re: XbpDialog in thread not refreshing on Sun, 24 Dec 2017 15:47:06 -0500 On 12/23/2017 11:23 AM, JUAN GONZALEZ wrote: > Hello friends. > I tried to modify the ProgressBar sample of Alaska, and wrote a UDF that > creates a thread object in which a basic dialog is shown: an XbpStatic with a > text according to the record being processed, another XbpStatic with the > progress bar and a button to abort the process. The dialog is a child of > SetAppWindow():drawingArea. And I use the oThread:cargo variable to exchange > information between the main thread and the thread of the progress bar. > The dialog with the progress bar works fine and is perfectly updated only when > the mouse pointer is over it, but when it is outside that area, the update > stops. Moving again inside the dialog, the update is done immediately. > I can not figure out why. I put a Tone() in the event loop of the secondary > thread, and I hear them, so the lines of the event loop are executed (and they > contain the steps to update the dialog). > I read Clayton Jones great tutorials about threads and windows and Roger > Donnay's one about multithreading, but I can not find an answer. > So, as I use :cargo variable as an array, I put in the fourth element the > dialog itself, and it works fine when I do oThread:cargo[4]:invalidateRect() > in the main thread. But when I tried the invalidateRect() in the thread, it > did not work. > Any suggestion about texts or tutorials about event loops in threads, paint > and draw events would be appreciated. > Thank you all. > With kind regards, > Juampa > Each thread needs an event loop Jim | |
JUAN GONZALEZ | Re: XbpDialog in thread not refreshing on Mon, 25 Dec 2017 16:00:11 +0100 Thank you very much Jim. But I still have a doubt. How do I implement an event loop when there is no need to do so? For example: 1) main function creates the progress dialog (in another thread) 2) then it runs a loop like: while !eof() AAdd(aList,CUSTOMER_ID) //to make an array with field contents skip oProgress:increment() //to update the progress bar enddo I am a Clipper programmer, so I guess there is some basic concepts about event s processing that I am misunderstanding. Do I have to write it as follows? while !eof() AAdd(aList,CUSTOMER_ID) //to make an array with field contents skip oProgress:increment() //to update the progress bar ************ while (nEvent:=AppEvent(@mp1, @mp2, @oXbp))<>xbeP_None oXbp:handleEvent(nEvent,mp1,mp2) enddo ************ enddo I do not know if this is really necessary (no dialog exists in the main thread, to pay attention to events) or there is another way to do it. Juampa James Loughner wrote in message news:71963370$587e2f47$307f37@news.alaska- software.com... >On 12/23/2017 11:23 AM, JUAN GONZALEZ wrote: >> Hello friends. >> I tried to modify the ProgressBar sample of Alaska, and wrote a UDF that >> creates a thread object in which a basic dialog is shown: an XbpStatic with a >> text according to the record being processed, another XbpStatic with the >> progress bar and a button to abort the process. The dialog is a child of >> SetAppWindow():drawingArea. And I use the oThread:cargo variable to exchange >> information between the main thread and the thread of the progress bar. >> The dialog with the progress bar works fine and is perfectly updated only when >> the mouse pointer is over it, but when it is outside that area, the update >> stops. Moving again inside the dialog, the update is done immediately. >> I can not figure out why. I put a Tone() in the event loop of the secondary >> thread, and I hear them, so the lines of the event loop are executed (and they >> contain the steps to update the dialog). >> I read Clayton Jones great tutorials about threads and windows and Roger >> Donnay's one about multithreading, but I can not find an answer. >> So, as I use :cargo variable as an array, I put in the fourth element the >> dialog itself, and it works fine when I do oThread:cargo[4]:invalidateRect() >> in the main thread. But when I tried the invalidateRect() in the thread, it >> did not work. >> Any suggestion about texts or tutorials about event loops in threads, paint >> and draw events would be appreciated. >> Thank you all. >> With kind regards, >> Juampa >> >Each thread needs an event loop > >Jim | |
James Loughner | Re: XbpDialog in thread not refreshing on Wed, 27 Dec 2017 10:23:00 -0500 Think of each thread as a separate program. Each thread that as GUI components must be able to process events. Your second example is right I use this procedure where oSel is reference to the GUI component PROCEDURE ModalLoop(oSel,nTimeout) LOCAL nEvent,mp1,mp2,oXbp,nStart IF nTimeout = NIL nTimeout := 0 ENDIF IF !EMPTY(oSel) nStart := INT(SECONDS()) DO WHILE oSel:Status() = XBP_STAT_CREATE nEvent := AppEvent( @mp1, @mp2, @oXbp,100 ) IF nEvent > 0 oXbp:HandleEvent( nEvent, mp1, mp2 ) ENDIF IF nTimeout > 0 IF INT(Seconds())-nStart > nTimeout .AND. oSel:Status() = XBP_STAT_CREATE oSel:Destroy() ENDIF ENDIF ENDDO ELSE MPMMSGBOX("Error occured in MODALLOOP. This could be a Windows error."+CHR(13)+"Recomend reboot. If this error happens often contact Merrimac","SYSTEM ERROR") ENDIF CLEAR TYPEAHEAD //eat any events left RETURN On 12/25/2017 10:00 AM, JUAN GONZALEZ wrote: > Thank you very much Jim. > But I still have a doubt. How do I implement an event loop when there is no > need to do so? > For example: > 1) main function creates the progress dialog (in another thread) > 2) then it runs a loop like: > while !eof() > AAdd(aList,CUSTOMER_ID) //to make an array with field contents > skip > oProgress:increment() //to update the progress bar > enddo > > I am a Clipper programmer, so I guess there is some basic concepts about event > s processing that I am misunderstanding. > > Do I have to write it as follows? > while !eof() > AAdd(aList,CUSTOMER_ID) //to make an array with field contents > skip > oProgress:increment() //to update the progress bar > ************ > while (nEvent:=AppEvent(@mp1, @mp2, @oXbp))<>xbeP_None > oXbp:handleEvent(nEvent,mp1,mp2) > enddo > ************ > enddo > > I do not know if this is really necessary (no dialog exists in the main > thread, to pay attention to events) or there is another way to do it. > Juampa > > > > James Loughner wrote in message news:71963370$587e2f47$307f37@news.alaska- > software.com... >> On 12/23/2017 11:23 AM, JUAN GONZALEZ wrote: >>> Hello friends. >>> I tried to modify the ProgressBar sample of Alaska, and wrote a UDF that >>> creates a thread object in which a basic dialog is shown: an XbpStatic with > a >>> text according to the record being processed, another XbpStatic with the >>> progress bar and a button to abort the process. The dialog is a child of >>> SetAppWindow():drawingArea. And I use the oThread:cargo variable to > exchange >>> information between the main thread and the thread of the progress bar. >>> The dialog with the progress bar works fine and is perfectly updated only > when >>> the mouse pointer is over it, but when it is outside that area, the update >>> stops. Moving again inside the dialog, the update is done immediately. >>> I can not figure out why. I put a Tone() in the event loop of the secondary >>> thread, and I hear them, so the lines of the event loop are executed (and > they >>> contain the steps to update the dialog). >>> I read Clayton Jones great tutorials about threads and windows and Roger >>> Donnay's one about multithreading, but I can not find an answer. >>> So, as I use :cargo variable as an array, I put in the fourth element the >>> dialog itself, and it works fine when I do > oThread:cargo[4]:invalidateRect() >>> in the main thread. But when I tried the invalidateRect() in the thread, it >>> did not work. >>> Any suggestion about texts or tutorials about event loops in threads, paint >>> and draw events would be appreciated. >>> Thank you all. >>> With kind regards, >>> Juampa >>> >> Each thread needs an event loop >> >> Jim | |
JUAN GONZALEZ | Re: XbpDialog in thread not refreshing on Wed, 27 Dec 2017 20:12:28 +0100 Thank you very much Jim! I'll keep studying "events logic" because I'm still not comfortable with it. With kind regards Juampa James Loughner wrote in message news:4aa03992$31b706dc$55d535@news.alaska- software.com... >Think of each thread as a separate program. Each thread that as GUI >components must be able to process events. Your second example is right > >I use this procedure where oSel is reference to the GUI component > >PROCEDURE ModalLoop(oSel,nTimeout) >LOCAL nEvent,mp1,mp2,oXbp,nStart > IF nTimeout = NIL > nTimeout := 0 > ENDIF > IF !EMPTY(oSel) > nStart := INT(SECONDS()) > DO WHILE oSel:Status() = XBP_STAT_CREATE > nEvent := AppEvent( @mp1, @mp2, @oXbp,100 ) > IF nEvent > 0 > oXbp:HandleEvent( nEvent, mp1, mp2 ) > ENDIF > IF nTimeout > 0 > IF INT(Seconds())-nStart > nTimeout .AND. oSel:Status() = >XBP_STAT_CREATE > oSel:Destroy() > ENDIF > ENDIF > ENDDO > ELSE > MPMMSGBOX("Error occured in MODALLOOP. This could be a Windows >error."+CHR(13)+"Recomend reboot. If this error happens often contact >Merrimac","SYSTEM ERROR") > ENDIF > > CLEAR TYPEAHEAD //eat any events left > >RETURN > > > >On 12/25/2017 10:00 AM, JUAN GONZALEZ wrote: >> Thank you very much Jim. >> But I still have a doubt. How do I implement an event loop when there is no >> need to do so? >> For example: >> 1) main function creates the progress dialog (in another thread) >> 2) then it runs a loop like: >> while !eof() >> AAdd(aList,CUSTOMER_ID) //to make an array with field contents >> skip >> oProgress:increment() //to update the progress bar >> enddo >> >> I am a Clipper programmer, so I guess there is some basic concepts about event >> s processing that I am misunderstanding. >> >> Do I have to write it as follows? >> while !eof() >> AAdd(aList,CUSTOMER_ID) //to make an array with field contents >> skip >> oProgress:increment() //to update the progress bar >> ************ >> while (nEvent:=AppEvent(@mp1, @mp2, @oXbp))<>xbeP_None >> oXbp:handleEvent(nEvent,mp1,mp2) >> enddo >> ************ >> enddo >> >> I do not know if this is really necessary (no dialog exists in the main >> thread, to pay attention to events) or there is another way to do it. >> Juampa >> >> >> >> James Loughner wrote in message news:71963370$587e2f47$307f37@news.alaska- >> software.com... >>> On 12/23/2017 11:23 AM, JUAN GONZALEZ wrote: >>>> Hello friends. >>>> I tried to modify the ProgressBar sample of Alaska, and wrote a UDF that >>>> creates a thread object in which a basic dialog is shown: an XbpStatic with >> a >>>> text according to the record being processed, another XbpStatic with the >>>> progress bar and a button to abort the process. The dialog is a child of >>>> SetAppWindow():drawingArea. And I use the oThread:cargo variable to >> exchange >>>> information between the main thread and the thread of the progress bar. >>>> The dialog with the progress bar works fine and is perfectly updated only >> when >>>> the mouse pointer is over it, but when it is outside that area, the update >>>> stops. Moving again inside the dialog, the update is done immediately. >>>> I can not figure out why. I put a Tone() in the event loop of the secondary >>>> thread, and I hear them, so the lines of the event loop are executed (and >> they >>>> contain the steps to update the dialog). >>>> I read Clayton Jones great tutorials about threads and windows and Roger >>>> Donnay's one about multithreading, but I can not find an answer. >>>> So, as I use :cargo variable as an array, I put in the fourth element the >>>> dialog itself, and it works fine when I do >> oThread:cargo[4]:invalidateRect() >>>> in the main thread. But when I tried the invalidateRect() in the thread, it >>>> did not work. >>>> Any suggestion about texts or tutorials about event loops in threads, paint >>>> and draw events would be appreciated. >>>> Thank you all. >>>> With kind regards, >>>> Juampa >>>> >>> Each thread needs an event loop >>> >>> Jim |