GUI程序开发概述
- 不同的操作系统GUI开发原理相同
- 不同的操作系统GUI SDK 不同
GUI 程序开发原理
- GUI程序在运行时会创建一个消息队列
- 系统内核将用户的键盘鼠标操作翻译成对应的程序消息
- 程序在运行过程中需要实时处理队列中的消息
- 当队列中没有消息时,程序将处于停滞状态,等待用户操作
经典的GUI程序
GUI程序开发的本质
- 在代码中用程序创建窗口以及窗口元素
- 在消息处理函数中根据程序消息做出不同的反应
GUI程序开发实例
以windows操作系统为例子
函数名 | 功能 |
---|---|
RegisterClass | 向系统注册GUI窗口式样 |
CreateWindow | 创建窗口或窗口元素 |
ShowWindow | 在屏幕上显示创建好的窗口 |
UpdateWindow | 刷新屏幕上的窗口 |
GetMessage | 获取程序消息队列中的消息 |
TranslateMessage | 翻译系统消息 |
DispatchMessage | 将消息发送到窗口处理函数 |
代码
#include <windows.h>
#define STYLE_NAME L"MainForm"
#define BUTTON_ID 919
/* 主窗口定义函数 */
BOOL DefineMainWindow(HINSTANCE hInstance);
/* 主窗口创建函数 */
HWND CreateMainWindow(HINSTANCE hInstance, wchar_t* title);
/* 主窗口内部元素创建函数 */
HWND CreateButton(HWND parent, int id, wchar_t* text);
/* 主窗口显示函数 */
HWND DisplayMainWindow(HWND hWnd, int nCmdShow);
/* 主窗口消息处理函数 */
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static HWND MainWindow = NULL; // 主窗口句柄标
BOOL WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg = {0};
/* 1.自定义主窗口样式 */
if( !DefineMainWindow(hInstance) )
{
return FALSE;
}
/* 2.创建主窗口 */
MainWindow = CreateMainWindow(hInstance, STYLE_NAME);
if( MainWindow )
{
/* 3.创建主窗口中的控件元素 */
CreateButton(MainWindow, BUTTON_ID, L"My Button");
/* 4.在屏幕上显示主窗口 */
DisplayMainWindow(MainWindow, nCmdShow);
}
else
{
return FALSE;
}
/* 5.进入消息循环 */
while( GetMessage(&Msg, NULL, NULL, NULL) )
{
/* 6.翻译并转换系统消息 */
TranslateMessage(&Msg);
/* 7.分发消息到对应的消息处理函数 */
DispatchMessage(&Msg);
}
return TRUE;
}
BOOL DefineMainWindow(HINSTANCE hInstance)
{
static WNDCLASS WndClass = {0}; // 系统结构体类型
// 用于描述窗口样式
WndClass.style = 0;
WndClass.cbClsExtra = 0;
WndClass.cbClsExtra = 0;
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW); // 定义窗口背景色
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 定义鼠标样式
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 定义窗口左上角图标
WndClass.hInstance = hInstance; // 定义窗口式样属于当前应用程序
WndClass.lpfnWndProc = WndProc; // 窗口消息处理函数
WndClass.lpszClassName = STYLE_NAME; // 窗口样式名
WndClass.lpszMenuName = NULL;
/* 将定义好的窗口式样注册到系统 */
return RegisterClass(&WndClass);
}
HWND CreateMainWindow(HINSTANCE hInstance, wchar_t* title)
{
HWND hwnd = NULL;
hwnd = CreateWindow(STYLE_NAME, // 通过定义好的窗口式样创建主窗口
title, // 主窗口标题
WS_OVERLAPPEDWINDOW, // 创建后主窗口的显示风格
CW_USEDEFAULT, // 主窗口左上角 x 坐标
CW_USEDEFAULT, // 主窗口左上角 y 坐标
CW_USEDEFAULT, // 主窗口宽度
CW_USEDEFAULT, // 主窗口高度
NULL, // 父窗口
NULL, // 窗口菜单栏
hInstance, // 主窗口属于当前应用程序
NULL); // 窗口参数
return hwnd;
}
HWND DisplayMainWindow(HWND hWnd, int nCmdShow)
{
ShowWindow(hWnd,nCmdShow); // 显示窗口
UpdateWindow(hWnd); // 刷新窗口
return hWnd;
}
HWND CreateButton(HWND parent, int id, wchar_t* text)
{
HINSTANCE hInstance = (HINSTANCE)GetWindowLong(parent, GWL_HINSTANCE);
HWND hwnd = NULL;
hwnd = CreateWindow(L"button", // 通过系统预定义式样创建窗口元素
text, // 窗口元素标题
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 窗口元素的显示风格
50, // 窗口元素在窗口中的左上角 x 坐标
50, // 窗口元素在窗口中的左上角 y 坐标
200, // 窗口元素的宽度
60, // 窗口元素的高度
parent, // 窗口元素所在的父窗口
(HMENU)id, // 窗口元素 ID 值
hInstance, // 窗口元素属于当前应用程序
NULL); // 窗口元素参数
return hwnd;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/* 调用系统提供的默认消息处理函数 */
return DefWindowProc(hWnd, message, wParam, lParam);
}