zoukankan      html  css  js  c++  java
  • 第6章 键盘_6.1-6.2 键盘基础与击键消息

    6.1 键盘基础

    6.1.1 谁获得了焦点?

    (1)活动窗口:桌面最上层窗口,其父窗口句柄为NULL,加亮标题栏或突出显示在任务栏。

    (2)焦点窗口:活动窗口的子孙窗口,通常是一个闪烁的插入符或虚线框指示输入焦点

    (3)捕获WM_SETFOCUS来确定其具有输入焦点,WM_KILLFOCUS说明正失去焦点

    (4)当所有程序都最小化时,没有窗口具有输入焦点,Windows仍将发送键盘消息给活动窗口。这时所有击键都产生WM_SYSKEYDOWN和WM_SYSKEYUP消息。

    6.1.2 队列和同步

    (1)两步法处理键消息:先把消息存储在系统消息队列里,再发送到应用程序消息队列里。具休:①击键事件→将扫描码转为消息,放入系统消息队列(注意不立即放入应用程序消息队列);②应用程序处理完前一个输入消息→Windows从系统队列取下一条消息放入应用程序消息队列。

    (2)两步处理法的原因——同步

         因为当应用程序1接收到一个特殊的、转换窗口焦点的击键动作时,后续的击键消息也应被转移到另一个程序(如应用程序2)的队列中去。如果键盘消息不经系统队列的缓冲,当用户输入太快,而应用程序1来不及没处理完这个特殊消息时,可能后续的击键消息又被发送到应用程序1的队列中来了,从而导致错误。因此,键盘消息要先放到系统队列中,起到同步的作用。

    6.1.3 击键和字符

    键盘消息(8个消息)

    两类消息

    非系统消息(未按ALT键)

    系统消息(按下ALT键)

    击键消息

    WM_KEYDOWN

    WM_KEYUP

    WM_SYSKEYDOWN

    WM_SYSKEYUP

    字符消息

    WM_CHAR

    WM_DEADCHAR

    WM_SYSCHAR

    WM_SYSDEADCHAR

    6.2 击键消息

    6.2.1 系统键击和非系统键击

    系统键击(按下ALT)

    非系统键击(未按ALT)

    case WM_SYSKEYDOWN:

         case WM_SYSKEUP:

         case WM_SYSCHAR:

           ……//拦截系统消息并处理;

     DefWindowProc(…);//要传下去

           return 0;

    case WM_KEYDOWN:

    case WM_KEUP:

    case WM_CHAR:

         //处理完后直接返回。

          return 0;

    6.2.2 虚拟键代码——wParam信息

    (1)键盘扫描码:键的真实键码,是按自然键盘硬件布局产生的,每个键都两个扫描码,即通码和断码(1个字节),满足:断码 = 通码+ 80H。即通码第7位为0,断码为1。

    (2)虚拟键:与为做到与设备无关方式来处理键盘,定义了虚拟键,命名以VK_开头,一般都是扫描码的通码。如Q键为16、W为17、E为18、T为19等。

    10进制

    16进制

    标识符

    常用?

    IBM兼容键盘

    备注

    1

    01

    VK_LBUTTON

     

    鼠标左键

    2

    02

    VK_RBUTTON

     

    鼠标右键

    3

    03

    VK_CANCEL

    Ctrl+Break

    4

    04

    VK_MBUTTON

     

    鼠标中键

    5

    05

    VK_XBUTTON1

     

    6

    06

    VK_XBUTTON2

     

    8

    08

    VK_BACK

    退格键

    1、通常使用字符消息(而不是击键消息)来处理这些键

    2、应用程序不必去监视Shift、Ctrl或Alt键的状态。

    9

    09

    VK_TAB

    Tab键

    12

    0C

    VK_CLEAR

     

    数字锁定键关闭时的数字键

    13

    0D

    VK_RETURN

    回车键(任意一个)

    16

    10

    VK_SHIFT

    Shift键(任意一个)

    17

    11

    VK_CONTROL

    Ctrl键(任意一个)

    18

    12

    VK_MENU

    Alt键(任意一个)

    19

    13

    VK_PAUSE

     

    Pause键

    20

    14

    VK_CAPITAL

    大写锁定键

    27

    1B

    VK_ESCAPE

    Esc键

    32

    20

    VK_SPACE

    空格键

    33

    21

    VK_PRIOR

    PageUp键

    34

    22

    VK_NEXT

    PageDown键

    35

    23

    VK_END

    End键

    36

    24

    VK_HOME

    Home键

    37

    25

    VK_LEFT

    左箭头

    38

    26

    VK_UP

    上箭头

    39

    27

    VK_RIGHT

    右箭头

    40

    28

    VK_DOWN

    下箭头

    41

    29

    VK_SELECT

     

    假想的键盘码

    42

    2A

    VK_PRINT

     

    43

    2B

    VK_EXCUTE

     

    44

    2C

    VK_SNAPSHOT

     

    Print Screen键

    45

    2D

    VK_INSERT

    Insert键

    46

    2E

    VK_DELETE

    Del键

    47

    2F

    VK_HELP

     

    48-57

    30-39

    主键盘上的0-9

    65-90

    41-5A

    A到Z

    91

    5B

    VK_LWIN

     

    左Windows键

    92

    5C

    VK_RWIN

     

    右Windows键

    93

    5D

    VK_APPS

     

    Application键

    96-105

    60-69

    VK_NUMPAD0-VK_NUMPAD9

     

    数字锁定键打开时,小键盘数字键的0-9

    数字小键盘

    106

    6A

    VK_MULTIPLY

     

    数字区的*

    107

    6B

    VK_ADD

     

    数字区的+

    108

    6C

    VK_SEPARATOR

     

    109

    6D

    VK_SUBTRACT

     

    数字区的-

    110

    6E

    VK_DECIMAL

     

    数字区的.

    111

    6F

    VK_DIVIDE

     

    数字区的/

    112-121

    70-79

    VK_F1到VK_F10

    功能键F1到F10

    一般仅使用前10个

    122-135

    7A-87

    VK_F11到VK_F24

     

    功能键F11到F24

    144

    90

    VK_NUMLOCK

     

    数字锁定键

    145

    91

    VK_SCROLL

     

    Scroll Lock键

     6.2.3 lParam信息

     

    消息字段

    说明

    1、重复计数
    (位0-15)

    ①大多数情况下为1,但如果按下一个键不放,将合并WM_KEYDOWN或WM_SYSKEYDOWN成一条单独的消息,并增加重复计数字段。

    ②重复计数>1,可能通过重复计数利用或废弃连续击键的消息。

    2、OEM扫描码
    (位16-23)

    键盘硬件产生的代码,是从BIOS中获得的。

    3、扩展键标记
    (位24)

    来自于IBM加强型的附加键时标记1。Windows通常忽略扩展键标记。
    扩展键:如F1、F2等Fx键,小键盘数字键

    4、内容代码
    (位29)

    ①按下ALT时(即WM_SYSKEY…)为1,不按时(WM_KEY…)为0。

    ②两种特殊情况:

      A、未按Alt(置0),但当所有活动窗口最小化,不具有输入焦点时,所有的击键将转为WM_SYSKEYUP或WM_SYSKEYDOWN。Windows发送这两种消息表明要自己处理,而不让窗口处理。

    B、非英语键盘上,部分字符是由Shift、Ctrl或Alt同另一个键组合产生的。这时被置1,但该消息并不是系统击键消息。

    5、键的先前状态
    (位30)

    ①如果原先的状态。即消息发送以前,按键原来的状态:按下的为1,按键释放的为0。

    ②WM_KEYUP或WM_SYSKEYUP先前状态总是1。

    ③WM_KEYDOWN或WM_SYSKEYDOWN可能为0或1。表示重复击键。

    6、转换状态
    (位31)

    ①正按下为0,正释放为1

    ②WM_KEYDOWN或WM_SYSKEYDOWN总为0.

    ③WM_KEYUP或WM_SYSKEYUP总为1.

     

     

    6.2.4 转义状态

    (1)3个获得键状态的函数对比

    GetKeyState

    ①从消息队列中取得键盘状态,只能在键盘消息处理程序中使用。

    ②返回值:高位为1(表示负数),表示键被按下。

    GetAsyncKeyState

    ①作用:判断某键是否down或up。

    ②返回值short型,最高位表示是否按下,up为0,down为1。最低位表示键在此函数调用之前是否被按下过。

    GetKeyboardState

    ①作用:获得所有的256个键(键盘按键、鼠标按键等等)的状态。

    ②参数是指向一个256bit的数组,存放所有键的状态

    ③当从windows消息队列中移除键盘消息时,才返回。

    (2)应用举例——获取按键状态的几种方法

    ① if ((nChar==0x041)&& (GetKeyState(VK_CONTROL)&0x8000))   //ctrl+A

    ②#defineKEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

    ③if(GetAsyncKeyState(VK_LSHIFT))

    6.2.5 使用击键消息——不产生字符的键盘消息放在WM_KEYDOWN或WM_KEYUP中处理

       如:处理光标移动键、Insert、Delete键的WM_KEYDOWN消息,在这些消息中可以通过GetKeyState检查Shift和Ctrl的状态。

    6.2.6 为SYSMETS加上键盘处理功能

     //SysMets.h

    /*-----------------------------------------------
    SYSMETS.H -- System metrics display structure
    -----------------------------------------------*/
    #pragma  once
    #include <windows.h>
    #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
    struct
    {
        int     iIndex;
        TCHAR * szLabel;
        TCHAR * szDesc;
    }
    sysmetrics[] =
    {
        SM_CXSCREEN, TEXT("SM_CXSCREEN"),
        TEXT("Screen width in pixels"),
        SM_CYSCREEN, TEXT("SM_CYSCREEN"),
        TEXT("Screen height in pixels"),
        SM_CXVSCROLL, TEXT("SM_CXVSCROLL"),
        TEXT("Vertical scroll width"),
        SM_CYHSCROLL, TEXT("SM_CYHSCROLL"),
        TEXT("Horizontal scroll height"),
        SM_CYCAPTION, TEXT("SM_CYCAPTION"),
        TEXT("Caption bar height"),
        SM_CXBORDER, TEXT("SM_CXBORDER"),
        TEXT("Window border width"),
        SM_CYBORDER, TEXT("SM_CYBORDER"),
        TEXT("Window border height"),
        SM_CXFIXEDFRAME, TEXT("SM_CXFIXEDFRAME"),
        TEXT("Dialog window frame width"),
        SM_CYFIXEDFRAME, TEXT("SM_CYFIXEDFRAME"),
        TEXT("Dialog window frame height"),
        SM_CYVTHUMB, TEXT("SM_CYVTHUMB"),
        TEXT("Vertical scroll thumb height"),
        SM_CXHTHUMB, TEXT("SM_CXHTHUMB"),
        TEXT("Horizontal scroll thumb width"),
        SM_CXICON, TEXT("SM_CXICON"),
        TEXT("Icon width"),
        SM_CYICON, TEXT("SM_CYICON"),
        TEXT("Icon height"),
        SM_CXCURSOR, TEXT("SM_CXCURSOR"),
        TEXT("Cursor width"),
        SM_CYCURSOR, TEXT("SM_CYCURSOR"),
        TEXT("Cursor height"),
        SM_CYMENU, TEXT("SM_CYMENU"),
        TEXT("Menu bar height"),
        SM_CXFULLSCREEN, TEXT("SM_CXFULLSCREEN"),
        TEXT("Full screen client area width"),
        SM_CYFULLSCREEN, TEXT("SM_CYFULLSCREEN"),
        TEXT("Full screen client area height"),
        SM_CYKANJIWINDOW, TEXT("SM_CYKANJIWINDOW"),
        TEXT("Kanji window height"),
        SM_MOUSEPRESENT, TEXT("SM_MOUSEPRESENT"),
        TEXT("Mouse present flag"),
        SM_CYVSCROLL, TEXT("SM_CYVSCROLL"),
        TEXT("Vertical scroll arrow height"),
        SM_CXHSCROLL, TEXT("SM_CXHSCROLL"),
        TEXT("Horizontal scroll arrow width"),
        SM_DEBUG, TEXT("SM_DEBUG"),
        TEXT("Debug version flag"),
        SM_SWAPBUTTON, TEXT("SM_SWAPBUTTON"),
        TEXT("Mouse buttons swapped flag"),
        SM_CXMIN, TEXT("SM_CXMIN"),
        TEXT("Minimum window width"),
        SM_CYMIN, TEXT("SM_CYMIN"),
        TEXT("Minimum window height"),
        SM_CXSIZE, TEXT("SM_CXSIZE"),
        TEXT("Min/Max/Close button width"),
        SM_CYSIZE, TEXT("SM_CYSIZE"),
        TEXT("Min/Max/Close button height"),
        SM_CXSIZEFRAME, TEXT("SM_CXSIZEFRAME"),
        TEXT("Window sizing frame width"),
        SM_CYSIZEFRAME, TEXT("SM_CYSIZEFRAME"),
        TEXT("Window sizing frame height"),
        SM_CXMINTRACK, TEXT("SM_CXMINTRACK"),
        TEXT("Minimum window tracking width"),
        SM_CYMINTRACK, TEXT("SM_CYMINTRACK"),
        TEXT("Minimum window tracking height"),
        SM_CXDOUBLECLK, TEXT("SM_CXDOUBLECLK"),
        TEXT("Double click x tolerance"),
        SM_CYDOUBLECLK, TEXT("SM_CYDOUBLECLK"),
        TEXT("Double click y tolerance"),
        SM_CXICONSPACING, TEXT("SM_CXICONSPACING"),
        TEXT("Horizontal icon spacing"),
        SM_CYICONSPACING, TEXT("SM_CYICONSPACING"),
        TEXT("Vertical icon spacing"),
        SM_MENUDROPALIGNMENT, TEXT("SM_MENUDROPALIGNMENT"),
        TEXT("Left or right menu drop"),
        SM_PENWINDOWS, TEXT("SM_PENWINDOWS"),
        TEXT("Pen extensions installed"),
        SM_DBCSENABLED, TEXT("SM_DBCSENABLED"),
        TEXT("Double-Byte Char Set enabled"),
        SM_CMOUSEBUTTONS, TEXT("SM_CMOUSEBUTTONS"),
        TEXT("Number of mouse buttons"),
        SM_SECURE, TEXT("SM_SECURE"),
        TEXT("Security present flag"),
        SM_CXEDGE, TEXT("SM_CXEDGE"),
        TEXT("3-D border width"),
        SM_CYEDGE, TEXT("SM_CYEDGE"),
        TEXT("3-D border height"),
        SM_CXMINSPACING, TEXT("SM_CXMINSPACING"),
        TEXT("Minimized window spacing width"),
        SM_CYMINSPACING, TEXT("SM_CYMINSPACING"),
        TEXT("Minimized window spacing height"),
        SM_CXSMICON, TEXT("SM_CXSMICON"),
        TEXT("Small icon width"),
        SM_CYSMICON, TEXT("SM_CYSMICON"),
        TEXT("Small icon height"),
        SM_CYSMCAPTION, TEXT("SM_CYSMCAPTION"),
        TEXT("Small caption height"),
        SM_CXSMSIZE, TEXT("SM_CXSMSIZE"),
        TEXT("Small caption button width"),
        SM_CYSMSIZE, TEXT("SM_CYSMSIZE"),
        TEXT("Small caption button height"),
        SM_CXMENUSIZE, TEXT("SM_CXMENUSIZE"),
        TEXT("Menu bar button width"),
        SM_CYMENUSIZE, TEXT("SM_CYMENUSIZE"),
        TEXT("Menu bar button height"),
        SM_ARRANGE, TEXT("SM_ARRANGE"),
        TEXT("How minimized windows arranged"),
        SM_CXMINIMIZED, TEXT("SM_CXMINIMIZED"),
        TEXT("Minimized window width"),
        SM_CYMINIMIZED, TEXT("SM_CYMINIMIZED"),
        TEXT("Minimized window height"),
        SM_CXMAXTRACK, TEXT("SM_CXMAXTRACK"),
        TEXT("Maximum dragable width"),
        SM_CYMAXTRACK, TEXT("SM_CYMAXTRACK"),
        TEXT("Maximum dragable height"),
        SM_CXMAXIMIZED, TEXT("SM_CXMAXIMIZED"),
        TEXT("Width of maximized window"),
        SM_CYMAXIMIZED, TEXT("SM_CYMAXIMIZED"),
        TEXT("Height of maximized window"),
        SM_NETWORK, TEXT("SM_NETWORK"),
        TEXT("Network present flag"),
        SM_CLEANBOOT, TEXT("SM_CLEANBOOT"),
        TEXT("How system was booted"),
        SM_CXDRAG, TEXT("SM_CXDRAG"),
        TEXT("Avoid drag x tolerance"),
        SM_CYDRAG, TEXT("SM_CYDRAG"),
        TEXT("Avoid drag y tolerance"),
        SM_SHOWSOUNDS, TEXT("SM_SHOWSOUNDS"),
        TEXT("Present sounds visually"),
        SM_CXMENUCHECK, TEXT("SM_CXMENUCHECK"),
        TEXT("Menu check-mark width"),
        SM_CYMENUCHECK, TEXT("SM_CYMENUCHECK"),
        TEXT("Menu check-mark height"),
        SM_SLOWMACHINE, TEXT("SM_SLOWMACHINE"),
        TEXT("Slow processor flag"),
        SM_MIDEASTENABLED, TEXT("SM_MIDEASTENABLED"),
        TEXT("Hebrew and Arabic enabled flag"),
        SM_MOUSEWHEELPRESENT, TEXT("SM_MOUSEWHEELPRESENT"),
        TEXT("Mouse wheel present flag"),
        SM_XVIRTUALSCREEN, TEXT("SM_XVIRTUALSCREEN"),
        TEXT("Virtual screen x origin"),
        SM_YVIRTUALSCREEN, TEXT("SM_YVIRTUALSCREEN"),
        TEXT("Virtual screen y origin"),
        SM_CXVIRTUALSCREEN, TEXT("SM_CXVIRTUALSCREEN"),
        TEXT("Virtual screen width"),
        SM_CYVIRTUALSCREEN, TEXT("SM_CYVIRTUALSCREEN"),
        TEXT("Virtual screen height"),
        SM_CMONITORS, TEXT("SM_CMONITORS"),
        TEXT("Number of monitors"),
        SM_SAMEDISPLAYFORMAT, TEXT("SM_SAMEDISPLAYFORMAT"),
        TEXT("Same color format flag")
    };

    //SysMets3.c

    /*----------------------------------------------------
    SYSMETS3.C -- System Metrics Display Program No. 3
    (c) Charles Petzold, 1998
    ----------------------------------------------------*/
    #define WINVER 0x0500
    #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[] = TEXT("SysMets3");
        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.lpszClassName = szAppName;
    
        if (!RegisterClass(&wndclass))
        {
            MessageBox(NULL, TEXT("Program requires Windows NT!"),
                szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName, TEXT("Get System Metrics No. 3"),
            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 message, WPARAM wParam, LPARAM lParam)
    {
        static int  cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
        HDC         hdc;
        int         i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
        PAINTSTRUCT ps;
        SCROLLINFO  si;
        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);
            // Save the width of the three columns
    
            iMaxWidth = 40 * cxChar + 22 * cxCaps;
            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_HSCROLL, SB_LINELEFT, 0);
                break;
            case VK_RIGHT:
                SendMessage(hwnd, WM_HSCROLL, SB_LINERIGHT, 0);
                break;
            }
            return 0;
        case WM_SIZE:
            cxClient = LOWORD(lParam);
            cyClient = HIWORD(lParam);
            // Set vertical scroll bar range and page size
            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);
            // Set horizontal scroll bar range and page size
            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:
            // Get all the vertial scroll bar information
            si.cbSize = sizeof (si);
            si.fMask = SIF_ALL;
            GetScrollInfo(hwnd, SB_VERT, &si);
            // Save the position for comparison later on
            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;
                break;
    
            default:
                break;
            }
            // Set the position and then retrieve it.  Due to adjustments
            //   by Windows it may not be the same as the value set.
            si.fMask = SIF_POS;
            SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
            GetScrollInfo(hwnd, SB_VERT, &si);
            // If the position has changed, scroll the window and update it
            if (si.nPos != iVertPos)
            {
                ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
                    NULL, NULL);
                UpdateWindow(hwnd);
            }
            return 0;
    
        case WM_HSCROLL:
            // Get all the vertial scroll bar information
            si.cbSize = sizeof (si);
            si.fMask = SIF_ALL;
            // Save the position for comparison later on
            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;
            }
            // Set the position and then retrieve it.  Due to adjustments
            //   by Windows it may not be the same as the value set.
            si.fMask = SIF_POS;
            SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
            GetScrollInfo(hwnd, SB_HORZ, &si);
    
            // If the position has changed, scroll the window 
            if (si.nPos != iHorzPos)
            {
                ScrollWindow(hwnd, cxChar * (iHorzPos - si.nPos), 0,
                    NULL, NULL);
            }
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            // Get vertical scroll bar position
            si.cbSize = sizeof (si);
            si.fMask = SIF_POS;
            GetScrollInfo(hwnd, SB_VERT, &si);
            iVertPos = si.nPos;
            // Get horizontal scroll bar position
            GetScrollInfo(hwnd, SB_HORZ, &si);
            iHorzPos = si.nPos;
            // Find painting limits
            iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
            iPaintEnd = min(NUMLINES - 1,
                iVertPos + ps.rcPaint.bottom / cyChar);
    
            for (i = iPaintBeg; i <= iPaintEnd; 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 + 22 * cxCaps + 40 * cxChar, y, szBuffer,
                    wsprintf(szBuffer, TEXT("%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, message, wParam, lParam);
    }
  • 相关阅读:
    模拟打车
    atm转账
    python字符串,列表,字典,集合的常用方法
    while和for的简单使用
    数据库的基本命令
    jmeter监控linux的性能
    jmeter的错误解决Cannot create PoolableConnectionFactory (Access denied for user 'root'@'localhost' (using password: YES))
    jmeter的正则参数化
    jmeter的参数化关联
    使用Python解析JSON
  • 原文地址:https://www.cnblogs.com/5iedu/p/4656169.html
Copyright © 2011-2022 走看看