【VC++】SetROP2を使用して十字線カーソルを実装する

0

    <機能>

    (1)画面上に長い十字線カーソルを表示します

    (2)画面上をダブルクリックするとポイント座標を表示します

     ※サンプルのためOnLButtonDblClkで表示しています

     ※再描画するためにはWM_PAINTで描画する必要があります

     

    <動作検証&開発環境>
    Visual Studio Community 2015

     

    <イメージ>

    画面上に十字線カーソルが表示されます

    VC++,MFC,十字,カーソル,十字線,オリジナル,SetROP2,

    ダブルクリックするとポイント座標を表示します

    VC++,MFC,十字,カーソル,十字線,オリジナル,SetROP2,

     

    <使い方>

    (1)CrossCursorプロジェクトを作成

    VisualStudio,プロジェクト,2015,

    (2)シングルドキュメント(SDK)、MFC標準を選択

    VisualStudio,プロジェクト,2015,

    (3)システムメニュー以外のチェックを外す

     (閉じるボタン「X」のみ表示する)

    VisualStudio,プロジェクト,2015,

    (4)本サンプルでは使用しない機能を外す

    VisualStudio,プロジェクト,2015,

    (5)クラスウィザードにてDrawCrossLineメンバ関数を追加

     名前:DrawCrossLine

     戻り値:void

     パラメータ:CPoint cp

    VisualStudio,プロジェクト,2015,メンバ関数,メソッド,

    (6)メッセージハンドラを追加

     ・WM_LBUTTONDBLCLK(ダブルクリックイベント)

     ・WM_MOUSEMOVE(マウス移動イベント)

     ・WM_SETCURSOR(カーソルセット)

    VisualStudio,プロジェクト,2015,メッセージハンドラ,

    (7)ソースの追加

     

    /* CrossCursorView.h */

     

    private:
        CPoint oldpo; //十字線の古いポイント位置を保持するための変数
     

    /* CrossCursorView.cpp */

     

    /*************************************************
    関数名 DrawCrossLine
    機能   カーソルのポイント位置より十字線(縦線+横線)を表示します
    *************************************************/

    void CCrossCursorView::DrawCrossLine(CPoint po)
    {
        RECT rect;
        HWND hWnd = (HWND)this->GetSafeHwnd();
        HDC hdc = ::GetDC(hWnd);

        //描画できるクライアント領域を取得
        ::GetClientRect(hWnd, &rect);
        //前景の描画モードを設定(色を反転させる)
        //SetROP2については
    MSDNを参照してください
        SetROP2(hdc, R2_NOT);

        //縦線を描画
        MoveToEx(hdc, po.x, 0, NULL);
        LineTo(hdc, po.x, rect.bottom);
        //横線を描画
        MoveToEx(hdc, 0, po.y, NULL);
        LineTo(hdc, rect.right, po.y);

        //デバイスコンテキストを開放
        ::ReleaseDC(hWnd, hdc);
    }

     

    /*************************************************
    関数名 OnLButtonDblClk
    機能   ダブルクリックによりポイント座標を表示します
    ※実際の描画はWM_PAINTで行う必要があります(再描画されないため)
    *************************************************/

    void CCrossCursorView::OnLButtonDblClk(UINT nFlags, CPoint point)
    {
        HWND hWnd = (HWND)this->GetSafeHwnd();
        HDC hdc = ::GetDC(hWnd);
        HPEN pen, oldpen;

        //表示する文字列を生成
        TCHAR tcstr[255];
        ZeroMemory(&tcstr, sizeof(tcstr));
        wsprintf(tcstr, L"(%d,%d)", point.x, point.y);

        //緑のペン
        pen = CreatePen(PS_SOLID, 5, RGB(0, 255, 0));
        oldpen = (HPEN)SelectObject(hdc, pen);

        //十字線を消去
        DrawCrossLine(point);

        //ポイント位置を中心に円を描画
        Ellipse(hdc, point.x - 10, point.y - 10, point.x + 10, point.y + 10);
        //ポイント位置を左上座標として文字列を描画
        SetTextColor(hdc, RGB(255, 0, 0));
        TextOut(hdc, point.x, point.y, tcstr, lstrlen(tcstr));
        DrawCrossLine(point);

        //ペンを戻す
        SelectObject(hdc, oldpen);
        //デバイスコンテキストを開放
        ::ReleaseDC(hWnd, hdc);
        //ペンオブジェクトを開放
        DeleteObject(pen);

    }

     

    /*************************************************
    関数名 OnMouseMove
    機能   マウスの動きに合わせて十字線を表示します
    *************************************************/

    void CCrossCursorView::OnMouseMove(UINT nFlags, CPoint point)
    {
        CClientDC dc(this);

        //古い十字線を消去
        DrawCrossLine(oldpo);
        //現在位置の十字線を描画
        DrawCrossLine(point);
        //現在位置を保持
        oldpo = point;
    }

     

    /*************************************************
    関数名 OnSetCursor
    機能   デフォルトのカーソルを4方向矢印(IDC_SIZEALL)に設定します
    *************************************************/

    BOOL CCrossCursorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
    {
        //カーソルの種類についてはMSDNを参照してください
        
        //ウェイトカーソル
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
        //ウェイトカーソル&矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_APPSTARTING));
        //クロスカーソル
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
        //4方向矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
        //斜め左下がり矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENESW));
        //斜め右下がり矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENWSE));
        //上下両方向矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
        //左右両方向矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
        //上矢印
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_UPARROW));
        //アイビーム
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM));
        //禁止
        //::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO));

     

        //4方向十字カーソルを選択

        ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
        return TRUE;

     

    よろしければポチッと押してください

    プログラマー ブログランキングへ

     

     

     



    calendar

    S M T W T F S
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
    << October 2017 >>

    profile

    others

    mobile

    qrcode