0

私は特定のフォームで 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();

これは正常に動作しますが、醜いコードであり、より良い解決策を見つけようとしています。

4

2 に答える 2

2

2 つの可能性が思い浮かびます。

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.
}

それが機能するためにはDllImportSetLastError=true.

于 2013-09-04T14:58:05.873 に答える
0

Form.showDialog() を使用していますか?

あればそうなります。代わりに Form.show() を使用してください。

于 2013-09-04T13:54:28.000 に答える