In Windows API programming how do I prevent mouse from leaving window? - winapi

How do I limit mouse to one particular HWND in Win32 API programming? This HWND is not necessarily created by me. It could be a browser window, or photoshop program window. I'm trying to write a program that doesn't let mouse leave particular Windows program. I can get HWND of the program by GetWindowText.

Check out MSDN: ClipCursor function
ClipCursor function (winuser.h)
Confines the cursor to a rectangular area on the screen. If a subsequent cursor position (set by the SetCursorPos function or the mouse) lies outside the rectangle, the system automatically adjusts the position to keep the cursor inside the rectangular area.
Syntax
BOOL ClipCursor(
[in, optional] const RECT *lpRect
);
Parameters
[in, optional] lpRect
Type: const RECT*
A pointer to the structure that contains the screen coordinates of the upper-left and lower-right corners of the confining rectangle. If this parameter is NULL, the cursor is free to move anywhere on the screen.
Return value
Type: BOOL
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Remarks
The cursor is a shared resource. If an application confines the cursor, it must release the cursor by using ClipCursor before relinquishing control to another application.

Related

PTVISIBLE always returns true when relevant point obscured by another window

I am trying to ascertain whether the mouse cursor is over a specific window and whether there are any other windows obscuring that window at that specific point. The relevant point is obtained in screen coordinates by way of a mouse hook. I then use the ptVisible function to determine this. My code is:
DC := GetDC(wnd);
try
Result := PtVisible(DC, pt.X, pt.Y);
finally
ReleaseDC(wnd, DC);
end;
This always returns false even when there is nothing obscuring the window represented by the wnd handle.
I found very little on the web as to proper use of ptVisible. Can anyone advise if I am using it incorrectly?
You are not using it correctly. From the docs page, PtVisible() "determines whether the specified point is within the clipping region of a device context." This has nothing to do with mouse location or location of a pixel within a window. This has specific uses to check whether the point is within the clipping region of a graphics device context.
If you want to check whether the mouse is within a certain window, you might want to try checking if your mouse coordinate is within GetWindowRect(). And then to check whether or not any windows overlap, you'd want to EnumWindows() and then IntersectRect()

My code isn't enough to show a triangle

The codes below is in winmain function after registering a class for the parent window:
RECT disrect;
HWND stat = CreateWindow("BUTTON","abcdef",
WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,10,150,500,100,dis,0,0,0);
HDC hdc=GetDC (stat);
FillRect(hdc,&disrect,CreateSolidBrush(RGB(3,5,54)));
SetTextColor(hdc,RGB(25,250,250));
POINT p[3];
p[1].x=280;
p[1].y=280;
p[2].x=280;
p[2].y=290;
p[3].x=285;
p[3].y=285;
Polygon(hdc,p,3);
TextOut(hdc,10,10,"hhhhh",5);
But when I run it, only shows a white rectangle into the parent window, neither the rect is filled with black brush, nor there is any text in it.
Could you guys tell me where I am wrong?
Unless you want to display animations, you should never try to directly write to a window that way, because many events could cause the window to redraw itself erasing what you have just written.
The correct way is to put it in the WM_PAINT handler.
A few issues, in addition to not using WM_PAINT.
First, merely calling CreateSolidBrush() is not enough to mark that brush as the one for your drawing operations to use. You have to select the brush into a DC (device context) before you can use it. This is done with the SelectObject() function. General usage looks like
HBRUSH prevBrush;
prevBrush = SelectObject(hdc, newBrush);
// drawing functions
SelectObject(hdc, prevBrush);
Yes, it is important to restore the previous brush when finished, even on a fresh DC; the initial state must be restored. The initial state uses a brush that draws nothing; this is why your Polygon() doesn't draw anything. SelectObject() is used for all the various things you use to draw with (pens, fonts, etc.), not just brushes.
Second, in C array indices start at 0 and go to size - 1, not start at 1 and go to size. So instead of saying pt[1], pt[2], and pt[3], you say pt[0], pt[1], and pt[2]. Your compiler should have warned you about this.
Third, as the documentation for CreateSolidBrush() will have said, once you are finished with the brush you must destroy it with DeleteObject(). You must do this after selecting the previous brush back in. You must also do this with the brush you used in the FillRect() call.

GetSystemMetrics vs. SystemParametersInfo

I needed to find out the height of the screen in order to resize a dialog. I am calling GetSystemMetrics with SM_CYFULLSCREEN and I am getting a certain number (1028 in my case). Per MSDN:
To get the coordinates of the portion of the screen not obscured by
the system taskbar or by application desktop toolbars, call the
SystemParametersInfo function with the SPI_GETWORKAREA value.
I called SystemParametersInfo as well to see what it returns and I get a different number for the height, 1050. Running spy, the area without taskbar is indeed of height 1050. Does anyone know why the different heights? Thanks
From the MSDN docs for SM_CYFULLSCREEN:
The height of the client area for a full-screen window on the primary display monitor, in pixels.
Relevant detail bolded, the client area is the part of the window without the borders and title bar. It is therefore substantially less than the actual primary screen height. Perhaps you meant to use SM_CYSCREEN instead. SPI_GETWORKAREA returns the available space for the entire window, the outer size, the one you'd pass to CreateWindowEx().

WinAPI to return Window Resizing Object size (This is the boarder around a window)

WinAPI to return Window Resizing Object size (This is the boarder around a window that allows you to resize the window). I just need the number of pixels it takes. (Under Windows 7, it looks like it is about 10 pixels.)
Also, what is the official name for this object?
I am coding in a language call PL/B and placing objects on their window. I am using GetWindowRect to get the window size, now I just need to adjust the size by the Window Resizing Object.
Generally, you're better off looking at GetClientRect and ClientToScreen, rather than trying to use GetWindowRect and trimming off the nonclient portions, but if you're dead set on doing that, try GetSystemMetrics with SM_CXSIZEFRAME and SM_CYSIZEFRAME.

How to get the full client rect?

The GetClientRect function, according to MSDN, is actually only good for determining the client width & height, since left & top are always zero. Is there a way to get the complete client coordinates, including left & top (either in screen space, or in window space)?
Call ClientToScreen on the top left and bottom right of the returned RECT. If you're using MFC, CWnd has a helper overload of CWnd::ClientToScreen that will do this transparently for you.
Maybe you are needing GetWindowRect.
You're looking for the GetWindowPlacement function. This function returns a WINDOWPLACEMENT struct which has an rcNormalPosition property which specifies the window's position when it is in the normal (rather than maximized or minimized) display state.
EDIT: itowilson's answer is actually cleaner because the WINDOWPLACEMENT structure also contains a bunch of data you don't need.

Resources