WINDOWS程序设计关于ScrollWindow的一点理解循环滚动 大区域与小区域绘制

首先是测试的代码

#include <windows.h>
#pragma comment(lib, "winmm")

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("HelloWin");
    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("The Hello 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;
    RECT        rect;
    static int cnt=0;
    static int PaintBegin;
    static int PaintEnd;
    static TCHAR* szTest[] = { TEXT("11111111111111111111"),
                               TEXT("22222222222222222222"),
                               TEXT("33333333333333333333"),
                               TEXT("44444444444444444444"),
                               TEXT("55555555555555555555") };
    static RECT rectTest;
    static TCHAR szBuffer[128];
    rectTest.top = 0; rectTest.left = 0;
    rectTest.right = 160; rectTest.bottom = 100;
    switch (message)
    {
    case WM_CREATE:
        PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
        return 0;
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_UP:
        case VK_DOWN:
            cnt++;
            ScrollWindow(hwnd, 0, -20, &rectTest, &rectTest);
            break;
        default:
            break;
        }
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        //一
        /*
        for (int i = 0; i < 5; i++)
        {
            TextOut(hdc, 0, i * 20, szTest[i], 20);
        }
        */
        //二
        /*
        if (cnt == 0)
        {
            for (int i = 0; i < 5; i++)
            {
                TextOut(hdc, 0, i * 20, szTest[i], 20);
            }
        }
        else
        {
            TextOut(hdc, 0, 4 * 20, szTest[cnt], 20);
        }
        */
        //三
        PaintBegin = max(0, cnt+ps.rcPaint.top/20);
        PaintEnd = (cnt == 0 ? 4 : (cnt + ps.rcPaint.bottom/20));
        GetClientRect(hwnd, &rect);
        for (int i = PaintBegin; i <= PaintEnd; i++)
        {
            TextOut(hdc, 0, (i - cnt) * 20, szTest[i%5], 20);
        }
        
    


        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

这个测试是对左上角的1小块区域进行滚动测试
经过代码一的测试,ScrollWindow函数确实只是单纯的将指定区域内的内容滚动,滚动后下面留下的区域成为无效区。所以WM_PAINT消息应该针对这个留下来的无效去进行绘制,即使WM_PAINT消息对整个大的区域进行了绘制也只有下面的一小块无效区的才能显示出来
经过代码二的测试,WM_PAINT消息针对无效区绘制是可行的,代码二可实现一部分的循环滚动即将移到上面的移动到下面只不过,当cnt变大时,越界了,同时WM_PAINT里有两套逻辑,代码二也仅仅针对了向下拖动了一行,两行,三行,……的情况
代码三的代码与前面编过的滚动条实验的代码类似,只不过由于是循环滚动,我可以视要输出的数组长度为无限,所以PaintEnd里面没有进行min,同时由于之前的滚动条的代码是针对整个客户区的,而这次循环滚动的代码一开始WM_PAINT是针对整个客户去的,但是滚动中是针对一小部分区域的,所以要进行一个判断,似乎这个判断逃避不了(应该是) 同时这个代码针对连续的移动也是可行的(应该是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值