99#include < cmath>
1010#include < iostream>
1111#include < limits>
12+ #include < string>
1213#include < vector>
1314#ifdef _WIN32
1415#include < windows.h>
@@ -41,6 +42,75 @@ LRESULT CALLBACK ContentProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) {
4142 return DefWindowProcW (hwnd, message, wp, lp);
4243}
4344
45+ // --serve: a window for a real-pointer check (tools/gui/core_window_snap_layout_test.ps1).
46+ // Prints the button's screen rectangle, then logs what the content receives.
47+ LRESULT CALLBACK LoggingContentProc (HWND hwnd, UINT message, WPARAM wp, LPARAM lp) {
48+ const char * name = message == WM_MOUSEMOVE ? " WM_MOUSEMOVE"
49+ : message == WM_MOUSELEAVE ? " WM_MOUSELEAVE"
50+ : message == WM_LBUTTONDOWN ? " WM_LBUTTONDOWN"
51+ : message == WM_LBUTTONUP ? " WM_LBUTTONUP"
52+ : nullptr ;
53+ // Moves in the title band (where the button is), each new point once.
54+ const int x = static_cast <short >(LOWORD (lp)), y = static_cast <short >(HIWORD (lp));
55+ static UINT last_message = 0 ;
56+ static int last_x = -1 , last_y = -1 ;
57+ const bool repeat = message == last_message && x == last_x && y == last_y;
58+ if (name && !repeat && (message != WM_MOUSEMOVE || y < 100 ))
59+ std::cout << " CONTENT " << name << " " << x << " " << y << std::endl;
60+ last_message = message;
61+ last_x = x;
62+ last_y = y;
63+ return DefWindowProcW (hwnd, message, wp, lp);
64+ }
65+
66+ int Serve () {
67+ SetProcessDPIAware ();
68+ Window window;
69+ window.SetTitle (" nativeapi snap layout" );
70+ window.SetBounds ({200 , 200 , 720 , 420 });
71+ window.SetTitleBarStyle (TitleBarStyle::Hidden);
72+ auto root = static_cast <HWND >(window.GetNativeObject ());
73+ WNDCLASSW cls = {};
74+ cls.lpfnWndProc = LoggingContentProc;
75+ cls.hInstance = GetModuleHandleW (nullptr );
76+ cls.hCursor = LoadCursor (nullptr , IDC_ARROW );
77+ cls.hbrBackground = static_cast <HBRUSH >(GetStockObject (GRAY_BRUSH ));
78+ cls.lpszClassName = L" NativeApiSnapLayoutContent" ;
79+ RegisterClassW (&cls);
80+ RECT client;
81+ GetClientRect (root, &client);
82+ CreateWindowExW (0 , cls.lpszClassName , L" " , WS_CHILD | WS_VISIBLE , 0 , 0 , client.right ,
83+ client.bottom , root, nullptr , cls.hInstance , nullptr );
84+ window.Show ();
85+ const double scale = GetDpiForWindow (root) / 96.0 ;
86+ const nativeapi::Rectangle button = {client.right / scale - 146 , 0 , 46 , 32 };
87+ if (!window.SetMaximizeButtonBounds (button)) {
88+ std::cout << " FAIL SetMaximizeButtonBounds" << std::endl;
89+ return 1 ;
90+ }
91+ POINT origin = {0 , 0 };
92+ ClientToScreen (root, &origin);
93+ // The button in the content window's own (physical) coordinates, which its
94+ // log uses.
95+ std::cout << " BUTTON_CONTENT " << std::lround (button.x * scale) << " "
96+ << std::lround (button.y * scale) << " " << std::lround (button.width * scale) << " "
97+ << std::lround (button.height * scale) << std::endl;
98+ std::cout << " READY " << std::lround (origin.x + button.x * scale) << " "
99+ << std::lround (origin.y + button.y * scale) << " " << std::lround (button.width * scale)
100+ << " " << std::lround (button.height * scale) << std::endl;
101+ const auto end = GetTickCount64 () + 60000 ;
102+ while (GetTickCount64 () < end && IsWindow (root)) {
103+ MSG message;
104+ while (PeekMessageW (&message, nullptr , 0 , 0 , PM_REMOVE )) {
105+ TranslateMessage (&message);
106+ DispatchMessageW (&message);
107+ }
108+ std::cout << std::flush;
109+ Sleep (10 );
110+ }
111+ return 0 ;
112+ }
113+
44114LPARAM ScreenPoint (HWND root, double scale, double x, double y) {
45115 POINT p = {static_cast <LONG >(std::lround (x * scale)), static_cast <LONG >(std::lround (y * scale))};
46116 ClientToScreen (root, &p);
@@ -49,8 +119,14 @@ LPARAM ScreenPoint(HWND root, double scale, double x, double y) {
49119#endif
50120} // namespace
51121
52- int main () {
122+ int main (int argc, char ** argv ) {
53123 Application::GetInstance ();
124+ #ifdef _WIN32
125+ if (argc > 1 && std::string (argv[1 ]) == " --serve" ) return Serve ();
126+ #else
127+ (void )argc;
128+ (void )argv;
129+ #endif
54130#ifndef _WIN32
55131 Window window;
56132 Check (!Window::IsMaximizeButtonBoundsSupported (), " unsupported on this platform" );
0 commit comments