第25周-window程序设计(基础篇)-第4章-SYSMETS.C窗口消息处理程序

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值