WindowsAPI窗口程序设计-基础语法
WindowsAPI窗口程序设计-基础语法
基本概念
WinMain
入口函数。
1 | INT WINAPI _tWinMain( |
MessageBox
消息提示框。
1 | INT WINAPI MessageBox( |
按钮取值:
1 | MB_ABORTRETRYIGNORE |
图标取值:
1 | MB_ICONEXCLAMATION |
默认按钮:
1 | MB_DEFBUTTON1 |
返回值:
1 | IDABORT |
例子:
1 | INT nRet = ::MessageBox(NULL, TEXT("Hello World!"), TEXT("Caption"), MB_OKCANCEL | MB_ICONINFORMATION | MB_DEFBUTTON2); |
字符串
开始
Visual C++中存在两套编码系统,分别是ANSI和Unicode,两套各自有不同的一套API,这里同一使用tchar的方法,让编译器根据项目属性决定(当然一般就Unicode)。
需要引入:
1 |
_tcslen
字符串长度。
1 | TCHAR szStr[] = TEXT("C语言"); |
_tcschr
字符串中首次出现的指定字符。
1 | TCHAR szStr[] = TEXT("C语言"); |
_tcsstr
字符串中查找另一个字符串。
1 | TCHAR szStr[] = TEXT("C语言"); |
_tcsupr/_tcslwr
转大、小写。这俩不安全,可使用_tcsupr_s
/_tcslwr_s
。
1 | TCHAR szStr[] = TEXT("C语言"); |
_tcscat
字符串拼接,用安全版本。
1 | TCHAR szStrDest[] = TEXT("C语言"); |
StringCchCopy
字符串复制。同类型函数有_tcscpy_s
、memcpy_s
等,但当出现不以0结尾的字符串时,这俩不能正确使用。
1 | TCHAR szStrDest[] = TEXT("C语言"); |
_tcscmp/CompareStringEx
字符串比较,短的小,一般按照字典序比较。
1 | TCHAR szStr1[] = TEXT("我爱老王"); |
还能按照中文拼音排序:
1 | TCHAR szStr1[] = TEXT("我爱老王"); |
这些内部都是用的CompareStringEx
实现的:
1 | INT CompareStringEx( |
dwCmpFlags一些枚举值:
标志 | 含义 |
---|---|
LINGUISTIC_IGNORECASE/NORM_IGNORECASE | 忽略大小写 |
NORM_IFNORESYMBOLS | 忽略符号和标点符号 |
NORM_LINGUISTIC_CASING | 大小写使用语言规则,而不是文件系统规则 |
SORT_DIGITSASNUMBERS | 字串前数字字符解释为数值型数字 |
例如上文的compare
函数可修改为:
1 | INT compare(CONST PVOID arg1, CONST PVOID arg2) { |
_tcstok
字符串分割。
1 | TCHAR strToken[] = TEXT("A string\tof ,,tokens\nand some more tokens"); |
qsort
字符串快速排序。
1 | setlocale(LC_ALL, "chs"); |
排序回调函数:
1 | INT compare(CONST PVOID arg1, CONST PVOID arg2) { |
数值与字符串互转
这东西太多了,这里只讲int转字符串。
1 | INT n = 0x12CFFE20; |
格式化字符串
1 | TCHAR szName[] = TEXT("xxx"); |
ANSI与Unicode互转
ANSI转Unicode用MultiByteToWideChar
:
1 | INT MultiByteToWideChar( |
例如:
1 | LPCSTR lpMultiByteStr = "xxx"; |
Unicode转ANSI用WideCharToMultiByte
,参数同上,后面多出来那俩就NULL就行。
1 | INT WideCharToMultiByte( |
这里不写了。
结构体对齐
对齐颗粒度可手动设置为1、2、4、8,例如4时:
1 |
|
想用系统默认就填show,然后警告里会提示,Win32是8,Win64是16。
窗口基础
概览
直接用Visual Studio自带模板即可,打开差不多就这样:
1 | // WindowsProject1.cpp : 定义应用程序的入口点。 |
上面这个加了些东西,导致不适合上手,删去快捷键、菜单、关于,程序比较简单了:
1 |
|
注册窗口类
用这个函数:
1 | ATOM WINAPI RegisterClassEx( |
分析WNDCLASSEX这个结构:
1 | wcex.cbSize = sizeof(WNDCLASSEX); |
图标和光标的加载方式:
1 | HICON WINAPI LoadIcon( |
系统预定义图标:
1 | IDI_APPLICATION/IDI_WINLOGO |
系统预定义光标:
1 | IDC_APPSTARTING |
背景画刷用GetStockObject
获取系统预定义背景画刷:
1 | HGDIOBJ GetStockObject( |
预定义的背景画刷在这儿就不写了,太多了。
创建窗口
创建窗口,并产生WM_CREATE消息:
1 | HWND WINAPI CreateWindowEx( |
实现:
1 | HWND hWnd = CreateWindowEx(0,szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 180, NULL,NULL, hInstance, NULL); |
窗口显示与刷新
显示窗口,并产生WM_SIZE、WM_SHOWWINDOW消息:
1 | BOOL WINAPI ShowWindow( |
刷新窗口客户区,产生WM_PAINT消息:
1 | BOOL WINAPI UpdateWindow( |
实例:
1 | ShowWindow(hWnd, nCmdShow); |
消息循环
从消息队列中获取消息:
1 | BOOL WINAPI GetMessage( |
MSG结构:
1 | typedef struct tagMSG { |
其中POINT结构为:
1 | typedef struct tagPOINT { |
将按键信息(按下WM_KEYUP、抬起WM_KEYDOWN)转换为字符消息(WM_CHAR),并将字符消息发送到调用线程的消息队列,下次调用GetMessage
时获取这个字符信息:
1 | BOOL WINAPI TranslateMessage( |
把GetMessage
获取的消息分发送到窗口:
1 | LRESULT WINAPI DispatchMessage( |
例子:
1 | MSG msg; |
窗口过程
名字随便起,但定义这样:
1 | LRESULT CALLBACK WindowProc( |
WM_CREATE消息,在CreateWindowEx
创建窗口时发送:
1 | case WM_CREATE: { |
当单击窗口关闭按钮时,产生WM_CLOSE消息,用DestroyWindow
完成窗口清理工作并产生WM_DESTROY消息。处理WM_DESTROY消息时用PostQuitMessage
并产生WM_QUIT消息,GetMessage
获取WM_QUIT消息后程序退出消息循环并将控制权返回给系统。
1 | VOID WINAPI PostQuitMessage( |
例如:
1 | case WM_DESTROY: { |
对于其他剩余不关心的消息的处理,用DefWindowProc
来处理就好了。
1 | LRESULT WINAPI DefWindowProc( |