Win32 SDK Gui编程系列之--Windows基本要素:控件

这篇博客介绍了Windows GUI编程中的控件类型,包括静态控件、按钮控件(普通按钮、单选按钮、复选框)、编辑控件、列表框控件和组合框控件的使用方法。通过实例展示了如何创建、操作这些控件,以及它们在不同场景下的应用,如设置按钮状态、处理用户输入等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Windows基本元素:控件 Windows中将按钮、复选框等作为组件使用的东西称为控件。本页面将介绍这些的使用方法。 基本的控件根据其窗口类名可以分为静态控件、按钮控件、编辑控件、列表框控件、组合框控件以及滚动条控件六种。

1.静态控件

静态控件虽然也能显示位图,但主要是用来仅显示文字的简单控件。用于显示标签等。可以是多行文本,文本的右端自动换行。但是,不带有滚动功能。下面展示了程序示例及其运行画面。

Static01.c

#include <windows.h>
#include <string.h>

#define WND_CLASS_NAME "My_Window"


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd;
    WNDCLASS wcl;
    MSG msg;

    char *text = "在长句子中,右端的折返是自动完成的。 但是,没有滚动功能";
    memset(&wcl, 0, sizeof(wcl));
    wcl.hInstance = hInstance;
    wcl.lpszClassName = WND_CLASS_NAME;
    wcl.lpfnWndProc = WindowProc;
    wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    if (!RegisterClass(&wcl)) return FALSE;
     
    hWnd = CreateWindowEx(0, WND_CLASS_NAME, "Windows Programming",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        10, 10, 400, 150, NULL, NULL, hInstance, NULL);
    if(!hWnd) return FALSE;
    CreateWindowEx(0, "STATIC", "即使这样\n窗口", WS_CHILD | WS_VISIBLE | WS_BORDER,
			10, 10, 150, 50, hWnd, (HMENU)1, hInstance, NULL);
    CreateWindowEx(0, "STATIC", text, WS_CHILD | WS_VISIBLE,
			170, 10, 200, 80, hWnd, (HMENU)1, hInstance, NULL);
    while (GetMessage(&msg,NULL,0,0) > 0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}


2.按钮控件

定义好的按钮等控件类不需要设置WNDCLASS。此外,按钮被按下时的绘制处理和消息处理都是默认支持的,因此无需进行任何设置。 这些控件通过在CreateWindow()函数的样式中指定WS_CHILD,并注册为当前窗口的子窗口。另外,在第8个参数hWndParent中,指定作为所有者的父窗口句柄。位置是根据所有者窗口的客户区坐标来确定的。下面展示了程序和运行结果。

Intro31x.c

#include <windows.h>
#include <stdio.h>
#include <string.h>

#define WND_CLASS_NAME "My_Window"
#define BID_1 	0
#define BID_2 	1

int nBtn = 0;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    char buf[256];
    switch (uMsg) {
    case WM_COMMAND:
	nBtn = wParam;
	switch(wParam) {
	case BID_1:
	    MessageBox(hwnd, "按下按钮1", "Button", MB_OK);
	    break;
	case BID_2:
	    MessageBox(hwnd, "按钮2被按下了", "Button", MB_OK);
	    break;
	}
	sprintf(buf, "ButtonAA %d", nBtn);
	SetWindowText(hwnd, buf);
	return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd;
    WNDCLASS wcl;
    MSG msg;

    memset(&wcl, 0, sizeof(wcl));
    wcl.hInstance = hInstance;
    wcl.lpszClassName = WND_CLASS_NAME;
    wcl.lpfnWndProc = WindowProc;
    wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    if (!RegisterClass(&wcl)) return FALSE;
     
    hWnd = CreateWindowEx(0, WND_CLASS_NAME, "Windows Programming",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        10, 10, 400, 100, NULL, NULL, hInstance, NULL);
    if(!hWnd) return FALSE;
    CreateWindowEx(0, "BUTTON", "按钮1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		  0, 0, 100, 50, hWnd, (HMENU)0, hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "按钮2", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		110, 0, 100, 50, hWnd, (HMENU)1, hInstance, NULL);
    while (GetMessage(&msg,NULL,0,0) > 0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}


当有多个按钮时,如果想要像单选按钮那样,只能使其中一个有效,可能会希望知道当前哪个按钮被按下。这可以通过稍微修改CreateWindow函数的样式来实现。这本质上是将外观设为按钮样式(BS_PUSHLIKE)的单选按钮。

Intro32a.c

// tcc intro32.c ../lib/winlib.o

#include <windows.h>
#include <stdio.h>
#include <string.h>

#define  WND_CLASS_NAME "My_Window"
#define  BID_1 	0
#define  BID_2	1
#define  BID_3 	2


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_COMMAND:
	switch(wParam) {
	case BID_1:
	    MessageBox(hwnd, "按下按钮1", "Button", MB_OK);
	    break;
	case BID_2:
	    MessageBox(hwnd, "按钮2被按下了", "Button", MB_OK);
	    break;
	case BID_3:
	    MessageBox(hwnd, "按下按钮3", "Button", MB_OK);
	    break;
	}
	return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd;
    WNDCLASS wcl;
    MSG msg;

    memset(&wcl, 0, sizeof(wcl));
    wcl.hInstance = hInstance;
    wcl.lpszClassName = WND_CLASS_NAME;
    wcl.lpfnWndProc = WindowProc;
    wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    if (!RegisterClass(&wcl)) return FALSE;
     
    hWnd = CreateWindowEx(0, WND_CLASS_NAME, "Windows Programming",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        10, 10, 350, 100, NULL, NULL, hInstance, NULL);
    if(!hWnd) return FALSE;
    CreateWindowEx(0, "BUTTON", "按钮1", 
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_PUSHLIKE | WS_GROUP,
		0, 0, 100, 50, hWnd, (HMENU)BID_1, hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "按钮2", 
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_PUSHLIKE,
		110, 0, 100, 50, hWnd, (HMENU)BID_2, hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "按钮3", 
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_PUSHLIKE,
		220, 0, 100, 50, hWnd, (HMENU)BID_3, hInstance, NULL);
    while (GetMessage(&msg,NULL,0,0) > 0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}


当按钮较多时,使用数组会比较方便。最初,要使某个按钮处于被按下状态,可以使用SendMessage函数。下面的程序设置了按下按钮时改变背景色。

Intro33a.c

#include <windows.h>
#include <stdio.h>
#include <string.h>

#define WND_CLASS_NAME "My_Window"

char      *btn[] = { "红色",   "蓝色",    "绿色",    "白色",   "黑色" };
COLORREF color[] = { 0xFF, 0xFF0000, 0xFF00, 0xFFFFFF,  0x0 };
int  idBtn;	// 选择中的按钮号码

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    HDC hdc;
    HBRUSH hBrush;
    RECT rect;

    switch (uMsg) {
    case WM_COMMAND:
	idBtn = wParam;
	InvalidateRect(hwnd, NULL, TRUE);
	return 0;
    case WM_PAINT:
        GetClientRect(hwnd, &rect);
        hdc = BeginPaint(hwnd, &ps)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值