0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MFCの部品をWindows.Forms.Formに埋め込む

Last updated at Posted at 2018-05-12

WinformsはForm#HandleでふつうにHWNDが取り出せるので、CWnd::AttachCWnd::DetachでMFCの部品をWindows.Forms.Formに貼り付けることができます。

C++/CLIを使うともっとスムーズにいくのかもしれませんが、なんかうまくいかなかったので次のようにしました。

手順

1. DLLを作る

MFCのDLLで、以下のような初期化と解放用の関数を作ります。

attach.cpp
/** WinFormsのhwndにattachし、newしたcwndを返す */
extern "C" __declspec(dllexport) CWnd* PASCAL attach(HWND hwnd) {
    auto w = std::make_unique<CWnd>();

    if (!w->Attach(hwnd)) { return nullptr; }

    // ... wに好きな部品を置く ...

    return w.release();
}

/** attachで作ったcwndをdetachとdeleteする */
extern "C" __declspec(dllexport) void PASCAL detach(Pair *p) {
    auto w = std::unique_ptr<CWnd>(cwnd);
    w->Detach();
}

2. ControlでHandleを渡して呼ぶ

作ったDLLの関数をコントロールで呼び出します。

SomeMFCControl.cs
public class GuestControl : Control
{
    /// <summary>アタッチしたMFCのCWnd</summary>
    private IntPtr CWnd { get; }

    [DllImport("attach")]
    private static extern IntPtr attach(IntPtr hwnd);
    [DllImport("attach")]
    private static extern void detach(IntPtr hwnd);

    public GuestControl()
    {
        CWnd = attach(Handle);
    }
    
    protected override void Dispose(bool disposing)
    {
       if (disposing)
       {
          detach(CWnd);
       }

       base.Dispose(disposing);
    }
}

あとはこのControlをフォームに貼り付ければ動きます。

参考リンク

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?