3

childFormPInvoke を介して SetParent API を使用して、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常に奇妙な場所に行き着きます。

私が間違っているのは何ですか?

4

5 に答える 5

8

ここでのすべての回答は完全に論理的なアプローチを示唆していますが、どれも私にとってはうまくいきませんでした。次に、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-10T00:04:16.013 に答える
6

SetParent現在デスクトップの子であるフォーム (つまり、親が設定されていないフォーム) で使用する場合は、スタイルを設定してWS_CHILDスタイルを削除する必要がありますWS_POPUP( MSDNエントリの「備考」セクションを参照してください。) Windows では、所有するすべてのウィンドウにWS_CHILDスタイル セットが必要です。これにより、フォームがパパが誰であるかがわからないため、左と上のプロパティが間違った値を報告/設定する原因になる可能性もあります。これは、場所を設定する前にSetWindowLong呼び出すことで修正できます。SetParent

//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-08T14:29:33.053 に答える
1

それはあなたの ShowDialog 呼び出しに依存します。親パラメータなしで ShowDialog を呼び出すと、親がリセットされます。

IWin32Window を実装し、HWND を Excel に返すラッパー クラスを作成できます。次に、それを childForm の ShowDialog 呼び出しに渡すことができます。

GetWindowPos を使用して Excel アプリケーションの位置を照会し、それに応じて childForm を設定することもできます。

于 2010-11-08T13:54:37.433 に答える
0

問題を診断するために、いくつかのことを試してください。

  • Left と Top を設定した後にブレークポイントを置きます。Left と Top はゼロを読み取りますか?
  • 最後に SetParent を呼び出します。
  • 再度 Left と Top を設定するメソッドを作成し、そのメソッドを BeginInvoke します。
  • 子ウィンドウが本当に子であることを確認してください。これを行うには、ShowDialog を呼び出し、親ウィンドウをクリックしてみます。ウィンドウが親ウィンドウへのフォーカスを防いでいることを確認してください。
于 2010-11-08T13:35:01.187 に答える
0

z オーダーを設定するウィンドウの hwnds を取得する方法を知っていると仮定すると、この pInvoke を使用できます。

    public stati class WindowsApi 
    {
     [DllImport("user32.dll")]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
        int X, int Y, int cx, int cy, uint uFlags);
    }



    public class WindowZOrderPositioner 
    {
         public void SetZOrder(IntPtr targetHwnd, IntPtr insertAfter)
         {
             IntPtr nextHwnd = IntPtr.Zero;

             WindowsAPI.SetWindowPos(targetHwnd, insertAfter, 0, 0, 0, 0, SetWindowPosFlags.NoMove | SetWindowPosFlags.NoSize | SetWindowPosFlags.NoActivate);
     }
于 2010-11-08T16:21:12.077 に答える