我一直在研究一个选项卡控制程序,最近才在 StackOverflow 上发帖寻求帮助。目前程序运行如下:
- 开始于
winMain
,创建main_hwnd
生成WM_CREATE
并被wndProc
调用 tab_hwnd
被创建为SysTabControl32
tab0_hwnd
,tab1_hwnd
, ...,tab4_hwnd
被创建- 在
tab0_hwnd
中,创建静态文本和按钮
- 在
- 返回
winMain
并被ShowWindow()
调用main_hwnd
,tab_hwnd
并且tab0_hwnd
- 进入一个循环,直到程序关闭。
当程序运行时,一切都是可见的;但是,按钮无法正常工作。同时,我在使用搜索错误时GetLastError()
,FormatMessage()
发现创建windows后tab#_hwnd
(其中#=0,1,2,3和4),出现如下错误:
错误6:句柄无效
我不确定为什么会出现此错误以及为什么按钮不起作用。另一位用户在之前的帖子中提出了以下建议:
"WM_COMMAND
被发送到直接父窗口,而不是祖父母,所以你要么必须子类化你的选项卡控件,要么让你的按钮将你的主窗口作为父窗口。- 安东·科瓦连科
编辑 1:我不确定如何按照 Anton Kovalenko 的建议对我的选项卡控件进行子类化。任何指向教程/注释解释的链接都将非常有帮助。
这是当前代码:
#define WIN32_LEAN_AND_MEAN
#pragma comment(lib, "comctl32.lib")
#define ID_FILE_EXIT 101
#define ID_HELP_ABOUT 102
#define ID_B_BLANK 1001
#define ID_B_HOME 1002
#define ID_B_SAVE 1003
#include <strsafe.h>
#include <windows.h>
#include <CommCtrl.h>
#include <iostream>
#include <ShlObj.h>
HWND main_hwnd, tab_hwnd, tab0_hwnd, tab1_hwnd, tab2_hwnd, tab3_hwnd, tab4_hwnd;
HINSTANCE tab_hinst;
TCHAR HomePath[MAX_PATH*2], SavePath[MAX_PATH*2];
WNDCLASSEX wc;
bool success=FALSE;
MSG msg;
HWND button;
static HWND text;
TCITEM tie;
int focus = 0, NotifyCase = 0;
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
// Call with ErrorExit(TEXT("ANYTHINGHERE"));
LRESULT CALLBACK WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE:
{
tab_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT, 681, 338,
hwnd, NULL, tab_hinst, NULL);
tab0_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
1, 22, 679, 315,
tab_hwnd, NULL, tab_hinst, NULL);
//ErrorExit(TEXT("HERE")); //<--- This gives error 6: Handle invalid
text = CreateWindow("Static","Home Directory",WS_CHILD | WS_VISIBLE,0,50,150,50,tab0_hwnd, 0, tab_hinst,0);
text = CreateWindow("Static","C:\\",WS_CHILD | WS_VISIBLE,200,50,150,50,tab0_hwnd, 0, tab_hinst,0);
button = CreateWindow("Button","Navigate to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,42,100,25,tab0_hwnd,(HMENU)ID_B_HOME,tab_hinst,0);
text = CreateWindow("Static","Save Directory",WS_CHILD | WS_VISIBLE,0,100,150,50,tab0_hwnd, 0, tab_hinst,0);
text = CreateWindow("Static","C:\\",WS_CHILD | WS_VISIBLE,200,100,150,50,tab0_hwnd, 0, tab_hinst,0);
button = CreateWindow("Button","Save to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,92,100,25,tab0_hwnd,(HMENU)ID_B_SAVE,tab_hinst,0);
tab1_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
1, 22, 679, 315,
tab_hwnd, NULL, tab_hinst, NULL);
tab2_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
1, 22, 679, 315,
tab_hwnd, NULL, tab_hinst, NULL);
tab3_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
1, 22, 679, 315,
tab_hwnd, NULL, tab_hinst, NULL);
tab4_hwnd = CreateWindowEx(
0,
"SysTabControl32",
"",
WS_CHILD,
1, 22, 679, 315,
tab_hwnd, NULL, tab_hinst, NULL);
tie.mask = TCIF_TEXT;
tie.pszText = "Paths";
TabCtrl_InsertItem(tab_hwnd, 0, &tie);
tie.pszText = "Output";
TabCtrl_InsertItem(tab_hwnd, 1, &tie);
tie.pszText = "Parameters";
TabCtrl_InsertItem(tab_hwnd, 2, &tie);
tie.pszText = "Configurations";
TabCtrl_InsertItem(tab_hwnd, 3, &tie);
tie.pszText = "Run";
TabCtrl_InsertItem(tab_hwnd, 4, &tie);
HMENU hMenu, hSubMenu;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "&Exit");
hSubMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help");
AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABOUT, "&About");
SetMenu(hwnd, hMenu);
}
break;
case WM_NOTIFY:
switch(((LPNMHDR)lParam) ->code)
{
case TCN_SELCHANGING:
switch(TabCtrl_GetCurFocus(tab_hwnd))
{
case 0:
ShowWindow(tab0_hwnd,SW_HIDE);
break;
case 1:
ShowWindow(tab1_hwnd,SW_HIDE);
break;
case 2:
ShowWindow(tab2_hwnd,SW_HIDE);
break;
case 3:
ShowWindow(tab3_hwnd,SW_HIDE);
break;
case 4:
ShowWindow(tab4_hwnd,SW_HIDE);
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
break;
}
break;
case TCN_SELCHANGE:
switch(TabCtrl_GetCurFocus(tab_hwnd))
{
case 0:
ShowWindow(tab0_hwnd,SW_SHOW);
break;
case 1:
ShowWindow(tab1_hwnd,SW_SHOW);
break;
case 2:
ShowWindow(tab2_hwnd,SW_SHOW);
break;
case 3:
ShowWindow(tab3_hwnd,SW_SHOW);
break;
case 4:
ShowWindow(tab4_hwnd,SW_SHOW);
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
break;
}
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
break;
case WM_COMMAND:
//MessageBox(tab0_hwnd,"HERE","OKAY",NULL);
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case ID_HELP_ABOUT:
return MessageBox(0, "This program is an alteration of ...", "About", MB_OK);
case ID_B_HOME:
if(BN_CLICKED == HIWORD(wParam)){
MessageBox(tab0_hwnd,"HERE","OKAY",NULL);
}
break;
case ID_B_SAVE:
if(BN_CLICKED == HIWORD(wParam)){
}
break;
case ID_B_BLANK:
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
InitCommonControls();
tab_hinst = hInstance;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "Home";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
main_hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"Home",
"The Home page",
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 700, 400,
NULL, NULL, hInstance, NULL);
if(main_hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(main_hwnd, nCmdShow);
ShowWindow(tab_hwnd,SW_SHOW);
ShowWindow(tab0_hwnd,SW_SHOW);
UpdateWindow(main_hwnd);
do{
PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage(&msg);
} while(msg.message!=WM_CLOSE && msg.message!=WM_QUIT);
return msg.wParam;
}