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_DEFPUSHBUTTONBS_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按钮不显示的主要内容,如果未能解决你的问题,请参考以下文章

win10右击开始按钮不显示控制面板

如何在不显示文本的情况下分配 Win32 EDIT 控件的窗口名称?

如何更改 win32 窗口上的文本?

如何读取文本文件并将其显示在 win 32 unicode 字符集中的编辑控件上?

Win10 最下面的任务栏不显示正在打开的窗口了,打开任何东西任务栏都不显示

c++ win32编辑框光标不闪烁