1、SYSMETS.C:
/*SYSMETS.C——System Metrics Display Program No.1*/
#include<window.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[] = TEXT("SysMets1");
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.lpseClassName = szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires Windows NT!"),
szAppName,MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName,TEXT("Get System Metrics No.1"),
WS_OVERLAPPEDWINDOW,
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 message,WPARAM wParam,LPARAM lParam)
{
static int cxChar,cxCaps,cyChar;
HDC hdc;
int i;
PAINTSTRUCT ps;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch(message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc,&tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3:2)*cxChar/2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd,hdc);
return 0;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
for (i = 0 ; i < NUMLINES ; i++)
{
TextOut (hdc, 0, cyChar * i, // <span style="font-family: Arial, Helvetica, sans-serif;">cyChar * i这个</span>参数指示了字符串顶端相对于显示区域顶部的图素位置
sysmetrics[i].szLabel, //文字的内容来自sysmetrics结构的szLabel字段。
lstrlen (sysmetrics[i].szLabel)) ;
TextOut (hdc, 22 * cxCaps, cyChar * i, //显示了对系统尺寸值的描述,第一列显示的最长的大写标识符有20个字符,用22是为了两列中多一点空间。
sysmetrics[i].szDesc,
lstrlen (sysmetrics[i].szDesc)) ;
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;//指定字符串结束的图素位置,以此向右对齐数字。
TextOut (hdc, 22 * cxCaps + 40 * cxChar, cyChar * i, szBuffer, //第三条TextOut叙述显示从GetSystemMetrics函数取得的数值。
wsprintf (szBuffer, TEXT ("%5d"), //值40*cxChar包含了第二列的宽度和第三列的宽度
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, message, wParam, lParam) ;
}
扩展阅读:
LRESULT就是LONG
CALLBACK专用在回调函数里,看看VC/BCB里的定义
VC:WINDEF.h
#define CALLBACK PASCAL //_pascal
#define WINAPI CDECL //_cdecl
BCB:windef.h
#define CALLBACK __stdcall
#define WINAPI __stdcall
__cdecl是
C/C++
和MFC程序默认使用的调用约定,也可以在
函数声明
时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数
弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
__stdcall调用约定用于调用Win32 API函数 。采用__stdcal约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
__fastcall 约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall。
在默认情况下,采用__cdecl方式,因此可以省略.
WINAPI一般用于修饰 动态链接库 中导出函数
CALLBACK仅用于修饰回调函数
/*显示区域大小:在窗口消息处理程序中处理WM_SIZE消息*/
static int cxClient,cyClient; //低字组中显示区域的宽度,高字组包含显示区域的高度
caseWM_SIZE;
cxClient = LOWORD(lParam);
cyClient = HIWORD(lparam);
return 0;
/*WINDEF.H的定义*/
#define LOWORD(I)(WORD)(I))|
#define HIWORD(I)(WORD)(((DWORD)(I) >> 16) & 0xFFFF))//这两个宏传回WORD值(16位的无正负号整数,范围从0到0xFFFF)
CS_HREDRAW|CS_VREDRAW //窗口类别种的定义,其告诉windows,水平或垂直发生改变,则强制更新显示区域。
/*显示区域内显示文字的总行数,结果为0时,表示高度太小无法显示一个完整字符*/
cyClient/cyChar
可编译代码:
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <windows.h>
#include"sysmets.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("SysMets");
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_HREDRAW|CS_VREDRAW; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("SysMets"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar,cxCaps,cyChar;
HDC hdc;
int i;
PAINTSTRUCT ps;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch (message) /* handle the messages */
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc,&tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3:2)*cxChar/2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd,hdc);
return 0;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
for (i = 0 ; i < NUMLINES ; i++)
{
TextOut (hdc, 0, cyChar * i, // <span style="font-family: Arial, Helvetica, sans-serif;">cyChar * i这个</span>参数指示了字符串顶端相对于显示区域顶部的图素位置
sysmetrics[i].szLabel, //文字的内容来自sysmetrics结构的szLabel字段。
lstrlen (sysmetrics[i].szLabel)) ;
TextOut (hdc, 22 * cxCaps, cyChar * i, //显示了对系统尺寸值的描述,第一列显示的最长的大写标识符有20个字符,用22是为了两列中多一点空间。
sysmetrics[i].szDesc,
lstrlen (sysmetrics[i].szDesc)) ;
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;//指定字符串结束的图素位置,以此向右对齐数字。
TextOut (hdc, 22 * cxCaps + 40 * cxChar, cyChar * i, szBuffer, //第三条TextOut叙述显示从GetSystemMetrics函数取得的数值。
wsprintf (szBuffer, TEXT ("%5d"), //值40*cxChar包含了第二列的宽度和第三列的宽度
GetSystemMetrics (sysmetrics[i].iIndex))) ;
SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}