1

Possible Duplicate:
Embedding HWND into external process using SetParent

I'm trying to embed a window from my process into the window of an external process using the SetParent function and have encountered a few problems that I'm hoping someone can help me out with. First off, here is an outline of what I am currently doing to embed my window into the application:

WND myWindow; //Handle to my application window
HWND externalWindow; //Handle to external application window

SetParent(myWindow,externalWindow);

//Remove WS_POPUP style and add WS_CHILD style
DWORD style = GetWindowLong(myWindow,GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD;
SetWindowLong(myWindow,GWL_STYLE,style);

This code works and my window appears in the other application, but introduces the following issues:

  • When my window gains input focus, the main application window of the external process loses focus (i.e. title bar changes color).
  • Keyboard shortcut commands of the main application do not work while my window has focus.

Does anybody know workarounds for these issues? I would like my window to be treated as just another child window of the main application.

Thanks.

Community
  • 1
  • 1
Sean
  • 19
  • 1
  • 2
  • I am not sure this is the right way to go. Most likely after fixing one flaw after a while you will discover another problem... – Kirill Kobelev Jul 06 '12 at 04:19
  • This is not very easy. Do you have the code of the external window? Try going for MDI Child! It is easier to let the parent provide a window that will be the parent window / frame for your childwindow then. If you have the code, there are ways to do that. You will have to extend the resource chain I believe. Do you have a chance of making your child process a DLL? – Mare Infinitus Jul 06 '12 at 05:31
  • 1
    @Mark Hall: You are right, it even seems to be an exact copy. – Mare Infinitus Jul 06 '12 at 05:36

1 Answers1

1

When my window gains input focus, the main application window of the external process loses focus (i.e. title bar changes color).

You need to use AttachThreadInput to attach your process's thread to the input queue of the host process. In addition to synchronizing message processing across all attached threads, this causes them to share focus, asynchronous key state, activation, and other input-related properties.

Keyboard shortcut commands of the main application do not work while my window has focus.

When your window has keyboard focus, the thread that owns your window receives all keyboard messages from the system. If you need the main window's UI thread to handle accelerators, you must somehow route keyboard input to that thread for preprocessing. How you do this depends largely on the UI technologies you are using for your applications and how you need accelerators to be processed.

Building a user interface that spans multiple threads in different processes is difficult and there are many pitfalls.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • @Mare Infinitus , ye it's an copy from Mark Hall, i met the same issues when embedding an external application(like a notepad.exe) in my apps. – Sean Jul 06 '12 at 06:29
  • Thnaks for you detailed suggestion, and i had a try like this: DWORD dwPtyID = ::GetWindowThreadProcessId(hWnd,NULL);// hWnd indiciate to the external app's handle. DWORD dwprocID = ::GetCurrentThreadId(); ::AttachThreadInput(dwprocID, dwPtyID, true); but this doesn't work. thanks again – Sean Jul 06 '12 at 06:34
  • 1
    What does "this doesn't work" mean? At what point does it not work? What error do you get? (For what it's worth: trying to embed another application that you don't control is likely not to work very well, if at all.) – James McNellis Jul 06 '12 at 15:46