Embedding window into another process

前端 未结 2 1383
醉话见心
醉话见心 2020-12-16 07:39

I have read some posts here on StackOverflow, but none has worked for me. Here is the code I am using to display the window of the standard Calculator on my form:

         


        
2条回答
  •  生来不讨喜
    2020-12-16 07:52

    Try this code. I took it from one of my older source codes. You will lose glass frame, but main menu is visible, and I didn't notice any problem in setting focus back to the embedded app. You should be able to do so using SetForegroundWindow() API function. Whenever you move your container form, your embedded app loses focus, so you need to call SetForegroundWindow again to restore focus :

    procedure ShowAppEmbedded(WindowHandle: THandle; Container: TWinControl);
    var
      WindowStyle : Integer;
      FAppThreadID: Cardinal;
    begin
      /// Set running app window styles.
      WindowStyle := GetWindowLong(WindowHandle, GWL_STYLE);
      WindowStyle := WindowStyle
                     - WS_CAPTION
                     - WS_BORDER
                     - WS_OVERLAPPED
                     - WS_THICKFRAME;
      SetWindowLong(WindowHandle,GWL_STYLE,WindowStyle);
    
      /// Attach container app input thread to the running app input thread, so that
      ///  the running app receives user input.
      FAppThreadID := GetWindowThreadProcessId(WindowHandle, nil);
      AttachThreadInput(GetCurrentThreadId, FAppThreadID, True);
    
      /// Changing parent of the running app to our provided container control
      Windows.SetParent(WindowHandle,Container.Handle);
      SendMessage(Container.Handle, WM_UPDATEUISTATE, UIS_INITIALIZE, 0);
      UpdateWindow(WindowHandle);
    
      /// This prevents the parent control to redraw on the area of its child windows (the running app)
      SetWindowLong(Container.Handle, GWL_STYLE, GetWindowLong(Container.Handle,GWL_STYLE) or WS_CLIPCHILDREN);
      /// Make the running app to fill all the client area of the container
      SetWindowPos(WindowHandle,0,0,0,Container.ClientWidth,Container.ClientHeight,SWP_NOZORDER);
    
      SetForegroundWindow(WindowHandle);
    end;
    

    You can call it this way:

      ShowAppEmbedded(FindWindow(nil, 'Calculator'), Panel1);
    

提交回复
热议问题