SDK Index Previous page Next page

ホバーボタンを作る その2


はじめに

今回は、Windows98やNT4.0以降で使えるようになったTrackMouseEventを使ったホバーボタンを作成します。このAPIを使うとマウスがウインドウ外に出たこととマウスが一定時間停止していることを知ることが出来ます。

今回のサンプルファイル

TrackMouseEvent

BOOL TrackMouseEvent(
  LPTRACKMOUSEEVENT lpEventTrack // TRACKMOUSEEVENT構造体のアドレス
);
TRACKMOUSEEVENT構造体にデータをセットして、このAPIを呼び出します。
戻り値は、成功したときは0以外の値が返ります。また0が返ってきたときにGetLastErrorを使うと拡張エラーコードが取得できます。

_TrackMouseEvent

TrackMouseEventと同じですが、こちらのAPIはTrackMouseEventが使えないときにTrackMouseEventをエミュレートしてくれます。Windows95+IE3.0以上の環境で使えるので、環境を特定したくない場合はこちらを使います。(サンプルでもこっちを使ってます)

TRACKMOUSEEVENT構造体

typedef struct tagTRACKMOUSEEVENT {
  DWORD cbSize;
  DWORD dwFlags;
  HWND hwndTrack;
  DWORD dwHoverTime;
} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;

DWORD cbSize
 構造体のサイズを入れます

DWORD dwFlags
 TME_LEAVE
  マウスカーソルがウインドウ外に出たときに、WM_MOUSELEAVEメッセージを送る。
 TME_HOVER
  マウスカーソルが一定時間停止していると、WM_MOUSEHOVERメッセージを送る。
 TME_CANCEL
  TME_LEAVE,TME_HOVERと組み合わせて使うことで、これらのメッセージを送らないようにします。
 TME_QUERY
  現在の設定内容を取得します。

 TME_LEAVE,TME_HOVER,TME_CANCELは組み合わせることが可能です

hWND hwndTrack
 メッセージを送るウインドウハンドルです。

DWORD dwHoverTime
 マウスが停止してからWM_MOUSEHOVERメッセージを送るまでの時間(ms)。HOVER_DEFAULTを指定するとデフォルトの時間が設定されます。

この構造体にデータを設定してTrackMouseEventを呼び出すと、指定したメッセージが呼び出されるようになります。ただし、これらのメッセージは一度きりなので、続けてメッセージが必要なときはもう一度TrackMouseEventを呼び出さないといけません。
TME_LEAVEとTME_HOVERの両方を指定しているときは、送られてきたメッセージに対応するフラグだけを設定すればOKです。WM_MOUSEHOVERが来たときはdwFlags=TME_HOVERとしてTrackMouseEventを呼び出します。

ソース

前回から変更のあったとこだけを書きます。説明も必要ないですね。
//マウスカーソルがボタン上に来たときの処理
void MouseEnter(void)
{
    TRACKMOUSEEVENT tme;

    g_BtnInfo.bHover = TRUE;

    tme.cbSize = sizeof(tme);
    tme.dwFlags = TME_LEAVE;
    tme.hwndTrack = g_BtnInfo.hWnd;
    _TrackMouseEvent(&tme);


    InvalidateRect(g_BtnInfo.hWnd, NULL, FALSE);
    UpdateWindow(g_BtnInfo.hWnd);
}

//マウスカーソルがボタン上から出たときの処理
void MouseLeave(void)
{
    g_BtnInfo.bHover = FALSE;

    InvalidateRect(g_BtnInfo.hWnd, NULL, FALSE);
    UpdateWindow(g_BtnInfo.hWnd);
}

//サブクラス化されたボタンのウインドウプロシージャ
LRESULT CALLBACK SubBtnProc(HWND hWnd, unsigned wMessage,
                  WPARAM wParam, LPARAM lParam)
{
    switch(wMessage) {
        case WM_LBUTTONDOWN:
            g_BtnInfo.bPush = TRUE;
            g_BtnInfo.bHover = FALSE;
            break;
        case WM_LBUTTONUP:
            g_BtnInfo.bPush = FALSE;
            break;

        case WM_MOUSEMOVE:
            if(!g_BtnInfo.bPush){   //左ボタンが押されているときは何もしない
                if(!g_BtnInfo.bHover){
                    MouseEnter();
                }
            }
            break;
        case WM_MOUSELEAVE:
            MouseLeave();
            break;
    }

    return CallWindowProc(g_BtnInfo.OrgProc, hWnd, wMessage,
        wParam, lParam);
}

おわりに

予定通り、今回はWin98以降で追加されたTrackMouseEventを使ってみました。次回はどうしようか全然決まってません。


to sdk prev next