• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

MFC Question: Detecing Right Click on Static Text Control

KevinMU1

Senior member
If I want to have an action when a static text control is right-clicked, does anyone know how to do this? I have tried using PreTranslateMessage, but I can't seem to get the rectangles and mouse click location to work together to detect if the click is inside the static text control or not... HELP! Is there a direct message to trap, or, if not, what's the set of window rectangle functions that I need to properly detect the click location inside PreTranslateMessage? THANKS!
 
When you detect a mouse event, you get the mouse coordinates in screen coordinates.
There is a way to transform screen coordinates to client coordinates, but I don't have a reference manual around.
After that, you just need to compare the client coordinates of the mouse with the ones from the rectangle of the Static Text Control...
 
That's what I've tried doing, but I can't figure out the right calls to get the coordinates to translate correctly, and based on what I see in the MSDN, it *should* be working. Operative word *should*... [sigh].....
 
If you subclass the static I think you'd be able to intercept the standard mouseup messages in the CMyStatic class.

If that doesn't do it, let us know. I've gone through similar coordinate juggling for sizing / placement and for drawing a 3D rectangle around a 3rd-party component, and might be able to look up which of the many window coordinate functions will do the job.
 
ClientToScreen and ScreenToClient are the general conversion APIs that you will need.
 
And I've been using them with no luck, that's why I was asking for specifically how it is done.

Here's what I've tried:

if( pMsg->message == WM_RBUTTONDOWN)
{
CRect StatusRect;
m_StatusCtrl.GetClientRect(StatusRect);
ClientToScreen(&StatusRect);

CPoint point = pMsg->pt;

// CPoint point;
// GetCursorPos(&point);
// DWORD Result = GetMessagePos();
// CPoint ItemPos(GET_X_LPARAM(Result), GET_Y_LPARAM(Result));

if (StatusRect.PtInRect(point))
{
TRACE0("Right click on client status\n");
}
}

I have tried 3 strategies for the point of the click... using the pMsg information, using GetCursorPos, and using GetMessagePos (which I have used successfully elsewhere in my program).

Is there a glaring error that anyone can see?

Thanks again.
 
My question is about this:
m_StatusCtrl.GetClientRect(StatusRect);

Is the variable properly initialized and in scope? What are the values of StatusRect? Are they reasonable? (After conversion in screen coordinates, of course).

You get the mouse coordinates ok, so StatusRect is where your problem lies. Give out the values, or step through with the debugger.
 
OnRButtonDown(UINT nFlags, CPoint point)

point provides a location of the mouse down with respect to the parent window.

m_StatusCtrl.GetClientRect(StatusRect);
ClientToScreen(&StatusRect);

provides the screen coordinates of the control.

Convert the point to screen coordinates and then determine if the screen point is within the screen rectangle. This is an expanded version of what Memphis was stating
 
m_StatusCtrl is the control for the static text object.

The values do seem reasonable.

The problem with the trace values is that the click points always seem to shifted down and right (down by about 10-20, right by about 50-100) of where the reported location of the control is. It's like it's adding in some other goofy piece of width and height that I can't find.

Using OnRButtonDown requires subclassing, which seems like overkill for this simple problem... but I may have to resort to that.
 
Originally posted by: KevinMU1
m_StatusCtrl is the control for the static text object.

The values do seem reasonable.

The problem with the trace values is that the click points always seem to shifted down and right (down by about 10-20, right by about 50-100) of where the reported location of the control is. It's like it's adding in some other goofy piece of width and height that I can't find.

Using OnRButtonDown requires subclassing, which seems like overkill for this simple problem... but I may have to resort to that.

On my testing I did not do any subclassing.

Just assigned the static text an unique ID and defined it as a control.
Using the Windows wizard, then assigned a Right button click action to the item and tested it as described above.

Your problem may be that you are not treating the item as an control.

 
Originally posted by: singh
Just subclass it would you!
but it's more fun to spend hours trying not to 😉

I understand though, I spent hours trying to get the tab control to properly load 256-color bitmaps with transparency and a custom palette, and none of the MSDN code did the job. I finally gave up and used push buttons instead.
 
I am reviving this OLD thread for one reason:

I had the same problem myself today, and I figured it out.

First of all, my suggestion of doing ClientToScreen or ScreenToClient was wrong. It does not give the right coordinates for some reason.

Basically, you have to do a GetClientRect, and compare it to the mouse coordinates. You get the mouse coordinates already in a form compatible to GetClientRect.
Here is what I did:
void CTestView:: onRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
RECT spacing;
if (popup == NULL)
popup = new CMenu;
else
popup->DestroyMenu();
popup->CreatePopupMenu();
GetClientRect(&spacing);
if (point.x < (abs(spacing.right-spacing.left)/2))
{
ClientToScreen(&point);
p_Doc->contextmenu(popup,1,&point);
}
else
{
ClientToScreen(&point);
p_Doc->contextmenu(popup,2,&point);
}


//CView:: onRButtonUp(nFlags, point);
}

This works beautifully for me.
Edit: Had to insert a space after :: to avoid smiley face
 
Thanks for posting that. Except I already just subclassed it like everyone was yelling at me to do. 😉

But it is good to see that I wasn't totally off of my rocker. I will copy this code into my archive in case I ever need it again. Thanks again for posting it.
 
Back
Top