Alaska Software Inc. - XbpDialog in thread not refreshing
Username: Password:
AuthorTopic: XbpDialog in thread not refreshing
JUAN GONZALEZXbpDialog 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 LoughnerRe: 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 GONZALEZRe: 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 LoughnerRe: 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 GONZALEZRe: 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