I have my function here working, but I am certainly going about it the wrong way.
My program uses FindWindow to find the correct window. I need to double click on a specific location on this window.
I made it work by always putting the window in the same location on the screen, but if I moved the window the program would try click on the hard-coded location I have provided and it would not work.
Here is the function:
void lobbyWindow(HWND main_client)
{
//RECT arect;
// GetWindowRect(main_client, &arect);
SetCursorPos(748,294);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
As you can see I just move the mouse to 748,294 and double click. What I want to do is set the mouse to 100,100 in the main_client window, so if I move the main_client window the mouse still clicks on the correct spot.
Use SendInput() instead, then you can use flags to move the cursor relative to the window -
Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
How i can simulate a double mouse click on window ( i khow handle) on x, y coordinate, using SendInput?
http://www.cplusplus.com/forum/windows/97017/
If the window you're clicking in is in another thread/process this approach is fundamentally flawed, because the window can move while you're sending the clicks - meaning even if you have the right position to start with there's no guarantee all the clicks will end up in the same place.
Having said that, you can convert a client-relative coordinate to screen-coordinates using the ClientToScreen API function:
POINT pt = { 100, 100 };
ClientToScreen(main_client, &pt);
Depending on the target window you may find you can simply post it a WM_LBUTTONDBLCLK message to simulate the input at the appropriate position:
PostMessage(main_client, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELPARAM(100, 100));
SetCursor() requires screen coordinates, so you need to calculate where your double-click would be in screen coordinates relative to the window's current screen location. You can do that by either:
using GetWindowRect() to retrieve the window's current screen coordinates, then offset that by the intended relative coordinates.
use ClientToScreen() or MapWindowPoints() to convert relative coordinates to screen coordinates.
Once you have the intended screen coordinates, you can pass them to SetCursor().
Related
I've noticed that once a window is created using "CreateWindowEx" with x=0, y=0 position coordinates, window does not appear to be located in the the 0,0 corner of the screen. Instead it appears at the x=9, y=0.
I'm using a single monitor.
I'm not modyfing it's position anywhere else.
Window is created as an overlapped parent window.
When window is created, WM_MOVE get's called with x=8, y=31. (Those are "client-area" coordinates)
(It's a bit strange that WM_MOVE y coordinate is 31px but in the screenshot you can see that it should be ~38px...)
Window is created by:
mHandle = ::CreateWindowEx(WS_EX_APPWINDOW, CLASS_NAME, APP_NAME, WS_OVERLAPPEDWINDOW, 0, 0, mWidth, mHeight, HWND_DESKTOP, nullptr, mInstance, this);
Any ideas on what I might be doing wrong? What might be the reason?
I have what should be an extremely simple goal yet it seems intractable. I have to get some precisely-sized screen pix for documentation so I thought it would make sense to add a control to size my app's window to the exact dimensions I want.
I'm working with VS2010.
Here's the relevant code from my wizard-generated dialog:
DlgSetWindowSize::DlgSetWindowSize(CWnd* pParent /*=NULL*/)
: CDialogEx(DlgSetWindowSize::IDD, pParent)
{
m_width = 0;
m_height = 0;
m_parent = pParent;
}
void DlgSetWindowSize::OnBnClickedOk()
{
CDialogEx::OnOK();
SetWindowPos(m_parent, 0, 0, m_width, m_height, SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);
}
and here is the call to it:
void CMyAppView::OnWindowSize()
{
DlgSetWindowSize d(this);
if (IDOK == d.DoModal())
{
Invalidate();
}
}
SetWindowPos returns a nonzero value, which indicates success according to the documentation (click here). Of course when running the dialog, I enter the pixel values I want for width and height. The debugger verifies that the expected values are being passed to SetWindowPos, and also that SetWindowPos gives a nonzero return. The bit switches in the last parameter to SetWindowPos are set to ignore the position parameters and only express the size parameters in that call, so that the window should be sized as I want without changing position.
Everything appears to be in order, but the window size doesn't change. I have applied this logic to my app's document window, and when that didn't work, I also applied it to the application's MainFrame window. Zero action.
Am I missing something here, or is there some completely different approach I should be using?
Judging by your use of CDialogEx and the naming convention, I guess you are using MFC, right?
Your call to SetWindowPos() operates on the dialog window itself, as this is a class method.
If you want to call parent's SetWindowPos(), you could do:
m_parent->SetWindowPos(0, 0, 0, m_width, m_height,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);
Also please note that in MFC Document-View architecture, the document doesn't have a window.
Alternatively, you could use Win API call:
::SetWindowPos(m_parent->GetSafeHwnd(), 0, 0, 0, m_width, m_height,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);
Like attached my photo, I want to get "Windowed Window's Screen coordinate of each Corner in X-window". (I draw red dots, which I want to get as Screen coordinates, in the following image. What I am going to do later is to get exact middle point of my OpenGL window in 2D screen coordinate.
I tried following code already:
int* getWindowPos(Display *dpy) {
int winPos[2];
Window myWin;
myWin = XRootWindow(dpy, 0);
XWindowAttributes xwa;
XGetWindowAttributes(dpy, myWin, &xwa);
// printf("%d %d\n", xwa.x, xwa.y);
return winPos;
}
but this "XWindowAttributes" always gives me 0 in x point ,0 in y point, and width 1600 and height 900, which is same as my screen resolution.
following is what I coded to create this windowed window.
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, 800, 600, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
You're storing your window into GLWin.win, but are querying the root window for its size and location. The "root window" is the full screen background window (desktop), so it makes sense that it's returning your screen resolution. Just pass your actual window (GLWin.win) to XGetAttributes() if you want those dimensions.
I have an MFC application that creates a CDialog. I'd like this CDialog to not show up in the middle of the screen, but rather off to the side of the screen so its barely visible or even minimized would be good.
How can I do this?
Use SetWindowPos in your OnInitDialog() function, like so:
BOOL CDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// (x,y) is the upper-left corner in screen coordinates
SetWindowPos( NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
return TRUE;
}
You can use SW_SHOWMINIMIZED flag in ShowWindow(SW_SHOWMINIMIZED). (SW_SHOWMINIMIZED ==> Opens the window in its minimized state, representing it as a button on the taskbar)
pDlg->Create(IDD_DLG_ID1,this);
pDlg->ShowWindow(SW_SHOWMINIMIZED);
This should be a simple one:
I have a CDialog with 2 buttons.
The dialog is always opened in full screen (No title bar \ Status, etc...) using m_pMainWnd->ShowWindow(SW_MAXIMIZE);
I want my buttons to snap to the edge of the screen.
There are no resizing or anything.
You know the width of the dialog (GetClientRect). You know the width of the buttons.
Assuming you are snapping to the right edge ...
Inside your CDialog::OnSize:
// Grab the CDialog's rect.
CRect winRect;
GetClientRect( &winRect );
// Grab the button's rect.
CRect buttonRect;
button.GetClientRect( &buttonRect );
// Now we need to set the top, left of the button to the right edge - the button width.
// The y position will remain the same.
button.SetWindowPos( NULL, winRect.right - buttonRect.Width(), buttonRect.top, 0, 0, SWP_NOZORDER | SWP_NOMOVE );