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);
}