...ing logging 4.0

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

DFL: バルーン通知のサンプルコード

以前の NotifyIcon のサンプルコードを拡張して、バルーン通知を表示できるようにしました。

WinForms の NotifyIcon クラスを踏襲する方針で始めましたが、 NOTIFYICONDATAW 構造体に定義されている機能が色々あるのに、 Windows API の Shell_NotifyIconW() の機能が WinForms ではあまり実装されていないようです。

今回、DFL の NotifyIcon クラスに 次のメソッドを追加することにしました(イベントハンドラ関係は未実装)。

void showBalloonTip(); // バルーン通知を表示
void balloonTipTitle(Dstring title); // バルーン通知のタイトルを設定
void balloonTipText(Dstring text); // バルーン通知のテキストを設定
void balloonTipIconStyle(BalloonTipIconStyle style); // バルーン通知のアイコンを選択又はユーザー定義
void balloonTipIcon(Icon icon); // バルーン通知用のアイコンを設定
void balloonTipSound(bool byes); // 通知音のオンオフ

サンプルコード

import dfl;

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

class MainForm : Form
{
    private NotifyIcon _notifyIcon;

    public this()
    {
        this.text = "NotifyIcon example";
        this.size = Size(300, 200);
        
        MenuItem menuItem1 = new MenuItem("Show");
        menuItem1.click ~= (MenuItem mi, EventArgs e) { msgBox("Hi!"); };

        MenuItem menuItem2 = new MenuItem("Close");
        menuItem2.click ~= (MenuItem mi, EventArgs e) { this.close(); };
        
        _notifyIcon = new NotifyIcon;
        _notifyIcon.icon = new Icon(r".\image\icon.ico");
        _notifyIcon.text = "This is tooltip text";
        _notifyIcon.contextMenu = new ContextMenu;
        _notifyIcon.contextMenu.menuItems.add(menuItem1);
        _notifyIcon.contextMenu.menuItems.add(menuItem2);
        _notifyIcon.show();

        // ここから新しい機能
        _notifyIcon.balloonTipTitle = "Balloon tip example";
        _notifyIcon.balloonTipText = "Welcome to the D world!";
        static if (false) // 既定のアイコンを使うときはこちら
        {
            _notifyIcon.balloonTipIconStyle = BalloonTipIconStyle.INFO;
            // _notifyIcon.balloonTipIconStyle = BalloonTipIconStyle.ERROR;
            // _notifyIcon.balloonTipIconStyle = BalloonTipIconStyle.WARNING;
            // _notifyIcon.balloonTipIconStyle = BalloonTipIconStyle.NONE;
        }
        else
        {
            _notifyIcon.balloonTipIconStyle = BalloonTipIconStyle.USER; // USER を設定すると balloonTipIcon が使われる。
            _notifyIcon.balloonTipIcon = new Icon(r".\image\icon2.ico");
        }
        _notifyIcon.balloonTipSound = true;
        _notifyIcon.showBalloonTip();
    }
}

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

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

応急処置

DMD に添付されている shellapi.d が古いようで、NOTIFYICONDATAW 構造体に hBalloonIcon が定義されていませんでした。

これが定義されていないとタスクトレイアイコンとバルーン通知アイコンを別々に設定できません。

仕方がないので、hBalloonIcon を持つ構造体 DFL_NOTIFYICONDATAW を自前で定義して、 ポインタをNOTIFYICONDATAW* にキャストして Shell_NotifyIcon() に与えるようにして、ごまかしました。

DFLのダウンロード

github.com

code.dlang.org