views:

267

answers:

3

I have a child window that is maximized within a parent.

It needs to be disabled so that it doesn't receive inputs until I press a key. When I press key 'A' for instance, I want the child window to be enabled, receive inputs sent with SendInput() and disable again.

So I do this:

EnableWindow( hwnd, TRUE );
SetForegroundWindow( hwnd);
SetFocus( hwnd);
Sleep(50);

SendInput()...x7-8 times

EnableWindow( hwnd, FALSE );

Now, EnableWindow functions work fine, except window misses some of the inputs. I tried to put some delay after EnableWindow (like 6-7 seconds!!) and still it doesn't work right.

I tried SetWindowPos() to have it update its frame, I tried setting the WS_DISABLE bit manually but still no luck. Inputs work fine if the child window is enabled all the time.

Any help is appreciated.

+1  A: 

A Child window is serviced by the same thread as it's parent window. So the send SendInput doesn't do any good unless you go back to the pump and handle the events before you disable the window again.

If you explain what you are trying to accomplish, we could probably give you a better way to do it. But in any case, at the very least you need to run a message pump after SendEvents until you run out of events.

Be aware the a pump will also pump other messages, so it may make your whole design fall over. But, here it is.

// process messages until the queue is empty.
//
MSG msg;
while (PeekMessage(&msg, NULL, 0, PM_REMOVE))
{
    // make sure we don't eat the quit message.
    if (WM_QUIT == msg.message)
    {
       PostQuitMessage();
       break;
    }

    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

Oh, and the Sleep() isn't doing anything useful, you can take it out.

Edit: this code goes after the SendInput call and before the window is disabled. You may also want to use it instead of Sleep() to get the window to settle down before you SendInput.

John Knoeller
It barely works if I take the Sleep() out. Most of the inputs that come afterwards are either sent before the window is in focus or messed up.The rest is as I said below.
Dogan Demir
A: 

Not an answer but I can't seem to comment on your (John) answer as I moved to a different computer.

I am sending Input macros (mouse+keyboard) to the child window 'on keypress' with SendInput(). Now, this child window covers the parent window screen (maximized inside the parent) and I need to be able to click on the surface of the parent window. If I don't disable the child, then the clicks are handled by the child and I don't want that. I'm not sure how I can explain better.

So simply put, I want to do bunch of SendInput() to child when I press a certain key and I want all inputs to be handled by the parent window otherwise.

The code segment above runs within the message handling function of the parent thread and I'm not sure if I got your answer. I can't figure out where your code goes.

Dogan Demir
Do you own the source code to the child window? You could fix the problem of clicking through the child in a different way if you could change its code.
John Knoeller
No I don't, thats the problem. The child window can be any application.
Dogan Demir
A: 

Instead of SendInput, I would try sending keyboard or mouse messages directly to the child window. For example:

EnableWindow(hwnd, TRUE);

SendMessage(hwnd, WM_KEYDOWN, ..., ...);
SendMessage(hwnd, WM_KEYUP, ..., ...);
// etc...

EnableWindow(hwnd, FALSE);
zildjohn01