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

目录
相关文章
|
27天前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
3月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
1天前
|
安全 Devops 测试技术
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
14 0
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
|
1月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
61 12
|
2月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
61 16
|
3月前
|
安全 JavaScript Java
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
54 12
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
|
2月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
2月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
3月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
2月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
157 6

热门文章

最新文章