Windows键盘操作

Author:秋时残叶
Date:2018.01.01
《Windows程序设计》笔记

1.获取键的状态

//若被按下,iState为负
iState = GetKeyState(VK_SHIFT);

//返回值最低位为1,与小灯保持一致
iState = GetKeyState(VK_CAPITAL);  //CapsLock

2.左右Shift键

GetKeyState(VK_LSHIFT);
GetKeyState(VK_RSHIFT);

3.四类字符消息
非系统字符(来自WM_KEYDOWN):

WM_CHAR
WM_DEADCHAR

系统字符(来自WM_SYSKEYDOWN):

WM_SYSCHAR
WM_DEADSYSCHAR

4.
lParam:和产生此字符码的击键消息中的lParam一样。
wParam:不是虚拟键码,为ANSI或UNICODE字符码。

5. SysMets4

//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"SysMets4";
    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_KEYDOWN:
        switch (wParam)
        {
        case VK_HOME:
            SendMessage(hWnd, WM_VSCROLL, SB_TOP, 0);
            break;

        case VK_END:
            SendMessage(hWnd, WM_VSCROLL, SB_BOTTOM, 0);
            break;

        case VK_PRIOR:
            SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0);
            break;

        case VK_NEXT:
            SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0);
            break;

        case VK_UP:
            SendMessage(hWnd, WM_VSCROLL, SB_LINEUP, 0);
            break;

        case VK_DOWN:
            SendMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, 0);
            break;

        case VK_LEFT:
            SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0);
            break;

        case VK_RIGHT:
            SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0);
            break;
        }
        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);
}

Output:

猜你喜欢

转载自www.cnblogs.com/coolcpp/p/windows-keyboard.html