views:

138

answers:

1

Background: I am using OmniThreadLibrary to load batch mode ADO stored procedures in the background. I am doing some slightly dodgy stuff by swapping the connection after opening the SP but that seems to be quite reliable. I'm using PostMessage to send messages back to the calling form and that works in my test applications. Primoz' comms channels work for me, I'm using those for inter-thread comms but for our main application I'm trying to avoid that dependency by using standard PostMessage calls as we do elsewhere in the app.

Problem: Unfortunately when I put this into our main application the PostMessage calls in the thread start failing with 1400:invalid window handle.

I have liberally added extra PostMessage calls and logging code to try to locate the problem, but I'm out of ideas now. The code is boilerplate:

const WM_PW_ADLQUEUEEMPTY = WM_USER + 11;
...
if PostMessage (OwnerHandle, WM_PW_ADLPROGRESS, QueueID, 10) then
    pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to  ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+')     OK for Queue ' + IntToStr (QueueID))
else
    pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to  ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') failed for Queue ' + IntToStr (QueueID));

But the log for a series of calls is not very revealing to me. note that the four hex digits after the time is the thread id from GetCurrentThreadID.

15:41:53.221 1614  TpwAsyncDataLoader.RunQueue WM_PW_ADLPROGRESS send to  00A5110C (IsWindow True)    OK for Queue -6
15:41:53.265 13B4  TADLQueue.Run WM_PW_ADLPROGRESS send to  00A5110C (IsWindow True)     OK for Queue -6
15:41:53.554 13B4  TADLQueueManager.WriteSysErrorMessageToDatabase Postmessage   00A5110C (IsWindow False)  failed with 1400  Invalid window handle

Can anyone shed some light on this? I'm confused at how a window handle can become invalid while I'm looking at it, but that's what it looks like to me.

The one thing I can think of is that the form I'm showing here isn't processing messages and I'm seeing a "message queue full" failure rather than the IsWindow(handle) failure that it looks like. How can I test for that?

+3  A: 
Lieven
Which basically means you never should store copies of window handles.
Jeroen Pluimers
@Jeroen: what can I say... *Guilty as charged* :)
Lieven
@Lieven: often, when I look at old code from me: boy, I have learned a lot in 25+ years of software development :-) And the more I learn, the more I know for sure I should learn even more...
Jeroen Pluimers
@Jeroen, at least, you shouldn't store copies of window handles from *VCL controls*. Other window handles are fine. In particular, it's safe to store a handle allocated with **`AllocateHWnd`**. Allocate that handle in the VCL thread. The other thread can post its messages there instead. Have it forward pertinent messages to the VCL control.
Rob Kennedy
You're right, the handle has changed on the form. It looks as though I'm going to have to add a comms channel to the base form we use, either by creating our own handle and message pump, or just an OmniThread comms channel.It's so nice to post my problem on Friday afternoon and have a solution by Monday morning. Thanks also Rob for your helpful comment.s
moz