我尝试通过PInvoke使用SetParent应用编程接口将childForm设置为Excel主窗口的子窗口:
Form childForm = new MyForm();
IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
SetParent(childForm.Handle, excelHandle);
childForm.StartPosition = FormStartPosition.Manual;
childForm.Left = 0;
childForm.Top = 0;正如您在上面看到的,我的意图也是将子级放置在Excel窗口的左上角。然而,由于某些原因,childForm总是会出现在某个奇怪的位置。
我到底做错了什么?
发布于 2010-11-10 08:04:16
虽然这里的所有答案都建议完全合乎逻辑的方法,但没有一个对我有效。然后我尝试了MoveWindow。出于某种原因,我不明白,它做到了。
代码如下:
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
...
Form childForm = new MyForm();
IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
SetParent(childForm.Handle, excelHandle);
MoveWindow(childForm.Handle, 0, 0, childForm.Width, childForm.Height, true);发布于 2010-11-08 22:29:33
在当前是桌面子级的窗体(换句话说,没有父级集的窗体)上使用SetParent时,必须设置WS_CHILD样式并删除WS_POPUP样式。(请参阅MSDN条目的备注部分。)Windows要求所有拥有的窗口都设置了WS_CHILD样式。这也可能导致left和top属性报告/设置错误的值,因为表单不知道它的爸爸是谁。您可以通过在SetParent之后但在尝试设置位置之前调用SetWindowLong来解决此问题:
//Remove WS_POPUP style and add WS_CHILD style
const UInt32 WS_POPUP = 0x80000000;
const UInt32 WS_CHILD = 0x40000000;
int style = GetWindowLong(this.Handle, GWL_STYLE);
style = (style & ~(WS_POPUP)) | WS_CHILD;
SetWindowLong(this.Handle, GWL_STYLE, style);发布于 2010-11-08 21:54:37
我相信这取决于您的ShowDialog调用。如果在不使用父参数的情况下调用ShowDialog,则会重置父参数。
您可以创建一个实现IWin32Window并将HWND返回到excel的包装类。然后,您可以将其传递给childForm的ShowDialog调用。
您还可以使用GetWindowPos查询excel应用程序的位置,然后相应地设置childForm。
https://stackoverflow.com/questions/4124025
复制相似问题