SetWindowPos无法处理Form.Show()

时间:2013-09-04 13:48:02

标签: c# winapi

我在某个Form上调用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();

工作正常,但只是丑陋的代码,我正在努力寻找更好的解决方案。

2 个答案:

答案 0 :(得分:2)

有两种可能性浮现在脑海中。

首先,你说在main.Shown,外部程序调用{​​{1}}来移动窗口。显示表单的代码需要2或3秒才能初始化,然后将窗口移出屏幕。调用SetWindowPos的外部程序在调用SetWindowPos 之前是否可能正在执行

如果您注释掉HideMainForm会怎样?窗户是否被移动了?

其次,你有:

HideMainForm

可能是SetWindowPos( pd.CurrentHandle, HWND_TOPMOST, r.X, r.Y, r.Width, r.Height, SetWindowPosFlags.DoNotChangeOwnerZOrder); 标志正在干扰DoNotChangeOwnerZOrder请求,并且该功能失败。 documentation说:

  

通过将hWndInsertAfter参数设置为HWND_TOPMOST并确保未设置SWP_NOZORDER标志,或者通过设置Z顺序中的窗口位置使其位于任何现有的最顶层窗口之上,可以将窗口设置为最顶层窗口。当一个非最顶层的窗口最顶层时,它拥有的窗口也是最顶层的。然而,它的主人并没有改变。

当然,这并没有说明HWND_TOPMOST标志的任何内容,但在一般情况下,如果在其上方放置了某些东西,则所有者的Z顺序将会改变。因此,如果您请求该标志并且该函数无法确保它,则该函数可能会失败。

您需要检查SWP_NOOWNERZORDER的返回值:

SetWindowPos

为了实现这一目标,您的bool success = SetWindowPos(...); if (!success) { int err = Marshal.GetLastWin32Error(); // the err value will give you information about why it failed. } 必须DllImport

答案 1 :(得分:0)

您使用的是Form.showDialog()吗?

如果是这样的话。改为使用Form.show()。