《Windows API每日一练》5.4 键盘消息和字符集

本节我们将通过实例来说明不同国家的语言、字符集和字体之间的差异,以及Windows系统是如何处理的。

本节必须掌握的知识点:

        第31练:显示键盘消息

        非英语键盘问题

        字符集和字体

        第32练:显示默认字体信息

        第33练:创建逻辑字体

5.4.1 第31练:显示键盘消息

/*------------------------------------------------------------------

031  WIN32 API 每日一练

     第31个例子:显示键盘按键消息

     SetBkMode函数

     GetKeyNameText函数

     ScrollWindow函数

(c) www.bcdaren.com, 2020

----------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("KEYVIEW1.C") ;

    (略)

     return msg.wParam ;

}

//窗口过程

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    static int cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar;

    static int cLinesMax, cLines;

    TEXTMETRIC tm;

    static RECT  rectScroll;

    static PMSG pmsg;

    HDC         hdc;

    PAINTSTRUCT ps;

    static TCHAR  szTop[] = TEXT("Message        Key       Char     Repeat Scan Ext ALT Prev Tran");

    static TCHAR  szUnd[] = TEXT("_______        ___       ____     ______ ____ ___ ___ ____ ____");

    static TCHAR* szFormat[2] = {

        TEXT("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),

        TEXT("%-13s            0X%04X%1s%c %6u %4d %3s %3s %4s %4s") };

    TCHAR szBuf[128], szKeyName[32];

    static TCHAR* szMessage[] = {

        TEXT("WM_KEYDOWN"), TEXT("WM_KEYUP"),

        TEXT("WM_CHAR"), TEXT("WM_DEADCHAR"),

        TEXT("WM_SYSKEYDOWN"), TEXT("WM_SYSKEYUP"),

        TEXT("WM_SYSCHAR"), TEXT("WM_SYSDEADCHAR") };

    int iType;

    static TCHAR* szYes = TEXT("Yes");

    static TCHAR* szNo = TEXT("No");

    static TCHAR* szDown = TEXT("Down");

    static TCHAR* szUp = TEXT("Up");

    switch (message)

    {

    case WM_CREATE:

    case WM_DISPLAYCHANGE://显示器分辨率改变时,此消息仅发送到顶级窗口

        //获得最大的客户区

        cxClientMax = GetSystemMetrics(SM_CXMAXIMIZED);

        cyClientMax = GetSystemMetrics(SM_CYMAXIMIZED);

        //获得等宽字体的大小

        hdc = GetDC(hwnd);

        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));//选入系统等宽字体

        GetTextMetrics(hdc, &tm);//检索字体文本的度量信息

        cxChar = tm.tmAveCharWidth;

        cyChar = tm.tmHeight;

        ReleaseDC(hwnd, hdc);

        //为消息数组分配内存

        if (pmsg) free(pmsg);

        cLinesMax = cyClientMax / cyChar;

        pmsg = malloc(cLinesMax* sizeof(MSG));

        cLines = 0;

        //return 0 ;  //继续执行WM_SIZE

    case WM_SIZE:

        cxClient = LOWORD(lParam);

        cyClient = HIWORD(lParam);

        //计算滚动窗口的范围

        rectScroll.top = cyChar; //第二行开始(因第1行为标题)

        rectScroll.left = 0;

//不等于cyClient,应等于每行高度*行数。

        rectScroll.bottom = cyChar*(cyClient / cyChar);

        rectScroll.right = cxClient;

        //重绘,该行不可删除,可能是WM_INPUTLANGCHANGE或WM_DISPLAYCHANGE引起

        InvalidateRect(hwnd, NULL, TRUE);

        return 0;

    case WM_KEYDOWN:

    case WM_KEYUP:

    case WM_CHAR:

    case WM_DEADCHAR:

    case WM_SYSKEYDOWN:

    case WM_SYSKEYUP:

    case WM_SYSCHAR:

    case WM_SYSDEADCHAR:

        //重新安排消息数组

        for (int i = cLinesMax - 1; i > 0; i--)

        {

            pmsg[i] = pmsg[i - 1];

        }

        //把当前消息存入消息数组的首元素

        pmsg[0].message = message;

        pmsg[0].hwnd = hwnd;

        pmsg[0].wParam = wParam;

        pmsg[0].lParam = lParam;

        cLines = min(cLines + 1, cLinesMax); //每按一个按键,增加一行。

        //滚屏

        ScrollWindow(hwnd, 0, -cyChar, &rectScroll, &rectScroll);

        //return 0;  //不直接return,因为系统击键消息还要调用DefWindowProc处理

    case WM_PAINT:

        hdc = BeginPaint(hwnd, &ps);

        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

        SetBkMode(hdc, TRANSPARENT);//背景模式---透明模式

        TextOut(hdc, 0, 0, szTop, lstrlen(szTop));

        TextOut(hdc, 0, 0, szUnd, lstrlen(szUnd));

        //显示消息数组的内容

        for (int i = 0; i < min(cLines, cyClient / cyChar - 1); i++)

        {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值