zoukankan      html  css  js  c++  java
  • 第6章 键盘_6.5 插入符号(不是光标)

    6.5.1 一些关于插入符号的函数

    函数

    说明

    CreateCaret

    创建和窗口关联的插入符号

    SetCaretPos

    设置窗口内的插入符号的位置

    ShowCaret

    显示插入符号

    HideCaret

    隐藏插入符号

    DestroyCaret

    销毁插入符号

    GetCaretPos

    当前插入符号的位置

    GetCaretBlinkTime

    获得和设置插入符号闪烁时间的函数

    SetCaretBlinkTime

    (1)创建和销毁Caret

    消息

    函数

    备注

    WM_SETFOCUS

    创建Caret

    不在WM_CREATE创建、WM_DESTROY中销毁的原因是一个消息队列仅支持一个Caret,多个窗口必须共享一个Caret。在窗口有焦点时创建,失去焦点时销毁。

    WM_KISSFOCUS

    销毁Caret

    (2)显示和隐藏Caret:

    A、创建后默认是隐藏的,要调用ShowCaret显示出来。

    B、在非WM_PAINT消息中:要绘制某些东西前必须HideCaret,绘制结束再ShowCaret。

    C、HideCaret是叠加的,Hide几次就要Show几次才能使插入符号可见。

    6.5.2 TYPER程序

    /*------------------------------------------------------------
    TYPER.C -- Typeing Program
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    #define  BUFFER(x,y) *(pBuffer+y*cxBuffer+x)
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        PSTR szCmdLine, int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT("Typer");
        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("This program requires Windows NT!"),
                szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName,                  // window class name
            TEXT("Typing Program"), // window caption
            WS_OVERLAPPEDWINDOW,        // window style
            CW_USEDEFAULT,              // initial x position
            CW_USEDEFAULT,              // initial y position
            CW_USEDEFAULT,              // initial x size
            CW_USEDEFAULT,              // initial y size
            NULL,                       // parent window handle
            NULL,                       // window menu handle
            hInstance,                  // program instance handle
            NULL);                     // creation parameters
    
        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)
    {
        HDC         hdc;
        PAINTSTRUCT ps;
        TEXTMETRIC tm;
        static DWORD dwCharSet = DEFAULT_CHARSET;
        static int cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer;
        static int xCaret, yCaret;
        static TCHAR* pBuffer = NULL;
    
        switch (message)
        {
        case WM_INPUTLANGCHANGE:
            dwCharSet = wParam;
            //继续执行下去
        case WM_CREATE:
            hdc = GetDC(hwnd);
            SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                dwCharSet, 0, 0, 0, FIXED_PITCH, 0));
            GetTextMetrics(hdc, &tm);
            cxChar = tm.tmAveCharWidth;
            cyChar = tm.tmHeight;
            DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
            ReleaseDC(hwnd, hdc);
            //继续执行下去
    
        case WM_SIZE:
            if (message == WM_SIZE)
            {
                cxClient = LOWORD(lParam);
                cyClient = HIWORD(lParam);
            }
    
            //以字符尺寸为单位,计算窗口大小
            cxBuffer = max(1, cxClient / cxChar);
            cyBuffer = max(1, cyClient / cyChar);
            //分配字符数组内存大小
            if (pBuffer != NULL) free(pBuffer);
            pBuffer = (TCHAR*)malloc(cxBuffer*cyBuffer*sizeof(TCHAR*));
    
            for (int y = 0; y < cyBuffer; y++)
            for (int x = 0; x < cxBuffer; x++)
                BUFFER(x, y) = ' ';   //初始化pBuffer为一个‘ ’空字符
            //将光标置入左上角
            xCaret = 0;
            yCaret = 0;
    
            if (hwnd == GetFocus())
            {
                SetCaretPos(xCaret*cxChar, yCaret*cyChar);
            }
    
            //重绘
            InvalidateRect(hwnd, NULL, TRUE);
            return 0;
        case WM_SETFOCUS:
            CreateCaret(hwnd, NULL, 2, cyChar);
            SetCaretPos(xCaret*cxChar, yCaret*cyChar);
            ShowCaret(hwnd);
            return 0;
        case WM_KILLFOCUS:
            HideCaret(hwnd);
            DestroyCaret();
            return 0;
        case WM_KEYDOWN:
            switch (wParam)
            {
            case VK_HOME:
                xCaret = 0;
                break;
            case VK_END:
                xCaret = cxBuffer - 1;
                break;
            case VK_PRIOR:
                yCaret = 0;
                break;
            case VK_NEXT:
                yCaret = cyBuffer - 1;
                break;
            case VK_RIGHT:
                xCaret = min(xCaret + 1, cxBuffer - 1);
                break;
            case VK_LEFT:
                xCaret = max(0, xCaret - 1);
                break;
            case VK_UP:
                yCaret = max(0, yCaret - 1);
                break;
            case VK_DOWN:
                yCaret = min(yCaret + 1, cyBuffer - 1);
                break;
            case VK_DELETE: //注意VK_BACK键当字符消息去处理,这里只处理VK_DELETE
                //将该行从当前位置后面字符依次前移一格
                for (int x = xCaret; x < cxBuffer - 1; x++)
                {
                    BUFFER(x, yCaret) = BUFFER(x + 1, yCaret);
                }
                BUFFER(cxBuffer - 1, yCaret) = ' ';//该行最后一个设为空字符。
                HideCaret(hwnd);
                hdc = GetDC(hwnd);
                SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                    dwCharSet, 0, 0, 0, FIXED_PITCH, 0));
                TextOut(hdc, xCaret * cxChar, yCaret * cyChar, &BUFFER(xCaret, yCaret), cyBuffer - xCaret); //重新输出该行xCaret后面的文字
                DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
                ReleaseDC(hwnd, hdc);
                ShowCaret(hwnd);
                break;
            }
            SetCaretPos(xCaret*cxChar, yCaret*cyChar);
            return 0;
        case WM_CHAR:
            switch (wParam)
            {
            case '': //退格键
                if (xCaret>0)
                {
                    xCaret--;
                    SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1); //1为repeat字段的值
                }
                break;
            case '	': //Tab键,8个字符长度
                do
                {
                    SendMessage(hwnd, WM_CHAR, ' ', 1);
                } while (xCaret % 8 != 0);
                break;
            case '
    ': //换行符,改变y到下一行,x坐标没变。
                if (++yCaret == cyBuffer)
                {
                    yCaret = 0;
                }
                break;
            case '
    ': //回车键
                xCaret = 0;
                if (++yCaret == cyBuffer)
                {
                    yCaret = 0;
                }
                break;
            case 'x1B':  //ESC键,清空屏幕 xhh表示1到2位十六进制所代表的任意字符
                for (int x = 0; x < cxBuffer; x++)
                for (int y = 0; y < cyBuffer; y++)
                    BUFFER(x, y) = ' ';
                xCaret = 0;
                yCaret = 0;
    
                InvalidateRect(hwnd, NULL, TRUE);
                break;
            default:
                BUFFER(xCaret, yCaret) = (TCHAR)wParam;
                HideCaret(hwnd);
                hdc = GetDC(hwnd);
                SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                    dwCharSet, 0, 0, 0, FIXED_PITCH, 0));
                TextOut(hdc, xCaret * cxChar, yCaret * cyChar, &BUFFER(xCaret, yCaret), 1);
                DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
                ReleaseDC(hwnd, hdc);
                ShowCaret(hwnd);
                if (++xCaret == cxBuffer) //插入符号后移
                {
                    xCaret = 0;
                    if (++yCaret == cyBuffer)
                    {
                        yCaret = 0;
                    }
                }
                break;
            }
            SetCaretPos(xCaret*cxChar, yCaret*cyChar);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                dwCharSet, 0, 0, 0, FIXED_PITCH, 0));
    
            for (int y = 0; y < cyBuffer; y++)
                TextOut(hdc, 0, y*cyChar, &BUFFER(0, y), cxBuffer);
            DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_DESTROY:
            if (pBuffer != NULL) free(pBuffer);
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
  • 相关阅读:
    kylin build 失败报错处理
    React
    MongoDB配置
    mysql8.0 问题
    Hadoop实战训练————MapReduce实现PageRank算法
    十六、Hadoop学习笔记————Zookeeper实战
    十五、Hadoop学习笔记————Zookeeper客户端的使用
    十五、Hadoop学习笔记————Zookeeper的环境搭建
    十四、Hadoop学习笔记————Zookeeper概述与基本概念
    十三、Hadoop学习笔记————Hive安装先决条件以及部署
  • 原文地址:https://www.cnblogs.com/5iedu/p/4656194.html
Copyright © 2011-2022 走看看