第2回 マウスカーソル

 

クライアントウィンドウ上のマウスカーソル制御は、各プログラムが任意に制御できるので、ここでは除外します。

また、コントロールパネルの「マウスのプロパティ」で登録すれば、自分の好きな形のマウスカーソルを使えます。

ここでは、上記以外のマウスカーソル制御についてお伝えします。

 

(1)ウェイト(砂時計)カーソル

MFCを利用したプログラムで、ウェイトカーソルを使いたい場合、普通(?)は、CWaitCursorクラスを使用すると思います。

BTMemoでもそうやってウェイトカーソルを使っています。

この場合、通常はコントロールパネルの「マウスのプロパティ」で登録されているマウスカーソルが表示されますが、

アプリケーションクラスのDoWaitCursorメンバ関数をオーバーライドすれば、それを変更する事ができます。

 

void CBTMemoApp::DoWaitCursor(int nCode)

{

    m_nWaitCursorCount += nCode;

    if (m_nWaitCursorCount > 0) {

        HCURSOR hcurPrev = ::SetCursor(::LoadCursor(MAKEINTRESOURCE(IDC_BUSY)));  // ここで独自のカーソルを指定します

            if (nCode > 0 && m_nWaitCursorCount == 1) m_hcurWaitCursorRestore = hcurPrev;

    }

    else {

        // turn everything off

        m_nWaitCursorCount = 0;     // prevent underflow

        ::SetCursor(m_hcurWaitCursorRestore);

    }

} 

 

 

 

(2)フレームウィンドウ上のマウスカーソル

通常、フレームウィンドウに対する操作ではドラッグ前とドラッグ中で違うマウスカーソルを使うことはできません。

例えば、マウスカーソルがキャプションバーの上にきたらにして、そのままドラッグしている途中(ウィンドウの移動中)はにするというようなことです。

それを行わないのがWindows流ということなのかもしれませんが…。

しかし、フレームウィンドウクラスのOnSetCursorメンバ関数をオーバーライドすれば、上記のようなことを行うことができます。

 

BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)

{

    if (message == 0) {

        ::SetCursor(g_hSelect);        // メニュー操作中の場合。

        return TRUE;

    }

    switch(nHitTest) {

    case HTCAPTION:                    // タイトルバーの領域内にある場合

        // マウスの左ボタンが押されているかどうかでマウスカーソルを使い分けます。

        ::SetCursor((message == WM_LBUTTONDOWN) ? g_hGrip : g_hMove);

        return TRUE;

    case HTCLIENT:                     // クライアント領域内にある場合は感知しません

        break;

    default:

        ::SetCursor(g_hSelect);

        return TRUE;

    }

    return CFrameWnd::OnSetCursor(pWnd, nHitTest, message);

}

 

備考:

g_hSelect、g_hGrip、g_hMoveは、マウスカーソルのハンドルが格納されているグローバル変数で、

プログラム起動時にハンドルが格納されています。

 

 

 

(3)ドラッグ中のマウスカーソル

 

BTMemoでは、OLEのドラッグ&ドロップの仕組みを使っていますが、ドラッグ中のマウスカーソル制御は実現できていません。

せめてBTMemoのウィンドウ上にある場合だけでもマウスカーソルを変更したいと、あれこれ試しては見ましたがだめでした。

 

実現方法を知っている方がいたら、ぜひその方法を教えてください。よろしくお願いします。