目录:
1:MessageBox -------------------------------- 1
2:MessageBox ---------------------------------4
3:MessageBox -------------------------------- 6
4:ShowWindow ---------------------------------9
5: UpdateWindow__更新窗口 -------------------------11
6:MSG 消息结构 ----------------------------------11
7: GetMessage ----------------------------------12
8:TranslateMessage --------------------------------13
9: DispatchMessage --------------------------------14
10:PAINTSTRUCT 结构 -------------------------------14
11:RECT 结构 ----------------------------------15
12:BeginPaint ----------------------------------16
13:GetClientRect ----------------------------------17
14:DrawText ----------------------------------17
15:EndPaint --------------------------------- 20
16:PostQuitMessage -------------------------------21
17:DefWindowProc -------------------------------22
18: DestroyWindow ------------------------------- 23
19:TextOut --------------------------------- 23
20:GetTextAlign --------------------------------- 24
21:SetTextAlign -------------------------------- 26
22:wsprintf ----------------------------------- 28
23:StringCchPrintf ------------------------------ 28
24:strlen ------------------------------------30
25:SUCCEEDED 和FAILED 宏 ------------------------ 31
26:StringCchLength ------------------------------ 31
27:StringCchCat -------------------------------- 33
28: lstrcat ---------------------------------- 34
29:StringCchCopy ------------------------------- 35
30:lstrcpy ------------------------------------ 36
31:GET_X_LPARAM和 GET_Y_LPARAM 宏 --------------- 37
32:TEXTMETRIC 结构 ----------------------------- 37
33: GetTextMetrics ---------------------------- 39
34:GetSystemMetrics ----------------------------- 40
35:SetScrollRange ----------------------------- 46
36:GetScrollPos ----------------------------- 47
37:GetScrollRange ------------------------------- 48
38: LOWORD 和HIWORD 宏 --------------------------50
39: WM_SIZE 消息 ------------------------------- 50
40:WM_VSCROLL 消息 ----------------------------- 51
41:WM_HSCROLL 消息 ------------------------------- 52
42:InvalidateRect -------------------------------- 54
43:SCROLLINFO 结构 ------------------------------- 55
44:SetScrollInfo -------------------------------- 56
45: GetScrollInfo -------------------------------- 57
46:ScrollWindow -------------------------------- 59
47:ScrollWidnowEx --------------------------------- 66
48:RGB 宏 --------------------------------------- 68
49:SetPixel -------------------------------------- 69
50:GetRValue、GetGValue和 GetBValue 宏 ------------ 70
51:GetPixel --------------------------------------- 71
52:SetPixelV ------------------------------------- 72
53:GetDC ---------------------------------------- 73
54:ReleaseDC -------------------------------------- 74
55: GetWindowDC --------------------------------- 75
56:CreateDC ------------------------------------- 76
57:CreateCompatibleDC ----------------------------- 77
58:CreateMetaFile -------------------------------- 78
59: CloseMetaFile -------------------------------- 79
60:MoveToEx -------------------------------------- 79
61:LineTo --------------------------------------- 80
62:POINT 结构 ----------------------------------- 81
63:GetCurrentPositionEx --------------------------- 82
64:Polyline -------------------------------------- 82
65:PolylineTo ----------------------------------- 83
66:PolyPolyline --------------------------------- 84
67:GetDeviceCaps ---------------------------------- 85
68:PolyBezier ------------------------------------ 91
69: PolyBezierTo --------------------------------- 92
70:Rectangle -------------------------------------- 93
71:Ellipse --------------------------------------- 94
72:RoundRect -------------------------------------- 95
73:Arc -------------------------------------------96
74:Chord ---------------------------------------- 98
75:Pie -----------------------------------------100
76:GetStockObject -------------------------------- 101
77:SelectObject -----------------------------------103
78:CreatePen ------------------------------------ 105
79:LOGPEN 结构 ----------------------------------- 106
80: CreatePenIndirect ---------------------------- 107
81: DeleteObject --------------------------------- 108
82:GetObject ------------------------------------- 109
83: GetCurrentObject ----------------------------- 110
84:SetDCBrushColor ------------------------------- 111
85:SetDCPenColor---------------------------------- 112
86: GetDCBrushColor------------------------------- 113
87:GetDCPenColor -------------------------------- 114
88:SetBkColor ----------------------------------- 115
89:SetBkMode ------------------------------------ 116
90:SetROP2 ------------------------------------- 116
91:GetROP2 -------------------------------------- 118
92:Polygon ------------------------------------- 119
93:PolyPolygon ---------------------------------- 120
94:SetPolyFillMode ------------------------------ 121
95:GetBkMode ------------------------------------ 123
96: GetPolyFillMode ----------------------------- 124
97:CreateSolidBrush ----------------------------- 124
98:LOGBRUSH 结构 -------------------------------- 125
99:CreateHatchBrush ------------------------------ 127
1:MessageBox
函数功能:
MessageBox 函数用于显示一个模态对话框,其中包含一个系统图标、 一组按钮和一个简短的特定于应用程序消息,如状态或错误的信息。
消息框中返回一个整数值,该值指示用户单击了哪个按钮。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
int WINAPI MessageBox(
_In_opt_ HWNDhWnd,
_In_opt_ LPCTSTRlpText,
_In_opt_ LPCTSTRlpCaption,
_In_ UINT uType
);
参数解析:
参数 | 含义 |
hWnd | 1. 该消息框的父窗口句柄 |
lpText | 消息框的内容 |
lpCaption | 消息框的标题 |
uType | 1. 指定一个决定对话框的内容和行为的位标志集 |
uType参数定义解析
按钮 | 含义 |
MB_OK | 默认值,有一个“确认”按钮在里面 |
MB_YESNO | 有“是”和“否”两个按钮在里面 |
MB_ABORTRETRYIGNORE | 有“中止”,“重试”和“跳过”三个按钮在里面 |
MB_YESNOCANCEL | 有“是”,“否”和“取消”三个按钮在里面 |
MB_RETRYCANCEL | 有“重试”和“取消”两个按钮在里面 |
MB_OKCANCEL | 有“确定”和“取消”两个按钮在里面 |
图标 | 含义 |
MB_ICONEXCLAMATION | 一个惊叹号出现在消息框: |
MB_ICONWARNING | 一个惊叹号出现在消息框(同上) |
MB_ICONINFORMATION | 一个圆圈中小写字母i组成的图标出现在消息框: |
MB_ICONASTERISK | 一个圆圈中小写字母i组成的图标出现在消息框(同上) |
MB_ICONQUESTION | 一个问题标记图标出现在消息框: |
MB_ICONSTOP | 一个停止消息图标出现在消息框: |
MB_ICONERROR | 一个停止消息图标出现在消息框(同上) |
MB_ICONHAND | 一个停止消息图标出现在消息框(同上) |
默认按钮 | 含义 |
MB_DEFBUTTON1 | 指定第一个按钮为默认按钮 |
MB_DEFBUTTON2 | 指定第二个按钮为默认按钮 |
MB_DEFBUTTON3 | 指定第三个按钮为默认按钮 |
MB_DEFBUTTON4 | 指定第四个按钮为默认按钮 |
消息框形态 | 含义 |
MB_APPLMODAL | 1. 在 hWnd 参数标识的窗口中继续工作以前,用户一定响应消息框 |
MB_SYSTEMMODAL | 1. 除了消息框有 WB_EX_TOPMOST 类型,否则 MB_APPLMODAL 和 MB_SYSTEMMODAL 一样 |
MB_TASKMODAL | 1. 如果参数 hWnd 为 NULL 的话,那么除了所有属于当前线程高层次的窗口失效外,MB_TASKMODAL 和 MB_APPLMODAL 一样 |
其他标志 | 含义 |
MB_DEFAULT_DESKTOP_ONLY | 1. 接收输入的当前桌面一定是一个默认桌面,否则函数调用失败 |
MB_HELP | 1. 把一个 Help 按钮增加到消息框 |
MB_RIGHT | 文本为右对齐 |
MB_RTLREADING | 用在 Hebrew 和 Arabic 系统中从右到左的顺序显示消息和大写文本 |
MB_SETFOREGROUND | 1. 消息框变为前景窗口 |
MB_TOPMOST | 消息框用 WS_EX_TOPMOST 窗口类型来创建 MB_SERVICE_NOTIFICATION |
返回值:
返回值 | 含义 |
IDOK | 用户按下了“确认”按钮 |
IDCANCEL | 用户按下了“取消”按钮 |
IDABORT | 用户按下了“中止”按钮 |
IDRETRY | 用户按下了“重试”按钮 |
IDIGNORE | 用户按下了“忽略”按钮 |
IDYES | 用户按下了“是”按钮 |
IDNO | 用户按下了“否”按钮 |
举例:
#include <windows.h>
int WINAPI WinMain(HINSTANCEhInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
MessageBox(NULL, TEXT("这是我在鱼C学的第一个程序!"), TEXT("打招呼"), MB_OKCANCEL| MB_ICONQUESTION | MB_DEFBUTTON2);
return 0;
}
1:MessageBox
Windows的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数)。
在创建应用程序窗口之前,必须调用 RegisterClass 函数来注册窗口类。该函数只需要一个参数,即指向 WNDCLASS 窗口类的指针。因为 WNDCLASS 类包含了窗口所拥有的基本属性。
结构原型:
typedef struct tagWNDCLASSW {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR*NPWNDCLASSW, FAR *LPWNDCLASSW;
成员解析:
成员 | 含义 |
style | 指定窗口类型,各种“类风格”(详见下方↓)可以使用按位或操作符组合起来 |
lpfnWndProc | 指定窗口过程(必须是回调函数) |
cbClsExtra | 预留的额外空间,一般为 0 |
cbWndExtra | 预留的额外空间,一般为 0 |
hInstance | 应用程序的实例句柄 |
hIcon | 为所有基于该窗口类的窗口设定一个图标 |
hCursor | 为所有基于该窗口类的窗口设定一个鼠标指针 |
hbrBackground | 指定窗口背景色 |
lpszMenuName | 指定窗口菜单 |
lpszClassName | 指定窗口类名 |
style 类风格解析
类风格 | 含义 |
CS_VREDRAW | 移动或者调整窗口的高度(垂直方向)时,重绘整个窗口 |
CS_HREDRAW | 移动或者调整窗口的宽度(水平方向)时,重绘整个窗口 |
CS_DBLCLKS | 当用户光标在窗口内双击时,允许发送双击消息给窗口过程 |
CS_OWNDC | 给予每个窗口实例分配一个唯一的 DC(注意,尽管这样是很方便,但它必须慎重使用,因为每个 DC 大约要占 800 个字节的内存) |
CS_CLASSDC | 该窗口类的所有窗口实例都共享一个窗口类 DC |
CS_PARENTDC | 1. 将子窗口的裁剪区域设置到父窗口的 DC 中去,这样子窗口便可以在父窗口上绘制自身。(注意,这是子窗口还是从系统缓存中获取 DC,而不是使用父窗口的 DC。) |
CS_NOCLOSE | 禁止系统菜单的关闭选项 |
CS_SAVEBITS | 1. 以位图形式保存被该窗口遮挡的屏幕部分,这样当给窗口移动以后,系统便可以用该保存的位图恢复屏幕移动的相应部分,从而系统不用向被该窗口遮挡的窗口发送 WM_PAINT 消息 |
CS_BYTEALIGNCLIENT | 在字节边界上(在 x 方向上)定位窗口的用户区域的位置 |
CS_BYTEALIGNWINDOW | 在字节边界上(在 x 方向上)定位窗口的位置 |
CS_GLOBALCLASS | 1. 当调用 CreateWindow 或 CreateWindowEx 函数来创建窗口时允许它的 hInstance 参数和注册窗口类时传递给 RegisterClass 的 hInstance 参数不同 |
1:MessageBox
函数功能:
CreateWindow 函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类,窗口标题,窗口风格,以及窗口的初始位置及大小(可选的)。函数也指该窗口的父窗口或所属窗口(如果存在的话),及窗口的菜单。
若要使用除 CreateWindow 函数支持的风格外的扩展风格,则使用 CreateWindowEx 函数代替 CreateWindow 函数。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTRlpClassName, // 窗口类名称
_In_opt_ LPCTSTRlpWindowName, // 窗口标题
_In_ DWORD dwStyle, // 窗口风格,或称窗口格式
_In_ int x, // 初始 x 坐标
_In_ int y, // 初始 y 坐标
_In_ int nWidth, // 初始 x 方向尺寸
_In_ int nHeight, // 初始 y 方向尺寸
_In_opt_ HWNDhWndParent, // 父窗口句柄
_In_opt_ HMENUhMenu, // 窗口菜单句柄
_In_opt_ HINSTANCEhInstance, // 程序实例句柄
_In_opt_ LPVOIDlpParam // 创建参数
);
参数解析:
参数 | 含义 |
lpClassName | 1. 窗口类名称,可以是一个指向 NULL 结束的字符串或一个整型数值 |
lpWindowName | 1. 窗口标题,一个指向 NULL 结束的字符串指针 |
dwStyle | 指定创建窗口的风格(详见下方↓) |
x | 1. 指定窗口的初始水平位置(x 坐标) |
y | 1. 指定窗口的初始垂直位置(y 坐标) |
nWidth | 1. 以设备单元指明窗口的宽度 |
nHeight | 1. 以设备单元指明窗口的高度 |
hWndParent | 1. 指向被创建窗口的父窗口或所有者窗口的句柄 |
hMenu | 1. 指向窗口菜单句柄,或依据窗口风格指明一个子窗口标识 |
hInstance | 与窗口相关联的模块实例的句柄 |
lpParam | 1. 指向一个值的指针,该值传递给窗口 WM_CREATE 消息。该值通过在 IParam 参数中的 CREATESTRUCT 结构传递 |
dwStyle 窗口风格解析
窗口风格 | 含义 |
WS_BORDER | 创建一个带边框的窗口 |
WS_CAPTION | 创建一个有标题框的窗口(包含了 WS_BODER 风格) |
WS_CHILD | 创建一个子窗口,这个风格的窗口不能拥有菜单也不能与 WS_POPUP 风格合用 |
WS_CHILDWINDOW | 与 WS_CHILD 相同 |
WS_CLIPCHILDREN | 当在父窗口内绘图时,排除子窗口区域,在创建父窗口时使用这个风格 |
WS_CLIPSIBLINGS | 1. 排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到 WM_PAINT 消息时,WS_CLIPSIBLINGS 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口 |
WS_DISABLED | 1. 创建一个初始状态为禁止的子窗口,一个禁止状态的窗口不能接受来自用户的输入信息 |
WS_DLGFRAME | 创建一个带对话框边框风格的窗口,这种风格的窗口不能带标题条 |
WS_GROUP | 1. 指定一组“控制窗口”的第一个“控制窗口” |
WS_HSCROLL | 创建一个有水平滚动条的窗口 |
WS_ICONIC | 创建一个初始状态为最小化状态的窗口,与 WS_MINIMIZE 风格相同 |
WS_MAXIMIZE | 创建一个初始状态为最大化状态的窗口 |
WS_MAXIMIZEBOX | 创建一个具有最大化按钮的窗口,该风格不能与 WS_EX_CONTEXTHELP 风格同时出现,同时必须指定 WS_SYSMENU 风格 |
WS_MINIMIZE | 创建一个初始状态为最小化状态的窗口,与 WS_ICONIC 风格相同 |
WS_MINIMIZEBOX | 创建一个具有最小化按钮的窗口,该风格不能与 WS_EX_CONTEXTHELP 风格同时出现,同时必须指定 WS_SYSMENU 风格 |
WS_OVERLAPPED | 产生一个层叠的窗口,一个层叠的窗口有一个标题条和一个边框,与 WS_TILED 风格相同 |
WS_OVERLAPPEDWINDOW | 相当于(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX),与 WS_TILEDWINDOW 风格相同 |
WS_POPUP | 创建一个弹出式窗口,该风格不能与 WS_CHILD 风格同时使用。 |
WS_POPUPWINDOW | 相当于(WS_POPUP | WS_BORDER | WS_SYSMENU),但 WS_CAPTION 和 WS_POPUPWINDOW 必须同时设定才能使窗口某单可见 |
WS_SIZEBOX | 创建一个可调边框的窗口,与 WS_THICKFRAME 风格相同 |
WS_SYSMENU | 创建一个在标题条上带有窗口菜单的窗口,必须同时设定 WS_CAPTION 风格 |
WS_TABSTOP | 1. 创建一个“控制窗口”,在用户按下 Tab 键时可以获得键盘焦点。 |
WS_THICKFRAME | 创建一个具有可调边框的窗口,与 WS_SIZEBOX 风格相同 |
WS_TILED | 产生一个层叠的窗口,一个层叠的窗口有一个标题和一个边框,与 WS_OVERLAPPED 风格相同 |
WS_TILEDWINDOW | 相当于(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX),与 WS_OVERLAPPEDWINDOW 风格相同 |
WS_VISIBLE | 创建一个初始状态为可见的窗口 |
WS_VSCROLL | 创建一个有垂直滚动条的窗口 |
返回值:
1. 如果函数成功,返回值为新窗口的句柄;
2. 如果函数失败,返回值为 NULL。
4:ShowWindow
函数功能:
ShowWindow 函数用于设置指定窗口的显示状态。
应用程序第一次调用 ShowWindow 时,应该使用 WinMain 函数的 nCmdshow 参数作为它的 nCmdShow 参数。在随后调用 ShowWindow 函数时,必须使用下列显示方式中的一个给定值,而不是由 WinMain 函数的 nCmdSHow 参数指定的值。
API 函数原型:
BOOL WINAPI ShowWindow(
_In_ HWNDhWnd,
_In_ intnCmdShow
);
参数解析:
参数 | 含义 |
hWnd | 窗口句柄 |
nCmdShow | 控制窗口如何显示,如果发送应用程序的程序提供了 STARTUPINFO 结构,则应用程序第一次调用 ShowWindow 时该参数被忽略。否则,在第一次调用 ShowWindow 函数时,该值应为在函数 WinMain 中 nCmdShow 参数。 |
在随后的调用中,nCmdShow 参数可以为下列值之一:
显示方式 | 含义 |
SW_FORCEMINIMIZE | 1. 最小化窗口,即使拥有窗口的线程被挂起也会最小化 |
SW_HIDE | 隐藏窗口并激活其他窗口 |
SW_MAXIMIZE | 最大化指定的窗口 |
SW_MINIMIZE | 最小化指定的窗口并且激活在 Z 序中的下一个顶层窗口 |
SW_RESTORE | 1. 激活并显示窗口 |
SW_SHOW | 在窗口原来的位置以原来的尺寸激活并显示窗口 |
SW_SHOWDEFAULT | 依据在 STARTUPINFO 结构中指定的 SW_FLAG 标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给 CreateProcess 函数的。 |
SW_SHOWMAXIMIZED | 激活窗口并将其最大化 |
SW_SHOWMINIMIZED | 激活窗口并将其最小化 |
SW_SHOWMINNOACTIVE | 1. 窗口最小化 |
SW_SHOWNA | 1. 以窗口原来的位置以原来的尺寸显示窗口 |
SW_SHOWNOACTIVATE | 1. 以窗口最近一次的位置和尺寸显示窗口 |
SW_SHOWNORMAL | 1. 激活并显示一个窗口 |
返回值:
1. 如果窗口之前可见,则返回值为非 0;
2. 如果窗口之前被隐藏,则返回值为 0。
5: UpdateWindow__更新窗口
函数功能:
UpdateWindow 函数绕过应用程序的消息队列,直接发送 WM_PAINT 消息给指定窗口的窗口过程。
如果窗口更新的区域不为空,UpdateWindow 函数通过发送一个 WM_PAINT 消息来更新指定窗口的客户区。如果更新区域为空,则不发送消息。
API 函数原型:
BOOL UpdateWindow(
_In_ HWNDhWnd
);
参数解析:
参数 | 含义 |
hWnd | 指定要更新的窗口的句柄. |
返回值:
1. 如果函数调用成功,返回值为非 0;
2. 如果函数调用不成功,返回值为 0。
UpdateWindow, WindowsSDK, WindowsAPI, SDK教程, UpdateWindow详解
6:MSG 消息结构
MSG 消息结构
在 Windows 程序中,消息是由 MSG 结构体来表示的。
结构原型:
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG, *LPMSG;
成员解析:
成员 | 含义 |
hwnd | 指定接收消息的窗口句柄 |
message | 1. 消息的标识符,由于数值不便于记忆,所以 Windows 将消息对应的数值定义为 WM_XXX 宏的形式 |
wParam | 指定消息的附加消息,确切的含义取决于消息成员的值 |
lParam | 指定消息的附加消息,确切的含义取决于消息成员的值 |
time | 该消息被投放到消息队列的时间 |
pt | 当消息被投放到消息队列的时,鼠标位于屏幕中的位置 |
7: GetMessage
函数功能:
GetMessage 函数的作用是从当前线程的消息队列里取出一个消息并填入 MSG结构 中。
该函数只能获取调用线程的消息,不能获得其他线程的消息。成功获取消息后,线程将从消息队列中删除该消息。如果消息队列为空,函数会一直等待直到有消息到来才有返回值。
API 函数原型:
BOOL WINAPI GetMessage(
_Out_ LPMSG lpMsg,
_In_opt_ HWNDhWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax
);
参数解析:
参数 | 含义 |
lpMsg | 指向 MSG 结构的指针 |
hWnd | 1. 需要检索消息的窗口的句柄,该窗口必须属于当前线程 |
wMsgFilterMin | 指定被检索的最小消息值的整数 |
wMsgFilterMax | 指定被检索的最大消息值的整数 |
返回值:
1. 如果函数取得 WM_QUIT 之外的其他消息,返回非零值;
2. 如果函数取得 WM_QUIT 消息,返回值是零;
3. 如果出现了错误,返回值是 -1。
8:TranslateMessage
函数功能:
TranslateMessage 函数将虚拟键消息转换为字符消息,字符消息被寄送到当前线程的消息队列里。
当下一次线程调用函数 GetMessage 或PeekMessage 时被读出。
API 函数原型:
BOOL WINAPI TranslateMessage(
_In_ constMSG *lpMsg
);
参数解析:
参数 | 含义 |
lpMsg | 指向含有消息的 MSG 结构的指针 |
返回值:
1. 如果消息被转换(字符消息被寄送到当前线程的消息队列里)则返回非零值;
2. 如果消息是 WM_KEYDOWN,WM_KEYUPWM_SYSKEYDOWN 或 WM_SYSKEYUP,返回非零值,不考虑转换;
3. 如果消息没被转换(字符消息没被寄送到调用线程的消息队列里)则返回值是零。
9: DispatchMessage
函数功能:
DispatchMessage 函数分派一个消息给窗口过程(回调函数),通常该消息从 GetMessage 函数获得。Windows 的控制权在该函数交给了应用程序。
API 函数原型:
LRESULT WINAPIDispatchMessage(
_In_ constMSG *lpmsg
);
参数解析:
参数 | 含义 |
lpmsg | 指向含有消息的 MSG结构 的指针 |
返回值:
1. 返回值是窗口过程返回的值;
2. 尽管返回值的含义依赖于被分派的消息,但返回值通常被忽略。
备注:
1. MSG 结构必须包含有效的消息值。
2. 如果参数 lpmsg 指向一个 WM_TIMER 消息,并且 WM_TIMER 消息的参数 lParam 不为 NULL,则调用 lParam 指向的函数,而不是调用窗口程序。
10:PAINTSTRUCT 结构
PAINTSTRUCT 结构包含一些窗口过程用来对客户区进行绘制的信息。
结构原型:
typedef struct tagPAINTSTRUCT{
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTErgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
成员解析:
成员 | 含义 |
hdc | 用于绘制的设备环境句柄 |
fErase | 1. 表示背景是否必须擦除,如果为非零值则擦除背景,否则不擦除背景 |
rcPaint | 一个 RECT结构,指定左上角和右下角的坐标确定一个要绘制的矩形范围 |
fRestore | 系统保留 |
fIncUpdate | 系统保留 |
rgbReserved | 系统保留 |
11:RECT 结构
RECT 结构定义了一个矩形的左上角和右下角的坐标。
结构原型:
typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT;
成员解析:
成员 | 含义 |
left | 指定矩形左上角的 x 坐标 |
top | 指定矩形左上角的 y 坐标 |
right | 指定矩形右下角的 x 坐标 |
bottom | 指定矩形右下角的 y 坐标 |
12:BeginPaint
函数功能:
BeginPaint 函数为指定窗口进行绘画工作的准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT结构中。
API 函数原型:
HDC BeginPaint(
_In_ HWND hwnd,
_Out_ LPPAINTSTRUCTlpPaint
);
参数解析:
参数 | 含义 |
hwnd | 需要重新绘制的窗口句柄 |
lpPaint | 指向 PAINTSTRUCT结构的指针,用于存放绘画相关的信息 |
返回值:
1. 如果函数成功,返回值是指定窗口的“显示设备描述表”句柄;
2. 如果函数失败,返回值是 NULL,表明没有得到显示设备的内容。
备注:
1. BeginPaint 函数自动设置显示设备内容的剪切区域,而排除任何更新区域外的区域。该更新区域可以通过 InvalidateRect 或 InvalidateRgn 函数设置,也可以是系统在改变大小、移动、创建、滚动后设置的,或者其他的影响客户区的操作来设置的。
2. 如果更新区域被标记为可擦除的,BeginPaint 发送一个 WM_ERASEBKGND 消息给窗口。
3. 一个应用程序除了响应 WM_PAINT 消息外,不应该调用 BeginPaint。
4. 每次调用 BeginPaint 都应该有相应的 EndPaint 函数。
5. 如果被绘画的客户区中有一个 caret(caret:插入符。是窗口客户区中的一个闪烁的线,块,或位图。插入符通常表示文本或图形将被插入的地方。即一闪一闪的光标),BeginPaint 自动隐藏该符号,而保证它不被擦除。
6. 如果窗口类有一个背景刷,BeginPaint 使用这个刷子来擦除更新区域的背景。
13:GetClientRect
函数原型:
GetClientRect 函数用于获取窗口客户区的坐标,客户区坐标指定客户区的左上角和右下角。
由于客户区坐标是相对窗口客户区的左上角而言的,因此左上角坐标为(0,0)
API 函数原型:
BOOL WINAPI GetClientRect(
_In_ HWND hWnd,
_Out_ LPRECTlpRect
);
参数解析:
参数 | 含义 |
hWnd | 需要获取客户区坐标的窗口句柄 |
lpRect | 1. 指向 RECT结构的指针,该结构有四个成员,分别为 left、top、right 和 bottom |
返回值:
1. 如果函数成功,返回值是非 0;
2. 如果函数失败,返回值是 0。
14:DrawText
函数原型:
DrawText 函数在指定的矩形里写入格式化的正文,根据指定的方法对正文格式化(扩展的制表符,字符对齐、折行等)。
需要指定更多的格式选项,可以使用 DrawTextEx 函数。
API 函数原型:
int DrawText(
_In_ HDC hDC,
_Inout_ LPCTSTRlpchText,
_In_ int nCount,
_Inout_ LPRECTlpRect,
_In_ UINT uFormat
);
参数解析:
参数 | 含义 |
hDC | 指定“显示设备描述表”句柄 |
lpchText | 1. 指向将被写入的字符串的指针,如果参数 nCount 是 -1,则字符串必须是以 \0 结束的 |
nCount | 1. 指向字符串中的字符数 |
lpRect | 指向 RECT结构的指针,其中包含文本将被置于其中的矩形的信息(按逻辑坐标) |
uFormat | 1. 指定格式化文本的方法 |
uFormat 参数各种标志解析
标志 | 含义 |
DT_BOTTOM | 对齐文字到矩形的底部,当且仅当设置了 DT_SINGLELINE 标志才有效 |
DT_CALCRECT | 1. 这个参数决定矩形的宽度和高度 |
DT_CENTER | 文本水平居中显示 |
DT_EDITCONTROL | 将拥有多行编辑控件的正文显示特性(尤其是平均字符宽度的计算方法,并且不会显示不可见的最后一行) |
DT_END_ELLIPSIS | 1. 对于显示的文本,如果结束的字符串的范围不在矩形内,它会被截断并以省略号标识 |
DT_EXPANDTABS | 1. 扩展制表符,每个制表符的缺省字符数是 8 |
DT_EXTERNALLEADING | 在行的高度里包含字体的外部标头(通常外部标头不被包含在正文行的高度里) |
DT_HIDEPREFIX | 1. 忽略正文中的前缀字符(&),并且前缀字符后面的字母不会出现下划线,其它前缀字符的调用方式不受影响 |
DT_INTERNAL | 用系统字体来计算正文尺寸 |
DT_LEFT | 正文左对齐 |
DT_MODIFYSTRING | 1. 允许系统修改给定的字符串来匹配显示的正文 |
DT_NOCLIP | 无裁剪绘制,使用 DT_NOCLIP 可以提高 DrawText 的效率 |
DT_NOFULLWIDTHCHARBREAK | 1. 在宽字符的字符串中防止行断开,因此折行规则相当于单字符的字符串 |
DT_NOPREFIX | 1. 关闭前缀字符的处理(通常 DrawText 解释 & 为给其后的字符加下划线,解释 && 为显示单个 &) |
DT_PATH_ELLIPSIS | 1. 对于过长的正文,自动替换字符串中间的字符为省略号(...),以确保结果能在合适的矩形内显示 |
DT_PREFIXONLY | 1. 仅仅在(&)前缀字符的位置下绘制一个下划线,但不绘制字符串中的任何其他字符 |
DT_RIGHT | 正文右对齐 |
DT_RTLREADING | 当设备环境的字体是希伯来文或阿拉伯文字体时,为双向正文安排从右到左的阅读顺序 |
DT_SINGLELINE | 显示正文的同一行,回车和换行符都不能换行 |
DT_TABSTOP | 1. 设置制表符,参数 uFormat 的 8~15 位(低位字中的高位字节)指定每个制表符的字符数,每个制表符的缺省字符数是 8 |
DT_TOP | 正文顶端对齐 |
DT_VCENTER | 使正文在矩形中垂直居中,当且仅当设置了 DT_SINGLELINE 标志才有效 |
DT_WORDBREAK | 1. 当一行中的字符将会延伸到由 lpRect 指定的矩形的边框时,此行自动地在单词之间断开 |
DT_WORD_ELLIPSIS | 截短不符合矩形的正文,并增加省略号(与 DT_END_ELLIPSIS 类似) |
返回值:
1. 如果函数调用成功,返回值是正文的高度(逻辑单位);
2. 如果指定了 DT_VCENTER 或 DT_BOTTOM,返回值是 lpRect -> top 到绘制的正文的底部的偏移值;
3. 如果函数调用失败,返回值是 0。
备注:
1. 函数 DrawText 用设备环境中的字体选择、正文颜色和背景颜色来写正文。
2. DrawText 裁剪正文,使之不会出现在指定矩形的外面,除非指定了 DT_NOCLIP。
3. 除非使用 DT_SINGLELINE 格式化,否则其余的格式都认为正文有多行。
4. 如果选择的字体对指定的矩形而言太大,DrawText 并不会试图去换成一种小字体。
5. 设备环境的正文对齐方式必须包括 TA_LEFT, TA_TOP 和 TA_NOUPDATECP 标志。
15:EndPaint
函数原型:
EndPaint 函数标记指定窗口的绘画过程结束。
这个函数在每次调用 BeginPaint 函数之后被调用(释放设备描述表),但仅仅在绘画完成以后。
API 函数原型:
BOOL EndPaint(
_In_ HWNDhWnd,
_In_ constPAINTSTRUCT *lpPaint
);
参数解析:
参数 | 含义 |
hWnd | 已经被重新绘制的窗口句柄 |
lpPaint | 指向 PAINTSTRUCT结构的指针,用于存放绘画相关的信息(该指针在调用 BeginPaint 时被赋值) |
返回值:
该函数返回值始终是非 0。
16:PostQuitMessage
函数原型:
PostQuitMessage 函数向系统表明有个线程有终止(退出)请求。这个函数通常用来响应WM_DESTROY 消息。
API 函数原型:
VOID WINAPI PostQuitMessage(
_In_ intnExitCode
);
参数解析:
参数 | 含义 |
nExitCode | 指定应用程序的退出代码,此值被用作 WM_QUIT 消息的 wParam 参数 |
返回值: 该函数没有返回值。
备注:
1. PostQuitMessage 函数的功能是发送一个 WM_QUIT 消息给线程的消息队列并立即返回。
2. 当线程从消息队列里取得 WM_QUIT 消息时,应当退出消息循环并将返回系统,返回给系统的退出值必须是消息WM_QUIT 的 wParam 参数(所以 WinMain 函数的返回值是 msg.wParam)。
17:DefWindowProc
函数功能:
DefWindowProc 函数调用缺省的窗口过程来处理那些窗口过程没有处理的任何消息,该函数是为了确保每个消息都被处理。
DefWindowProc函数传入和窗口过程同样的参数。
API 函数原型:
LRESULT WINAPI DefWindowProc(
_In_ HWNDhWnd,
_In_ UINTMsg,
_In_ WPARAMwParam,
_In_ LPARAMlParam
);
参数解析:
参数 | 含义 |
hWnd | 指定接收消息的窗口句柄 |
Msg | 1. 消息的标识符,由于数值不便于记忆,所以 Windows 将消息对应的数值定义为 WM_XXX 宏的形式 |
wParam | 指定消息的附加消息,确切的含义取决于消息成员的值 |
lParam | 指定消息的附加消息,确切的含义取决于消息成员的值 |
返回值:
1. 返回值就是消息处理结果,它取决于发送的消息。
18: DestroyWindow
函数功能:
DestroyWindow 用于销毁一个指定的窗口,该函数通过发送 WM_DESTROY 消息和 WM_NCDESTROY 消息使窗口无效并移除其键盘焦点。
DestroyWindow 函数还销毁窗口的菜单,清空线程的消息队列,销毁与窗口过程相关的定时器,解除窗口对剪贴板的拥有权,打断剪贴板器的查看链。
如果指定的窗口拥有子窗口或拥有其它窗口,该函数将自动先销毁其子窗口或所拥有的窗口,然后再销毁自身。
API 函数原型:
BOOL WINAPI DestroyWindow(
_In_ HWNDhWnd
);
参数解析:
参数 | 含义 |
hWnd | 指定将被销毁的窗口句柄 |
返回值:
1. 如果函数成功执行,返回值为非 0;
2. 如果函数执行失败,返回值为 0。
备注:
1. 一个线程不能使用本函数销毁别的线程创建的窗口。
2. 如果这个窗口是一个不具有 WS_EX_NOPARENTNOTIFY 样式的子窗口,则销毁窗口时将发WM_PARENTNOTIFY 消息给其父窗口。
19:TextOut
函数功能:
TextOut 函数使用当前选择的字体、背景颜色和文本颜色,将一个字符串绘画于窗口的指定位置。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL TextOut(
_In_ HDChdc,
_In_ intnXStart,
_In_ intnYStart,
_In_ LPCTSTRlpString,
_In_ intcchString
);
参数解析:
参数 | 含义 |
hdc | 设备环境句柄 |
nXStart | 指定用于字符串对齐的基准点的逻辑 x 坐标(有关基准点请看下边备注) |
nYStart | 指定用于字符串对齐的基准点的逻辑 y 坐标 |
lpString | 1. 指向将被绘制字符串的指针 |
cchString | lpString 字符串的长度(有多少个字符) |
返回值:
1. 如果函数调用成功,返回值为非 0;
2. 如果函数调用失败,返回值为 0。
备注:字符串对齐的基准点取决于当前的文本对齐模式。应用程序可以通过调用 GetTextAlign 获得当前的文本对齐模式,通过调用SetTextAlign 修改该模式。
20:GetTextAlign
GetTextAlign 函数获得指定的设备环境下的文字对齐方式的设置。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
UINT GetTextAlign(
_In_ HDChdc
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
返回值:
1. 如果函数调用失败,返回值是 GDI_ERROR;
2. 如果函数调用成功,返回值是文字对齐标志的状态。
该返回值是下列值的组合:
值 | 含义 |
TA_BASELINE | 基准点在正文的基线上 |
TA_BOTTOM | 基准点在限定矩形的底边上(限定矩形的含义请看下边备注) |
TA_TOP | 基准点在限定矩形的顶边上 |
TA_CENTER | 基准点在限定矩形的中心水平对齐位置 |
TA_LEFT | 基准点在限定矩形的左边上 |
TA_RIGHT | 基准点在限定矩形的右边上 |
TA_RTLREADING | 1. 适用于中东 Windows 版本:正文从右到左的阅读顺序排列,与缺省的从左到右正好相反 |
TA_NOUPDATECP | 每次输出调用后当前状态不改变 |
TA_UPDATECP | 每次输出调用后当前状态改变 |
若当前字体有一条缺省的垂直基线(如Kanji),下列值用于取代 TA_BASELINE 和 TA_CENTER:
值 | 含义 |
VTA_BASELINE | 基准点在正文的基线上 |
VTA_CENTER | 基准点与限定矩形的中心垂直对齐 |
备注:
1. 默认值是 TA_LEFT, TA_TOP 和 TA_NOUPDATECP
2. 限定矩形是指能将正文字符串的所有字符单元限定于其中的矩形
3. 限定矩形的尺寸可通过调用 GetTextExtentPoint32 来获得
4. 文字对齐标志决定 TextOut 和 ExtTextOut 如何将正文字符串与基准点对齐
5. 文字对齐标志不必是单个的标志位,可以等于0
6. 标志必须按相关的组来检查,如下:
TA_LEFT, TA_RIGHT, andTA_CENTER
TA_BOTTOM, TA_TOP, and TA_BASELINE
TA_NOUPDATECP and TA_UPDATECP
如果当前字体有缺省的垂直基线,相关的标志如下所示:
TA_LEFT, TA_RIGHT, andVTA_BASELINE
TA_BOTTOM, TA_TOP, and VTA_CENTER
TA_NOUPDATECP and TA_UPDATECP
7. 要验证一个特定的标志在返回值中被设置,应用程序必须执行以下步骤:
(例子:如何设置文本对齐模式)
对该标志及其相关标志实施位OR操作;
对结果和返回值实施位AND操作;
检查结果值和标志是否相等。
21:SetTextAlign
函数功能:
SetTextAlign 函数为指定设备环境设置文字的对齐标志。
API 函数原型:
UINT SetTextAlign(
_In_ HDChdc,
_In_ UINTfMode
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
fMode | 1. 文本对齐标志 |
使用下面的列表中的掩码指定文本对齐方式:
值 | 含义 |
TA_BASELINE | 基准点在正文的基线上 |
TA_BOTTOM | 基准点在限定矩形的底边上(限定矩形的含义请看下边备注) |
TA_TOP | 基准点在限定矩形的顶边上 |
TA_CENTER | 基准点在限定矩形的中心水平对齐位置 |
TA_LEFT | 基准点在限定矩形的左边上 |
TA_RIGHT | 基准点在限定矩形的右边上 |
TA_NOUPDATECP | 1. 适用于中东 Windows 版本:正文从右到左的阅读顺序排列,与缺省的从左到右正好相反 |
TA_RTLREADING | 每次输出调用后当前状态不改变 |
TA_UPDATECP | 每次输出调用后当前状态改变 |
若当前字体有一条缺省的垂直基线(如Kanji),下列值用于取代 TA_BASELINE 和 TA_CENTER:
值 | 含义 |
VTA_BASELINE | 基准点在正文的基线上 |
VTA_CENTER | 基准点与限定矩形的中心垂直对齐 |
默认值是TA_LEFT, TA_TOP 和 TA_NOUPDATECP。
返回值:
1. 如果函数调用失败,返回值是 GDI_ERROR;
2. 如果函数调用成功,返回值是文字对齐方式的前一个设置。
备注:
1. 限定矩形是指能将正文字符串的所有字符单元限定于其中的矩形
2. TextOut 和 ExtTextOut 函数用文字对齐标志来将一个正文字符串定位于显示器或者其他设备
3. 该标志指定了基准点与限定正文的矩形的位置关系,基准点可以是当前位置,也可是传给正文输出函数的一个点
4. 设置左对齐文本的做好方法可以是如下:
SetTextAlign (hdc, GetTextAlign(hdc) & (~TA_CENTER))
或者
SetTextAlign (hdc,TA_LEFT | <other flags>)
你当然可以使用 SetTextAlign (hdc, TA_LEFT) 来达到这个目的,但是这个方法会丢失所有的垂直基线或者从右到左的设置。
5. 调用 SetTextAlign 函数时,如果使用 TA_UPDATECP 标志,Windows 会忽略 TextOut 的 xStart 和 yStart 参数,而使用由 MoveToEx、LineTo 或更改目前位置的另一个函数设定的位置。
22:wsprintf
函数功能:
wsprintf 函数用于把数据格式化写入到指定的缓冲区里,输出缓冲区里的的值取决于格式说明符(即"%"),如果写入的是文字,此函数给写入的文字的末尾追加一个'\0',函数的返回值是写入的长度,但不包括最后的'\0'
注意:实际编程中不要再使用该函数,请使用 StringCchPrintf 或StringCbPrint 代替。
API 函数原型:
int __cdecl wsprintf(
_Out_ LPTSTRlpOut,
_In_ LPCTSTR lpFmt,
_In_ ...
);
参数解析:
参数 | 含义 |
lpOut | 1. 指定格式化数据将要写入的缓冲区 |
lpFmt | 1. 格式化字符串 |
... | 可变参数,参数的个数取决 lpFmt 参数 |
返回值:
1. 如果函数调用成功,返回值与计划写入缓冲区的字符个数相等(不包含最后的'\0');
2. 如果函数调用失败,返回值小于计划写入缓冲区的字符个数,可通过调用 GetLastError 获取详细的错误信息。
23:StringCchPrintf
函数功能:
StringCchPrintf 函数用于把数据格式化写入到指定的缓冲区里,该函数要求提供目标缓冲区的大小,确保不会发生越界访问。
微软推荐使用该函数替代以下函数:
sprintf, swprintf, _stprintf
wsprintf
wnsprintf
_snprintf, _snwprintf,_sntprintf
API 函数原型:
HRESULT StringCchPrintf(
_Out_ LPTSTRpszDest,
_In_ size_t cchDest,
_In_ LPCTSTR pszFormat,
_In_ ...
);
参数解析:
参数 | 含义 |
pszDest | 指定格式化数据将要写入的缓冲区 |
cchDest | 1. 缓冲区大小 |
pszFormat | 1. 格式化字符串 |
... | 可变参数,参数的个数取决 pszFormat 参数 |
返回值:
这个函数返回一个 HRESULT,而不是像 sprintf 一样返回存储在其目标缓冲区的字节数。我们强烈建议您使用 SUCCEEDED和 FAILED 宏来测试这个函数的返回值。
返回值可以是以下任意一个值:
返回代码 | 描述 |
S_OK | 表示有足够的空间将拷贝到 pszDest,没有发生截断 |
STRSAFE_E_INVALID_PARAMETER | cchDest 的值为 0 或大于 STRSAFE_MAX_CCH |
STRSAFE_E_INSUFFICIENT_BUFFER | 1. 由于缓冲区空间不足而导致的复制失败 |
备注:
使用 StringCchPrintf 函数需要添加头文件:strsafe.h
代码演示:
#include "strsafe.h"
......
TCHAR pszDest[30];
size_t cchDest = 30;
LPCTSTR pszFormat =TEXT("从你家到鱼C工作室需要 %f 公里!");
HRESULT hr =StringCchPrintf(pszDest, cchDest, pszFormat, 123.45);
......
24:strlen
函数功能:
lstrlen 函数用于计算指定字符串的长度(不包含'\0),注意:实际编程中不要再使用该函数,请使用 StringCchLength 或StringCbLength 代替。
API 函数原型:
int WINAPI lstrlen(
_In_ LPCTSTRlpString
);
参数解析:
参数 | 含义 |
lpString | 指向以'\0'为终止符的字符串 |
返回值:
1. 该函数返回指定字符串的字符数;
2. 如果是空字符串,则返回 0。
安全建议:
错误的使用 lstrlen 函数将可能会危害到应用程序的安全:lstrlen 函数假定 lpString 参数是以'\0'结尾的字符串,如果事实上传入的参数不按套路出牌,则会造成缓冲区溢出,最终导致程序无法按照期望正常运行。
25:SUCCEEDED 和 FAILED 宏
宏功能:
SUCCEEDED 宏表示测试成功,FAILED 宏表示测试失败。
宏定义:
#define SUCCEEDED(hr) (((HRESULT)(hr))>= 0)
#define FAILED(hr) (((HRESULT)(hr))< 0)
参数解析:
参数 | 含义 |
hr | 1. 状态码 |
返回值:
1. 如果 hr 的值大于等于 0,则结果为TRUE;
2. 如果 hr 的值小于 0,则结果为FALSE。
26:StringCchLength
函数功能:
StringCchLength 函数用于确定字符串是否超过了规定的长度,以字符为计算单位。
微软推荐使用该函数替代以下函数:
strlen, wcslen, _tcslen
API 函数原型:
HRESULT StringCchLength(
_In_ LPCTSTR psz,
_In_ size_t cchMax,
_Out_ size_t*pcch
);
参数解析:
参数 | 含义 |
psz | 指向待检查的字符串 |
cchMax | 1. psz 参数里最大允许的字符数量,包括'\0' |
pcch | 1. psz 参数指向字符串的字符个数,不包括'\0' |
返回值:
这个函数返回一个 HRESULT,而不是指定字符串的字符个数。我们强烈建议您使用 SUCCEEDED 和 FAILED 宏来测试这个函数的返回值。
返回值可以是以下任意一个值:
返回代码 | 描述 |
S_OK | psz 指向的字符串不为空,且字符串的长度(包括'\0')小于等于 cchMax |
STRSAFE_E_INVALID_PARAMETER | 1. psz 指向空字符串 |
备注:
1. 对比 StringCchLength 所替代的函数,StringCchLength 是可以使你的代码正确处理缓存区的一个附加功能。因为小的缓冲处理会牵连很多安全问题,例如缓存区溢出
2. 使用 StringCchLength 函数需要添加头文件:strsafe.h
27:StringCchCat
函数功能:
StringCchCat 函数的功能是将一个字符串拼接到另一个字符串。StringCchCat 函数要求提供目标缓冲区的长度,以确保写入数据不会超出缓冲区的末尾。
微软推荐使用该函数替代以下函数:
strcat, wcscat, _tcsat
lstrcat
StrCat
StrCatBuff
API 函数原型:
HRESULT StringCchCat(
_Inout_ LPTSTRpszDest,
_In_ size_t cchDest,
_In_ LPCTSTR pszSrc
);
参数解析:
参数 | 含义 |
pszDest | 1. 目标缓冲区,同时包含第一个字符串 |
cchDest | 1. 目标缓冲区的大小(字符个数) |
pszSrc | 第二个字符串 |
返回值:
这个函数返回一个 HRESULT,而不是拼接好的字符串指针。我们强烈建议您使用 SUCCEEDED 和 FAILED 宏来测试这个函数的返回值。
返回值可以是以下任意一个值:
返回代码 | 描述 |
S_OK | 字符串正常拼接 |
STRSAFE_E_INVALID_PARAMETER | 1. cchDest 参数的值为 0 |
STRSAFE_E_INSUFFICIENT_BUFFER | 1. 因缓冲区空间不足导致失败 |
28: lstrcat
函数功能:
lstrcat 函数的功能是将一个字符串拼接在另一个字符串后边。
注意:实际编程中不要再使用该函数,请使用 StringCchCat 代替。
API 函数原型:
LPTSTR WINAPI lstrcat(
_Inout_ LPTSTRlpString1,
_In_ LPTSTR lpString2
);
参数解析:
参数 | 含义 |
lpString1 | 一个以'\0'为结尾的字符串,该字符串空间必须大到足以容纳本身及另一个字符串 |
lpString2 | 一个以'\0'为结尾的字符串,该字符串将拼接到 lpString1 指向的字符串后边 |
返回值:
1. 如果函数调用成功,返回指向拼接好的字符串指针;
2. 如果函数调用失败,返回值为 NULL,并且 lpString1 可能会变成非 '\0' 结束的字符串。
安全建议:
1. 不正确的使用 lstrcat 函数,可能会损害应用程序的安全性
2. lstrcat 函数使用结构化异常处理(SEH)来捕捉访问冲突和其他错误。当该函数捕获 SEH 错误,如果没有以'\0'结尾的字符串,则返回 NULL,且不把错误通知调用者。因此,把空间不足作为错误的条件是不安全的
3. lpString1 必须足够大,以增加 lpString2 和结束'\0',否则可能发生缓冲区溢出
4. 在最坏的情况下,缓冲区溢出可能允许攻击者可执行代码注入到你的进程,尤其是当 lpString1 是一个基于堆栈的缓冲区
29:StringCchCopy
函数功能:
StringCchCopy 函数的功能是复制一个字符串到缓冲区。StringCchCopy 函数要求提供目标缓冲区的长度,以确保写入数据不会超出缓冲区的末尾。
微软推荐使用该函数替代以下函数:
strcpy, wcscpy, _tcscpy
lstrcpy
StrCpy
API 函数原型:
HRESULT StringCchCopy(
_Out_ LPTSTRpszDest,
_In_ size_t cchDest,
_In_ LPCTSTR pszSrc
);
参数解析:
参数 | 含义 |
pszDest | 缓冲区,用于接收拷贝过来的字符串 |
cchDest | 1. 目标缓冲区的大小(字符个数) |
pszSrc | 待拷贝的字符串 |
返回值:
这个函数返回一个 HRESULT,而不是指向缓冲区的指针。我们强烈建议您使用 SUCCEEDED 和 FAILED 宏来测试这个函数的返回值。
返回值可以是以下任意一个值:
返回代码 | 描述 |
S_OK | 字符串正常拷贝 |
STRSAFE_E_INVALID_PARAMETER | 1. cchDest 参数的值为 0 |
STRSAFE_E_INSUFFICIENT_BUFFER | 1. 因缓冲区空间不足导致失败 |
30:lstrcpy
函数功能:
lstrcpy 函数的功能是复制一个字符串到缓冲区。
注意:实际编程中不要再使用该函数,请使用 StringCchCopy 代替。
API 函数原型:
LPTSTR WINAPI lstrcpy(
_Out_ LPTSTRlpString1,
_In_ LPTSTR lpString2
);
参数解析:
参数 | 含义 |
lpString1 | 1. 缓冲区,用于接收来自 lpString2 参数指向的字符串 |
lpString2 | 待拷贝的字符串 |
返回值:
1. 如果函数调用成功,返回指向缓冲区的指针;
2. 如果函数调用失败,返回值是 NULL,并且 lpString1 可能会变成非 '\0' 结束的字符串。
安全建议:
1. 不正确的使用 lstcpy 函数,可能会损害应用程序的安全性
2. lstrcpy 函数使用结构化异常处理(SEH)来捕捉访问冲突和其他错误。当该函数捕获 SEH 错误,如果没有以'\0'结尾的字符串,则返回 NULL,且不把错误通知调用者。因此,把空间不足作为错误的条件是不安全的
3. lpString1 必须足够大,以增加 lpString2 和结束'\0',否则可能发生缓冲区溢出
4. 在最坏的情况下,缓冲区溢出可能允许攻击者可执行代码注入到你的进程,尤其是当 lpString1 是一个基于堆栈的缓冲区
31:GET_X_LPARAM和 GET_Y_LPARAM 宏
宏功能:
通过 lParam 参数获得相关消息触发的坐标 (x , y)
宏定义:
#define LOWORD(lp) ((WORD)(((DWORD_PTR)(lp)) &0xffff))
#define HIWORD(lp) ((WORD)((((DWORD_PTR)(lp)) >>16) & 0xffff))
#define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
#define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
参数解析:
参数 | 含义 |
lParam | 将要被转换的 lParam 参数 |
返回值:
1. GET_X_LPARAM(lParam) 返回坐标的 x 值;
2. GET_Y_LPARAM(lParam) 返回坐标的 y 值。
重要备注:
1. 使用该宏需要包含头文件:windowsx.h。
2. 不要再使用 LOWORD 和 HIWORD 去获取鼠标的坐标了,因为在多显示器的情况下会得到错误的坐标。
32:TEXTMETRIC 结构
TEXTMETRIC 结构
TEXTMETRIC 结构记录当前设备环境中有关字体的各种信息。
TEXTMETRIC 结构成员的值的单位取决于设备环境中当前选定的映射模式,默认的映射模式是MM_TEXT,所以它们的值是以像素为单位的。
结构原型:
typedef struct tagTEXTMETRIC
{
LONG tmHeight;
LONG tmAscent;
LONG tmDescent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
TCHAR tmFirstChar;
TCHAR tmLastChar;
TCHAR tmDefaultChar;
TCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRIC, *PTEXTMETRIC;
成员解析:
成员 | 含义 |
tmHeight | 字符高度(tmAscent + tmDescent) |
tmAscent | 字符上部高度(基线以上) |
tmDescent | 字符下部高度(基线以下) |
tmInternalLeading | 内部间距(包含在 tmHeight 中),该间距通常被用于显示重音符号 |
tmExternalLeading | 外部间距,这个值是字体设计者建议在两行文字间留出的空间大小 |
tmAveCharWidth | 1. 字体中小写字符的平均宽度(一般定义为字母 x 的宽度) |
tmMaxCharWidth | 字体中最宽字符的宽度 |
tmWeight | 字体的粗细轻重程度 |
tmOverhang | 加入某些拼接字体上的附加高度 |
tmDigitizedAspectX | 字体设计所针对的设备水平方向 |
tmDigitizedAspectY | 字体设计所针对的设备垂直方向 |
tmFirstChar | 为字体定义的第一个字符 |
tmLastChar | 为字体定义的最后一个字符 |
tmDefaultChar | 字体中所没有字符的替代字符 |
tmBreakChar | 定义文本对齐截断操作所显示的字符 |
tmItalic | 如果该值非零,则为斜体字体 |
tmUnderlined | 如果该值非零,则为带下横线字体 |
tmStruckOut | 如果该值非零,则为带删除线字体(字符中间画一条线) |
tmPitchAndFamily | 1. 如果低位为 0,表示等宽字体,小写和大写字母平均宽度一样 |
tmCharSet | 字体的字符集 |
33: GetTextMetrics
函数功能:
GetTextMetrics 函数将当前字体的信息填充到指定缓冲区(TEXTMETRIC结构)
API 函数原型:
BOOL GetTextMetrics(
_In_ HDC hdc,
_Out_ LPTEXTMETRIClptm
);
参数解析:
参数 | 含义 |
hdc | 设备环境句柄 |
lptm | 指向 TEXTMETRIC结构的指针,该结构用于获得字体信息 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 要确定一种字体是否为 TrueType 字体,可以通过调用 GetTextMetrics 函数,然后检查TEXTMETRIC.tmPitchAndFamily 的值是否为 TMPF_TRUETYPE
2. 注意,调用 GetDC 函数返回的是一个未初始化的 DC,它具有“系统”(一个位图字体)作为默认字体。因此你需要先选择一种字体到 DC
34:GetSystemMetrics
函数功能:
GetSystemMetrics 函数返回 Windows 中各种图形项(图标、鼠标指针、标题栏和滚动条等)的尺寸信息。
在不同的显卡和驱动中,这些尺寸是不一样的,为了在程序中做到与设备无关的图形输出,GetSystemMetrics是一个很重要的函数。
注意:GetSystemMetrics 函数获取的所有尺寸均以像素为单位。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
int WINAPI GetSystemMetrics(
_In_ intnIndex
);
参数解析:
参数 | 含义 |
nIndex | 该参数是一个索引值,函数返回该索引值对应的配置信息 |
nIndex 参数是一个索引值,可以是以下列表中任意一个:
注意:
所有 SM_CX* 开头表示宽(横向),SM_CY* 开头表示高(纵向),如果是返回布尔类型的数据,用非 0 值表示 TRUE,用 0 表示 FALSE
注释:括号内代表宏的值
索引值 | 含义 |
SM_ARRANGE(56) | 指定系统如何排列最小化窗口 |
SM_CLEANBOOT(67) | 指定系统如何启动: |
SM_CMONITORS(80) | 有多少个显示器 |
SM_CMOUSEBUTTONS(43) | 鼠标上有多少个按钮,如果为 0 则没有安装鼠标 |
SM_CONVERTIBLESLATEMODE(0x2003) | 笔记本电脑或平板模式,0 为平板模式,非 0 表示其他模式 |
SM_CXBORDER(5) | 1. 一个窗口边框的宽 |
SM_CXCURSOR(13) | 1. 光标的宽 |
SM_CXDLGFRAME(7) | 这个值与 SM_CXFIXEDFRAME 是相同的 |
SM_CXDOUBLECLK(36) | 双击有效的矩形区域的宽度 |
SM_CXDRAG(68) | 鼠标在某个矩形内单击移动被认为是拖拽 |
SM_CXEDGE(45) | 3-D 边框的宽度 |
SM_CXFIXEDFRAME(7) | 1. 具有标题栏但不可以调整大小的窗口边框的宽度 |
SM_CXFOCUSBORDER(83) | 1. DrawFocusRect 函数画出的矩形左右边框的宽度 |
SM_CXFRAME(32) | 这个值等同于 SM_CXSIZEFRAME |
SM_CXFULLSCREEN(16) | 客户区在全屏模式下的宽度 |
SM_CXHSCROLL(21) | 水平滚动条上箭头位图的宽度 |
SM_CXHTHUMB(10) | 水平滚动条滑块的宽度 |
SM_CXICON(11) | 1. 图标的默认宽度 |
SM_CXICONSPACING(38) | 一个网格单元的大图标视图中项的宽度 |
SM_CXMAXIMIZED(61) | 最大化顶级窗口的宽度 |
SM_CXMAXTRACK(59) | 一个具有标题栏及可调整大小的窗口所能达到的最大宽度 |
SM_CXMENUCHECK(71) | 菜单上位图的宽度 |
SM_CXMENUSIZE(54) | 菜单条按钮的宽度 |
SM_CXMIN(28) | 窗口的最小宽度 |
SM_CXMINIMIZED(57) | 最小化窗口的宽度 |
SM_CXMINSPACING(47) | 各个最小化窗体所占的矩形的宽度,该值需要大于等于 SM_CXMINIMIZED |
SM_CXMINTRACK(34) | 1. 窗口支持拖拽的最小宽度 |
SM_CXPADDEDBORDER(92) | 1. 带标题栏窗口边框的填充量 |
SM_CXSCREEN(0) | 1. 主显示屏的屏幕宽度 |
SM_CXSIZE(30) | 标题栏上按钮的宽度 |
SM_CXSIZEFRAME(32) | 可调整大小的窗口的边框的宽度 |
SM_CXSMICON(49) | 推荐的小图标的宽度(一般出现在窗口标题栏) |
SM_CXSMSIZE(52) | 小标题按钮的宽度 |
SM_CXVIRTUALSCREEN(78) | 虚拟屏幕的宽度(虚拟屏幕是所有显示器的边框) |
SM_CXVSCROLL(2) | 垂直滚动条的宽度 |
SM_CYBORDER(6) | 1. 一个窗口边框的高 |
SM_CYCAPTION(4) | 标题区域的高度 |
SM_CYCURSOR(14) | 1. 光标的高 |
SM_CYDLGFRAME(8) | 这个值与 SM_CYFIXEDFRAME 是相同的 |
SM_CYDOUBLECLK(37) | 双击有效的矩形区域的高度 |
SM_CYDRAG(69) | 鼠标在某个矩形内单击移动被认为是拖拽 |
SM_CYEDGE(46) | 3-D 边框的高度 |
SM_CYFIXEDFRAME(8) | 1. 具有标题栏但不可以调整大小的窗口边框的高度 |
SM_CYFOCUSBORDER(84) | 1. DrawFocusRect 函数画出的矩形上下边框的高度 |
SM_CYFRAME(33) | 这个值等同于 SM_CYSIZEFRAME |
SM_CYFULLSCREEN(17) | 客户区在全屏模式下的高度 |
SM_CYHSCROLL(3) | 水平滚动条上箭头位图的高度 |
SM_CYICON(12) | 1. 图标的默认高度 |
SM_CYICONSPACING(39) | 一个网格单元的大图标视图中项的高度 |
SM_CYKANJIWINDOW(18) | 对于系统的双字节字符集版本,这个是汉字在窗口底部的高度 |
SM_CYMAXIMIZED(62) | 最大化顶级窗口的高度 |
SM_CYMAXTRACK(60) | 一个具有标题栏及可调整大小的窗口所能达到的最大高度 |
SM_CYMENU(15) | 单行菜单栏的高 |
SM_CYMENUCHECK(72) | 菜单上位图的高度 |
SM_CYMENUSIZE(55) | 菜单条按钮的高度 |
SM_CYMIN(29) | 窗口的最小高度 |
SM_CYMINIMIZED(58) | 最小化窗口的高度 |
SM_CYMINSPACING(48) | 各个最小化窗体所占的矩形的高度,该值需要大于等于 SM_CYMINIMIZED |
SM_CYMINTRACK(35) | 1. 窗口支持拖拽的最小高度 |
SM_CYSCREEN(1) | 1. 主显示屏的屏幕高度 |
SM_CYSIZE(31) | 标题栏上按钮的高度 |
SM_CYSIZEFRAME(33) | 可调整大小的窗口的边框的高度 |
SM_CYSMCAPTION(51) | 小标题的高度 |
SM_CYSMICON(50) | 推荐的小图标的高度(一般出现在窗口标题栏) |
SM_CYSMSIZE(53) | 小标题按钮的高度 |
SM_CYVIRTUALSCREEN(79) | 虚拟屏幕的高度(虚拟屏幕是所有显示器的边框) |
SM_CYVSCROLL(20) | 垂直滚动条的宽度 |
SM_CYVTHUMB(9) | 垂直滚动条滑块框的高度 |
SM_DBCSENABLED(42) | 如果 User32.dll 支持 DBCS 返回非 0 值,否则返回 0 |
SM_DEBUG(22) | 如果已安装的 User.exe 的调试版本返回非 0 值,否则返回 0 |
SM_DIGITIZER(94) | 1. 如果当前的操作系统是 Windows 7 或者 Windows Server 2008 R2 并且 Tablet PC input 服务已启动,则返回非 0 值,否则返回 0 |
SM_IMMENABLED(82) | 如果启用了输入法管理器或输入法编辑器功能,则返回非 0,否则返回 0 |
SM_MAXIMUMTOUCHES(95) | 1. 如果有在系统中的数字化仪,则返回非 0,否则返回 0 |
SM_MEDIACENTER(87) | 如果当前的操作系统是 Windows XP(MCE,媒体中心版),则返回非 0,否则返回 0 |
SM_MENUDROPALIGNMENT(40) | 如果下来菜单相应的菜单栏项目是右对齐的,则返回非 0,否则如果是左对齐返回 0 |
SM_MIDEASTENABLED(74) | 如果系统启用了希伯来语和阿拉伯语的语言,则返回非 0,否则返回 0 |
SM_MOUSEPRESENT(19) | 1. 如果安装了鼠标返回非 0,否则返回 0 |
SM_MOUSEHORIZONTALWHEELPRESENT(91) | 如果鼠标有水平滚动轮,则返回非 0,否则返回 0 |
SM_MOUSEWHEELPRESENT(75) | 如果鼠标有垂直滚动轮,则返回非 0,否则返回 0 |
SM_NETWORK(63) | 1. 如果存在网络,则返回值最后一位被设置为 1,否则返回 0 |
SM_PENWINDOWS(41) | 如果安装了 Windows 手写画板的扩展,则返回非 0,否则返回 0 |
SM_REMOTECONTROL(0x2001) | 1. 该系统信息是用在终端服务环境下,用于判断当前的终端服务器会话是否被远程控制 |
SM_REMOTESESSION(0x1000) | 1. 该系统信息是用在终端服务环境下 |
SM_SAMEDISPLAYFORMAT(81) | 1. 如果所有的显示器具有相同的颜色格式,则返回非 0,否则返回 0 |
SM_SECURE(44) | 该系统信息被忽略,它总是返回 0 |
SM_SERVERR2(89) | 如果系统是 Windows Server 2003 R2 则返回内部版本号,否则返回 0 |
SM_SHOWSOUNDS(70) | 如果用户需要应用程序可视化音频信息,则返回非 0,否则返回 0 |
SM_SHUTTINGDOWN(0x2000) | 1. 如果当前会话关闭返回非 0,否则返回 0 |
SM_SLOWMACHINE(73) | 如果计算机拥有一个低端(慢速)处理器,则返回非 0,否则返回 0 |
SM_STARTER(88) | 如果当前的操作系统是 Windows 7 入门版,Windows Vista 入门版,或 Windows XP 入门版,则返回非 0,否则返回 0 |
SM_SWAPBUTTON(23) | 如果鼠标左右键的含义互相交换,则返回非 0,否则返回 0 |
SM_SYSTEMDOCKED(0x2004) | 反映了底座模式,返回 0 为非底座模式,否则返回非 0 |
SM_TABLETPC(86) | 1. 如果当前的操作系统是 Windows XP Tablet PC 版,或者如果当前的操作系统是 Windows Vista 或 Windows 7 且 Tablet PC input 服务已启动,则返回非 0,否则返回 0 |
SM_XVIRTUALSCREEN(76) | 1. 虚拟屏幕左侧的坐标(虚拟屏幕是所有显示器的边框) |
SM_YVIRTUALSCREEN(77) | 1. 虚拟屏幕顶侧的坐标(虚拟屏幕是所有显示器的边框) |
返回值:
1. 如果函数调用成功,返回值索引参数对应的配置信息;
2. 如果函数调用失败,返回值是 0。
35:SetScrollRange
函数功能:
SetScrollRange 函数设置所指定滚动条范围的最小值和最大值。
注意:SetScrollRange 函数提供了向后的兼容性。但新的应用程序应该提倡使用 SetScrollInfo 函数代替。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL SetScrollRange(
_In_ HWNDhWnd,
_In_ intnBar,
_In_ intnMinPos,
_In_ intnMaxPos,
_In_ BOOLbRedraw
);
参数解析:
参数 | 含义 |
hWnd | 1. 滚动条控件的句柄或带有标准滚动条窗体的句柄 |
nBar | 指定将要设置哪类滚动条的参数: |
nMinPos | 指定滚动位置的最小值 |
nMaxPos | 指定滚动位置的最大值 |
bRedraw | 指定滚动条是否被重画以反映变化(如果这个参数为 TRUE,滚动条将被重画;如果为 FALSE 则不被重画) |
返回值:
1. 如果函数调用成功,返回值为非 0;
2. 如果函数调用失败,返回值为 0。
备注:
1. 将 SetScrollRange 函数中的 nMinPos 和 nMaxPos 参数设置为一样的值,可以达到隐藏滚动条的目的。但在处理滚动条消息时,应用程序不应该调用 SetScrollRange 函数来隐藏滚动条。新的应用程序应该调用ShowScrollBar 函数来隐藏滚动条。
2. 如果调用 SetScrollPos 函数之后马上调用 SetScrollRange 函数,则 SetScrollPos 函数中的 bRedraw 参数一定要设置为零值(FALSE),以防止滚动条被画两次。
3. 标准滚动条的缺省范围是 0 到100。滚动条控件的缺省值为 NULL(参数 nMinPos 和 nMaxPos 的值均为零)。两个范围值之间的不同之处在于由参数 nMinPos 和 nMaxPos 指定,不过不能超过 MAXLONG 定义的大小。
4. 因为说明滚动条位置的消息 WM_HSCROLL 和 WM_VSCROLL 是 16 位数据,所以那些只依赖于说明位置数据消息的应用程序在SetScrollRange 函数的参数 nMaxPos 中有一个实际最大值 65,535。但是,因为 SetScrolllnfo,SetScrollPos, SetScrollRange,GetScrolllnfo,GetScrollPos 和 GetScrollRange 函数都支持 32 位的滚动条位置数据,所以有一个解决 16 位 WM_HSCROLL 和WM_VSCROLL 消息阻碍的途径,请参见函数 GetScrolllnfo 的有关技术说明。
5. 如果参数 nBar 设置为 SB_CTL 并且参数 hWnd 所标识的不是一个标准的滚动条控件。系统将发送一个 SBM_SETRANGE 消息到窗体用以设置滚动条消息。这将允许 SetScrollRange 函数操作一个定制的伪滚动条控件。如果窗体没有处理SBM_SETRANGE 消息,SetScrollRange 函数将调用失败。
36:GetScrollPos
函数功能:
GetScrollPos 函数获取指定滚动条中滚动按钮的当前位置。当前位置是一个根据当前滚动范围而定的相对值。例如,如果滚动范围是 0~10,滚动按钮恰好在中间的位置,则其当前位置就为 50。
注意:该函数提供了向后兼容性,新的应用程序应该使用 GetScrollInfo 函数代替。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
int GetScrollPos(
_In_ HWNDhWnd,
_In_ intnBar
);
参数解析:
参数 | 含义 |
hWnd | 1. 滚动条控件的句柄或带有标准滚动条窗体的句柄 |
nBar | 指定哪类滚动条的当前位置将被返回: |
返回值:
1. 如果函数调用成功,返回值是指定滚动条的当前位置;
2. 如果函数调用失败,返回值是 0。
备注:
1. GetScrollPos 函数可以使应用程序使用 32 位数据的滚动位置。尽管消息 WM_HSCROLL 和 WM_VSCROLL 只支持 16 位的数据,而 SetScrollPos,SetScrollRange,GetScrollPos 和 GetscrollRange 函数都支持 32 位的滚动条数据,因此,应用程序在处理任 WM_HSCROLL 或 WM_VSCROLL 消息时可以调用 GetScrollPos 函数来获得 32 位数据的滚动条位。
2. 为了获得在一个 WM_HSCROLL 或 WM_VSCROLL 消息的 SB_THUMBTRACK 请求码的滚动框(滑块)的 32位数据的位置,请使用 GetScrollInfo 函数。
37:GetScrollRange
函数功能:
GetScrollRange 函数获得指定滚动条的范围。
注意:GetScrollRange 函数提供了向后的兼容性。但新的应用程序应该提倡使用 GetScrollInfo 函数代替。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL GetScrollRange(
_In_ HWND hWnd,
_In_ int nBar,
_Out_ LPINTlpMinPos,
_Out_ LPINTlpMaxPos
);
参数解析:
参数 | 含义 |
hWnd | 1. 滚动条控件的句柄或带有标准滚动条窗体的句柄 |
nBar | 指定将要设置哪类滚动条的参数: |
lpMinPos | 指向存放最小位置的整型变量 |
lpMaxPos | 指向存放最大位置的整型变量 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 如果指定的窗口没有标准的滚动条或不是滚动条控件,GetScrollRange 函数将零复制到 lpMinPos 和 lpMaxPos 参数中。
2. 标准滚动条的默认范围是 0 到 100。滚动条控件的缺省值为空。
3. 因为说明滚动条位置的消息 WM_HSCROLL 和 WM_VSCROLL 是 16 位数据,所以那些只依赖于说明位置数据消息的应用程序在SetScrollRange 函数的参数 nMaxPos 中有一个实际最大值 65,535。但是,因为 SetScrolllnfo,SetScrollPos, SetScrollRange,GetScrolllnfo,GetScrollPos 和 GetScrollRange 函数都支持 32 位的滚动条位置数据,所以有一个解决 16 位 WM_HSCROLL 和WM_VSCROLL 消息阻碍的途径,请参见函数 GetScrolllnfo 的有关技术说明。
4. 如果参数 nBar 设置为 SB_CTL 并且参数 hWnd 所标识的不是一个标准的滚动条控件。系统将发送一个 SBM_GETRANGE 消息到窗体用以设置滚动条消息。这将允许 GetScrollRange 函数操作一个定制的伪滚动条控件。如果窗体没有处理SBM_GETRANGE 消息,GetScrollRange 函数将调用失败。
38: LOWORD和 HIWORD 宏
宏功能:
获得指定 32 位数据的低 16位数据和高 16 位数据。
小甲鱼温馨提醒:不要使用 LOWORD 和 HIWORD 宏去获取鼠标的坐标,因为在多显示器的情况下会得到错误的坐标。应该使用 GET_X_LPARAM和 GET_Y_LPARAM 宏来获取。
宏定义:
#define LOWORD(lParam) ((WORD)(((DWORD_PTR)(lParam)) & 0xffff))
#define HIWORD(lParam) ((WORD)((((DWORD_PTR)(lParam)) >> 16) & 0xffff))
参数解析:
参数 | 含义 |
lParam | 32 位的目标数据 |
返回值:
1. LOWORD(lParam) 返回 lParam 的低16 位数据;
2. HIWORD(lParam) 返回 lParam 的高16 位数据。
39: WM_SIZE消息
消息含义:
当主窗口的客户区部分大小改变时,操作系统将给应用程序发送 WM_SIZE 消息。
应用程序通过窗口过程接收该消息(请关注:《Windows程序设计(SDK)》视频教学)。
消息定义:
#define WM_SIZE 0x0005
参数解析:
wParam:指出窗口的新状态
wParam 参数可以是下列值之一:
值 | 含义 |
SIZE_MAXHIDE(4) | 当该应用程序的其他窗口被最大化的时候,消息被发送往所有的弹出窗口 |
SIZE_MAXIMIZED(2) | 该窗口被最大化 |
SIZE_MAXSHOW(3) | 当该应用程序的其他窗口已经恢复到原来大小的时候,消息被发送往所有的弹出窗口 |
SIZE_MINIMIZED(1) | 该窗口被最小化 |
SIZE_RESTORED(0) | 该窗口的大小发生变化,但不是最大化(SIZE_MAXIMIZED)或最小化(MINIMIZED) |
lParam:指出当前客户区的大小(宽度和高度)
1. lParam 参数的低 16 位指定了新窗口的宽度;
2. lParam 参数的高 16 位制定了新窗口的高度。
小甲鱼温馨提醒:可以通过 LOWORD宏和 HIWORD宏来获取 lParam 参数的低 16 位和高16 位。
返回值:
1. 如果窗口过程响应该消息,必须返回 0。
40:WM_VSCROLL消息
消息含义:
当窗口的标准垂直滚动条有滚动事件发生时,操作系统向窗口的消息队列投入一条WM_VSCROLL 消息。
此消息也适用于触发垂直滚动条控件。
应用程序通过窗口过程接收该消息(请关注:《Windows程序设计(SDK)》视频教学)。
消息定义:
#define WM_VSCROLL 0x0115
参数解析:
wParam:当 LOWORD(wParam) 的结果(取低 16 位)为SB_THUMBPOSITION 或 SB_THUMBTRACK 时,HIWORD(wParam) 的值(取高 16 位)是当前滑块在滚动框的位置。
小甲鱼温馨提示:
当 wParam 的低 16 位的值是 SB_THUMBTRACK 时,wParam 的高 16 位是用户拖动滑块的当前位置
当 wParam 的低 16 位的值是 SB_THUMBPOSITION 时,wParam 的高 16 位是用户松开鼠标按键时滑块的最终位置
对于其他的滚动操作,wParam 的高 16 位应该被忽略
LOWORD(wParam) 的结果(取低 16 位)代表了鼠标在滚动条上的动作,这个值被称之为“通知码”,由一个以“SB”开头的标识符定义。
该通知码是下列值之一:
值 | 含义 |
SB_BOTTOM | 滚动到底部(键盘 End 按键触发) |
SB_ENDSCROLL | 完成滚动操作(松开鼠标) |
SB_LINEDOWN | 向下滚动一行 |
SB_LINEUP | 向上滚动一行 |
SB_PAGEDOWN | 向下滚动一页 |
SB_PAGEUP | 向上滚动一页 |
SB_THUMBPOSITION | 1. 用户有拖动滚动条的操作,并已经松开了鼠标按钮 |
SB_THUMBTRACK | 1. 用户拖动滚动条滑块触发此消息 |
SB_TOP | 滚动到顶端(键盘 Home 按键触发) |
lParam:如果该参数等于 0,说明它是标准的窗口滚动条;如果该参数等于滚动条窗口句柄,说明它是滚动条控件。
返回值:
1. 如果窗口过程响应该消息,必须返回 0。
41:WM_HSCROLL消息
消息含义:
当窗口的标准水平滚动条有滚动事件发生时,操作系统向窗口的消息队列投入一条WM_HSCROLL 消息。
此消息也适用于触发水平滚动条控件。
应用程序通过窗口过程接收该消息(请关注:《Windows程序设计(SDK)》视频教学)。
消息定义:
#define WM_HSCROLL 0x0114
参数解析:
wParam:wParam:当 LOWORD(wParam) 的结果(取低 16 位)为SB_THUMBPOSITION 或 SB_THUMBTRACK 时,HIWORD(wParam) 的值(取高 16 位)是当前滑块在滚动框的位置。
小甲鱼温馨提示:
当 wParam 的低 16 位的值是 SB_THUMBTRACK 时,wParam 的高 16 位是用户拖动滑块的当前位置
当 wParam 的低 16 位的值是 SB_THUMBPOSITION 时,wParam 的高 16 位是用户松开鼠标按键时滑块的最终位置
对于其他的滚动操作,wParam 的高 16 位应该被忽略
LOWORD(wParam) 的结果(取低 16 位)代表了鼠标在滚动条上的动作,这个值被称之为“通知码”,由一个以“SB”开头的标识符定义。
该通知码是下列值之一:
值 | 含义 |
SB_ENDSCROLL | 完成滚动操作(松开鼠标) |
SB_LEFT | 滚动到左边 |
SB_RIGHT | 滚动到右边 |
SB_LINELEFT | 向左滚动一行 |
SB_LINERIGHT | 向右滚动一行 |
SB_PAGELEFT | 向左滚动一页 |
SB_PAGERIGHT | 向右滚动一页 |
SB_THUMBPOSITION | 1. 用户有拖动滚动条的操作,并已经松开了鼠标按钮 |
SB_THUMBTRACK | 1. 用户拖动滚动条滑块触发此消息 |
lParam:如果该参数等于 0,说明它是标准的窗口滚动条;如果该参数等于滚动条窗口句柄,说明它是滚动条控件。
返回值:
1. 如果窗口过程响应该消息,必须返回 0。
42:InvalidateRect
函数功能:
InvalidateRect 函数向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL InvalidateRect(
_In_ HWNDhWnd,
_In_ constRECT *lpRect,
_In_ BOOLbErase
);
参数解析:
参数 | 含义 |
hWnd | 1. 指向待更新的客户区所在的窗体的句柄 |
lpRect | 1. 一个指向 RECT结构的指针,指定无效区域的矩形,该矩形将会被重新绘制 |
bErase | 1. 指定更新区域内的背景是否重绘 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 在下一个 WM_PAINT 消息产生前,所有 ValidateRect 或 ValidateRgn 函数产生的更新区域会被拼接成一个大的更新区域。
2. 当更新区域不为空并且窗口的消息队列中没有其他消息,系统向窗口过程发送 WM_PAINT 消息,令其重绘。
3. 如果任何一个更新区域的 bErase 参数为 TRUE,整个背景会被擦除重绘。
43:SCROLLINFO结构
SetScrollInfo 函数通过 SCROLLINFO 结构设置滚动条参数(或者 SBM_SETSCROLLINFO 消息),GetScrollInfo 函数也通过 SCROLLINFO 结构获得滚动条参数(或者 SBM_GETSCROLLINFO 消息)。
结构原型:
typedef struct tagSCROLLINFO {
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, *LPCSCROLLINFO;
成员解析:
成员 | 含义 |
cbSize | 1. 该结构的大小(以字节为单位) |
fMask | 指定被设置或获取的滚动条参数,该参数可以由下列标志组成: |
nMin | 滚动条范围的最小值 |
nMax | 滚动条范围的最大值 |
nPage | 页面的大小,滚动条通过这个值来动态确定滑块的大小 |
nPos | 滑块的位置 |
nTrackPos | 当前滑块的位置 |
如在使用上有任何不同,可以参考小甲鱼的《Windows程序设计(SDK)》第 14 讲:滚动条3
44:SetScrollInfo
函数功能:
SetScrollInfo 函数用于设置滚动条的参数,其中包括:滚动范围的最小值和最大值,页面的大小,以及滑块的位置。如果需要,该函数还可以重绘滚动条。
API 函数原型:
int SetScrollInfo(
_In_ HWNDhwnd,
_In_ intfnBar,
_In_ LPCSCROLLINFOlpsi,
_In_ BOOLfRedraw
);
参数解析:
参数 | 含义 |
hwnd | 1. 滚动条控件的句柄或带有标准滚动条窗体的句柄 |
fnBar | 指定将要设置哪类滚动条的参数: |
lpsi | 1. 指向 SCROLLINFO结构 |
fRedraw | 指定滚动条是否被重画以反映变化(如果这个参数为 TRUE,滚动条将被重画;如果为 FALSE 则不被重画) |
返回值
SetScrollInfo 函数的返回值是滚动按钮的当前位置。
备注:
SetScrollInfo 函数将会检查 SCROLLINFO结构中的 nPage 和 nPos 两个成员的值的范围(nPage 成员的值必须是 0 ~ nMax-nMin+1;nPos 成员的值必须是在 nMin 到 nMax - max(nPage-1, 0) 之间),如果任何一个值超过了范围,函数将在指定范围内为它设置一个值。
如在使用上有任何不同,可以参考小甲鱼的《Windows程序设计(SDK)》第 14 讲:滚动条3
45: GetScrollInfo
函数功能:
GetScrollInfo 函数用于获取滚动条的参数,其中包括:滚动范围的最小值和最大值,页面的大小,以及滑块的位置。
API 函数原型:
BOOL GetScrollInfo(
_In_ HWND hwnd,
_In_ int fnBar,
_Inout_ LPSCROLLINFOlpsi
);
参数解析:
参数 | 含义 |
hwnd | 1. 滚动条控件的句柄或带有标准滚动条窗体的句柄 |
fnBar | 指定将要设置哪类滚动条的参数: |
lpsi | 1. 指向 SCROLLINFO结构 |
返回值:
1. 如果函数成功获取滚动条的参数,则返回值是非 0;
2. 如果函数没有获取滚动条的参数,则返回值是 0。
备注:
1. 尽管滚动条消息 WM_HSCROLL 和 WM_VSCROLL 可以通过 HIWORD(wParam) 取得滚动条的位置(当 LOWORD(wParam) 通知码为 SB_THUMBPOSITION 和 SB_THUMBTRACK 的时候),但得到是 16 位的滚动条位置。如果想要得到 32 位的滚动条数据,可以使用 GetScrollInfo 函数。
2. 为了在 WM_HSCROLL 或 WM_VSCROLL 的 SB_THUMBTRACK 通知码中获得滚动条滑块的 32 位的位置,可以通过调用 GetScrollInfo 函数并设置 SCROLLINFO结构 fMask 成员的值为 SIF_TRACKPOS 实现。GetScrollInfo 函数将滚动条滑块的位置存放在 SCROLLINFO 结构的 nTrackPos 成员中。这将使得用户在移动滑块时你可以及时获得滑块的位置。
【API档案】版权归鱼C工作室(www.fishc.com)所有,转载请注明来源。
示例:
SCROLLINFO si;
case WM_HSCROLL:
switch(LOWORD(wparam)) {
case SB_THUMBTRACK:
// Initialize SCROLLINFO structure
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_TRACKPOS;
// Call GetScrollInfo to get current tracking
// position in si.nTrackPos
if (!GetScrollInfo(hwnd, SB_HORZ, &si) )
return 1; // GetScrollInfo failed
break;
.
.
.
}
如在使用上有任何不同,可以参考小甲鱼的《Windows程序设计(SDK)》第 14 讲:滚动条3
46:ScrollWindow
函数功能:
ScrollWindow 函数滚动指定窗口的客户区内容。
注意:该函数提供了向后兼容性,新的应用程序应该使用 ScrollWindowsEx 函数代替。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL ScrollWindow(
_In_ HWNDhWnd,
_In_ intXAmount,
_In_ intYAmount,
_In_ constRECT *lpRect,
_In_ constRECT *lpClipRect
);
参数解析:
参数 | 含义 |
hWnd | 指向客户区将被滚动的窗口句柄 |
XAmount | 1. 在设备单元中,指定水平滚动的数量 |
YAmount | 1. 在设备单元中,指定垂直滚动的数量 |
lpRect | 1. 指向 RECT结构指针,该结构指定了将要滚动的客户区范围 |
lpClipRect | 1. 指向 RECT结构指针,该结构指定了要滚动的裁剪区域 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 如果在被滚动的窗口中含有插入符,ScrollWindow 函数将自动隐藏插入符,以防它被擦掉。当滚动结束后再恢复插入符,插入符的位置相应的被调整。
2. 未被 ScrollWindow 函数覆盖的区域不会被重绘,但该区域会与窗口更新区域组合,当应用程序最终收到 WM_PAINT 的消息时,组合区域统一重绘。为了在滚动操作的同时重画未覆盖区域,则应在调用 ScrollWindow 函数后马上调用UpdateWindow 函数。
3. 如果 lpRect 参数的值为 NULL,则窗口中的任何子窗口的位置由参数 XAmount 和 Yamount 的数值决定移动距离;窗口中无效的区域(未重绘)也会移动。
4. 当 lpRect 参数为 NULL 时,ScrollWindow函数可以执行得更快。
5. 如果 lpRect 参数不为 NULL,则窗口中的子窗口的位置不改变,窗口中无效的区域(未重绘)也不移动。为了防止 lpRect 参数不为 NULL 时更新的问题,需要在调用 ScrollWindow 函数前调用 UpdateWindow 函数重绘窗口。
/*-------------------------------------------------------------------
【API档案】ScrollWindow 函数使用例子
鱼C工作室 -- www.fishc.com
--------------------------------------------------------------------*/
LRESULT CALLBACK WndProc(HWNDhwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
static int xClient; // 客户区的宽度
static int yClient; // 客户区的高度
static int xClientMax; // 客户区内容显示的最大宽度(超过此宽度则加入滚动条)
static int xChar; // 字体的平均水平宽度
static int yChar; // 字体的垂直高度
static int xUpper; // 字体的大写字符的水平宽度
static int xPos; // 当前水平滚动条滑块的位置
static int yPos; // 当前垂直滚动条滑块的位置
int i; // 循环计数器
int x, y; // 水平和垂直的坐标
int FirstLine; // 失效区域的第一行(需重绘的第一行)
int LastLine; // 失效区域的最后一行((需重绘的最后一行))
HRESULT hr;
size_t abcLength; // 用于存放 abc 数组的长度
// 创建要显示的行(呃,打印的内容我就不翻译了吧...)
#define LINES 28
static TCHAR *abc[] = {
TEXT("anteater"),TEXT("bear"), TEXT("cougar"),
TEXT("dingo"),TEXT("elephant"), TEXT("falcon"),
TEXT("gazelle"),TEXT("hyena"), TEXT("iguana"),
TEXT("jackal"),TEXT("kangaroo"), TEXT("llama"),
TEXT("moose"),TEXT("newt"), TEXT("octopus"),
TEXT("penguin"),TEXT("quail"), TEXT("rat"),
TEXT("squid"),TEXT("tortoise"), TEXT("urus"),
TEXT("vole"),TEXT("walrus"), TEXT("xylophone"),
TEXT("yak"),TEXT("zebra"),
TEXT("This line containswords, but no character. Go figure."),
TEXT("")
};
switch (message)
{
case WM_CREATE:
// 获得设备环境句柄
hdc = GetDC(hwnd);
// 获得文本中字体的大小
GetTextMetrics(hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily& 1 ? 3 : 2) * xChar / 2;
yChar = tm.tmHeight +tm.tmExternalLeading;
// 释放设备环境句柄
ReleaseDC(hwnd, hdc);
// 设置客户区的最大宽度
// (我们这里设置为 48 个小写字符的宽度 + 12 个大写字符的宽度)
xClientMax = 48 * xChar + 12 *xUpper;
return 0;
case WM_SIZE:
// 获得客户区的尺寸
yClient = HIWORD(lParam);
xClient = LOWORD(lParam);
// 设置垂直滚动条范围和页面大小(设置页面大小将决定滑块的粗细)
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = LINES - 1;
si.nPage = yClient / yChar;
SetScrollInfo(hwnd, SB_VERT,&si, TRUE);
// 设置水平滚动条范围和页面大小(设置页面大小将决定滑块的粗细)
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + xClientMax / xChar;
si.nPage = xClient / xChar;
SetScrollInfo(hwnd, SB_HORZ,&si, TRUE);
return 0;
case WM_HSCROLL:
// 获得水平滚动条的所有信息
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_HORZ,&si);
// 保存当前滑块位置,迟些进行比较
xPos = si.nPos;
switch (LOWORD(wParam))
{
// 用户点击滚动条左边的三角形
case SB_LINELEFT:
si.nPos -= 1;
break;
// 用户点击滚动条右边的三角形
case SB_LINERIGHT:
si.nPos += 1;
break;
// 用户点击滑块左边的滚动条轴
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
// 用户点击滑块右边的滚动条轴
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
// 用户拖动滚动条
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
// 设置滚动条滑块的新位置
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ,&si, TRUE);
// 获得滚动条滑块的位置,由于窗口调整,它可能不是同一个值
GetScrollInfo(hwnd, SB_HORZ,&si);
// 与此前的保存的值进行比较,如果不同则滚动窗口
if (si.nPos != xPos)
{
ScrollWindow(hwnd, xChar * (xPos - si.nPos), 0, NULL, NULL);
}
return 0;
case WM_VSCROLL:
// 获得垂直滚动条的所有信息
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT,&si);
// 保存当前滑块位置,迟些进行比较
yPos = si.nPos;
switch (LOWORD(wParam))
{
// 用户点击键盘 Home 按键
case SB_TOP:
si.nPos= si.nMin;
break;
// 用户点击键盘 End 按键
case SB_BOTTOM:
si.nPos = si.nMax;
break;
// 用户点击滚动条上边的三角形
case SB_LINEUP:
si.nPos -= 1;
break;
// 用户点击滚动条下边的三角形
case SB_LINEDOWN:
si.nPos += 1;
break;
// 用户点击滑块上边的滚动条轴
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// 用户点击滑块下边的滚动条轴
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// 用户拖动滚动条
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
// 设置滚动条滑块的新位置
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT,&si, TRUE);
// 获得滚动条滑块的位置,由于窗口调整,它可能不是同一个值
GetScrollInfo(hwnd, SB_VERT,&si);
// 与此前的保存的值进行比较,如果不同则滚动窗口
if (si.nPos != yPos)
{
ScrollWindow(hwnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
caseWM_PAINT:
// 准备绘制
hdc = BeginPaint(hwnd, &ps);
// 获得垂直滚动条的位置
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT,&si);
yPos = si.nPos;
// 获得水平滚动条的位置
GetScrollInfo(hwnd, SB_HORZ,&si);
xPos = si.nPos;
// 计算需要重绘的区域
FirstLine = max(0, yPos +ps.rcPaint.top / yChar);
LastLine = min(LINES - 1, yPos +ps.rcPaint.bottom / yChar);
for (i = FirstLine; i <=LastLine; i++)
{
x = xChar * (1 - xPos);
y = yChar * (i - yPos);
// 使用安全字符串函数获得字符串长度
hr = StringCchLength(abc[i], 55, &abcLength);
if ((FAILED(hr)) | (abcLength == NULL))
{
// 获取字符串长度失败的提示...
}
// 在客户区绘制一行数据
TextOut(hdc, x, y, abc[i], abcLength);
}
// 绘制完毕
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
47:ScrollWidnowEx
函数功能: ScrollWindowEx函数滚动指定窗口的客户区内容。
API 函数原型:
int ScrollWindowEx(
_In_ HWND hWnd,
_In_ int dx,
_In_ int dy,
_In_ const RECT *prcScroll,
_In_ const RECT *prcClip,
_In_ HRGN hrgnUpdate,
_Out_ LPRECTprcUpdate,
_In_ UINT flags
);
参数解析:
参数 | 含义 |
hWnd | 指向客户区将被滚动的窗口句柄 |
dx | 1. 在设备单元中,指定水平滚动的数量 |
dy | 1. 在设备单元中,指定垂直滚动的数量 |
prcScroll | 1. 指向 RECT结构指针,该结构指定了将要滚动的客户区范围 |
prcClip | 1. 指向 RECT结构指针,该结构指定了要滚动的裁剪区域 |
hrgnUpdate | 1. 指向由于滚动而无效的区域的句柄 |
prcUpdate | 1. 指向 RECT结构,该结构指定由于滚动而无效的矩形的边界 |
flags | 指定控制滚动的标志 |
flags 参数由下列标志组合:
标志 | 含义 |
SW_ERASE | 通过发送 WM_ERASEBKGND 消息给窗口,令其擦除新的无效区域(需同时指定 SW_INVALIDATE 消息) |
SW_INVALIDATE | 滚动后,使得 hrgnUpdate 参数指定的区域无效 |
SW_SCROLLCHILDREN | 1. 滚动所有由参数 prcScroll 指定的相交重叠的子窗口 |
SW_SMOOTHSCROLL | Windows 98/Me, Windows 2000/XP:使用平滑滚动,使用 HIWORD(flags) 指出平滑滚动需要多少时间(以毫秒为单位) |
返回值:
1. 如果函数调用成功,返回值是 SIMPLEREGION(矩形的无效区域),COMPLEXREGION(非矩形的无效区域;重叠的矩形)或 NULLREGION(没有无效区域);
2. 如果函数调用失败,返回值是 ERROR。
备注:
1. 如果flags 参数的 SW_INVALIDATE 和 SW_ERASE 标志没有被设定,那么 ScrollWindowEx 函数不能使滚动过的区域失效。如果 flags 参数中任何一个标志被设置,ScrollWindowEx 函数就可以使该区域失效。这个区域就不会被更新直到应用程序调用 UpdateWindow 函数,或调用 RedrawWindow 函数(指定 RDW_UPDATENOW 或 RDW_ERASENOW 标志),或响应 WM_PAINT 消息。
2. 如果窗口拥有 WS_CLIPCHILDREN 类型,那么由 hrgnUpdate 和 prcUpdate 参数指定的返回区域描述了必须更新的滚动窗口的全部区域,包括所需更新子窗口的任何区域。
3. 如果 flags 参数的 SW_SCROLLCHILDREN 标志被设置,那么在子窗口的一部分被滚动时,系统将不能完全更新屏幕。位于矩形外边的滚动子窗体部分不被擦除,也不在它的新方向上被重绘。为了移动子窗体使之完全不在 prcScroll 参数指定的矩形中,可以使用 DeferWindowPos 函数。如果 SW_SCROLLCHILDREN 标志被设置并且插入符矩形和滚动矩形相交重叠,则光标也重新设置。
4. 所有输入和输出坐标(prcScroll, prcClip, prcUpdate 和 hrgnUpdate)均被定义为客户端,无论窗口是否具 CS_OWNDC 或 CS_CLASSDC 类型。必要的话,还可以使用 LPtoDP 和 DPtoLP 函数来转换逻辑坐标和设备坐标。
48:RGB 宏
宏功能:
RGB 宏有三个参数(byRed, byGreen, byBlue),功能是将这三个参数转换为COLORREF 颜色值。
注释:COLORREF 颜色被定义为 DWORD 类型(4 个字节),用于表示 RGB 颜色。
宏定义:
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
参数解析:
参数 | 含义 |
byRed | 红色的颜色值 |
byGreen | 绿色的颜色值 |
byBlue | 蓝色的颜色值 |
小甲鱼忍不住罗嗦补充一句:色彩中不能再分解的基本色称之为原色,红绿蓝即三原色,将它们按照不同比例混合,可以搭配出所有的颜色。
返回值:
1. 返回三个参数转换后的 COLORREF 颜色值
备注:
1. 每个颜色可以指定的颜色值是 0 ~ 255,三个参数同时为 0,即黑色,同时为 255 即白色。
2. 通过 GetRValue、GetGValue和 GetBValue 宏可以分别从 COLORREF 颜色值中获得红色、绿色、蓝色的颜色值。
49:SetPixel
函数功能:
SetPixel 函数将指定坐标处的像素设为指定的颜色。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
COLORREF SetPixel(
_In_ HDChdc,
_In_ intx,
_In_ inty,
_In_ COLORREFcrColor
);
参数解析:
参数 | 含义 |
hdc | 设备环境句柄 |
x | 指定要设置的像素点的 X 轴坐标,按逻辑单位表示坐标 |
y | 指定要设置的像素点的 Y 轴坐标,按逻辑单位表示坐标 |
crColor | 1. 指定该像素点的颜色 |
注释:COLORREF 颜色被定义为 DWORD 类型(4 个字节),用于表示 RGB 颜色。
返回值:
1. 如果函数调用成功,那么返回值就是函数设置像素的 RGB 颜色值(这个值可能与 crColor 指定的颜色有所不同,之所以有时发生这种情况是因为没有找到对指定颜色进行真正匹配造成的);
2. 如果函数调用失败,那么返回值是 -1。
可以是以下值
返回值 | 含义 |
ERROR_INVALID_PARAMETER | 一个或者多个参数不正确 |
备注:
1. 如果像素点坐标位于当前剪裁区之外,那么该函数执行失败。
2. 不是所有设备都支持 SetPixel 函数。有关详情,请参考 GetDeviceCaps。
50:GetRValue、GetGValue 和 GetBValue 宏
宏功能:
GetRValue、GetGValue 和 GetBValue 宏分别从 RGB 颜色值(COLORREF)中获得红色、绿色、蓝色的颜色值。
宏定义:
#define GetRValue(rgb) (LOBYTE(rgb))
#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) (LOBYTE((rgb)>>16))
参数解析:
参数 | 含义 |
rgb | 指定一个 RGB 颜色值(COLORREF) |
返回值:
1. 分别返回三原色(红色、绿色、蓝色)的颜色值。
备注:
颜色值的取值范围是 0 ~ 255
51:GetPixel
函数功能:
GetPixel 函数获得指定坐标处的像素的 RGB 颜色值。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
COLORREF GetPixel(
_In_ HDChdc,
_In_ intnXPos,
_In_ intnYPos
);
参数解析:
参数 | 含义 |
hdc | 设备环境句柄 |
nXPos | 指定要获取的像素点的 X 轴坐标,按逻辑单位表示坐标 |
nYPos | 指定要获取的像素点的 Y 轴坐标,按逻辑单位表示坐标 |
返回值:
1. 返回值是 COLORREF 值,指定像素的 RGB(可以通过 GetRValue、GetGValue和 GetBValue 宏分别获得红、绿、蓝分别的色值);
2. 如果指定的像素点在当前剪裁区之外;那么返回值是 CLR_INVALID。
备注:
1. 如果像素点坐标位于当前剪裁区之外,那么该函数执行失败。
2. 不是所有设备都支持 GetPixel 函数。有关详情,请参考 GetDeviceCaps。
3. 位图必须选入设备环境中,否则也会返回 CLR_INVALID
52:SetPixelV
函数功能:
SetPixelV 函数将指定坐标处的像素设为指定的颜色(与 SetPixel 一样,但效率高一些)。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL SetPixelV(
_In_ HDChdc,
_In_ intX,
_In_ intY,
_In_ COLORREFcrColor
);
参数解析:
参数 | 含义 |
hdc | 设备环境句柄 |
x | 指定要设置的像素点的 X 轴坐标,按逻辑单位表示坐标 |
y | 指定要设置的像素点的 Y 轴坐标,按逻辑单位表示坐标 |
crColor | 1. 指定该像素点的颜色 |
注释:COLORREF 颜色被定义为 DWORD 类型(4 个字节),用于表示 RGB 颜色。
返回值:
1. 如果函数调用成功,返回值为非 0;
2. 如果函数调用失败,返回值为 0。
备注:
1. 不是所有设备都支持 SetPixelV 函数。有关详情,请参考 GetDeviceCaps。
2. SetPixelV 函数比 SetPixel 函数快,因为 SetPixelV 不需要返回实际绘制的像素值(返回布尔类型)。
53:GetDC
函数功能:
GetDC 函数用户获得指定窗口的客户区或整个屏幕的设备环境句柄,随后,你可以在 GDI 函数中使用该句柄在设备环境中绘图。
设备环境是一个不公开的数据结构,它的值供 GDI 函数内部使用。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
HDC GetDC(
_In_ HWNDhWnd
);
参数解析:
参数 | 含义 |
hWnd | 1. 指定的窗口句柄 |
返回值:
1. 如果函数调用成功,返回值是指定窗口的客户区的设备环境句柄;
2. 如果函数调用失败,返回值是 NULL。
备注:
1. GetDC 函数根据指定类型的窗口获得普通的、典型的或特有的设备环境。
2. 对于普通的设备环境,GetDC 函数在每次调用的时候为它赋值默认属性;对于典型的和特有的设备环境,GetDC函数不改变先前设置的属性。
3. 在使用普通的设备环境绘图之后,必须调用 ReleaseDc函数释放该设备环境;典型的和特有的设备环境则不需要释放,设备环境的个数仅受有效内存的限制。
4. 有一点要特别注意,GetDC 函数对系统的开销相对比较大,如果你的应用程序里使用了几百个 GetDC 函数而又不通过 ReleaseDC 函数释放的话,那么你机器运行速度将是龟速。
54:ReleaseDC
函数功能:
ReleaseDC 函数用于释放设备环境,以供其他应用程序使用。
ReleaseDC 函数的效果取决于设备环境的类型,它只能释放普通的和窗口设备环境;对于典型的和特有的设备环境则无效。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
int ReleaseDC(
_In_ HWNDhWnd,
_In_ HDChDC
);
参数解析:
参数 | 含义 |
hWnd | 指定的窗口句柄 |
hDC | 指定将要被释放的设备环境句柄 |
返回值:
返回值说明设备环境是否成功释放
1. 如果设备环境成功释放,返回 1;
2. 如果设备环境没有释放,返回 0。
备注:
1. 每次调用 GetWindowDC 函数和 GetDC 函数获得普通的设备环境之后,应用程序必须调用 ReleaseDC 函数来释放设备环境。
2. 应用程序不能调用 ReleaseDC 函数来释放由 CreateDC 函数创建的设备环境,CreateDC 创建的设备环境只能使用DeleteDC 函数来删除。
3. ReleaseDC 函数必须跟 GetDC 函数同在一个线程内调用。
55: GetWindowDC
函数功能:
GetWindowDC 函数用于获得的整个窗口(包括非客户区)的设备环境,例如标题栏、菜单、滚动条,以及边框。
一个窗口的设备环境允许在任何地方绘画,因为该设备环境的原点为窗口的左上角,而不是客户区。
GetWindowDC 函数每次获得设备环境时都为它赋值默认属性。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
HDC GetWindowDC(
_In_ HWNDhWnd
);
参数解析:
参数 | 含义 |
hWnd | 1. 指定的窗口句柄 |
小甲鱼注释:如果 hWnd 的值是 NULL,GetWindowDC 函数获得的是主显示器(多显示器的情况下)的设备环境,可以通过调用 EnumDisplayMonitors 和 CreateDC 函数获得其他显示器的设备环境。
返回值:
1. 如果函数调用成功,返回值是指定窗口的设备环境句柄;
2. 如果函数调用失败,返回值是 NULL。
备注:
1. GetWindowDC 函数获得的设备环境包含窗口的非客户区,在非客户区进行绘画是不推荐的。
2. 可以通过调用 GetSystemMetrics 函数来获得非客户区的各个部位(如标题栏、菜单或滚动条等)的尺寸。
3. GetDC 函数也可用于获得整个屏幕的设备环境。
4. 绘制结束后,必须调用 ReleaseDC 函数释放设备环境,如没有释放设备环境,对有绘画需求的应用程序将带来严重的影响。
56:CreateDC
函数功能:
CreateDC 函数通过使用指定的名字为一个设备创建设备环境。
API 函数原型:
注释:_In_ 说明该参数是输入的,_out_ 说明该参数是输出的,_opt_ 说明该参数是可选参数。
HDC CreateDC(
LPCTSTRlpszDriver,
_In_ LPCTSTRlpszDevice,
LPCTSTRlpszOutput,
_In_ constDEVMODE *lpInitData
);
参数解析:
参数 | 含义 |
lpszDriver | 1. 指向一个以 NULL 为结束符的字符串指针,它可以是 TEXT("DISPLAY") 或显示设备的名称 |
lpszDevice | 1. 指向一个以 NULL 为结束符的字符串指针,该字符串指定了正在使用的特定输出设备的名字(注意:不是打印机模式名) |
lpszOutput | 这个参数必须为 NULL(仅为兼容 16 位系统而存在) |
lpInitData | 1. 指向一个 DEVMODE 结构,该结构包含指定设备驱动程序初始化时需要的数据 |
返回值:
1. 如果函数调用成功,返回值是指定设备的设备环境句柄;
2. 如果函数调用失败,返回值是 NULL。
备注:
1. 注意,设备环境的句柄在任何时候都只能由单线程使用。
2. 对于 lpszDriver 和 lpszDevice 参数,可以通过调用 EnumDisplayDevices 函数获得显示设备的名字。
3. 如果你不再需要设备环境,请调用 DeleteDC 函数。
57:CreateCompatibleDC
函数功能:
CreateCompatibleDC 函数创建一个与指定设备兼容的内存设备环境(DC)。
API 函数原型:
注释:_In_ 说明该参数是输入的。
HDC CreateCompatibleDC(
_In_ HDChdc
);
参数解析:
参数 | 含义 |
hdc | 1. 指定一个存在的设备环境句柄 |
返回值:
1. 如果函数调用成功,返回值是内存设备环境句柄;
2. 如果函数调用失败,返回值是 NULL。
备注:
1. 内存设备环境是仅在内存中的;当内存设备环境被创建时,它的显示界面是标准的一个单色像素宽和一个单色像素高;在一个应用程序可以使用内存设备环境进行绘图操作之前,它必须选择一个高和宽都正确的位图到设备环境中;可以通过调用 CreateCompatibleBitmap 函数指定高、宽和色彩组合以满足函数调用的需要。
2. 当一个内存设备环境被创建时,所有的特性都被设置为默认值;可以把内存设备环境当作一个普通的设备环境那样去使用:可以设置属性、获得当前的设置、为它选择画笔,刷子和区域。
3. CreateCompatibleDc 函数只适用于支持光栅操作的设备,应用程序可以通过调用 GetDeviceCaps 函数来确定一个设备是否支持这些操作。
4. 当不再需要内存设备环境时,可调用 DeleteDc 函数删除它。
58:CreateMetaFile
函数功能:
CreateMetaFile 函数用于创建一个图元文件的设备环境。
注意:该函数只兼容 Windows 格式的图元文件;对于新的应用程序,推荐使用功能更加卓越的增强型图元文件;调用 CreateEnhMetaFile 函数可以创建增强型图元文件对应的设备环境。
API 函数原型:
注释:_In_ 说明该参数是输入的。
HDC CreateMetaFile(
_In_ LPCTSTRlpszFile
);
参数解析:
参数 | 含义 |
lpszFile | 1. 一个以 NULL 字符为结尾的指针,指向将被创建的 Windows 格式的图元文件的名称 |
返回值:
1. 如果函数调用成功,返回值是 Windows 格式的图元文件的设备环境句柄;
2. 如果函数调用失败,返回值是 NULL。
59: CloseMetaFile
函数功能:
CloseMetaFile 函数用于关闭指定图元文件的设备环境,并返回一个图元文件句柄。
注意:该函数只兼容 Windows 格式的图元文件;对于新的应用程序,推荐使用功能更加卓越的增强型图元文件;调用 CreateEnhMetaFile 函数可以创建增强型图元文件对应的设备环境(调用CloseEnhMetaFile 来关闭它)。
API 函数原型:
注释:_In_ 说明该参数是输入的。
HMETAFILE CloseMetaFile(
_In_ HDChdc
);
参数解析:
参数 | 含义 |
hdc | 图元文件的设备环境句柄,用于创建 Windows 格式的图元文件 |
返回值:
1. 如果函数调用成功,返回值是 Windows 格式的图元文件句柄;
2. 如果函数调用失败,返回值是 NULL。
60:MoveToEx
函数功能:
MoveToEx 函数将当前绘图位置移动到某个具体的点,同时也可获得之前位置的坐标。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL MoveToEx(
_In_ HDC hdc,
_In_ int X,
_In_ int Y,
_Out_ LPPOINTlpPoint
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
X | 指定新位置的 X 轴坐标,按逻辑单位表示坐标 |
Y | 指定新位置的 Y 轴坐标,按逻辑单位表示坐标 |
lpPoint | 1. 一个 POINT结构的指针,用于获得之前位置的坐标 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. MoveExTo 函数将影响所有的绘图函数。
2. 在默认的设备环境中,点 (0, 0) 为最初设定的当前位置。
61:LineTo
函数功能:
LineTo 函数使用当前画笔绘制一条线,线段从当前位置连到一个指定的点 (x, y)。
当这个函数调用完毕后,当前位置变成 (x, y)。
小甲鱼提示:所绘制的线段并不包含指定的点 (x, y)。
API 函数原型:
注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
BOOL LineTo(
_In_ HDChdc,
_In_ intnXEnd,
_In_ intnYEnd
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
nXEnd | 1. 线段终点X坐标位置,采用逻辑坐标表示。 |
nYEnd | 1. 线段终点Y坐标位置,采用逻辑坐标表示。 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
62:POINT 结构
POINT 结构定义了一个点的 x 坐标和 y 坐标。
结构原型:
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT;
成员解析:
成员 | 含义 |
x | 被定义的点的 x 坐标 |
y | 被定义的点的 y 坐标 |
63:GetCurrentPositionEx
函数功能:
GetCurrentPositionEx 函数用于获取逻辑坐标中的当前位置。
API 函数原型:
BOOL GetCurrentPositionEx(
_In_ HDC hdc,
_Out_ LPPOINTlpPoint
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
lpPoint | 一个 POINT结构的指针,用于获得当前逻辑坐标的位置 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
64:Polyline
函数功能:
Polyline 函数将指定数组的连接点绘制成一系列线段(折线)。
API 函数原型:
注释:_In_ 说明该参数是输入的。
BOOL Polyline(
_In_ HDChdc,
_In_ constPOINT *lppt,
_In_ intcPoints
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
lppt | 一个指向 POINT结构的数组的指针(折线的顶点) |
cPoints | 1. lppt 参数指向的数组中顶点(POINT结构)的个数 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 该折线是使用当前画笔,通过将指定数组中的顶点依次连接绘制出来的。
2. 不像 LineTo 或 PolylineTo 函数,Polyline 函数既不会用到当前位置,也不会去修改它。
65:PolylineTo
函数功能:
PolylineTo 函数将指定数组的连接点绘制成一系列线段(折线)。
API 函数原型:
注释:_In_ 说明该参数是输入的。
BOOL PolylineTo(
_In_ HDChdc,
_In_ constPOINT *lppt,
_In_ DWORDcCount
);
参数解析:
参数 | 含义 |
hdc | 指定设备环境句柄 |
lppt | 一个指向 POINT结构的数组的指针(折线的顶点) |
cCount | 1. lppt 参数指向的数组中顶点(POINT结构)的个数 |
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 不像 Polyline<