Open mpolicki opened 6 years ago
Hi, thanks for bringing this up.
User32.ScreenToClient/User32.ClientToScreen
NativeWindow
, the client area (not the non client area) of the window is the client. From the perspective of Windows, the entire Window (including NC - the title bar, etc) is the client. Applying this concept should give you the correct usage.This does the conversion in relation to the window (i.e, taking the NonClient area, based on the style of the Window - It may have a title bar, it may not. It may be borderless, it may not. It relieves the user of the API from thinking about these complexities). This is very useful when the window has children (which it usually does). Say, have a native window that is drawing a bunch of DirectX items. Now, you can just pass their co-ordinates onto these methods to get them in correct relation to the window. The adjustment is done with AdjustWindowRectEx
/InverseAdjustWindowRectEx
, while the ScreenToClient
/ClientToScreen
(which by the way you are probably better off not using in most cases - MapWindowPoints
is the correct replacement for it) is correctly done by MapWindowPoints
.
Also adding to that, it exposes a public virtual
method, that's in turn called by the methods that just take a single argument this.ClientToScreen(clientRect)
to facilitate exactly that. If in a case your window has a more complex implementation - then you can manually override it to provide the correct transformation. So, say you have an usual NC Client implementation, you can just do the transformation in here, so all it's children of external items can get a correct adjusted value.
You will have to do this at some point to build a correct layout with a set of children. This just facilitates that.
Please have a look at the DwmWindow
for it's uses:
https://github.com/prasannavl/WinApi/blob/master/WinApi.Utils/DwmWindow.cs
Non normal NC windows are in most cases notoriously complicated and hard to implement. This is one of those things that help in implementing such so effortlessly.
Right, thanks for elaborating. I'm sure the default implementation is useful for the purposes you describe, however for the basic case of having a regular overlapped window, it does the wrong thing, at least from the perspective of someone coming from a WinAPI background. So it would be useful if the different semantics of these methods were somehow indicated.
From the perspective of the Window
, this client area (not the non client area) is the client
. From the perspective of Windows, the entire Window is the client
. Hopefully, that makes sense to you.
May be WindowClientToScreen
/ScreenToWindowClient
to clear the confusion? Or perhaps just document it properly and leave it. Any feedback would be welcome.
From the perspective of the Window, this client area (not the non client area) is the client. From the perspective of Windows, the entire Window is the client. Hopefully, that makes sense to you.
It does, but I'm not quite sure why taking the perspective of Windows is relevant. Using the word "client" in the sense of "client area" for anything other than the client area of a window as defined by the API docs is confusing, and at the very least should be explicitly documented.
May be WindowClientToScreen/ScreenToWindowClient to clear the confusion? Or perhaps just document it properly and leave it. Any feedback would be welcome.
Frankly, I'm not sure what to call it. Take ClientToScreen
for example; it takes a rectangle in coordinates relative to the client area of the window, translates them to screen coordinates, enlarges the rectangle by the size of the non-client area, and returns the enlarged rectangle. I honestly don't know what to call this operation...ClientToScreenAndAdjust
maybe?
How about LocalClientToScreen
or just LocalToScreen
to avoid confusion with the established ClientToScreen
semantics of the Windows API?
I tried using the
ScreenToClient
andClientToScreen
methods inWinApi/WinApi/Windows/NativeWindow.cs
because I thought they did the same thing as the Windows functions of the same name. But, after getting unexpected results, I noticed that the methods hadAdjustWindowRectEx
/InverseAdjustWindowRectEx
calls in them as well, which results in something other than a simple client/screen coordinate transformation. This left me confused as to the purpose of the methods, so could you please clarify whether the intent really is something other than a simple client/screen coordinate transformation?