📄 win.c
字号:
/* note: winpos coordinates are relative to parent */
MapWindowPoints(GetParent(hwnd), 0, (LPPOINT)&rc2, 2);
trace("pos: (%ld,%ld)-(%ld,%ld)\n", rc2.left, rc2.top, rc2.right, rc2.bottom);
#if 0 /* Uncomment this once the test succeeds in all cases */
ok(EqualRect(&rc1, &rc2), "rects do not match\n");
#endif
GetClientRect(hwnd, &rc2);
DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)&rc1);
MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
ok(EqualRect(&rc1, &rc2), "rects do not match (%ld,%ld-%ld,%ld) / (%ld,%ld-%ld,%ld)\n",
rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom );
break;
}
case WM_NCCREATE:
{
BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd, cs->hwndParent, cs->style);
if (got_getminmaxinfo)
trace("%p got WM_GETMINMAXINFO\n", hwnd);
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
ok(got_getminmaxinfo, "main: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
else
ok(!got_getminmaxinfo, "main: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
break;
}
case WM_COMMAND:
if (test_lbuttondown_flag)
ShowWindow((HWND)wparam, SW_SHOW);
break;
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
static LRESULT WINAPI tool_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_GETMINMAXINFO:
{
MINMAXINFO* minmax = (MINMAXINFO *)lparam;
trace("hwnd %p, WM_GETMINMAXINFO, %08x, %08lx\n", hwnd, wparam, lparam);
trace("ptReserved (%ld,%ld), ptMaxSize (%ld,%ld), ptMaxPosition (%ld,%ld)\n"
" ptMinTrackSize (%ld,%ld), ptMaxTrackSize (%ld,%ld)\n",
minmax->ptReserved.x, minmax->ptReserved.y,
minmax->ptMaxSize.x, minmax->ptMaxSize.y,
minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021);
break;
}
case WM_NCCREATE:
{
BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd, cs->hwndParent, cs->style);
if (got_getminmaxinfo)
trace("%p got WM_GETMINMAXINFO\n", hwnd);
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
ok(got_getminmaxinfo, "tool: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
else
ok(!got_getminmaxinfo, "tool: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
break;
}
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
static BOOL RegisterWindowClasses(void)
{
WNDCLASSA cls;
cls.style = CS_DBLCLKS;
cls.lpfnWndProc = main_window_procA;
cls.cbClsExtra = 0;
cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "MainWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
cls.style = 0;
cls.lpfnWndProc = tool_window_procA;
cls.cbClsExtra = 0;
cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "ToolWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
return TRUE;
}
static void verify_window_info(HWND hwnd, const WINDOWINFO *info, BOOL test_borders)
{
RECT rcWindow, rcClient;
UINT border;
DWORD status;
ok(IsWindow(hwnd), "bad window handle\n");
GetWindowRect(hwnd, &rcWindow);
ok(EqualRect(&rcWindow, &info->rcWindow), "wrong rcWindow\n");
GetClientRect(hwnd, &rcClient);
/* translate to screen coordinates */
MapWindowPoints(hwnd, 0, (LPPOINT)&rcClient, 2);
ok(EqualRect(&rcClient, &info->rcClient), "wrong rcClient\n");
ok(info->dwStyle == (DWORD)GetWindowLongA(hwnd, GWL_STYLE),
"wrong dwStyle: %08lx != %08lx\n", info->dwStyle, GetWindowLongA(hwnd, GWL_STYLE));
ok(info->dwExStyle == (DWORD)GetWindowLongA(hwnd, GWL_EXSTYLE),
"wrong dwExStyle: %08lx != %08lx\n", info->dwExStyle, GetWindowLongA(hwnd, GWL_EXSTYLE));
status = (GetActiveWindow() == hwnd) ? WS_ACTIVECAPTION : 0;
ok(info->dwWindowStatus == status, "wrong dwWindowStatus: %04lx != %04lx\n",
info->dwWindowStatus, status);
if (test_borders && !IsRectEmpty(&rcWindow))
{
trace("rcWindow: %ld,%ld - %ld,%ld\n", rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
trace("rcClient: %ld,%ld - %ld,%ld\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
ok(info->cxWindowBorders == (unsigned)(rcClient.left - rcWindow.left),
"wrong cxWindowBorders %d != %ld\n", info->cxWindowBorders, rcClient.left - rcWindow.left);
border = min(rcWindow.bottom - rcClient.bottom, rcClient.top - rcWindow.top);
ok(info->cyWindowBorders == border,
"wrong cyWindowBorders %d != %d\n", info->cyWindowBorders, border);
}
ok(info->atomWindowType == GetClassLongA(hwnd, GCW_ATOM), "wrong atomWindowType\n");
ok(info->wCreatorVersion == 0x0400, "wrong wCreatorVersion %04x\n", info->wCreatorVersion);
}
static void FixedAdjustWindowRectEx(RECT* rc, LONG style, BOOL menu, LONG exstyle)
{
AdjustWindowRectEx(rc, style, menu, exstyle);
/* AdjustWindowRectEx does not include scroll bars */
if (style & WS_VSCROLL)
{
if(exstyle & WS_EX_LEFTSCROLLBAR)
rc->left -= GetSystemMetrics(SM_CXVSCROLL);
else
rc->right += GetSystemMetrics(SM_CXVSCROLL);
}
if (style & WS_HSCROLL)
rc->bottom += GetSystemMetrics(SM_CYHSCROLL);
}
static void test_nonclient_area(HWND hwnd)
{
DWORD style, exstyle;
RECT rc_window, rc_client, rc;
BOOL menu;
BOOL is_win9x = GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == 0;
style = GetWindowLongA(hwnd, GWL_STYLE);
exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
menu = !(style & WS_CHILD) && GetMenu(hwnd) != 0;
GetWindowRect(hwnd, &rc_window);
trace("window: (%ld,%ld)-(%ld,%ld)\n", rc_window.left, rc_window.top, rc_window.right, rc_window.bottom);
GetClientRect(hwnd, &rc_client);
trace("client: (%ld,%ld)-(%ld,%ld)\n", rc_client.left, rc_client.top, rc_client.right, rc_client.bottom);
/* avoid some cases when things go wrong */
if (IsRectEmpty(&rc_window) || IsRectEmpty(&rc_client) ||
rc_window.right > 32768 || rc_window.bottom > 32768) return;
CopyRect(&rc, &rc_client);
MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
FixedAdjustWindowRectEx(&rc, style, menu, exstyle);
trace("calc window: (%ld,%ld)-(%ld,%ld)\n", rc.left, rc.top, rc.right, rc.bottom);
ok(EqualRect(&rc, &rc_window), "window rect does not match: style:exstyle=0x%08lx:0x%08lx, menu=%d\n", style, exstyle, menu);
CopyRect(&rc, &rc_window);
DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)&rc);
MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
trace("calc client: (%ld,%ld)-(%ld,%ld)\n", rc.left, rc.top, rc.right, rc.bottom);
ok(EqualRect(&rc, &rc_client), "client rect does not match: style:exstyle=0x%08lx:0x%08lx, menu=%d\n", style, exstyle, menu);
/* Win9x doesn't like WM_NCCALCSIZE with synthetic data and crashes */;
if (is_win9x)
return;
/* and now test AdjustWindowRectEx and WM_NCCALCSIZE on synthetic data */
SetRect(&rc_client, 0, 0, 250, 150);
CopyRect(&rc_window, &rc_client);
MapWindowPoints(hwnd, 0, (LPPOINT)&rc_window, 2);
FixedAdjustWindowRectEx(&rc_window, style, menu, exstyle);
trace("calc window: (%ld,%ld)-(%ld,%ld)\n",
rc_window.left, rc_window.top, rc_window.right, rc_window.bottom);
CopyRect(&rc, &rc_window);
DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)&rc);
MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
trace("calc client: (%ld,%ld)-(%ld,%ld)\n", rc.left, rc.top, rc.right, rc.bottom);
ok(EqualRect(&rc, &rc_client), "synthetic rect does not match: style:exstyle=0x%08lx:0x%08lx, menu=%d\n", style, exstyle, menu);
}
static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
static const char *CBT_code_name[10] = {
"HCBT_MOVESIZE",
"HCBT_MINMAX",
"HCBT_QS",
"HCBT_CREATEWND",
"HCBT_DESTROYWND",
"HCBT_ACTIVATE",
"HCBT_CLICKSKIPPED",
"HCBT_KEYSKIPPED",
"HCBT_SYSCOMMAND",
"HCBT_SETFOCUS" };
const char *code_name = (nCode >= 0 && nCode <= HCBT_SETFOCUS) ? CBT_code_name[nCode] : "Unknown";
trace("CBT: %d (%s), %08x, %08lx\n", nCode, code_name, wParam, lParam);
/* on HCBT_DESTROYWND window state is undefined */
if (nCode != HCBT_DESTROYWND && IsWindow((HWND)wParam))
{
if (pGetWindowInfo)
{
WINDOWINFO info;
/* Win98 actually does check the info.cbSize and doesn't allow
* it to be anything except sizeof(WINDOWINFO), while Win95, Win2k,
* WinXP do not check it at all.
*/
info.cbSize = sizeof(WINDOWINFO);
ok(pGetWindowInfo((HWND)wParam, &info), "GetWindowInfo should not fail\n");
/* win2k SP4 returns broken border info if GetWindowInfo
* is being called from HCBT_DESTROYWND or HCBT_MINMAX hook proc.
*/
verify_window_info((HWND)wParam, &info, nCode != HCBT_MINMAX);
}
}
switch (nCode)
{
case HCBT_CREATEWND:
{
#if 0 /* Uncomment this once the test succeeds in all cases */
static const RECT rc_null;
RECT rc;
#endif
LONG style;
CBT_CREATEWNDA *createwnd = (CBT_CREATEWNDA *)lParam;
trace("HCBT_CREATEWND: hwnd %p, parent %p, style %08lx\n",
(HWND)wParam, createwnd->lpcs->hwndParent, createwnd->lpcs->style);
ok(createwnd->hwndInsertAfter == HWND_TOP, "hwndInsertAfter should be always HWND_TOP\n");
/* WS_VISIBLE should be turned off yet */
style = createwnd->lpcs->style & ~WS_VISIBLE;
ok(style == GetWindowLongA((HWND)wParam, GWL_STYLE),
"style of hwnd and style in the CREATESTRUCT do not match: %08lx != %08lx\n",
GetWindowLongA((HWND)wParam, GWL_STYLE), style);
#if 0 /* Uncomment this once the test succeeds in all cases */
if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
ok(GetParent((HWND)wParam) == hwndMessage,
"wrong result from GetParent %p: message window %p\n",
GetParent((HWND)wParam), hwndMessage);
}
else
ok(!GetParent((HWND)wParam), "GetParent should return 0 at this point\n");
ok(!GetWindow((HWND)wParam, GW_OWNER), "GW_OWNER should be set to 0 at this point\n");
#endif
#if 0 /* while NT assigns GW_HWNDFIRST/LAST some values at this point,
* Win9x still has them set to 0.
*/
ok(GetWindow((HWND)wParam, GW_HWNDFIRST) != 0, "GW_HWNDFIRST should not be set to 0 at this point\n");
ok(GetWindow((HWND)wParam, GW_HWNDLAST) != 0, "GW_HWNDLAST should not be set to 0 at this point\n");
#endif
ok(!GetWindow((HWND)wParam, GW_HWNDPREV), "GW_HWNDPREV should be set to 0 at this point\n");
ok(!GetWindow((HWND)wParam, GW_HWNDNEXT), "GW_HWNDNEXT should be set to 0 at this point\n");
#if 0 /* Uncomment this once the test succeeds in all cases */
if (pGetAncestor)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -