我在StackOverflow上看过一些帖子,但没有一个对我有用.这是我用来在我的表单上显示标准计算器窗口的代码:
procedure TForm1.Button1Click(Sender: TObject); var Tmp: Cardinal; R: TRect; begin CalcWindow := FindWindow(nil,'Calculator'); if (CalcWindow <> 0) then begin GetWindowThreadProcessID(CalcWindow,CalcProcessID); Tmp := GetWindowLong(CalcWindow,GWL_STYLE); Tmp := (Tmp and not WS_POPUP) or WS_CHILD; SetWindowLong(CalcWindow,GWL_STYLE,Tmp); GetWindowRect(CalcWindow,R); SetForegroundWindow(CalcWindow); Windows.SetParent(CalcWindow,Panel1.Handle); SetWindowPos(CalcWindow,HWND_TOPMOST,SWP_NOSIZE or SWP_FRAMECHANGED); AttachThreadInput(GetCurrentThreadID(),CalcWindow,True); end; end;
它确实在我的窗体上显示窗口,但玻璃边框有时丢失(特别是当我移动窗体时),很难将焦点恢复到嵌入窗口(我需要多次单击).
可能是什么导致了这个?另外,您是否看到使用此方法可能遇到的任何潜在问题?
感谢您的时间.
解决方法
试试这个代码.我从一个较旧的源代码中获取了它.您将失去玻璃框架,但主菜单是可见的,我没有注意到将焦点设置回嵌入式应用程序时出现任何问题.您应该可以使用SetForegroundWindow()API函数执行此操作.每当您移动容器表单时,嵌入式应用程序都会失去焦点,因此您需要再次调用SetForegroundWindow来恢复焦点:
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,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,GetWindowLong(Container.Handle,GWL_STYLE) or WS_CLIPCHILDREN); /// Make the running app to fill all the client area of the container SetWindowPos(WindowHandle,Container.ClientWidth,Container.ClientHeight,SWP_NOZORDER); SetForegroundWindow(WindowHandle); end;
你可以这样称呼它:
ShowAppEmbedded(FindWindow(nil,'Calculator'),Panel1);