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);
}