• 学习windows编程 day2 之滚动条使用


    相关函数:

    setscrollrange,setscrollpos,getscrollrange,getscrollpos

    使用滚动条时我们需要进行的操作:

    1.初始化滚动条范围和位置

    在窗口创建时WM_CREATE响应时可以完成

    SetScrollRange(hwnd, SB_VERT, 0, NUMLINES,FALSE);
    SetScrollPos(hwnd, SB_VERT, 0, TRUE);

    2.处理窗口过程的滚动条消息

    在响应WM_VSCROLL时处理

    switch(LOWORD(wParam))
    {
       case SB_LINEUP:
             ....
             break;
       case SB_LINEDOWN:
             ....
             break;
       case SB_PAGEUP:
             ....
             break;
       case SB_PAGEDOWN:
             ....
             break;
       case SB_THUMBTRACK:
             ....
             break;
       case SB_THUMBPOSITION:
             ....
             break;
    }    

    注意在wParam参数中的低十六位中可以获取鼠标在滚动条上的动作使用LOWORD(wParam)

    当滚动条动作为SB_THUMBPOSITION或SB_THUMBTRACK时,可以在wParam参数中的高十六位中获取位置HIWORD(wParam)

    3.更新滑块位置

    SetScrollPos(hwnd, SB_VERT, XXX, TRUE);

    4.根据滚动条变化更新客户端内容

    可以在处理滚动条消息是设置全局参数,在WM_PAINT响应时做出响应更新

    为了及时更新客户端内容

    可以使用

    InvalidateRect(hwnd, NULL, TRUE);

    向消息队列中发送消息WM_PAINT,此消息会放在消息队列后面,知道其他消息处理完毕才会响应

    或者使用

    UpdateWindow(hwnd);

    非队列化消息,跳过消息循环机制直接处理更新窗口

     全部代码:

    #include <windows.h>
    #include <strsafe.h>
    #include "SysMet.h"
    
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iShowCmd)
    {
        static TCHAR szClassName[] = TEXT("MyWindow5");
        MSG msg;
        HWND hwnd;
    
        WNDCLASS wndclass;
        wndclass.cbClsExtra=0;
        wndclass.cbWndExtra=0;
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.hCursor = LoadCursor(NULL, IDI_APPLICATION);
        wndclass.hIcon = LoadIcon(NULL, IDC_ARROW);
        wndclass.hInstance = hInstance;
        wndclass.lpfnWndProc = WndProc;
        wndclass.lpszClassName = szClassName;
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW;
    
        if (!RegisterClass(&wndclass))
        {
            MessageBox(NULL, TEXT("this program must run in win nt!"), TEXT("ERROR"), MB_OK);
            return 0;
        }
    
        hwnd = CreateWindow(szClassName,
            TEXT("MyWindowProgram"),
            WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            NULL,
            NULL,
            hInstance,
            NULL
            );
    
        ShowWindow(hwnd,iShowCmd);
        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;
        RECT rect;
        TCHAR szBuffer[100];
        TEXTMETRIC tm;
        static int cxChar, cyChar, cxCaps,iVscrollPos;//大写占1.5倍
        size_t st;
        int y;
        static int cxClient, cyClient;
        switch (message)
        {
        case WM_CREATE:
            iVscrollPos = 0;
            SetScrollRange(hwnd, SB_VERT, 0, NUMLINES,FALSE);//后面代表是否现在重画窗口
            SetScrollPos(hwnd, SB_VERT, 0, TRUE);
    
            hdc = GetDC(hwnd);
            GetTextMetrics(hdc, &tm);
            cxChar = tm.tmAveCharWidth;
            cyChar = tm.tmExternalLeading + tm.tmHeight;
            cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2)*cxChar / 2;
            ReleaseDC(hwnd,hdc);
            break;
        case WM_SIZE:
            cxClient = LOWORD(lParam);
            cyClient = HIWORD(lParam);
    
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            for (int i = 0; i < NUMLINES;i++)
            {
                y = cyChar*(i - iVscrollPos);
                //获取的大量数据
                StringCchLength(sysmetrics[i].szLabel, 1024, &st);
                TextOut(hdc, 0, y, sysmetrics[i].szLabel, st);
    
                StringCchLength(sysmetrics[i].szDesc, 1024, &st);
                TextOut(hdc, 40 * cxCaps, y, sysmetrics[i].szDesc, st);
    
                SetTextAlign(hdc,TA_RIGHT|TA_TOP);
                StringCchPrintf(szBuffer, 100, L"%d    %d  %5d", i + 1,iVscrollPos, GetSystemMetrics(sysmetrics[i].iIndex));
                StringCchLength(szBuffer, 100, &st);
                TextOut(hdc, 40 * cxCaps + 40 * cxChar, y, szBuffer, st);
                SetTextAlign(hdc, TA_LEFT|TA_TOP);
            }
    
            //获取屏幕分辨率
    //         cxClient=GetSystemMetrics(SM_CXSCREEN);    //水平
    //         cyClient=GetSystemMetrics(SM_CYSCREEN);    //垂直
    //         StringCchPrintf(szBuffer, 100, L"screen : %d * %d px", cxClient, cyClient);
    //         //在屏幕中心写字
    //         GetClientRect(hwnd, &rect);
    //         DrawText(hdc, szBuffer, -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
            
            
            EndPaint(hwnd, &ps);
            break;
        case WM_VSCROLL:
            hdc = GetDC(hwnd);
            GetClientRect(hwnd, &rect);
            if (LOWORD(wParam) == SB_LINEUP)
            {
                iVscrollPos -= 1;
            }
            else if (LOWORD(wParam) == SB_LINEDOWN)
            {
                iVscrollPos += 1;
            }
            else if (LOWORD(wParam) == SB_PAGEUP)
            {
                iVscrollPos -= cyClient / cyChar;
            }
            else if (LOWORD(wParam) == SB_PAGEDOWN)
            {
                iVscrollPos += cyClient / cyChar;
            }
            else if (LOWORD(wParam) == SB_THUMBTRACK)
            {
                DrawText(hdc, L"Slider.....", -1, &rect, DT_RIGHT | DT_VCENTER);
            }
            else if (LOWORD(wParam) == SB_THUMBPOSITION)
            {
                iVscrollPos = HIWORD(wParam);
            }
            ReleaseDC(hwnd, hdc);
    
            iVscrollPos = max(0, min(iVscrollPos, NUMLINES));
            if (iVscrollPos != GetScrollPos(hwnd, SB_VERT))
             {
                InvalidateRect(hwnd, NULL, TRUE);
                SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_QUIT:
            break;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vue+layui制作列表页
    基础JQ框架
    MVC返回数据流,ajax接受并保存文件
    js验证表单
    jq扩展获取表单值、设置值
    常用sql记录
    JSON
    JS和JQUERY的区别
    用面向对象的方式进行数据访问
    win7旗舰版梦幻主题补丁~完美你的桌面
  • 原文地址:https://www.cnblogs.com/ssyfj/p/8503319.html
Copyright © 2020-2023  润新知