SetWindowPos 在 Form.Show() 上不起作用
本文关键字:不起作用 Show Form SetWindowPos | 更新日期: 2023-09-27 18:30:18
我在某个表单上调用 Form.Show(),然后做一些事情导致显示的表单上的一些更新。
我想在这段时间内使用 SetWindowPos 将此窗口窗体移动到另一个位置。可悲的是,SetWindowPos的调用完全没有做任何事情。可能是因为从不闲置?
知道谁来解决这个问题吗?
谢谢
编辑:一些代码:
main.Show();
main.initBase(); //Takes 2-3 seconds
main.HideMainForm(); //Moves the form to (10000, 10000), to hide it (can't change that it's an old programm)
在main.Shown
活动中,我调用了另一个程序,而不是调用 SetWindowPos(pd.CurrentHandle, HWND_TOPMOST, r.X, r.Y, r.Width, r.Height, SetWindowPosFlags.DoNotChangeOwnerZOrder);
其中 r 是所选显示器的矩形
我试过了
EventHandler ev = new EventHandler((s, e) =>
{
main.Close();
ev = new EventHandler((s2, e2) => { });
});
main.Shown += ev;
main.ShowDialog();
main.Show();
这工作正常,但只是丑陋的代码,我正在尝试找到更好的解决方案。
我想到了两种可能性。
首先,你说在main.Shown
,外部程序调用SetWindowPos
来移动窗口。显示表单的代码需要 2 或 3 秒来初始化,然后将窗口移出屏幕。调用SetWindowPos
的外部程序是否有可能在调用HideMainForm
之前执行?
如果您注释掉HideMainForm
会怎样?窗口会移动吗?
其次,你有:
SetWindowPos(
pd.CurrentHandle,
HWND_TOPMOST,
r.X, r.Y, r.Width, r.Height,
SetWindowPosFlags.DoNotChangeOwnerZOrder);
可能是 DoNotChangeOwnerZOrder
标志干扰了HWND_TOPMOST
请求,并且函数失败。文档说:
通过将 hWndInsertAfter 参数设置为 HWND_TOPMOST 并确保未设置 SWP_NOZORDER 标志,或者按 Z 顺序设置窗口的位置,使其位于任何现有的最顶层窗口之上,可以将窗口设置为最顶层窗口。当非最顶层窗口设为最顶层时,其拥有的窗口也设置为最顶层。但是,其所有者不会更改。
当然,这并不能说明SWP_NOOWNERZORDER
标志,但在一般情况下,如果将某些东西放在其上方,所有者的 Z 顺序会发生变化。因此,如果您请求该标志并且函数无法确保它,则该函数可能会失败。
您需要检查 SetWindowPos
的返回值:
bool success = SetWindowPos(...);
if (!success)
{
int err = Marshal.GetLastWin32Error();
// the err value will give you information about why it failed.
}
为此,您的DllImport
必须具有 SetLastError=true
.
你使用的是 Form.showDialog() 吗?
如果是这样,就会发生这种情况。请改用 Form.show()。