LoginSignup
1
0

More than 5 years have passed since last update.

MFC PictureCtrl 上にラバーバンドを出す

Last updated at Posted at 2018-06-30

MFC環境での、PictureControl 上でラバーバンドを作成するときのサンプル。
PictureControl を使うと、WM_MOUSEMOVE などのイベントがそのままでは取れません。
リソースエディタの設定で Notify を True に設定すると、PictureControl を張り付けた親のダイアログのPreTranslateMessage() で、イベントをとれるようになります。
あとは、ラバーバンドの一般的なLDown/Up,MouseMove の処理を行ってやればかけます。

ちょっとはまったポイントは、
SetCapture()とデバイスコンテキストの取得先が、
PictureControl からでないといけなかったこと。
PreTranslateMessage() で取得する座標がデスクトップの座標になっていたこと。

冷静に考えれば自然とそうなるのですが、サンプル参考にしながら書くと
なかなか気づきにくかった。。。

IDC_IMAGE_CTRL ... PictureControl の ID名

補足:
OnLButtonUp() などの UINT nFlags は、ひとまず0固定で。
入力されたキーをとる処理を書けば、ちゃんとしたものになるのでしょうが、
これは必要に応じて。。。

SampleAppDlg.cpp
void SampleAppDlg::InitFocusInfo()
{
    focusRect_.bottom = 0;
    focusRect_.left = 0;
    focusRect_.right = 0;
    focusRect_.top = 0;

    isDrawing_ = false;
}

void SampleAppDlg::OnMouseMove(UINT nFlags, CPoint point)
{
    if (isDrawing_ == false) {
        return;
    }

    const RECT newFocusRect = { focusRect_.left ,focusRect_.top ,point.x, point.y };

    HDC hDC = GetDlgItem(IDC_IMAGE_CTRL)->GetDC()->GetSafeHdc();
    DrawFocusRect(hDC, &focusRect_);
    focusRect_ = newFocusRect;
    DrawFocusRect(hDC, &focusRect_);
    ReleaseDC(GetDlgItem(IDC_IMAGE_CTRL)->GetDC());

    CDialogEx::OnMouseMove(nFlags, point);
}

void SampleAppDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
    ReleaseCapture();

    HDC hDC = GetDlgItem(IDC_IMAGE_CTRL)->GetDC()->GetSafeHdc();
    DrawFocusRect(hDC, &focusRect_);
    InitFocusInfo();
    ReleaseDC(GetDlgItem(IDC_IMAGE_CTRL)->GetDC());

    CDialogEx::OnLButtonUp(nFlags, point);
}

void COpenCVApplicationDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    if (isDrawing_ == true) {
        return;
    }
    GetDlgItem(IDC_IMAGE_CTRL)->SetCapture();
    isDrawing_ = true;

    focusRect_.left = point.x;
    focusRect_.top = point.y;


    CDialogEx::OnLButtonDown(nFlags, point);
}

BOOL SampleAppDlg::PreTranslateMessage(MSG* pMsg)
{
    if (pMsg->hwnd == GetDlgItem(IDC_IMAGE_CTRL)->GetSafeHwnd()) {

        RECT rect;
        GetDlgItem(IDC_IMAGE_CTRL)->GetWindowRect(&rect);
        POINT point;
        point.x = pMsg->pt.x - rect.left;
        point.y = pMsg->pt.y - rect.top;

        switch (pMsg->message) {
        case WM_LBUTTONDOWN:
            OnLButtonDown(0, point);
            break;
        case WM_LBUTTONUP:
            OnLButtonUp(0, point);
            break;
        case WM_MOUSEMOVE:
            OnMouseMove(0, point);
            break;
        }
    }
    return CDialogEx::PreTranslateMessage(pMsg);
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0