C++ Windows窗口程序:子窗口控件之按钮类button

简介: C++ Windows窗口程序:子窗口控件之按钮类button

Windows窗口程序设计中,按钮、文本编辑框等控件都作为一个子窗口在WM_CREATE事件中创建的。其中按钮类button有多种类型和风格,常见的单选钮、复选钮、分组框也在此类中,见下表:

子窗口控件:按钮类button
按钮类型,可以是按钮风格与窗口风格的组合
窗口风格:
WS_CHILD             子窗口,必须有
WS_VISIBLE           窗口可见,一般都有
WS_DISABLED          禁用窗口,创建初始状态为灰色不可用的按钮时使用
WS_TABSTOP           可用Tab键选择
WS_GROUP             成组,用于成组的单选按钮中的第一个按钮
按钮风格:
BS_PUSHBUTTON        下压式按钮,也即普通按钮
BS_CHECKBOX          复选按钮,不常用
BS_AUTOCHECKBOX      含自动选中状态的复选按钮
BS_RADIOBUTTON       单选按钮,不常用
BS_AUTORADIOBUTTON   含自动选中状态的单选按钮
BS_3STATE            三态复选按钮,不常用
BS_AUTO3STATE        含自动选中状态的三态复选按钮
BS_GROUPBOX          分组框,用来放置单选或复选按钮的
BS_OWNERDRAW         用于自定义形状的类型,比如画个圆形的按钮
以上风格指定了创建的按钮类型,不能同时使用,但必须有其一
其中非自动类型的按钮需要自己编程来实现选中与否的状态切换
BS_BITMAP            按钮上将显示位图
BS_DEFPUSHBUTTON     设置为默认按钮,只用于下压式按钮,一个对话框中只能指定一个默认按钮
创建方法:
        HWND hwndButton;
        hwndButton = CreateWindow ( TEXT("button"),        /*子窗口类名称*/
                TEXT("Command Button"),                    /*按钮上的文字*/
            WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,     /*按钮类型*/
              left, top, width, height,                  /*位置*/
                hwnd,                                      /*父窗口句柄*/
                (HMENU)IDcmdButton,                        /*按钮ID,一个自定义整型常量*/
                ((LPCREATESTRUCT) lParam)->hInstance, NULL);
    if (!hwndButton) MessageBox(NULL,"创建按钮失败","Message",MB_OK|MB_ICONERROR);
    ShowWindow(hwndButton,SW_SHOW);
        UpdateWindow(hwndButton);

再来用DEV-C++的windows application示例代码,创建这十种button类按钮。(代码获得方法见上一篇博文《C++ 用DEV-C++建一个Windows窗口程序带文本框和命令按钮》)

先建一个结构数组,存放这些按钮类型常数:

struct button {
  int swStyle;
  const char *szText;
}
Buttons[] = {
  BS_PUSHBUTTON,    TEXT("普通按钮"),
  BS_DEFPUSHBUTTON, TEXT("默认按钮"),
  BS_RADIOBUTTON,   TEXT("单选按钮"),
  BS_CHECKBOX,    TEXT("复选按钮"),
  BS_3STATE,      TEXT("三态按钮"),
  BS_AUTORADIOBUTTON, TEXT("自动单选按钮"),
  BS_AUTOCHECKBOX,  TEXT("自动复选按钮"),
  BS_AUTO3STATE,    TEXT("自动三态按钮"),
  BS_GROUPBOX,    TEXT("按钮分组框"),
  BS_OWNERDRAW,   TEXT("自画类型按钮")
};


然后在WM_CREATE事件中遍历数组创建全部按钮,在WM_COMMAND事件中写入鼠标单击响应代码就完成了:

#include <windows.h>
struct button {
  int swStyle;
  const char *szText;
}
Buttons[] = {
  BS_PUSHBUTTON,    TEXT("普通按钮"),
  BS_DEFPUSHBUTTON, TEXT("默认按钮"),
  BS_RADIOBUTTON,   TEXT("单选按钮"),
  BS_CHECKBOX,    TEXT("复选按钮"),
  BS_3STATE,      TEXT("三态按钮"),
  BS_AUTORADIOBUTTON, TEXT("自动单选按钮"),
  BS_AUTOCHECKBOX,  TEXT("自动复选按钮"),
  BS_AUTO3STATE,    TEXT("自动三态按钮"),
  BS_GROUPBOX,    TEXT("按钮分组框"),
  BS_OWNERDRAW,   TEXT("自画类型按钮")
};
/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
  int num = sizeof Buttons / sizeof Buttons[0];
  switch(Message) {
    //在 WM_CREATE 事件中创建所有按钮类型 
    case WM_CREATE: {
      for (int i = 0; i < num; i++) {
        CreateWindow( TEXT("button"),
        Buttons[i].szText,
        WS_CHILD | WS_VISIBLE | WS_TABSTOP | Buttons[i].swStyle,
        80 + (i >= num / 2 ? 240 : 0),
        60 + i * 50 - (i >= num / 2 ? 250 : 0),
        160, 40,
        hwnd,
        (HMENU)i,
        ((LPCREATESTRUCT) lParam)->hInstance,
        NULL);
      }
      break;
    }
    //在 WM_COMMAND 事件中会响应button类的鼠标单击,但其中GROUPBOX不响应操作
    case WM_COMMAND: {
      MessageBox(NULL, Buttons[LOWORD(wParam)].szText, "Button_Click()", MB_OK);
      break;
    }
    /* Upon destruction, tell the main thread to stop */
    case WM_DESTROY: {
      PostQuitMessage(0);
      break;
    }
    /* All other messages (a lot of them) are processed using default procedures */
    default:
      return DefWindowProc(hwnd, Message, wParam, lParam);
  }
  return 0;
}
/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wc; /* A properties struct of our window */
  HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
  MSG msg; /* A temporary location for all messages */
  /* zero out the struct and set the stuff we want to modify */
  memset(&wc,0,sizeof(wc));
  wc.cbSize    = sizeof(WNDCLASSEX);
  wc.lpfnWndProc   = WndProc; /* This is where we will send messages to */
  wc.hInstance   = hInstance;
  wc.hCursor     = LoadCursor(NULL, IDC_ARROW);
  /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wc.lpszClassName = "WindowClass";
  wc.hIcon     = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
  wc.hIconSm     = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
  if(!RegisterClassEx(&wc)) {
    MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
    return 0;
  }
  hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Button Style",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, /* x */
    CW_USEDEFAULT, /* y */
    640, /* width */
    480, /* height */
    NULL,NULL,hInstance,NULL);
  if(hwnd == NULL) {
    MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
    return 0;
  }
  /*
    This is the heart of our program where all input is processed and 
    sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
    this loop will not produce unreasonably high CPU usage
  */
  while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
    TranslateMessage(&msg); /* Translate key codes to chars if present */
    DispatchMessage(&msg); /* Send it to WndProc */
  }
  return msg.wParam;
}


运行效果图:

2021022100073797.png

目录
相关文章
|
2月前
|
消息中间件 编译器 API
Windows窗口程序
Windows窗口程序
|
2月前
|
编译器 C语言 C++
|
1月前
|
Windows
windows系统bat批处理 开机一键多个程序
windows系统bat批处理 开机一键多个程序
24 1
|
2月前
|
Windows
LabVIEW启用/禁用Windows屏幕保护程序
LabVIEW启用/禁用Windows屏幕保护程序
33 4
LabVIEW启用/禁用Windows屏幕保护程序
|
1月前
|
C++ UED 开发者
逆向学习 MFC 篇:视图分割和在 C++ 的 Windows 窗口程序中添加图标的方法
逆向学习 MFC 篇:视图分割和在 C++ 的 Windows 窗口程序中添加图标的方法
18 0
|
2月前
|
存储 安全 搜索推荐
Windows之隐藏特殊文件夹(自定义快捷桌面程序)
Windows之隐藏特殊文件夹(自定义快捷桌面程序)
|
2月前
|
Windows
Windows 程序自启动实现方法详解
Windows 程序自启动实现方法详解
61 0
|
12天前
|
设计模式 安全 编译器
【C++11】特殊类设计
【C++11】特殊类设计
33 10
|
17天前
|
C++
C++友元函数和友元类的使用
C++中的友元(friend)是一种机制,允许类或函数访问其他类的私有成员,以实现数据共享或特殊功能。友元分为两类:类友元和函数友元。类友元允许一个类访问另一个类的私有数据,而函数友元是非成员函数,可以直接访问类的私有成员。虽然提供了便利,但友元破坏了封装性,应谨慎使用。
46 9
|
13天前
|
存储 编译器 C语言
【C++基础 】类和对象(上)
【C++基础 】类和对象(上)