Author: 秋时残叶
Date: 2017.12.29
《windows程序设计》笔记
1.
BOOL InvalidateRect(HWND hwnd, CONST RECT *lpRect, BOOL bErase); //使矩形失效,以产生WM_PAINT消息
2.
BOOL InvalidateRng(HWND hwnd, HRGN hRgn, BOOL bErase);
BOOL ValidateRect(HWND hwnd, CONST RECT *lpRect); //使客户区中任意矩形变得有效
4. 获取设备环境句柄
4_1.
HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint); //擦去无效区域的背景以便绘图
【使用GDI函数】
EndPaint(HWND hwnd, CONST PAINTSTRUCT *lpPaint);
typedef struct tagPAINTSTRUCT { // ps
HDC hdc;
BOOL fErase; //0 意味window在先前的BeginPaint()中已经擦除了无效区域的背景(若要自定义擦除方式,需要处理WM_ERAEBKGND)
画刷是hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH)指定的。
RECT rcPaint; //定义了无效矩形的边界
BOOL fRestore; //其它windows内部使用
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;
4_2.
hdc = GetDC(hwnd); //获取窗口客户区环境句柄
【使用GDI函数】
ReleaseDC(hwnd, hdc);
注:GetDC不会将无效区域有效化,若要整个客户区有效化,可以用:
ValidateRect(hwnd, NULL);
HDC GetWindowDC(HWND hwnd); //GetDC返回的是窗口客户区的设备环境句柄,GetWindowDC返回的是整个窗口的设备环境句柄
//WM_NCPAINT //非客户区绘制消息
5.
BOOL TextOut(HDC hdc, //可BeginPaint()返回,也可是GetDC获取的, 环境中的属性决定了文本显示的特性
int nxStart, //逻辑坐标, "MM_TEXT"映射属性
int nyStart,
LPCTSTR lpString, //指向字符串的指针
int cbString //字符串中的字符数
);
TextOut(hdc, x, y, psText, iLength);
6.
SYSTEM_FONT //系统字体, 等宽字体, 标题栏,菜单,对话框中使用
7.
int GetSystemMetrics(int nIndex); /获取用户界面尺寸,包括键盘,鼠标...等信息
8.
BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm); //获取字体尺寸
//字符尺寸结构,仅关心前7个
typedef struct tagTEXTMETRIC { // tm
LONG tmHeight; //tmAscent + tmDescent
LONG tmAscent; //基线之上最大高度
LONG tmDescent; //基线之下最大高度
LONG tmInternalLeading; //内部间距
LONG tmExternalLeading; //建议在两行文字间留出的空间大小
LONG tmAveCharWidth; //小写字母加权平均宽度
LONG tmMaxCharWidth; //字体中最宽字符的宽度
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
BCHAR tmFirstChar;
BCHAR tmLastChar;
BCHAR tmDefaultChar;
BCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily; //低位决定字体是否为等宽字体 1:变宽 0:等宽
BYTE tmCharSet;
} TEXTMETRIC;
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
wprintf TextOut组合使用:
TCHAR szBuffer[40];
int iLength;
iLength = wprintf(szBuffer, TEXT("text"));
TextOut(hdc, x, y, szBuffer, iLength);
9.
UINT SetTextAlign(HDC hdc, UINT fMode); //字符对齐方式
10. 滚动条(旧函数)
10_1.
BOOL SetScrollRange(hwnd, iBar, iMin, iMax, bRedraw); //设置滚动条范围
//iBar: SB_VERT SB_HORZ
//bRedraw:需要windows根据新的范围来重绘按钮,bRedraw设为TRUE
//若在调用SetScrollRange后还将调用其它函数来调整滚动条的显示时,设为FALSE以免过多重绘
10_2.
int SetScrollPos(hwnd, iBar, iPos, bRedraw); //指定滑块在滚动条范围中的位置
10_3.
BOOL GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos); //获取滚动条当前范围
10_4.
int GetScrollPos(HWND hwnd, int nBar); //获取滚动条当前位置
滚动条消息
WM_VSCROLL WM_HSCROLL都伴随着wParam和lParam消息参数
当滚动条是窗口的一部分时, 可以忽略lParam参数:只用于滚动条是子窗口时,通常在对话框中
wParam低位字:鼠标在滚动条上的动作 "通知码" SB_xxx
含有LEFT,RIGHT的标识符用于水平滚动条中
含有UP,DOWN,TOP,BOTTOM的用于垂直滚动条中
11. Win32新引入滚动条函数
11_1.
int SetScrollInfo(hwnd, iBar, &si, bRedraw);
//iBar:SB_VERT SB_HORZ SB_CTL(表示一个滚动条控件)
//&si LPSCROLLINFO
typedef struct tagSCROLLINFO { // si
UINT cbSize; //sizeof(SCROLLINFO)
UINT fMask; //要设置或获取的值 一个或多个以SIF_xxx的标志
int nMin; //范围的最小值
int nMax; //范围的最大值
UINT nPage; //页面大小
int nPos; //当前位置
int nTrackPos; //当前追踪位置
}SCROLLINFO;
typedef SCROLLINFO FAR *LPSCROLLINFO;
例子:
SCROLLINFO si;
si.cbSize = sizeof(si); //先将size设为该结构的大小
//或者:
si.cbSize = sizeof(SCROLLINFO);
注:设置大小是为了以后的windows版本可以扩充结构而同时保持与以前的应用程序兼容
【fMask:】
SetScrollInfo:
SIF_RANGE:必须在nMin和nMax中指定滚动条的位置
SIF_POS:须在nPos字段中指定滚动条的位置
SIF_PAGE: 指定页面大小
SIF_TRACKPOS:只用于set中,只在处理SB_THUMBTRACK或SB_THUMBPOSRION的WM_VSCROLL或WM_HSCROLL时,
函数返回时, nTrackPos将返回当前滑块的位置(32位整数)
SIF_DISABLENOSCROLL:原来让滚动条不显示的设置这里将禁用滚动条 不想隐藏滚动条时调用
SIF_ALL:SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS的组合
GetScrollInfo:
SIF_RANGE:nMin和nMax将返回当前的范围
SIF_POS时: nPos返回滚动条的位置
SIF_PAGE: 获取页面大小
11_2.
GetScrollInfo(hwnd, iBar, &si); //获取滚动条信息
12.
ScrollWindow(hwnd, x, y, NULL, NULL); //滚动窗口
实例:SysMets1
//sysmets.h
#pragma once
#include <windows.h>
#define NUMLINES ((int)(sizeof sysmetrics / sizeof sysmetrics[0]))
struct
{
int iIndex;
TCHAR * szLabel;
TCHAR * szDesc;
}
sysmetrics[] =
{
SM_CXSCREEN, L"SM_CXSCREEN",
L"Screen width in pixels",
SM_CYSCREEN, L"SM_CYSCREEN",
L"Screen height in pixels",
SM_CXVSCROLL, L"SM_CXVSCROLL",
L"Vertical scroll width",
SM_CYHSCROLL, L"SM_CYHSCROLL",
L"Horizontal scroll height",
SM_CYCAPTION, L"SM_CYCAPTION",
L"Caption bar height",
SM_CXBORDER, L"SM_CXBORDER",
L"Window border width",
SM_CYBORDER, L"SM_CYBORDER",
L"Window border height",
SM_CXFIXEDFRAME, L"SM_CXFIXEDFRAME",
L"Dialog window frame width",
SM_CYFIXEDFRAME, L"SM_CYFIXEDFRAME",
L"Dialog window frame height",
SM_CYVTHUMB, L"SM_CYVTHUMB",
L"Vertical scroll thumb height",
SM_CXHTHUMB, L"SM_CXHTHUMB",
L"Horizontal scroll thumb width",
SM_CXICON, L"SM_CXICON",
L"Icon width",
SM_CYICON, L"SM_CYICON",
L"Icon height",
SM_CXCURSOR, L"SM_CXCURSOR",
L"Cursor width",
SM_CYCURSOR, L"SM_CYCURSOR",
L"Cursor height",
SM_CYMENU, L"SM_CYMENU",
L"Menu bar height",
SM_CXFULLSCREEN, L"SM_CXFULLSCREEN",
L"Full screen client area width",
SM_CYFULLSCREEN, L"SM_CYFULLSCREEN",
L"Full screen client area height",
SM_CYKANJIWINDOW, L"SM_CYKANJIWINDOW",
L"Kanji window height",
SM_MOUSEPRESENT, L"SM_MOUSEPRESENT",
L"Mouse present flag",
SM_CYVSCROLL, L"SM_CYVSCROLL",
L"Vertical scroll arrow height",
SM_CXHSCROLL, L"SM_CXHSCROLL",
L"Horizontal scroll arrow width",
SM_DEBUG, L"SM_DEBUG",
L"Debug version flas",
SM_SWAPBUTTON, L"SM_SWAPBUTTON",
L"Mouse buttons swapped flag",
SM_CXMIN, L"SM_CXMIN",
L"Minimum window width",
SM_CYMIN, L"SM_CYMIN",
L"Mininmum window height",
SM_CXSIZE, L"SM_CXSIZE",
L"Min/Max/Close button width",
SM_CYSIZE, L"SM_CYSIZE",
L"Min/Max/Close button height",
SM_CXSIZEFRAME, L"SM_CXSIZEFRAME",
L"Window sizing frame width",
SM_CYSIZEFRAME, L"SM_CYSIZEFRAME",
L"Window sizing frame height",
SM_CXMINTRACK, L"SM_CXMINTRACK",
L"Minimum window tracking width",
SM_CYMINTRACK, L"SM_CYMINTRACK",
L"Minimum window tracking height",
SM_CXDOUBLECLK, L"SM_CXDOUBLECLK",
L"Double click x tolerance",
SM_CYDOUBLECLK, L"SM_CYDOUBLECLK",
L"Double click y tolerance",
SM_CXICONSPACING, L"SM_CXICONSPACING",
L"Horizontal icon spacing",
SM_CYICONSPACING, L"SM_CYICONSPACING",
L"Vertical icon spacing",
SM_MENUDROPALIGNMENT, L"SM_MENUDROPALIGNMENT",
L"Left or right menu drop",
SM_PENWINDOWS, L"SM_PENWINDOWS",
L"Pen extensions installed",
SM_DBCSENABLED, L"SM_DBCSENABLED",
L"Double-byte Char Set enabled",
SM_SECURE, L"SM_SECURE",
L"Security present flag",
SM_CXEDGE, L"SM_CXEDGE",
L"3 - D border width",
SM_CYEDGE, L"SM_CYEDGE",
L"3 - D border height",
SM_CXMINSPACING, L"SM_CXMINSPACING",
L"Minimized window spacing width",
SM_CYMINSPACING, L"SM_CYMINSPACING",
L"Minimized window spacing height",
SM_CXSMICON, L"SM_CXSMICON",
L"Small icon width",
SM_CYSMICON, L"SM_CYSMICON",
L"Small icon height",
SM_CYSMCAPTION, L"SM_CYSMCAPTION",
L"Small caption height",
SM_CXSMSIZE, L"SM_CXSMSIZE",
L"Small caption button width",
SM_CYSMSIZE, L"SM_CYSMSIZE",
L"Small caption button height",
SM_CXMENUSIZE, L"SM_CXMENUSIZE",
L"Menu bar button width",
SM_CYMENUSIZE, L"SM_CYMENUSIZE",
L"Menu bar button height",
SM_ARRANGE, L"SM_ARRANGE",
L"How minimized",
SM_CXMINIMIZED, L"SM_CXMINIMIZED",
L"Minimized window width",
SM_CYMINIMIZED, L"SM_CYMINIMIZED",
L"Minimized window height",
SM_CXMAXTRACK, L"SM_CXMAXTRACK",
L"Maximum draggable width",
SM_CYMAXTRACK, L"SM_CYMAXTRACK",
L"Maximum draggable height",
SM_CXMAXIMIZED, L"SM_CXMAXIMIZED",
L"Width of maximized window",
SM_CYMAXIMIZED, L"SM_CYMAXIMIZED",
L"Height of maximized window",
SM_NETWORK, L"SM_NETWORK",
L"Network present flag",
SM_CLEANBOOT, L"SM_CLEANBOOT",
L"How system was booted",
SM_CXDRAG, L"SM_CXDRAG",
L"Avoid drag x tolerance",
SM_CYDRAG, L"SM_CYDRAG",
L"Avoid drag y tolerance",
SM_SHOWSOUNDS, L"SM_SHOWSOUNDS",
L"Present sounds visually",
SM_CXMENUCHECK, L"SM_CXMENUCHECK",
L"Menu check-mark width",
SM_CYMENUCHECK, L"SM_CYMENUCHECK",
L"Menu check-mark height",
SM_SLOWMACHINE, L"SM_SLOWMACHINE",
L"Slow processor flag",
SM_MIDEASTENABLED, L"SM_MIDEASTNABLED",
L"Hebrew and Arabic enabled flag",
SM_MOUSEWHEELPRESENT, L"SM_MOUSEWHEELPRESENT",
L"Mouse wheel present flag",
SM_XVIRTUALSCREEN, L"SM_XVIRTUALSCREEN",
L"Virtual screen x origin",
SM_YVIRTUALSCREEN, L"SM_YVIRTUALSCREEN",
L"Virtual screen y origin",
SM_CXVIRTUALSCREEN, L"SM_CXVIRTUALSCREEN",
L"Virtual screen width",
SM_CYVIRTUALSCREEN, L"SM_VYVIRTUALSCREEN",
L"Virtual screen height",
SM_CMONITORS, L"SM_CMONITORS",
L"Number of monitors",
SM_SAMEDISPLAYFORMAT, L"SM_SAMEDISPLAYFORMAT",
L"Same color format flag"
};
//main.cpp
#include <windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = L"SysMets1";
HWND hWnd;
WNDCLASS wndclass;
MSG msg;
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 = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, L"This program requires Windows!", szAppName, MB_ICONERROR);
return 0;
}
hWnd = CreateWindow(szAppName, L"Get System Metrics No. 1",
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
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 uMsg, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cyChar, cxCaps, cyClient, iVscrollPos;
HDC hdc;
int i, y;
PAINTSTRUCT ps;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch (uMsg)
{
case WM_CREATE:
hdc = GetDC(hWnd);
GetTextMetrics(hdc, &tm); //获取字体尺寸
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2; //依据变宽还是等宽字体设置宽度
ReleaseDC(hWnd, hdc);
SetScrollRange(hWnd, SB_VERT, 0, NUMLINES - 1, FALSE); //设定范围
SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE); //设定初始位置
return 0;
case WM_VSCROLL:
switch (LOWORD(wParam))
{
case SB_LINEUP:
iVscrollPos -= 1;
break;
case SB_LINEDOWN:
iVscrollPos += 1;
break;
case SB_PAGEUP:
iVscrollPos -= cyClient / cyChar; //移动一屏文字
break;
case SB_PAGEDOWN:
iVscrollPos += cyClient / cyChar;
break;
case SB_THUMBPOSITION:
iVscrollPos = HIWORD(wParam); //移动后的滚动条位置,新滑块位置就是wParam高位
break;
default:
break;
}
iVscrollPos = max(0, min(iVscrollPos, NUMLINES - 1)); //保证值在滚动条范围内
if (iVscrollPos != GetScrollPos(hWnd, SB_VERT)) //若当前位置 != 先前位置,则更新位置
{
SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE);
InvalidateRect(hWnd, NULL, FALSE); //使整个窗口无效
//UpdateWindow(hWnd); //有无效区域, 调用窗口过程 立即更新
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i = 0; i < NUMLINES; i++)
{
y = cyChar * (i - iVscrollPos); //显示的y坐标
TextOut(hdc, 0, y,
sysmetrics[i].szLabel,
lstrlen(sysmetrics[i].szLabel));
TextOut(hdc, 22 * cxCaps, y,
sysmetrics[i].szDesc,
lstrlen(sysmetrics[i].szDesc));
SetTextAlign(hdc, TA_RIGHT | TA_TOP); //设置接下来文字的对齐方式
TextOut(hdc, 22 * cxCaps + 40 * cxChar, y, szBuffer,
wsprintf(szBuffer, L"%5d",
GetSystemMetrics(sysmetrics[i].iIndex)));
SetTextAlign(hdc, TA_LEFT | TA_TOP); //还原对齐方式
}
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
输出:
实例:SysMets3
//sysmets.h
#pragma once
#pragma once
#include <windows.h>
#define NUMLINES ((int)(sizeof sysmetrics / sizeof sysmetrics[0]))
struct
{
int iIndex;
TCHAR * szLabel;
TCHAR * szDesc;
}
sysmetrics[] =
{
SM_CXSCREEN, L"SM_CXSCREEN",
L"Screen width in pixels",
SM_CYSCREEN, L"SM_CYSCREEN",
L"Screen height in pixels",
SM_CXVSCROLL, L"SM_CXVSCROLL",
L"Vertical scroll width",
SM_CYHSCROLL, L"SM_CYHSCROLL",
L"Horizontal scroll height",
SM_CYCAPTION, L"SM_CYCAPTION",
L"Caption bar height",
SM_CXBORDER, L"SM_CXBORDER",
L"Window border width",
SM_CYBORDER, L"SM_CYBORDER",
L"Window border height",
SM_CXFIXEDFRAME, L"SM_CXFIXEDFRAME",
L"Dialog window frame width",
SM_CYFIXEDFRAME, L"SM_CYFIXEDFRAME",
L"Dialog window frame height",
SM_CYVTHUMB, L"SM_CYVTHUMB",
L"Vertical scroll thumb height",
SM_CXHTHUMB, L"SM_CXHTHUMB",
L"Horizontal scroll thumb width",
SM_CXICON, L"SM_CXICON",
L"Icon width",
SM_CYICON, L"SM_CYICON",
L"Icon height",
SM_CXCURSOR, L"SM_CXCURSOR",
L"Cursor width",
SM_CYCURSOR, L"SM_CYCURSOR",
L"Cursor height",
SM_CYMENU, L"SM_CYMENU",
L"Menu bar height",
SM_CXFULLSCREEN, L"SM_CXFULLSCREEN",
L"Full screen client area width",
SM_CYFULLSCREEN, L"SM_CYFULLSCREEN",
L"Full screen client area height",
SM_CYKANJIWINDOW, L"SM_CYKANJIWINDOW",
L"Kanji window height",
SM_MOUSEPRESENT, L"SM_MOUSEPRESENT",
L"Mouse present flag",
SM_CYVSCROLL, L"SM_CYVSCROLL",
L"Vertical scroll arrow height",
SM_CXHSCROLL, L"SM_CXHSCROLL",
L"Horizontal scroll arrow width",
SM_DEBUG, L"SM_DEBUG",
L"Debug version flas",
SM_SWAPBUTTON, L"SM_SWAPBUTTON",
L"Mouse buttons swapped flag",
SM_CXMIN, L"SM_CXMIN",
L"Minimum window width",
SM_CYMIN, L"SM_CYMIN",
L"Mininmum window height",
SM_CXSIZE, L"SM_CXSIZE",
L"Min/Max/Close button width",
SM_CYSIZE, L"SM_CYSIZE",
L"Min/Max/Close button height",
SM_CXSIZEFRAME, L"SM_CXSIZEFRAME",
L"Window sizing frame width",
SM_CYSIZEFRAME, L"SM_CYSIZEFRAME",
L"Window sizing frame height",
SM_CXMINTRACK, L"SM_CXMINTRACK",
L"Minimum window tracking width",
SM_CYMINTRACK, L"SM_CYMINTRACK",
L"Minimum window tracking height",
SM_CXDOUBLECLK, L"SM_CXDOUBLECLK",
L"Double click x tolerance",
SM_CYDOUBLECLK, L"SM_CYDOUBLECLK",
L"Double click y tolerance",
SM_CXICONSPACING, L"SM_CXICONSPACING",
L"Horizontal icon spacing",
SM_CYICONSPACING, L"SM_CYICONSPACING",
L"Vertical icon spacing",
SM_MENUDROPALIGNMENT, L"SM_MENUDROPALIGNMENT",
L"Left or right menu drop",
SM_PENWINDOWS, L"SM_PENWINDOWS",
L"Pen extensions installed",
SM_DBCSENABLED, L"SM_DBCSENABLED",
L"Double-byte Char Set enabled",
SM_SECURE, L"SM_SECURE",
L"Security present flag",
SM_CXEDGE, L"SM_CXEDGE",
L"3 - D border width",
SM_CYEDGE, L"SM_CYEDGE",
L"3 - D border height",
SM_CXMINSPACING, L"SM_CXMINSPACING",
L"Minimized window spacing width",
SM_CYMINSPACING, L"SM_CYMINSPACING",
L"Minimized window spacing height",
SM_CXSMICON, L"SM_CXSMICON",
L"Small icon width",
SM_CYSMICON, L"SM_CYSMICON",
L"Small icon height",
SM_CYSMCAPTION, L"SM_CYSMCAPTION",
L"Small caption height",
SM_CXSMSIZE, L"SM_CXSMSIZE",
L"Small caption button width",
SM_CYSMSIZE, L"SM_CYSMSIZE",
L"Small caption button height",
SM_CXMENUSIZE, L"SM_CXMENUSIZE",
L"Menu bar button width",
SM_CYMENUSIZE, L"SM_CYMENUSIZE",
L"Menu bar button height",
SM_ARRANGE, L"SM_ARRANGE",
L"How minimized",
SM_CXMINIMIZED, L"SM_CXMINIMIZED",
L"Minimized window width",
SM_CYMINIMIZED, L"SM_CYMINIMIZED",
L"Minimized window height",
SM_CXMAXTRACK, L"SM_CXMAXTRACK",
L"Maximum draggable width",
SM_CYMAXTRACK, L"SM_CYMAXTRACK",
L"Maximum draggable height",
SM_CXMAXIMIZED, L"SM_CXMAXIMIZED",
L"Width of maximized window",
SM_CYMAXIMIZED, L"SM_CYMAXIMIZED",
L"Height of maximized window",
SM_NETWORK, L"SM_NETWORK",
L"Network present flag",
SM_CLEANBOOT, L"SM_CLEANBOOT",
L"How system was booted",
SM_CXDRAG, L"SM_CXDRAG",
L"Avoid drag x tolerance",
SM_CYDRAG, L"SM_CYDRAG",
L"Avoid drag y tolerance",
SM_SHOWSOUNDS, L"SM_SHOWSOUNDS",
L"Present sounds visually",
SM_CXMENUCHECK, L"SM_CXMENUCHECK",
L"Menu check-mark width",
SM_CYMENUCHECK, L"SM_CYMENUCHECK",
L"Menu check-mark height",
SM_SLOWMACHINE, L"SM_SLOWMACHINE",
L"Slow processor flag",
SM_MIDEASTENABLED, L"SM_MIDEASTNABLED",
L"Hebrew and Arabic enabled flag",
SM_MOUSEWHEELPRESENT, L"SM_MOUSEWHEELPRESENT",
L"Mouse wheel present flag",
SM_XVIRTUALSCREEN, L"SM_XVIRTUALSCREEN",
L"Virtual screen x origin",
SM_YVIRTUALSCREEN, L"SM_YVIRTUALSCREEN",
L"Virtual screen y origin",
SM_CXVIRTUALSCREEN, L"SM_CXVIRTUALSCREEN",
L"Virtual screen width",
SM_CYVIRTUALSCREEN, L"SM_VYVIRTUALSCREEN",
L"Virtual screen height",
SM_CMONITORS, L"SM_CMONITORS",
L"Number of monitors",
SM_SAMEDISPLAYFORMAT, L"SM_SAMEDISPLAYFORMAT",
L"Same color format flag"
};
//main.cpp
#include <windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = L"SysMets1";
HWND hWnd;
WNDCLASS wndclass;
MSG msg;
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 = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, L"This program requires Windows!", szAppName, MB_ICONERROR);
return 0;
}
hWnd = CreateWindow(szAppName, L"Get System Metrics No. 1",
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
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 uMsg, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cyChar, cxCaps, cyClient, cxClient, iMaxWidth;
HDC hdc;
int i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
PAINTSTRUCT ps;
SCROLLINFO si;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch (uMsg)
{
case WM_CREATE:
hdc = GetDC(hWnd);
GetTextMetrics(hdc, &tm); //获取字体尺寸
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2; //依据变宽还是等宽字体设置宽度
ReleaseDC(hWnd, hdc);
//SetScrollRange(hWnd, SB_VERT, 0, NUMLINES - 1, FALSE); //设定范围
//SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE); //设定初始位置
iMaxWidth = 40 * cxChar + 22 * cxCaps;
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
//设置垂直滚动条范围和页面大小
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = NUMLINES - 1;
si.nPage = cyClient / cyChar;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
//设置水平滚动条范围和页面大小
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + iMaxWidth / cxChar;
si.nPage = cxClient / cxChar;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
return 0;
case WM_VSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hWnd, SB_VERT, &si); //获取滚动条信息
iVertPos = si.nPos; //当前位置
switch (LOWORD(wParam))
{
case SB_TOP:
si.nPos += si.nMin;
break;
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;
default:
break;
}
si.fMask = SIF_POS;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
GetScrollInfo(hWnd, SB_VERT, &si);
if (si.nPos != iVertPos) //若当前位置 != 先前位置,则滚动窗口
{
ScrollWindow(hWnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL);
UpdateWindow(hWnd);
}
return 0;
case WM_HSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hWnd, SB_HORZ, &si); //获取滚动条信息
iHorzPos = 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_THUMBPOSITION:
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 != iHorzPos)
{
ScrollWindow(hWnd, cxChar * (iHorzPos - si.nPos), 0, NULL, NULL);
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//获取垂直滚动条位置
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(hWnd, SB_VERT, &si);
iVertPos = si.nPos;
//获取水平滚动条位置
GetScrollInfo(hWnd, SB_HORZ, &si);
iHorzPos = si.nPos;
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);
for (i = 0; i < NUMLINES; i++)
{
x = cxChar * (1 - iHorzPos);
y = cyChar * (i - iVertPos);
TextOut(hdc, x, y,
sysmetrics[i].szLabel,
lstrlen(sysmetrics[i].szLabel));
TextOut(hdc, x + 22 * cxCaps, y,
sysmetrics[i].szDesc,
lstrlen(sysmetrics[i].szDesc));
SetTextAlign(hdc, TA_RIGHT | TA_TOP); //设置接下来文字的对齐方式
TextOut(hdc, x + 32 * cxCaps + 40 * cxChar, y, szBuffer,
wsprintf(szBuffer, L"%5d",
GetSystemMetrics(sysmetrics[i].iIndex)));
SetTextAlign(hdc, TA_LEFT | TA_TOP); //还原对齐方式
}
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
输出: