我尝试在500x500窗口中创建一个按钮,问题是,按钮没有出现在窗口中,单击窗口会触发按钮的过程/处理程序:
#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;
}
我错过了什么?
答案 0 :(得分:5)
这不是你创建按钮的方式。
按钮控件使用由公共控件库预定义的特殊窗口类。您不需要注册窗口类,它已经注册。有关使用常用控件的建议阅读是here on MSDN。
您只需要调用CreateWindow
,只需确保使用正确的类名:WC_BUTTON
(由公共控件头文件定义为"BUTTON"
)。
对于控件,您通常还希望包含WS_TABSTOP
样式,而对于某个按钮,您需要包含button styles之一 - 例如BS_DEFPUSHBUTTON
或{{1 }}
最后,当您致电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);
样式,因此您不需要此代码(并且您可能不应该将WS_VISIBLE
与您的子窗口一起使用):
nCmdShow
最后,我无法帮助,但请注意您使用的是ANSI字符串文字。今天的所有Windows应用程序都应该使用Unicode支持构建,这需要您使用宽字符串文字。要获取这些内容,请为每个// unnecessary code:
ShowWindow(ButtonHandle, nCmdShow);
UpdateWindow(ButtonHandle);
添加前缀并使用L
类型:LPCWSTR
不这样做 应该生成编译错误;新项目的默认设置定义LPCWSTR FrameClassName = L"MainWindow";
预处理程序符号。如果你的项目没有完成,你现在就应该这样做。
答案 1 :(得分:0)
在Windows XP下创建具有视觉风格的按钮时,您需要加载comctl32.dll
。
#include <CommCtrl.h> // somewhere at the top of your code file
#pragma comment(lib, "Comctl32.lib") // if necessary
// create manifest to use XP visual style
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
// before creating button call:
InitCommonControls(); // necessary to enable Visual style on WinXP