WIn32API - 子类化 window,我的第一次尝试
WIn32API - Subclassing a window, my first attempt
我一直在尝试通过子类化父 window 过程来创建子 window。我遇到了一些我无法理解的非常奇怪的行为。
CreateWindow()
调用后,代码停止执行并立即跳转到代码块的顶部(这是一条 WM_CREATE
消息)并无限地重新执行所有内容循环。
我以前从来没有这样做过,所以我不知道我做错了什么。这是代码。
LRESULT CALLBACK EditorProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
HWND RichEdit;
HWND Toolbar;
HWND ListboxType, ListboxArch;
HWND hwndBuildButton;
HWND Labels;
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rect);
switch (message)
{
case WM_CREATE:
LoadLibrary(TEXT ("Msftedit.dll"));
//Create Child Windows
RichEdit = CreateWindow(MSFTEDIT_CLASS, TEXT("EDITOR"), WS_CHILD | ES_MULTILINE | WS_VISIBLE | WS_BORDER,
0, 0, 0, 0, hwnd, RichEditorID, GetModuleHandle(NULL), NULL);
Toolbar = CreateWindow(TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_FLAT, 0, 0, 0, 0, hwnd,
ToolBarID, GetModuleHandle(NULL), NULL);
ListboxType = CreateWindow(WC_LISTBOX, NULL, WS_CHILD| WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 2,
GetModuleHandle(NULL), NULL);
ListboxArch = CreateWindow(WC_LISTBOX, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 3,
GetModuleHandle(NULL), NULL);
hwndBuildButton = CreateWindow(WC_BUTTON, L"Build", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, Toolbar, ChildID1 + 4,
GetModuleHandle(NULL), NULL);
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
OriginalProc = SetWindowLong(Labels, GWL_WNDPROC, LabelProc);
EnumChildWindows(hwnd, EditorChildProc, (LPARAM)&rect);
return 0;
这是子类 window 过程:
LRESULT CALLBACK LabelProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TCHAR ArchLabel[] = (L"Architecture:");
TCHAR BuildLabel[] = (L"Build Type:");
hdc = GetDC(hwnd);
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetTextAlign(hdc, TA_TOP);
TextOut(hdc, 50, 50, ArchLabel, ARRAYSIZE(ArchLabel));
TextOut(hdc, 100, 50, BuildLabel, ARRAYSIZE(BuildLabel));
EndPaint(hwnd, &ps);
return TRUE;
}
ReleaseDC(hwnd, hdc);
return CallWindowProcA(OriginalProc, hwnd, message, wParam, lParam);
}
代码在以下位置停止并重复:
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
免责声明:此答案中的所有内容都是假设,因为我们看不到所有代码。
我希望在这一行:
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
szEditorName 与您的 parent window 名称不同 class。
如果是,为什么你对无限循环感到惊讶?
你创建parent szEditorName window,在WM_CREATE创建child windows,但是最后
window 与 parent 有相同的 class,所以相同的 window 过程,所以 EditorProc 被一次又一次地调用......
我一直在尝试通过子类化父 window 过程来创建子 window。我遇到了一些我无法理解的非常奇怪的行为。
CreateWindow()
调用后,代码停止执行并立即跳转到代码块的顶部(这是一条 WM_CREATE
消息)并无限地重新执行所有内容循环。
我以前从来没有这样做过,所以我不知道我做错了什么。这是代码。
LRESULT CALLBACK EditorProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
HWND RichEdit;
HWND Toolbar;
HWND ListboxType, ListboxArch;
HWND hwndBuildButton;
HWND Labels;
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rect);
switch (message)
{
case WM_CREATE:
LoadLibrary(TEXT ("Msftedit.dll"));
//Create Child Windows
RichEdit = CreateWindow(MSFTEDIT_CLASS, TEXT("EDITOR"), WS_CHILD | ES_MULTILINE | WS_VISIBLE | WS_BORDER,
0, 0, 0, 0, hwnd, RichEditorID, GetModuleHandle(NULL), NULL);
Toolbar = CreateWindow(TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_FLAT, 0, 0, 0, 0, hwnd,
ToolBarID, GetModuleHandle(NULL), NULL);
ListboxType = CreateWindow(WC_LISTBOX, NULL, WS_CHILD| WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 2,
GetModuleHandle(NULL), NULL);
ListboxArch = CreateWindow(WC_LISTBOX, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 3,
GetModuleHandle(NULL), NULL);
hwndBuildButton = CreateWindow(WC_BUTTON, L"Build", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, Toolbar, ChildID1 + 4,
GetModuleHandle(NULL), NULL);
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
OriginalProc = SetWindowLong(Labels, GWL_WNDPROC, LabelProc);
EnumChildWindows(hwnd, EditorChildProc, (LPARAM)&rect);
return 0;
这是子类 window 过程:
LRESULT CALLBACK LabelProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TCHAR ArchLabel[] = (L"Architecture:");
TCHAR BuildLabel[] = (L"Build Type:");
hdc = GetDC(hwnd);
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetTextAlign(hdc, TA_TOP);
TextOut(hdc, 50, 50, ArchLabel, ARRAYSIZE(ArchLabel));
TextOut(hdc, 100, 50, BuildLabel, ARRAYSIZE(BuildLabel));
EndPaint(hwnd, &ps);
return TRUE;
}
ReleaseDC(hwnd, hdc);
return CallWindowProcA(OriginalProc, hwnd, message, wParam, lParam);
}
代码在以下位置停止并重复:
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
免责声明:此答案中的所有内容都是假设,因为我们看不到所有代码。
我希望在这一行:
Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
GetModuleHandle(NULL), NULL);
szEditorName 与您的 parent window 名称不同 class。 如果是,为什么你对无限循环感到惊讶?
你创建parent szEditorName window,在WM_CREATE创建child windows,但是最后 window 与 parent 有相同的 class,所以相同的 window 过程,所以 EditorProc 被一次又一次地调用......