Is there anyway when mouse moving find the control mouse is over on it? I mean if you have a dialog with some labels and text boxes, and the mouse move to label, notify me that label name, after that if move it to text box notify the text box name.
If you handle WM_MOUSEMOVE within your dialog, you can grab the mouse position, convert it to dialog coordinates, and determine what control lies underneath the cursor point.
After some research, I came to this code which let me know if the mouse cursor is over my control in a dialog box.
//Handling mouse move in mfc dialog
void CDialogRoll::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rect1;
m_FrameArea.GetClientRect(&rect1); //control rectangle
m_FrameArea.ClientToScreen(&rect1)
ScreenToClient(&rect1); //dialog coordinates`
if (point.x >= rect1.left && point.x <= rect1.right && point.y >= rect1.top &&
point.y <= rect1.bottom) {
char str[100];
sprintf(str, "%d-%d", point.x - rect1.left, point.y - rect1.top);
}
CDialogEx::OnMouseMove(nFlags, point);
}
Related
I have to receive the current mouse cursor coordinates in mm/inch, while the cursor hovers over a QWidget.
Already tried: mouseMoveEvent
void darstellung::mouseMoveEvent(QMouseEvent *event){
qDebug() << event->pos();
}
I activated the MouseTracking in the MainWindow constructor as well.
setMouseTracking(true);
It seems that the mouseMoveEvent will only return the cursor position, if the left mouse button is pressed.
I have the same issue, hasMouseTracking() returns false on widget
my Workaround:
//position relative to window| |you might add some ->parentWidget()
QPoint relPos = QCursor::pos() - this->window()->pos();
the positions are relative to virtual screen-coordinates on windows. eg: my widget is displayed at the 2nd monitor, which is left to the 1st -> that gives x=-1000 y=200 (in pixel)
check capability:
if(this->hasMouseTracking() ){
this->setMouseTracking(true);
qDebug("mousetracking on");
}else qDebug("\nmousetracking not available\n");
some useless hints:
https://doc.qt.io/qt-6/qwidget.html#grabMouse (this one is no good practice)
https://stackoverflow.com/a/30960032
So in your constructor you can add a line
this->viewport()->setMouseTracking(true) and then override
mouseMoveEvent
At the beginning, sorry about my English.
I'm now learning how to build a MFC application in visual studio 2015. I'm using Direct2D to draw lines in a window.
When left button is down, my OnLbuttonDown() function is called:
void CMyProjectNameView::OnLButtonDown(UINT nFlags, CPoint point)
{
startPoint = point; // start point of the line, a gloable variable.
pRenderTarget->BeginDraw();
CView::OnLButtonDown(nFlags, point);
}
When left button is up, my OnLButtonUp() function is called:
void CMyProjectNameView::OnLButtonUp(UINT nFlags, CPoint point)
{
pRenderTarget->DrawLine(startPoint, point, m_pbrush, 1.0f); // draw the line
pRenderTarget->EndDraw();
CView::OnLButtonUp(nFlags, point);
}
So it will draw a line in the window when I drag my mouse, and it works fine yesterday.
The problem is when I run it today, it suddenly become abnormal. The start point coordinates and end point coordinates is two times bigger than before. So When I draw the line, the line shows on the bottom right position compared to the position it supposed to be.
For instance, if I draw a line from (100,100) to (500,500), a line start from (100,100) to (500,500) will appear on screen, but when I click left button of my mouse at (100,100), move it to (500,500) and release left button, a line from (200,200) to (1000,1000) will be drawn.
OnLButtonDown(UINT nFlags, CPoint point)
OnLButtonUp(UINT nFlags, CPoint point)
So basically, these two point above is scaled before they are passed in. Do I accidentally change any configurations? Is there any way to fix this? I am sure I didn't change my code.
Coordinates for DrawLine are in device-Independent pixels. See also DPI and Device-Independent Pixels
You have probably changed the size of client rectangle, it needs to be adjusted. Try also to resize the window and see if it gets the right coordinates.
CRect rc;
GetClientRect(&rc);
D2D1_SIZE_F size = pRenderTarget->GetSize();
const float x = size.width / rc.right;
const float y = size.height / rc.bottom;
D2D1_POINT_2F p1;
D2D1_POINT_2F p2;
p1.x = 100 * x;
p1.y = 100 * y;
p2.x = 500 * x;
p2.y = 500 * y;
pRenderTarget->DrawLine(p1, p2, brush);
So basically am learning OpenGL and the GLFW libraries from the tutorial on page: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboard-and-mouse/
My problems is with this less lesson showing the control of camera movement with mouse.
Basicaly it makes the application to get "FPS" like camera, with disabled cursor being moved on center of screen with each frame. But the camera gets crazy when we lose focus on the window and then it regains. For example if we click on the window to regain focus away from the middle of view, the camera will be moved by big amount. I tried to fix this issue with adding window focus callback:
void window_focus_callback(GLFWwindow* window, int focused){
if (focused)
{
//center mouse on screen
int width, height;
glfwGetWindowSize(window, &width, &height);
glfwSetCursorPos(window, 1024 / 2, 768 / 2);
windowFocused = true;
}
else
{
windowFocused = false;
}
And in the main application loop:
if(windowFocused) computeMatricesFromInputs();
But for some reason this solution doesnt work.
Is there any way to fix this issue using glfw?
Question is a bit old, but I recently suffered a similar issue. So just sharing, more solutions exist.
I use GLFW_CURSOR_DISABLED. In this mode the mouse position is not (yet) updated when you receive the 'on' focus event, so call to GetCursorPos delivers the previous value. The new cursor position arrives in the MouseMove callback AFTER the 'on' focus event.
I solved it by keeping track of the regain of focus and use this int he OnMouseMove callback to either dispatch a MouseInit (to snap the cursor) or a regular MouseMove.
This way I can ALT+TAB out of my window and return with the cursor somewhere else without nasty jumps/rotations of the camera.
void InputManagerGLFW::Callback_OnMouseMove(
GLFWwindow* window,
double xpos, //
double ypos) //
{
if (!mFocusRegained)
{
mMouseBuffer.Move(xpos, ypos);
}
else
{
mFocusRegained = false;
mMouseBuffer.Init(xpos, ypos);
}
}
void InputManagerGLFW::Callback_OnFocus(
GLFWwindow* window,
int focused)
{
if (focused)
{
// The window gained input focus
// Note: the mouse position is not yet updated
// the new position is provided by the mousemove callback AFTER this callback
Log::Info("focus");
// use flag to indicate the OnMouseMove that we just regained focus,
// so the first mouse move must be handled differently
mFocusRegained = true;
// this will NOT work!!!
// double x,y;
// glfwGetCursorPos(window,&x,&y);
// mMouseBuffer.Init(x,y);
}
else
{
// The window lost input focus
Log::Info("focus lost");
}
}
I'm currently working on project which will have two RichEdit controls one close to the other: let's say RichEdit1 is on left and RichEdit2 is on the right.
The user scenario I want to enable in the project is:
User mouse LButton down at somewhere in RichEdit1, e.g. before the 3rd char, in total 7 chars.
User drag the mouse to RichEdit2, e.g. after the 6th char, in total 11 chars.
User mouse LButton up.
I want to see both RichEdit1 3rd char to end and RichEdit2 begin to 6th char are selected.
Currently I notice that once mouse LButton down on RichEdit1, after I move the mouse to RichEdit2, the RichEdit2 could not receive mouse event before I release mouse.
Any suggestion will be appreciated. Thank you!
When the mouse button is pressed down on RichEdit1, it captures the mouse, thus subsequent mouse messages are sent to RichEdit1 until the mouse button is released. That is why RichEdit2 does not receive any mouse events while dragging over RichEdit2.
You will have to process the mouse move messages in RichEdit1 and check if their coordinates are outside of RichEdit1's client area. If so, convert them into coordinates relative to RichEdit2's client's area and then send EM_SETSEL/EM_EXSETSEL messages to RichEdit2 as needed. For example:
int RichEdit2StartIndex = -1;
...
// in RichEdit1's message handler...
case WM_MOUSEMOVE:
{
if ((wParam & MK_LBUTTON) == 0)
break;
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
RECT r;
GetClientRect(hwndRichEdit1, &r);
if (xPos < (r.right - r.left))
{
if (RichEdit2StartIndex != -1)
{
SendMessage(hwndRichEdit2, EM_SETSEL, -1, 0);
RichEdit2StartIndex = -1;
}
}
else
{
POINT pt;
pt.x = xPos;
pt.y = yPos;
MapWindowPoints(hwndRichEdit1, hwndRichEdit2, &pt, 1);
POINTL pl;
Pl.x := pt.x;
Pl.y := pt.y;
int idx = SendMessage(hwndRichEdit2, EM_CHARFROMPOS, 0, (LPARAM)&Pl);
if (idx != -1)
{
if (RichEdit2StartIndex == -1)
RichEdit2StartIndex = idx;
SendMessage(hwndRichEdit2, EM_SETSEL, RichEdit2StartIndex, idx);
}
}
break;
}
Vice versa when dragging a selection from RichEdit2 to RichEdit1.
And make sure that both RichEdit controls have the ES_NOHIDESEL style applied so you can see the selection in both controls at the same time.
I need to move window by right mouse button. The window has no caption, titlebar. By left button it works
void CMyHud::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SendMessage(WM_SYSCOMMAND, SC_MOVE|0x0002);
CDialogEx::OnLButtonDown(nFlags, point);
}
But if I place this code on OnRButtonDown it dosen't work. What is the problem?
Well, the solution is found, thanks to Mark Ransom:
CRect pos;
void CMyHud::OnRButtonDown(UINT nFlags, CPoint point)
{
pos.left = point.x;
pos.top = point.y;
::SetCapture(m_hWnd);
CDialogEx::OnRButtonDown(nFlags, point);
}
void CMyHud::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd = CWnd::FromHandle(m_hWnd);
CRect r;
if(GetCapture() == pWnd)
{
POINT pt;
GetCursorPos(&pt);
GetWindowRect(r);
pt.x -= pos.left;
pt.y -= pos.top;
MoveWindow(pt.x, pt.y, r.Width(), r.Height(),TRUE);
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CMyHud::OnRButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
CDialogEx::OnRButtonUp(nFlags, point);
}
In your OnRButtonDown function, do a SetCapture to ensure all mouse messages are routed to your window while the mouse button is down. Also store the mouse position in a member variable. Now, in your OnMouseMove function, check to see if GetCapture returns an object with the same HWND as yours - if it does, calculate the difference between the current mouse position and the saved one, then call MoveWindow to move the window.
In regards to left-mouse click:
SC_MOVE|0x0002 comes out as 0xF012 or SC_DRAGMOVE. This is apparently an undocumented constant. There is probably a good reason Microsoft doesn't want anybody to use this, that's why they have hidden it.
Also WM_SYSCOMMAND is a notification message. You should respond to it, not send it. To drag the window with left-mouse click:
message map ...
ON_WM_NCHITTEST()
LRESULT CMyDialog::OnNcHitTest(CPoint p)
{
//responding to a notification message
return HTCAPTION;
}
To drag the window with right-mouse you have to override OnRButtonDown, OnMouseMove, OnRButtonUp and make your own routine. But Window's behaviour gets very confusing. Is that really worth it?
you can use mouse message to realize.
WM_RBUTTONDOWN, WM_MOUSEMOVE