Alaska Software Inc. - Event in wrong thread
Username: Password:
AuthorTopic: Event in wrong thread
James Loughner Event in wrong thread
on Wed, 07 Dec 2011 15:49:20 -0500
I have a multi-threaded app. I'm seeing occasional random occurrences 
where an event is processed in the wrong event loop. ie an event that 
should be processed in the worker thread is being processed in the main 
event loop. This leads to errors such as
oError:description  :Unknown/Invalid symbol for alias

This is because the event invoked a database function and the dbf is not 
open in the main. I know this because the error log shows only the DBFs 
that are open in main not the ones in the thread where the event should 
have been processed.

Anyone else seeing this or have any ideas how to correct or work around 
this????

Jim
AUGE_ OHRRe: Event in wrong thread
on Wed, 07 Dec 2011 23:31:57 +0100
hi,

>I have a multi-threaded app. I'm seeing occasional random occurrences where
>an event is processed in the wrong event loop. ie an event that should be
>processed in the worker thread is being processed in the main event loop.

hm ... did you "send" a Event to a Thread / Main ?

> This leads to errors such as
> oError:description  :Unknown/Invalid symbol for alias

i know the Error with Thread ... but these Error are not "normal" Threads

Question : did you use activeX or ownerdraw ?

activeX are running in GUI Thread while Ownerdraw use UI Thread
see Sample PDR 5580 for GUI Thread
see Sample PDR 6312 for UI Thread

> Anyone else seeing this or have any ideas how to correct or work around
> this????

i do "send" result e.g from activeX to Parent like this

     PostAppEvent(myEvent,aDataArray,aMoreArray,self:setparent() )

in Parent Loop i have

    Case nEvent = myEvent
        Do_Next_Step(mp1,mp2)  -> aDataArray,aMoreArray

greetings by OHR
Jimmy
James Loughner Re: Event in wrong thread
on Wed, 07 Dec 2011 20:25:48 -0500
Use Ownerdraw on all buttons and the main menu.

Don't use ActiveX

The problem is that an event that should be handled in the  worker 
thread is some how being processed in the main thread. All error logs 
show thread 1 and the open areas are just the DBF's open in the main 
thread which accounts for the unknown alias error.

Some stack reports show the problem start on a button press but others 
do not and it starts in a browse or some other random place. This is a 
huge program of about 500K lines.

Maybe if I knew what thread a object was created on I could filter out 
any errant events in the loop???

Jim



On 12/07/2011 05:31 PM, AUGE_ OHR wrote:
> hi,
>
>> I have a multi-threaded app. I'm seeing occasional random occurrences where
>> an event is processed in the wrong event loop. ie an event that should be
>> processed in the worker thread is being processed in the main event loop.
>
> hm ... did you "send" a Event to a Thread / Main ?
>
>> This leads to errors such as
>> oError:description  :Unknown/Invalid symbol for alias
>
> i know the Error with Thread ... but these Error are not "normal" Threads
>
> Question : did you use activeX or ownerdraw ?
>
> activeX are running in GUI Thread while Ownerdraw use UI Thread
> see Sample PDR 5580 for GUI Thread
> see Sample PDR 6312 for UI Thread
>
>> Anyone else seeing this or have any ideas how to correct or work around
>> this????
>
> i do "send" result e.g from activeX to Parent like this
>
>       PostAppEvent(myEvent,aDataArray,aMoreArray,self:setparent() )
>
> in Parent Loop i have
>
>      Case nEvent = myEvent
>          Do_Next_Step(mp1,mp2)  ->  aDataArray,aMoreArray
>
> greetings by OHR
> Jimmy
>
>
>
AUGE_ OHRRe: Event in wrong thread
on Thu, 08 Dec 2011 06:38:27 +0100
hi,

> Use Ownerdraw on all buttons and the main menu.
> ...
> Some stack reports show the problem start on a button press

this is why i ask for Ownerdraw. i guess you call it this Way

   oPb:activate := {| u1, u2, oSelf | Do_SomeThing()  }

while Ownerdraw run in UI Thread i do this

   oPb:activate := {| u1, u2, oSelf | 
PostAppEvent(myEvent,,,oSelf:setparent() )

and in Parent Loop i have

   Case nEvent = myEvent
            Do_SomeThing()


> Maybe if I knew what thread a object was created on I could filter out 
> any errant events in the loop???

ThreadInfo() will give you more Info. EventSpy can help you to figure out 
with @oXbp just send the Event

greetings by OHR
Jimmy
James Loughner Re: Event in wrong thread
on Thu, 08 Dec 2011 19:09:48 -0500
Hmm if the event is processed by the wrong thread it executed in the 
wrong thread. I don't see how your code helps. Also Your solution is 
very restrictive and would require hundreds of different loops in the 
program this size and complexity.

Basically I think I just need to know in what thread an object is 
created. I think the Windows API may be able to do that but Xbase++ does 
not seem to uncover that info. After all Windows must know what thread 
to send an event.

Jim

On 12/08/2011 12:38 AM, AUGE_ OHR wrote:
> hi,
>
>> Use Ownerdraw on all buttons and the main menu.
>> ...
>> Some stack reports show the problem start on a button press
>
> this is why i ask for Ownerdraw. i guess you call it this Way
>
>     oPb:activate := {| u1, u2, oSelf | Do_SomeThing()  }
>
> while Ownerdraw run in UI Thread i do this
>
>     oPb:activate := {| u1, u2, oSelf |
> PostAppEvent(myEvent,,,oSelf:setparent() )
>
> and in Parent Loop i have
>
>     Case nEvent = myEvent
>              Do_SomeThing()
>
>
>> Maybe if I knew what thread a object was created on I could filter out
>> any errant events in the loop???
>
> ThreadInfo() will give you more Info. EventSpy can help you to figure out
> with @oXbp just send the Event
>
> greetings by OHR
> Jimmy
>
>
AUGE_ OHRRe: Event in wrong thread
on Fri, 09 Dec 2011 07:36:40 +0100
hi,

> Hmm if the event is processed by the wrong thread it executed in the wrong 
> thread.

if it happend after you activate a Ownerdraw Pushbutton
you might still be in UI Thread while "drawing" ?!

your Errorlog will not show you UI Thread ... it will show
"lost" Alias ... "unknow Member" ...  or IDSC ( "Interne Datenstrukturen 
beschdigt" )



>I don't see how your code helps.

PostAppEvent(myEvent,,,oSelf:setparent() ) will go to Xbase++ Message Queue
myEvent is UserDef so it will "pass" all "internal" Message Queue and only 
"your" Eventloop will "catch" it



> Also Your solution is  very restrictive and would require hundreds of 
> different loops in the program this size and complexity.

do you use

   ::oPb:activate := {|| PostAppEvent( xbeP_Close,,,::setparent() ) }

it is a normal Way to "send" a Event and let Window "react" on it



> Basically I think I just need to know in what thread an object is created. 
> I think the Windows API may be able to do that but Xbase++ does not seem 
> to uncover that info. After all Windows must know what thread to send an 
> event.

not shure how to get "Information" about Xbase++ "internal" GUI Thread
or how Alaska implement MEASUREITEMSTRUCT() / DRAWITEMSTRUCT()
for Ownerdraw ... i so began to make my own "native" Controls using ot4xb

greetings by OHR
Jimmy
James Loughner Re: Event in wrong thread
on Fri, 09 Dec 2011 02:28:58 -0500
On 12/09/2011 01:36 AM, AUGE_ OHR wrote:
> hi,
>
>> Hmm if the event is processed by the wrong thread it executed in the wrong
>> thread.
>
> if it happend after you activate a Ownerdraw Pushbutton
> you might still be in UI Thread while "drawing" ?!
>
> your Errorlog will not show you UI Thread ... it will show
> "lost" Alias ... "unknow Member" ...  or IDSC ( "Interne Datenstrukturen
> beschädigt" )
>
>
>
>> I don't see how your code helps.
>
> PostAppEvent(myEvent,,,oSelf:setparent() ) will go to Xbase++ Message Queue
> myEvent is UserDef so it will "pass" all "internal" Message Queue and only
> "your" Eventloop will "catch" it
>
Witch loop the program has many each thread has it's own loop and the 
main is always active


>
>
>> Also Your solution is  very restrictive and would require hundreds of
>> different loops in the program this size and complexity.
>
> do you use
>
>     ::oPb:activate := {|| PostAppEvent( xbeP_Close,,,::setparent() ) }
>
> it is a normal Way to "send" a Event and let Window "react" on it
>

Nope normally do a direct call

>
>
>> Basically I think I just need to know in what thread an object is created.
>> I think the Windows API may be able to do that but Xbase++ does not seem
>> to uncover that info. After all Windows must know what thread to send an
>> event.
>
> not shure how to get "Information" about Xbase++ "internal" GUI Thread
> or how Alaska implement MEASUREITEMSTRUCT() / DRAWITEMSTRUCT()
> for Ownerdraw ... i so began to make my own "native" Controls using ot4xb

Do not use ActiveX so not an issue also this is very infrequent error 
but there is a pattern the error always has to do with unknown alias and 
always occurs in thread 1 ie main thread the stack indicates that the 
program should have been in a worker thread. Don't care about how 
Xbase++ tracks the thread number just need to know what thread a object 
is created in then I can test in the main loop and ignore all events 
that are on objects not created in the same thread as the loop. I'd have 
to subclass all XBP classes to do it myself I was hoping some one would 
know how to get a thread id of an object from a windows call. I may try 
it with just my owner draw (shadowbutton) class seems that is the one 
causing the thread skipping


Jim

>
> greetings by OHR
> Jimmy
>
>
AUGE_ OHRRe: Event in wrong thread
on Fri, 09 Dec 2011 09:16:44 +0100
hi,

> Witch loop the program has many each thread has it's own loop and the main
> is always active

allways to the parent of the Ownerdraw Xbpart which crash

> Do not use ActiveX so not an issue

MEASUREITEMSTRUCT() / DRAWITEMSTRUCT() are
what Window use and Xbase++ "wrapp" it into UI Thread

this "internal" Thread will receive WM_MEASUREITEM
and  WM_DRAWITEM Command

> I'd have  to subclass all XBP classes to do it myself I was hoping

you have control over "your" Thread but not over "internal" Threads
as Ownerdraw will EVAL() your Codeblock in its GUI Thread.

   ::oMeasureitemstruct:_link_(lp,.F.)
   IF ::oMeasureitemstruct:CtlType = ODT_LISTBOX .AND. ;
      ::oMeasureitemstruct:CtlID   = APP_ID_LISTBOX

       Xbase++ Codeblock Slot
      IF VALTYPE( ::MeasureItem ) == "B"

         ::aDims := { ::oMeasureitemstruct:itemWidth ,;
                      ::oMeasureitemstruct:itemHeight  }
         
          now "send" it to Xbase
         
         EVAL( ::MeasureItem, ::oMeasureitemstruct:itemID, ::aDims ,Self)


as long you are not subclasswindow() using ot4xb i do not know
how you want to get WM Command without writing your own "native" Control

greetings by OHR
Jimmy
Chris AndriesRe: Event in wrong thread
on Fri, 09 Dec 2011 17:40:31 +0100
Hi Jim,

Glad to see this error happens also in other applications. 

I have seen this problem on a regular base in the errorlogs users send to
me. This error occurs on places where it couldn't be possible. In my
errorlog also the 'open aliases' doesn't make any sense at all. I can't
reproduce or simulate it.

If had this error in code as this sample:

1. if stock->(fieldpos("test")) > 0
2.     cTest := stock->test
3. endif

In the error the 'oError:description  :Unknown/Invalid symbol for alias' is
on line 2. This doesn't make any sense at all. You description of the
problem, that this is executed in the main thread makes sense to me. The
alias doesn't exist in the main thread, and in the error log there are no
open aliases in the list.

I'm afraid it is something in Xbase++ we have to live with...

Best regards,
Chris Andries.

"James Loughner" <jwrl@suddenlink.net> wrote in message
news:400e5893$52c69697$dc9e7@news.alaska-software.com...
> I have a multi-threaded app. I'm seeing occasional random occurrences
> where an event is processed in the wrong event loop. ie an event that
> should be processed in the worker thread is being processed in the main
> event loop. This leads to errors such as
> oError:description  :Unknown/Invalid symbol for alias
>
> This is because the event invoked a database function and the dbf is not
> open in the main. I know this because the error log shows only the DBFs
> that are open in main not the ones in the thread where the event should
> have been processed.
>
> Anyone else seeing this or have any ideas how to correct or work around
> this????
>
> Jim
AUGE_ OHRRe: Event in wrong thread
on Fri, 09 Dec 2011 21:33:18 +0100
hi,

> I'm afraid it is something in Xbase++ we have to live with...

did you remember Codejock Calender and "lost alias" ?
the same Solution works fine with Ownerdraw as i show above.

greetings by OHR
Jimmy
James Loughner Re: Event in wrong thread
on Fri, 09 Dec 2011 17:17:37 -0500
Look very carefully at the stack reported in the error also the thread 
that is reported. It may very well be that ownerdraw is throwing threads 
off but in any case it can happen just about anywhere. Some seem to come 
from browse events where no owner draw is used in my app. But always the 
error happens in the main loop and main thread (1). It is not in anyway 
reproducible. I mayslf have never seen it just in reports from the field.

I did have a problem where events started processing in the main when 
the worker thread was closed. I think the users were double clicking the 
quit buttons. I use a special event loop function for all worker loops 
so I just cleared keyboard (to clear the event que) the exit of the loop 
and the problem seems to go away. But the error was differnt non 
existent method type.

Jim








n 12/09/2011 11:40 AM, Chris Andries wrote:
> Hi Jim,
>
> Glad to see this error happens also in other applications. 
>
> I have seen this problem on a regular base in the errorlogs users send to
> me. This error occurs on places where it couldn't be possible. In my
> errorlog also the 'open aliases' doesn't make any sense at all. I can't
> reproduce or simulate it.
>
> If had this error in code as this sample:
>
> 1. if stock->(fieldpos("test"))>  0
> 2.     cTest := stock->test
> 3. endif
>
> In the error the 'oError:description  :Unknown/Invalid symbol for alias' is
> on line 2. This doesn't make any sense at all. You description of the
> problem, that this is executed in the main thread makes sense to me. The
> alias doesn't exist in the main thread, and in the error log there are no
> open aliases in the list.
>
> I'm afraid it is something in Xbase++ we have to live with...
>
> Best regards,
> Chris Andries.
>
> "James Loughner"<jwrl@suddenlink.net>  wrote in message
> news:400e5893$52c69697$dc9e7@news.alaska-software.com...
>> I have a multi-threaded app. I'm seeing occasional random occurrences
>> where an event is processed in the wrong event loop. ie an event that
>> should be processed in the worker thread is being processed in the main
>> event loop. This leads to errors such as
>> oError:description  :Unknown/Invalid symbol for alias
>>
>> This is because the event invoked a database function and the dbf is not
>> open in the main. I know this because the error log shows only the DBFs
>> that are open in main not the ones in the thread where the event should
>> have been processed.
>>
>> Anyone else seeing this or have any ideas how to correct or work around
>> this????
>>
>> Jim
>
>
James Loughner Re: Event in wrong thread
on Fri, 09 Dec 2011 19:13:39 -0500
Made this change

Added a nthread ivar to shadowbutton (Ownerdraw object) class and set it 
to the current theradID()

in main loop

    DO WHILE .T.
        nEvent := AppEvent( @mp1, @mp2, @oXbp )
        IF oXbp:IsDerivedFrom("ShadowButton") .AND. oXbp:nThread != 
ThreadID()
           Loop       skip shadow button event if not from this thread
        ENDIF
        oXbp:HandleEvent( nEvent, mp1, mp2 )
    ENDDO


This may or may not mitigate the problem at least from throwing errors

If the thread skip is not permanent then I expect this to be just a bad 
click sort of condition to the user.

We will see. Stay tuned it will take a while to see if this helps at all.

Jim



On 12/09/2011 05:17 PM, James Loughner wrote:
> Look very carefully at the stack reported in the error also the thread
> that is reported. It may very well be that ownerdraw is throwing threads
> off but in any case it can happen just about anywhere. Some seem to come
> from browse events where no owner draw is used in my app. But always the
> error happens in the main loop and main thread (1). It is not in anyway
> reproducible. I mayslf have never seen it just in reports from the field.
>
> I did have a problem where events started processing in the main when
> the worker thread was closed. I think the users were double clicking the
> quit buttons. I use a special event loop function for all worker loops
> so I just cleared keyboard (to clear the event que) the exit of the loop
> and the problem seems to go away. But the error was differnt non
> existent method type.
>
> Jim
>
>
>
>
>
>
>
>
> n 12/09/2011 11:40 AM, Chris Andries wrote:
>> Hi Jim,
>>
>> Glad to see this error happens also in other applications. 
>>
>> I have seen this problem on a regular base in the errorlogs users send to
>> me. This error occurs on places where it couldn't be possible. In my
>> errorlog also the 'open aliases' doesn't make any sense at all. I can't
>> reproduce or simulate it.
>>
>> If had this error in code as this sample:
>>
>> 1. if stock->(fieldpos("test"))> 0
>> 2. cTest := stock->test
>> 3. endif
>>
>> In the error the 'oError:description :Unknown/Invalid symbol for
>> alias' is
>> on line 2. This doesn't make any sense at all. You description of the
>> problem, that this is executed in the main thread makes sense to me. The
>> alias doesn't exist in the main thread, and in the error log there are no
>> open aliases in the list.
>>
>> I'm afraid it is something in Xbase++ we have to live with...
>>
>> Best regards,
>> Chris Andries.
>>
>> "James Loughner"<jwrl@suddenlink.net> wrote in message
>> news:400e5893$52c69697$dc9e7@news.alaska-software.com...
>>> I have a multi-threaded app. I'm seeing occasional random occurrences
>>> where an event is processed in the wrong event loop. ie an event that
>>> should be processed in the worker thread is being processed in the main
>>> event loop. This leads to errors such as
>>> oError:description :Unknown/Invalid symbol for alias
>>>
>>> This is because the event invoked a database function and the dbf is not
>>> open in the main. I know this because the error log shows only the DBFs
>>> that are open in main not the ones in the thread where the event should
>>> have been processed.
>>>
>>> Anyone else seeing this or have any ideas how to correct or work around
>>> this????
>>>
>>> Jim
>>
>>
>
AUGE_ OHRRe: Event in wrong thread
on Sun, 11 Dec 2011 00:30:22 +0100
hi,

>    DO WHILE .T.
>        nEvent := AppEvent( @mp1, @mp2, @oXbp )
>        IF oXbp:IsDerivedFrom("ShadowButton") .AND. oXbp:nThread != 
> ThreadID()
>           Loop       skip shadow button event if not from this thread
>        ENDIF
>        oXbp:HandleEvent( nEvent, mp1, mp2 )
>    ENDDO

try add : .AND. ThreadId() != UIThreadId()

greetings by OHR
Jimmy
James Loughner Re: Event in wrong thread
on Sat, 10 Dec 2011 21:07:30 -0500
Baby steps one, thing at a time. Problem is that this can not be tested 
directly since it is not a reproducible problem. Have to wait and see if 
the error reports from the field stop for this problem.

Note that so far all the reports show the error occurred in thread 1 
when the process should have been in some worker thread. I have seen 
none that indicate a UIThread ID. But I'll keep this in mind.

I hate spooky problems. 

Jim

On 12/10/2011 06:30 PM, AUGE_ OHR wrote:
> hi,
>
>>     DO WHILE .T.
>>         nEvent := AppEvent( @mp1, @mp2, @oXbp )
>>         IF oXbp:IsDerivedFrom("ShadowButton") .AND. oXbp:nThread !=
>> ThreadID()
>>            Loop       skip shadow button event if not from this thread
>>         ENDIF
>>         oXbp:HandleEvent( nEvent, mp1, mp2 )
>>     ENDDO
>
> try add : .AND. ThreadId() != UIThreadId()
>
> greetings by OHR
> Jimmy
>
>
Peter AlderliestenRe: Event in wrong thread
on Mon, 12 Dec 2011 13:37:00 +0100
Jim,

> I hate spooky problems. 

Are you doing any database operations during the ownerdrawing of items. 
That could pose a problem, because the drawing itself is done in a
different thread.
Just a guess.

Peter
James Loughner Re: Event in wrong thread
on Mon, 12 Dec 2011 17:01:38 -0500
No

Of course DB operation are happening in the worker thread and as an 
activate event. But no DBF in the actual ownerdraw code. It seem that in 
some rare circumstances the activation event slips to the main thread 
since that is where the errors happen . Note this is not the same as the 
UIthread which drive the ownerdraw.

Jim

On 12/12/2011 07:37 AM, Peter Alderliesten wrote:
> Jim,
>
>> I hate spooky problems. 
>
> Are you doing any database operations during the ownerdrawing of items.
> That could pose a problem, because the drawing itself is done in a
> different thread.
> Just a guess.
>
> Peter
AUGE_ OHRRe: Event in wrong thread
on Tue, 13 Dec 2011 08:00:04 +0100
hi,

the "ultimative" Test would be to "disable" Ownerdraw with

   ::drawMode := XBP_DRAW_NORMAL

in your Ownerdraw Class to see if you still got those Errors.

i do have 1 User in German Xbaseforum who does
have Ownerdraw related Problem with PDR_LFU

i have build in Option for Start Parameter

   no Parameter     -> XBP_DRAW_OWNERADVANCED
   Parameter /Ano -> XBP_DRAW_OWNER
   Parameter /Dno -> XBP_DRAW_NORMAL

so he can figure out which Version run on his 2 PC

greetings by OHR
Jimmy
Pablo BotellaRe: Event in wrong thread
on Tue, 13 Dec 2011 09:21:51 +0100
Hi,

Seems at any point PostAppEvent() ( or equivalent code if the trouble comes from the Xbase++ internals) is using SetAppWindow() instead of your XBP to place the event to the wright queue 
So I think your task must be determine if the PostAppEvent() causing the trouble come from your code and can be fixed easy or comes from the Xbase++ internal code and in that case you must convince Alaska guys to open the corresponding PDR to fix.

I would start seaching for the PostAppEvent() calls in the app , I know it will be hardif the app is so big, but cannot imagine another way to start checking.

Regards,

Pablo Botella
Clifford WiernikRe: Event in wrong thread
on Mon, 19 Dec 2011 20:02:58 -0600
On 12/13/2011 2:21 AM, Pablo Botella wrote:
> Hi,
>
> Seems at any point PostAppEvent() ( or equivalent code if the trouble comes from the Xbase++ internals) is using SetAppWindow() instead of your XBP to place the event to the wright queue
> So I think your task must be determine if the PostAppEvent() causing the trouble come from your code and can be fixed easy or comes from the Xbase++ internal code and in that case you must convince Alaska guys to open the corresponding PDR to fix.
>
> I would start seaching for the PostAppEvent() calls in the app , I know it will be hardif the app is so big, but cannot imagine another way to start checking.
>
> Regards,
>
> Pablo Botella

Jim,

I had exactly the same problem in my application when using Express++. 
It appeared in one of the routines where Roger processes hot keys.  It 
happened when I had multiple dialogs open, each running in its own 
thread.  If you switched from one window to the next, in production, it 
would cause a lost focus to occur, which triggered a valid type clause. 
  Unfortunately the application had changed focus to the other dialog in 
a different thread but he processing of the hotkey exception used 
language of the type postappevent(..... oXbp) where oXbp was defined as 
setappfocus() which was in the thread that was now in focus, not the 
thread that started the hotkey process.  Since the variable in question 
was a private, it was thread specific.  I tried changing the variable to 
a local, but it only masked the problem and caused an alias issue later 
on as the event was posted to the wrong thread.

I could simulate the problem but not duplicate it by putting a different 
thread's dialog on top of the other dialog and having a timer send an 
esc to the hidden dialog.  I know the issue is the setappfocus() but did 
not want to try to change the existing express++ library.

How I resolved it was to use an undocumented method provided by Alaska 
:SetOwnerThread(), which provides the thread assigned to an object.

This was the code:

LOCAL lStatus := .f., i, oLastFocus, oAppFocus := SetAppFocus(), ;
       lError, nIterations := 0

IF oXbp:setOwnerthread() # oAppFocus:setownerthread()   Thanks to 
Cliff Wiernik
   oAppFocus := oXbp                                      PC CAW 
03-06-09 Testing back to the original methodology
  RETURN .f.
ENDIF

It allowed me to trap the error situation and change the value only for 
that time.  It has resolved the problem without side effects.

Maybe it be of use to you.

Cliff.
James Loughner Re: Event in wrong thread
on Tue, 20 Dec 2011 16:47:42 -0500
Ok did not know setownerthread.

Well to update, to date we have not seen the error again since my 
changes to the main loop and adding a nthreadID to my shadowbutton class

to reiterate

    DO WHILE .T.
        nEvent := AppEvent( @mp1, @mp2, @oXbp )
        IF oXbp:IsDerivedFrom("ShadowButton") .AND. oXbp:nThread != 
ThreadID()
           Loop       skip shadow button event if not from this thread
        ENDIF
        oXbp:HandleEvent( nEvent, mp1, mp2 )
    ENDDO


So it looks like a problem with Ownerdraw which is not unexpected

I may make it more general with the setownerthread method now that I 
know about it

    DO WHILE .T.
        nEvent := AppEvent( @mp1, @mp2, @oXbp )
        IF oXbp:setownerthread() != ThreadID()
           Loop       skip any event if not from this thread
        ENDIF
        oXbp:HandleEvent( nEvent, mp1, mp2 )
    ENDDO



Jim


On 12/19/2011 09:02 PM, Clifford Wiernik wrote:
>
> Jim,
>
> I had exactly the same problem in my application when using Express++.
> It appeared in one of the routines where Roger processes hot keys. It
> happened when I had multiple dialogs open, each running in its own
> thread. If you switched from one window to the next, in production, it
> would cause a lost focus to occur, which triggered a valid type clause.
> Unfortunately the application had changed focus to the other dialog in a
> different thread but he processing of the hotkey exception used language
> of the type postappevent(..... oXbp) where oXbp was defined as
> setappfocus() which was in the thread that was now in focus, not the
> thread that started the hotkey process. Since the variable in question
> was a private, it was thread specific. I tried changing the variable to
> a local, but it only masked the problem and caused an alias issue later
> on as the event was posted to the wrong thread.
>
> I could simulate the problem but not duplicate it by putting a different
> thread's dialog on top of the other dialog and having a timer send an
> esc to the hidden dialog. I know the issue is the setappfocus() but did
> not want to try to change the existing express++ library.
>
> How I resolved it was to use an undocumented method provided by Alaska
> :SetOwnerThread(), which provides the thread assigned to an object.
>
> This was the code:
>
> LOCAL lStatus := .f., i, oLastFocus, oAppFocus := SetAppFocus(), ;
> lError, nIterations := 0
>
> IF oXbp:setOwnerthread() # oAppFocus:setownerthread()  Thanks to Cliff
> Wiernik
> oAppFocus := oXbp  PC CAW 03-06-09 Testing back to the original
> methodology
>  RETURN .f.
> ENDIF
>
> It allowed me to trap the error situation and change the value only for
> that time. It has resolved the problem without side effects.
>
> Maybe it be of use to you.
>
> Cliff.
>
AUGE_ OHRRe: Event in wrong thread
on Tue, 20 Dec 2011 23:33:32 +0100
hi,

> How I resolved it was to use an undocumented method provided by Alaska
> :SetOwnerThread(), which provides the thread assigned to an object.

cant find SetOwnerThread() in Knowledge Base.
does a PDR exist for that Problem ?

greetings by OHR
Jimmy
Clifford WiernikRe: Event in wrong thread
on Sat, 24 Dec 2011 13:16:34 -0600
On 12/20/2011 4:33 PM, AUGE_ OHR wrote:
> hi,
>
>> How I resolved it was to use an undocumented method provided by Alaska
>> :SetOwnerThread(), which provides the thread assigned to an object.
>
> can´t find SetOwnerThread() in Knowledge Base.
> does a PDR exist for that Problem ?
>
> greetings by OHR
> Jimmy
>
>
>
>
>
Don't know that they setup a PDF.  I don't think it is a bug in my case 
as I know what the cause is, but cannot recreate in live production 
though it happens in live production.  I can emulate it and it causes a 
problem due to the way Express++ uses setappfocus() in this case with 
when using multiple dialogs in different threads.

Cliff.