CreateWindowEx invalid X position once created - c++

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?

Related

OpenCv border top and left OpenGL frame c++

I'm using a self compiled of OpenCv 3.3 with OPENGL and CUDA enabled on Windows 7.
I'm having trouble to display an image in fullscreen mode without any border.
I use the following minimal example for my test:
// Name of window
std::string name = "Test Window";
// Create window
cv::namedWindow(name, CV_WINDOW_OPENGL | cv::WINDOW_NORMAL);
cvSetWindowProperty(name.c_str(), CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
// Create a frame at resolution
cv::Size size = cv::Size(1920, 1080);
cv::cuda::GpuMat emptyFrame;
cv::Mat frame(size, CV_8UC(3));
// Fill it in blue
cv::rectangle(frame, cv::Rect(0, 0, size.width, size.height), cv::Scalar(255, 0, 0), CV_FILLED);
emptyFrame.upload(frame);
// Size window to full resolution
cv::resizeWindow(name, size.width, size.height);
while(1)
{
// Display an empty frame
cv::imshow(name, emptyFrame);
cv::waitKey(40);
}
This code show me a full screen windows paint in blue, however it remain a ONE pixel border on top and left border:
Grey left and top border
The border seem not to be the border as explained here:
https://stackoverflow.com/a/38494752/1570628
In fact it's the background of the main window created by OpenCv.
Digging into OpenCv code, it effectivelly create 2 windows inside cvNamedWindow function:
mainhWnd = CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED, rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0 );
if( !mainhWnd )
CV_ERROR( CV_StsError, "Frame window can not be created" );
ShowWindow(mainhWnd, SW_SHOW);
//YV- remove one border by changing the style
hWnd = CreateWindow("HighGUI class", "", (defStyle & ~WS_SIZEBOX) | WS_CHILD, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd, 0, hg_hinstance, 0);
if( !hWnd )
CV_ERROR( CV_StsError, "Frame window can not be created" );
So the 'border' we saw is the mainhWnd (Main HighGUI class) color.
However, it mean that my displayed image in blue is shifted by one pixel to the rigth and bottom of my screen, so I loose 1 line of pixel on bottom and right side because they overflow the screen.
I can see that it's the case because on a dual screen I can see the right line of pixel overflow on my second screen. More over, if I draw an horizontal line to the last line of my image, it doesn't appear, same occur on vertical line for last column of my image.
For testing solution, I tried to change style of mainhWnd and hWnd directly in OpenCv code by using many combination of flags, also testing using WS_POPUP, but anyway I always have this top and left border.
I also tried solution here but it do not remove the border:
https://stackoverflow.com/a/6512315/1570628
Do anyone have a clue for my problem?
Regards.
Hey this worked for me (at least it did on python, and since you just have to change a flag, i believe this will work for you too)
Change this flag "CV_WINDOW_OPENGL | cv::WINDOW_NORMAL)" to this flag "WINDOW_FREERATIO"
And voila! Problem Solved

How to get Windowed Window's Screen coordinate of each Corner in X-window?

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.

C++ mouse click on certain spot in window

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().

Create a CDialog in the corner of the screen

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);

Anchor buttons in a dialog when using SW_MAXIMIZE

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 );