none
click location within MFC Picture control RRS feed

  • Question

  • I have a picture control in my dialog box, showing some image.

    I need to detect the click location within thisMFC picture control (IDC_STATIC_BITMAP).

    How do I do that?

    Thank you.

     
    Friday, September 21, 2018 8:26 PM

Answers


  • First, you could try overriding the PreTranslateMessage function in your self-define dialog class.
    like this:

    BOOL CMFCDialogOneDlg::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_STATIC_BITMAP)->GetSafeHwnd() == pMsg->hwnd)
    		OnLButtonDown(MK_LBUTTON, pMsg->pt);   //passes the coordinates of the clicked Point in the dialog box
    
    	return CDialogEx::PreTranslateMessage(pMsg);
    }

    Then , you should judge the Point within MFC Picture control or not in the OnLButtonDown function.(lRect is the area of pircture control),like this:

    if((point.x>=lRect.left && point.x<=lRect.right) && (point.y>=lRect.top && point.y<=lRect.bottom))
    {
    	// detect the click location within this MFC picture control
    }

    A couple of observations --

    Standard MFC message handling will pass a dialog's client area coordinates of a mouse click to its OnLButtonDown handler.  The PreTranslateMessage override above passes screen coordinates.  I suggest this be conformed to pass client area coordinates.  That way, any other processing that might be performed in the OnLButonDown handler receives the proper coordinates.

    Also, the PreTranslateMessage override code also passes MK_LBUTTON to OnLButtonDown.  I suggest this be changed to pass pMsg->wParam.  That way, OnLButtonDown receives the actual state information.

    If these suggestions were adopted the code would be -

    if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_STATIC_BITMAP)->GetSafeHwnd() == pMsg->hwnd)
    {
    	CPoint point(pMsg->pt);
    	ScreenToClient(&point);
    
    	OnLButtonDown(pMsg->wParam, point);    //passes the coordinates of the clicked Point in the dialog box
    }
    
    

    Consequently, the test in the OnLButtonDown handler might look like -

    void CMFCStaticDlg::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	CRect rect;
    	m_StatBMP.GetWindowRect(&rect);
    	ScreenToClient(&rect);
    	if (rect.PtInRect(point))
    	{
    		// Do something
    	}
    
    	CDialogEx::OnLButtonDown(nFlags, point);
    }
    

    • Marked as answer by mh1000 Monday, September 24, 2018 9:10 PM
    Monday, September 24, 2018 12:11 PM

All replies

  • You need to add SS_NOTIFY style on this control .

    https://docs.microsoft.com/en-us/windows/desktop/controls/stn-clicked

    -Seetharam


    • Edited by Seetharam Friday, September 21, 2018 9:05 PM
    • Proposed as answer by Guido Franzke Monday, September 24, 2018 5:50 AM
    Friday, September 21, 2018 9:03 PM
  • In addition to setting SS_NOTIFY I suggest you derive a class from CStatic so that you can handle WM_LBUTTONDOWN in order to obtain mouse coordinates.  The STN_CLICKED notification message does not include location information.
    • Proposed as answer by Guido Franzke Monday, September 24, 2018 5:50 AM
    Friday, September 21, 2018 10:10 PM
  • Thank you, guys, for the reply.

    I made my Pic Control notify enabled in the wizard, that means SS_NOTIFY is set.

    Now I made  OnLButtonDown handler in my entire dialog that contains this pic control....

    What's next?

    Friday, September 21, 2018 10:59 PM
  • Thank you, guys, for the reply.

    I made my Pic Control notify enabled in the wizard, that means SS_NOTIFY is set.

    Now I made  OnLButtonDown handler in my entire dialog that contains this pic control....

    What's next?

    Well, the location of the mouse click in the client area of the picture control is passed to the OnLButtonDown handler function.   That's the information you said that you wanted.  You should derive your own class from CStatic to make this work as I suggested earlier.


    • Edited by RLWA32 Friday, September 21, 2018 11:10 PM
    Friday, September 21, 2018 11:05 PM
  • Haven't made my own class from CStatic yet...

    I just tested and noticed that I can capture the cursor pt coord outside of my Pic Ctrl, but not inside of it.

     

    Friday, September 21, 2018 11:25 PM
  • Haven't made my own class from CStatic yet...

    I just tested and noticed that I can capture the cursor pt coord outside of my Pic Ctrl, but not inside of it.

     


    That's why you want to derive your own class -- so you capture the mouse activity within the control.
    Friday, September 21, 2018 11:29 PM
  • Hi,

    Thanks for posting here.

    >> How do I do that?

    First, you could try overriding the PreTranslateMessage function in your self-define dialog class.
    like this:

    BOOL CMFCDialogOneDlg::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_STATIC_BITMAP)->GetSafeHwnd() == pMsg->hwnd)
    		OnLButtonDown(MK_LBUTTON, pMsg->pt);   //passes the coordinates of the clicked Point in the dialog box
    
    	return CDialogEx::PreTranslateMessage(pMsg);
    }

    Then , you should judge the Point within MFC Picture control or not in the OnLButtonDown function.(lRect is the area of pircture control),like this:

    if((point.x>=lRect.left && point.x<=lRect.right) && (point.y>=lRect.top && point.y<=lRect.bottom))
    {
    	// detect the click location within this MFC picture control
    }

    Hope it can help you.

    Best Wishes,

    Jack Zhang


    MSDN Community Support&amp;amp;amp;amp;lt;br/&amp;amp;amp;amp;gt; Please remember to click &amp;amp;amp;amp;amp;quot;Mark as Answer&amp;amp;amp;amp;amp;quot; the responses that resolved your issue, and to click &amp;amp;amp;amp;amp;quot;Unmark as Answer&amp;amp;amp;amp;amp;quot; if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact &amp;amp;amp;amp;lt;a href=&amp;amp;amp;amp;quot;mailto:MSDNFSF@microsoft.com&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;MSDNFSF@microsoft.com&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;

    Monday, September 24, 2018 8:28 AM
    Moderator

  • First, you could try overriding the PreTranslateMessage function in your self-define dialog class.
    like this:

    BOOL CMFCDialogOneDlg::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_STATIC_BITMAP)->GetSafeHwnd() == pMsg->hwnd)
    		OnLButtonDown(MK_LBUTTON, pMsg->pt);   //passes the coordinates of the clicked Point in the dialog box
    
    	return CDialogEx::PreTranslateMessage(pMsg);
    }

    Then , you should judge the Point within MFC Picture control or not in the OnLButtonDown function.(lRect is the area of pircture control),like this:

    if((point.x>=lRect.left && point.x<=lRect.right) && (point.y>=lRect.top && point.y<=lRect.bottom))
    {
    	// detect the click location within this MFC picture control
    }

    A couple of observations --

    Standard MFC message handling will pass a dialog's client area coordinates of a mouse click to its OnLButtonDown handler.  The PreTranslateMessage override above passes screen coordinates.  I suggest this be conformed to pass client area coordinates.  That way, any other processing that might be performed in the OnLButonDown handler receives the proper coordinates.

    Also, the PreTranslateMessage override code also passes MK_LBUTTON to OnLButtonDown.  I suggest this be changed to pass pMsg->wParam.  That way, OnLButtonDown receives the actual state information.

    If these suggestions were adopted the code would be -

    if (pMsg->message == WM_LBUTTONDOWN && GetDlgItem(IDC_STATIC_BITMAP)->GetSafeHwnd() == pMsg->hwnd)
    {
    	CPoint point(pMsg->pt);
    	ScreenToClient(&point);
    
    	OnLButtonDown(pMsg->wParam, point);    //passes the coordinates of the clicked Point in the dialog box
    }
    
    

    Consequently, the test in the OnLButtonDown handler might look like -

    void CMFCStaticDlg::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	CRect rect;
    	m_StatBMP.GetWindowRect(&rect);
    	ScreenToClient(&rect);
    	if (rect.PtInRect(point))
    	{
    		// Do something
    	}
    
    	CDialogEx::OnLButtonDown(nFlags, point);
    }
    

    • Marked as answer by mh1000 Monday, September 24, 2018 9:10 PM
    Monday, September 24, 2018 12:11 PM
  • Thank you so much, guys.

    I also used ScreenToClient and it worked perfectly.

    Thank you again.

    Monday, September 24, 2018 9:10 PM
  • Hi, could you please share your solution. I am also trying to do the same but not able to do that. I can capture the mouse events outside the picture control but not inside.

    Regards.

    Monday, September 23, 2019 1:31 AM
  • The responses to this topic contain two methods of handling a mouse click inside an MFC Picture control.

    The solution accepted by the OP was to override the parent dialog's PreTranslateMessage function to identify and handle mouse clicks that occur inside the picture control.  Code for this solution is shown above.

    The other option mentioned was to derive your own class from CStatic that would be able to handle mouse clicks occurring inside the control.

    If you have more questions about this topic you should start a new thread to ask them and provide the details that are specific to your own circumstance.

    Monday, September 23, 2019 10:56 AM