...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

DFL: ContextMenuのサンプルコード

コンテキストメニューのサンプルです。

特に難しいことはないですね。

ただ、mouseDownイベントを使って右クリックを検出した方が、DFLらしいかもしれません。

import dfl;
import core.sys.windows.windows;

version(Have_dfl) // For DUB.
{
}
else
{
    pragma(lib, "dfl.lib");
}

class MainForm : Form
{
    private ContextMenu _contextMenu;
    
    this()
    {
        this.text = "ContextMenu example";
        this.size = Size(350, 200);
        
        _contextMenu = new ContextMenu();
        MenuItem contextMenuItem1 = new MenuItem("Kyoto");
        contextMenuItem1.click ~= (MenuItem mi, EventArgs e) {
            msgBox("Kyoto");
        };
        MenuItem contextMenuItem2 = new MenuItem("Tokyo");
        contextMenuItem2.click ~= (MenuItem mi, EventArgs e) {
            msgBox("Tokyo");
        };
        MenuItem contextMenuItem3 = new MenuItem("Osaka");
        contextMenuItem3.click ~= (MenuItem mi, EventArgs e) {
            msgBox("Osaka");
        };
        _contextMenu.menuItems.add(contextMenuItem1); // 1つだけでも
        _contextMenu.menuItems.addRange([contextMenuItem2, contextMenuItem3]); // 配列を渡すこともできる
    }

    // 右クリックした位置にメニューを表示するためにウィンドウプロシージャをoverrideする
    // Control.mouseDownイベントでもできそう?
    override void wndProc(ref Message msg)
    {
        switch (msg.msg)
        {
            case WM_RBUTTONDOWN:
            {
                if (_contextMenu)
                {
                    POINT pt;
                    GetCursorPos(&pt);
                    _contextMenu.show(this, Point(&pt));
                }
                return;
            }
         default:
            {
                super.wndProc(msg);
                return;
            }
        }
    }
}

static this()
{
    Application.enableVisualStyles();
}

void main()
{
    Application.run(new MainForm());
}

DFLのダウンロード

github.com

追記

GitHubのサンプルコードは、mouseDownイベントを使った方法に変更しました。

ひとつ注意事項があります。 MouseEventArgsで与えられるマウス座標はクライアント座標です。 コンテキストメニューを表示する座標はスクリーン座標で指定しなければならないので、クライアント座標からスクリーン座標に変換する必要があります。

this.mouseDown ~= (Control c, MouseEventArgs e) {
    if (e.button & MouseButtons.RIGHT)
    {
        if (_contextMenu)
        {
            Point pt = Point(e.x, e.y);
            ClientToScreen(handle, &pt.point);
            _contextMenu.show(this, pt);
        }
    }
};