zoukankan      html  css  js  c++  java
  • 文本输出与滚动条

    #include<windows.h>
    #include"SYSMET.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.lpszClassName = 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 | WS_VSCROLL,
            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)
    {
        HDC hdc;
        PAINTSTRUCT ps;
        static int cxChar, cxCaps, cyChar, cyClient, iVscrollPos;
        TEXTMETRIC tm;
        int i, y;
        TCHAR szBuffer[10];
    
        switch (message)
        {
        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);
            return 0;
        case WM_SIZE:
            cyClient = HIWORD(lParam);      //客户区高度
            return 0;
        case WM_VSCROLL:
            switch (LOWORD(wParam))
            {
            case SB_LINEUP:
                iVscrollPos -= 1;
                break;
            case SB_LINEDOWN:
                iVscrollPos += 1;
                break;
            case SB_PAGEUP:
                iVscrollPos -= cyClient / cyChar;
                break;
            case SB_PAGEDOWN:
                iVscrollPos += cyClient / cyChar;
                break;
            case SB_THUMBPOSITION:
                iVscrollPos = HIWORD(wParam);
                break;
            }
            iVscrollPos = max(0, min(iVscrollPos, NUMLINES - 1));
            if (iVscrollPos != GetScrollPos(hwnd, SB_VERT))
            {
                SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
                InvalidateRect(hwnd, NULL, TRUE);                //使客户区无效,从而发送WM_PAINT进行重绘
            }
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            for (i = 0; i < NUMLINES; i++)
            {
                y = cyChar * (i - iVscrollPos);
                TextOut(hdc, 0, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));
    
                TextOut(hdc, 22 * cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));
                SetTextAlign(hdc, TA_RIGHT | TA_TOP);                                                                //设置右对齐
                TextOut(hdc, 22 * cxCaps + 40 * cxChar, y, szBuffer, wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].Index)));
                SetTextAlign(hdc, TA_LEFT | TA_TOP);
            }
            EndPaint(hwnd, &ps);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    获取句柄和释放句柄只能在一跳消息中,CreateDC除外
    case WM_PAINT:
        return 0;
    这种代码会使windows不停发生WM_PAINT,因为没有使用BeginPaint使无效区域有效化,即一直处于无效状态,所以才会一直发送WM_PAINT。
    GetWindowDC返回的是整个窗口的设备环境句柄,GetWindowDC返回的句柄可以在窗口的标题栏进行输出,相应的,程序也要处理WM_NCPAINT(非客户区绘制)消息。
    GetDC返回的设备环境句柄中的裁剪矩形是整个客户区,所以可以在客户区任意部分绘制,即使没有无效矩形也没有关系。GetDC不会讲无效区域有效化,如果要使整个客户区有效化,需调用ValidateRect(hwnd, NULL)。而InvalidateRect(hwnd, NULL, TRUE)会是整个客户区无效化,并使其后调用的BeginPaint擦除原有的背景。
    在设定完滚动条的坐标之后立即调用InvalidateRect会生成WM_PAINT消息以进行图形绘制,但是由于WM_PAINT消息在消息队列中处于低优先级,所以你可能不那么及时地看到绘制出来的界面,所以使用UpdateWindow函数进行
  • 相关阅读:
    存储结构接收数组
    oracle数据库sql根据查看执行计划优化sql--走不走索引
    多线程--Thread
    java常用集合族谱
    设计模式之二 适配模式
    Tomcat优化问题
    设计模式之一
    C++虚函数表,虚表指针,内存分布
    设计模式
    linux环境下的时间编程
  • 原文地址:https://www.cnblogs.com/Lu3ky-Athena/p/13626226.html
Copyright © 2011-2022 走看看