How to catch left click event for coordinates MFC Picture Control

0

I am trying to follow an example to register click events so I can grab coordinates for my mandelbrot experiment. I am trying to get the x and y coordinates of the output picture box image that is created when the mandelbrot is compiled. The issue is that it does not recognise UWM_ON_TNB_LCLICKED and UWM_ON_TNB_RCLICKED.

I followed the example word by word but I'm not sure what I am supposed to put in place of UWM_ON_TNB_LCLICKED and UWM_ON_TNB_RCLICKED. The picture box where I want the user to click in is called IDC_BMP. I am trying to only get the coordinates within the picturebox IDC_BMP so that I can apply my zoom.

enter image description here

mbrotDlg.h

protected:

**afx_msg LRESULT OnTnbLClicked(WPARAM wParam, LPARAM /* lParam  */);
afx_msg LRESULT OnTnbRClicked(WPARAM wParam, LPARAM /* lParam */);**
DECLARE_MESSAGE_MAP()

public:
afx_msg void OnBnClickedBtnCompile();
afx_msg void OnBnClickedBtnTest();

mbrotDlg.cpp

BEGIN_MESSAGE_MAP(CMandelbrotExperimentDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTNCOMPILE, &CMandelbrotExperimentDlg::OnBnClickedBtnCompile) //Start Monitoring Button
ON_BN_CLICKED(IDC_BUTTON1, &CMandelbrotExperimentDlg::OnBnClickedBtnTest) //Start Monitoring Button
ON_REGISTERED_MESSAGE(UWM_ON_TNB_LCLICKED, OnTnbLClicked)
ON_REGISTERED_MESSAGE(UWM_ON_TNB_RCLICKED, OnTnbRClicked)

Functions:

LRESULT CMandelbrotExperimentDlg::OnTnbLClicked(WPARAM wParam, LPARAM /* lParam  */) { return 0; }
LRESULT CMandelbrotExperimentDlg::OnTnbRClicked(WPARAM wParam, LPARAM /* lParam */) { return 0; }

I have tried the following but the program just crashes on startup. It crashes on the PreTranlateMessage function.

Unhandled exception at 0x00B8D789 in Mandelbrot Experiment.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00602F20).

mbrotDlg.cpp

BOOL CMandelbrotExperimentDlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_BMP)->GetSafeHwnd() == 
pMsg->hwnd)
{
    CPoint point(pMsg->pt);
    ScreenToClient(&point);

    OnLButtonDown(pMsg->wParam, point);   
}

return CMandelbrotExperimentDlg::PreTranslateMessage(pMsg);

}


 void CMandelbrotExperimentDlg::OnLButtonDown(UINT nFlags, CPoint point)
 {
// TODO: Add your message handler code here and/or call default

CRect rect;
m_picture.GetWindowRect(&rect);
ScreenToClient(&rect);
if (rect.PtInRect(point))
{
    // Do something
}

CMandelbrotExperimentDlg::OnLButtonDown(nFlags, point);
}

I have got it almost working, when I hover the mouse over the preview image it executes the event on the picture control. However I have an error in this line of the code (indicated in comments):

BEGIN_MESSAGE_MAP(CStaticSub, CStatic)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()


void CStaticSub::OnMouseMove(UINT nFlags, CPoint point)
{

    ScreenToClient(&point);
    CString str;
    str.Format("[%d, %d]", point.x, point.y); // Error on this line
    this->GetParent()->GetDlgItem(IDC_EDIT10)->SetWindowText(str);

    CStatic::OnMouseMove(nFlags, point);

}

If I set str to "Hello" I see it appear in one of the edit boxes when I hover over the picture.

c++
mfc
asked on Stack Overflow Mar 13, 2020 by Mr Tea • edited Mar 14, 2020 by Andrew Truckle

1 Answer

-1

To make this work, I created a class derived from CStatic as shown below:

CStaticSub.h

#pragma once
 #include <afxdialogex.h>

class CStaticSub :
public CStatic
{
    public:
    CStatic m_pic;

    DECLARE_MESSAGE_MAP()
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};

I added a public CStatic variable called m_pic which will be used by my picture control on my main dialog.

CStaticSub.cpp

#include "pch.h"
#include "CStaticSub.h"
#include "Mandelbrot Experiment.h"
#include "Mandelbrot ExperimentDlg.h"


BEGIN_MESSAGE_MAP(CStaticSub, CStatic)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

void CStaticSub::OnMouseMove(UINT nFlags, CPoint point)
{
    ScreenToClient(&point);
    CString strx;
    CString stry;
    strx.Format(_T("%d"), point.x);
    stry.Format(_T("%d"), point.y);
    this->GetParent()->GetDlgItem(IDC_EDIT10)->SetWindowText(strx);
    this->GetParent()->GetDlgItem(IDC_EDIT11)->SetWindowText(stry);

    CStatic::OnMouseMove(nFlags, point);

  }

Then in the main dialog I then subclassed the picture control:

Mandelbrot Experiment.h

class CMandelbrotExperimentDlg : public CDialogEx
{
    // Construction
public:
   CMandelbrotExperimentDlg(CWnd* pParent = nullptr);   // standard constructor
   CStaticSub m_pic;

Then in the main dialog .cpp I created the function that would fire on mousemove or mouseclick as shown below:

Mandelbrot ExperimentDlg.cpp

void mynamespace::CMandelbrotExperimentDlg::OnMouseMove(UINT nFlags, CPoint point)
{   
    //Get the Picture Control's Rect To check
    CRect rect;
    m_pic.GetWindowRect(rect);
    ScreenToClient(&rect);

    //Store The Cursor Position
    CPoint pt;
    GetCursorPos(&pt);

    //Make it as LPARAM and send it
    LPARAM lp = MAKELPARAM(pt.x, pt.y);

    //If the mouse is hovering over the picture control..
    if (rect.PtInRect(point))
    {
        m_pic.SendMessage(WM_MOUSEMOVE, 0, lp);
    }

    CDialog::OnMouseMove(nFlags, point);
}

Finally I added the message event

BEGIN_MESSAGE_MAP(CMandelbrotExperimentDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTNCOMPILE, &CMandelbrotExperimentDlg::OnBnClickedBtnCompile) 
//Start Monitoring Button
ON_BN_CLICKED(IDC_BUTTON1, &CMandelbrotExperimentDlg::OnBnClickedBtnTest) 

//THIS ONE!
ON_WM_MOUSEMOVE(OnMouseMove)


END_MESSAGE_MAP()

This could be adapted for mouse clicks also. I felt that hover was better in the end.

answered on Stack Overflow Mar 14, 2020 by Mr Tea • edited Mar 14, 2020 by Mr Tea

User contributions licensed under CC BY-SA 3.0