win32按钮没有显示

时间:2013-05-26 12:53:55

标签: c winapi button

我尝试在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;
}

我错过了什么?

2 个答案:

答案 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