我尝试在500x500窗口中创建一个按钮,问题是,按钮没有出现在窗口中,单击Windows单独触发按钮的过程/处理程序:
#include <windows.h>
LRESULT CALLBACK MainWindowHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ButtonHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam);
LPCSTR FrameClassName = "MainWindow";
LPCSTR ButtonClassName = "Button";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX Frame;
HWND FrameHandle;
WNDCLASSEX Button;
HWND ButtonHandle;
MSG Msg;
Frame.cbSize = sizeof(WNDCLASSEX);
Frame.style = 0;
Frame.lpfnWndProc = MainWindowHandler;
Frame.cbClsExtra = 0;
Frame.cbWndExtra = 0;
Frame.hInstance = hInstance;
Frame.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Frame.hCursor = LoadCursor(NULL, IDC_ARROW);
Frame.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
Frame.lpszMenuName = NULL;
Frame.lpszClassName = FrameClassName;
Frame.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
Button.cbSize = sizeof(WNDCLASSEX);
Button.style = 0;
Button.lpfnWndProc = ButtonHandler;
Button.cbClsExtra = 0;
Button.cbWndExtra = 0;
Button.hInstance = hInstance;
Button.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Button.hCursor = LoadCursor(NULL, IDC_ARROW);
Button.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
Button.lpszMenuName = FrameClassName;
Button.lpszClassName = ButtonClassName;
Button.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&Frame))
{
MessageBox(NULL,"Registration Failure","ERROR",MB_ICONWARNING| MB_OK);
return 0;
}
if(!RegisterClassEx(&Button))
{
MessageBox(NULL,"Registration Failure","ERROR",MB_ICONWARNING| MB_OK);
return 0;
}
FrameHandle = CreateWindowEx(WS_EX_CLIENTEDGE,
FrameClassName,
"Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
NULL, NULL, hInstance, NULL);
ButtonHandle = CreateWindowEx(0, ButtonClassName, "My Button",
WS_CHILD | WS_VISIBLE, 250, 250, 30, 20, FrameHandle,
(HMENU)FrameHandle, hInstance, NULL);
SendDlgItemMessage(ButtonHandle, 12, WM_SETFONT,
(WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));
ShowWindow(FrameHandle, nCmdShow);
UpdateWindow(FrameHandle);
ShowWindow(ButtonHandle, nCmdShow);
UpdateWindow(ButtonHandle);
while(GetMessage(&Msg,NULL,0,0)>0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
LRESULT CALLBACK MainWindowHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDOWN:
MessageBox(obj,"CLICKED!","BUTTON",0);
break;
case WM_CLOSE:
DestroyWindow(obj);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(obj, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK ButtonHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(obj);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(obj, msg, wParam, lParam);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
这不是你创建按钮的方式.
按钮控件使用由公共控件库预定义的特殊窗口类.您不需要注册窗口类,它已经注册.MSDN上有关使用通用控件的推荐读物.
您只需要调用CreateWindow,只需确保使用正确的类名:( WC_BUTTON由公共控件头文件定义"BUTTON").
对于控件,您通常也希望包含WS_TABSTOP样式,特别是对于按钮,您需要包含一个按钮样式 -eg BS_DEFPUSHBUTTON或BS_PUSHBUTTON.
最后,hMenu当您调用时,您传递的参数值不正确CreateWindow.对于子窗口(如控件),这是控件的唯一标识符,而不是其父窗口的句柄.如果它是第一个控件,您可以给它一个ID 1.最好在代码中使用常量,以便以后可以通过编程方式与控件进行交互.
#include <CommCtrl.h> // somewhere at the top of your code file
ButtonHandle = CreateWindowEx(0,
WC_BUTTON,
"My Button",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
250, 250, 30, 20,
FrameHandle,
(HMENU)1, // or some other unique ID for this ctrl
hInstance,
NULL);
Run Code Online (Sandbox Code Playgroud)
由于你已经包含了这个WS_VISIBLE样式,你不需要这个代码(你可能不应该使用nCmdShow你的子窗口):
// unnecessary code:
ShowWindow(ButtonHandle, nCmdShow);
UpdateWindow(ButtonHandle);
Run Code Online (Sandbox Code Playgroud)
最后,我不禁注意到你正在使用ANSI字符串文字.今天的所有Windows应用程序都应该使用Unicode支持构建,这需要您使用宽字符串文字.为了获得这些,为它们每个前缀添加L并使用LPCWSTR类型:LPCWSTR FrameClassName = L"MainWindow";不这样做应该产生编译器错误; 新项目的默认设置定义UNICODE预处理器符号.如果没有为您的项目完成,您应该立即执行此操作.