课题需要,要用MFC,简单记下学习知识点。
int WINAPI MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
WINAPI 为宏定义 #define WINAPI __stdcall
LPCTSTR 是自定义数据类型,等价于 const char *
凡是以 “P” 开头的都是指针(pointer)类型("LP"是老式写法)
Windows 数据类型名命名的规律
无符号类型:一般是以“U”开头,比如“INT”对应的“UINT”。
指针类型:其指向的数据类型前加“LP”或“P”,比如指向 DWORD 的指针类型为“LPDWORD”和“PDWORD”。
句柄类型:以“H”开头。比如,HWND 是window(WND简写)也就是窗口的句柄,菜单(MENU)类型对应的句柄类型为 “HMENU” 等等。
typedef int INT; /* 整形 */
typedef unsigned int UINT; /* 无符号整形 */
typedef unsigned int *PUINT; /* 无符号整形指针 */
typedef int BOOL; /* 布尔类型 */
typedef unsigned char BYTE; /* 字节 */
typedef unsigned short WORD; /* WORD (无符号短整型) */
typedef unsigned long DWORD; /* DOUBLE WORD (无符号长整形)*/
typedef float FLOAT; /* 浮点型 */
typedef FLOAT *PFLOAT; /* 指向float类型指针 */
typedef BOOL near *PBOOL; /* 指向布尔类型指针 */
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE; /* 指向字节类型指针 */
typedef BYTE far *LPBYTE;
typedef int near *PINT; /* 整形指针 */
typedef int far *LPINT;
typedef WORD near *PWORD; /* 指向WORD类型的指针 */
typedef WORD far *LPWORD;
typedef long far *LPLONG; /* 指向长整形的指针 */
typedef DWORD near *PDWORD; /* 指向DWORD类型的指针 */
typedef DWORD far *LPDWORD;
typedef void far *LPVOID; /* 指向void类型的指针 */
typedef CONST void far *LPCVOID; /* 指向void类型的常指针 */
宽字符与Unicode
在C语言中,我们使用char来定义字符,占用一个字节,最多只能表示128个字符,也就是ASCII码中的字符。计算机起源于美国,char 可以表示所有的英文字符,在以英语为母语的国家完全没有问题。
但是世界上存在很多不同的语言,例如汉语、汉语、日语等有成千上万个字符,需要用多个字节来表示,称之为宽字符(Wide Character)。Unicode 是宽字符编码的一种,已经被现代计算机指定为默认的编码方式,Windows 2000以后的操作系统,包括Windows 2000、XP、Vista、Win7、Win8、Win10、Windows Phone、Windows Server 等(它们统称为 Windows NT)都从底层支持Unicode,存取效率比 char 要高。
#include <stdio.h>
#include<iostream>
#include <wchar.h>
int main() {
char ch = 'A';
wchar_t wch = 'A';
char str[] = "C语言中文网";
wchar_t wstr[] = L"C语言中文网";
printf("ch=%d, wch=%d, str=%d, wstr=%d\n", sizeof(ch), sizeof(wch), sizeof(str), sizeof(wstr));
system("pause");
return 0;
}
运行结果:
ch=1, wch=2, str=12, wstr=14
wstr 之所以比 str 多两个字节是因为:字符 'C' 占用两个字节,字符串结束标志 '\0' 也占用两个字节。
句柄:
在Windows编程中,不同窗口、控件、图像等都对应一个唯一的数字(初学者可以理解为 ID),称为句柄(Handle)。通过句柄,程序可以获取对应资源的各种信息,也可以使用、修改、删除该资源。
消息结构体
消息其实是一个结构体,名字为 MSG,定义为:
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;
一个完整的Windows程序框架:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
) {
static TCHAR szClassName[] = TEXT("HelloWin"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; //窗口类
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景画刷
wndclass.lpszMenuName = NULL; //窗口菜单
wndclass.lpszClassName = szClassName; //窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口类的名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
);
//显示窗口
ShowWindow(hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow(hwnd);
/**********第③步:消息循环**********/
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); //翻译消息
DispatchMessage(&msg); //分派消息
}
return msg.wParam;
}
/**********第④步:窗口过程**********/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hdc; //设备环境句柄
PAINTSTRUCT ps;
RECT rect;
switch (message) {
//窗口绘制消息
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(
hdc,
TEXT("你好,欢迎来到C语言中文网"),
-1,
&rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER
);
EndPaint(hwnd, &ps);
return 0;
//窗口销毁消息
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}