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

目录
相关文章
|
3月前
|
安全 Ubuntu iOS开发
Nessus Professional 10.10 Auto Installer for Windows - Nessus 自动化安装程序
Nessus Professional 10.10 Auto Installer for Windows - Nessus 自动化安装程序
199 3
Nessus Professional 10.10 Auto Installer for Windows - Nessus 自动化安装程序
|
3月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
177 11
|
5月前
|
Ubuntu Linux Windows
如何在Ubuntu系统中安装Wine,借此来运行Windows程序
熟悉的登录画面出现,在Ubuntu系统中扫描登录微信程序。
|
5月前
|
Unix Linux 编译器
解决在Windows平台上运行Golang程序时出现的syscall.SIGUSR1未定义错误。
通过这种结构,你的代码既可以在支持 SIGUSR1 信号的系统上正常工作,又可以在不支持这些信号的 Windows 系统上编译通过,确保跨平台的兼容性和功能的完整性。
235 0
|
6月前
|
Windows
Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序
Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序
173 2
|
7月前
|
Windows
Windows下版本控制器(SVN)-启动服务器端程序
Windows下版本控制器(SVN)-启动服务器端程序
253 4
|
8月前
|
安全 Devops 测试技术
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
177 0
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
|
7月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
204 0
|
7月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
321 0
|
11月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。