win32按钮不显示
Posted
技术标签:
【中文标题】win32按钮不显示【英文标题】:win32 button not showimg 【发布时间】:2013-05-26 12:53:54 【问题描述】:我尝试在 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;
我错过了什么?
【问题讨论】:
【参考方案1】:这不是你创建按钮的方式。
按钮控件使用由公共控件库预定义的特殊窗口类。您不需要注册窗口类,它已经注册了。使用常用控件的推荐阅读是here on MSDN。
您只需要调用CreateWindow
,只需确保使用正确的类名:WC_BUTTON
(由公共控件头文件定义为"BUTTON"
)。
对于控件,您通常还需要包含 WS_TABSTOP
样式,特别是对于按钮,您需要包含 button styles 之一——例如,BS_DEFPUSHBUTTON
或 BS_PUSHBUTTON
。
最后,当您调用CreateWindow
时,您为hMenu
参数传递了错误的值。对于子窗口(如控件),这是控件的唯一标识符,而不是其父窗口的句柄。如果它是第一个控件,您可以给它一个 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
):
// unnecessary code:
ShowWindow(ButtonHandle, nCmdShow);
UpdateWindow(ButtonHandle);
最后,我不禁注意到您使用的是 ANSI 字符串文字。今天所有的 Windows 应用程序都应该使用 Unicode 支持构建,这要求您使用宽字符串文字。要获得这些,请在每个前面加上 L
并使用 LPCWSTR
类型:LPCWSTR FrameClassName = L"MainWindow";
不这样做应该会产生编译器错误;新项目的默认设置定义了 UNICODE
预处理器符号。如果您的项目还没有这样做,那么您现在就应该这样做。
【讨论】:
@Maurice 一个好的教程可能会有用。通过反复试验学习 Win32 API 编程是相当困难的!最好的资源是 Charles Petzold 的经典著作,Programming Windows, 5th edition。但如果做不到这一点,this online tutorial 也不错。【参考方案2】:在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
【讨论】:
以上是关于win32按钮不显示的主要内容,如果未能解决你的问题,请参考以下文章
如何在不显示文本的情况下分配 Win32 EDIT 控件的窗口名称?
如何读取文本文件并将其显示在 win 32 unicode 字符集中的编辑控件上?