Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

huangapple go评论69阅读模式
英文:

C Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

问题

我正在尝试使用ScrollWindowEx()来创建一个窗口并创建自己的滚动视图(v-scroll),在处理WM_MOUSEWHEEL窗口消息时它有效,但显示了错误和无效的内容。我的窗口宽度为700,高度为600,我绘制了一个高度为1000的矩形,我尝试向下滚动窗口以查看矩形的底部,但永远无法到达底部。

#include <stdio.h>
#include <windows.h>
#include <gdiplus.h>
// 其他代码...

以下是图片链接,显示了应用程序启动时的情况以及向下滚动和向上滚动时的情况:

应用程序启动时的图片:
Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

向下滚动时的图片:
Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

向上滚动时的图片:
Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

英文:

I'm trying to create a window and create own scroll viewer (v-scroll) using ScrollWindowEx() in handling the WM_MOUSEWHEEL window message and it worked but shows me wrong and invalid contents.
My window is a window with 700 width and 600 height and i draw a rectangle with 1000 height and i tried to scroll down the window to see the end of the rectangle but never arrvied to its end.

#include &lt;stdio.h&gt;
#include &lt;windows.h&gt;
#include &lt;gdiplus.h&gt;

int SCREEN_SIZE_WIDTH,
        SCREEN_SIZE_HEIGHT;

static unsigned long long GDI_PLUS_TOKEN;
static GdiplusStartupInput GDI_PLUS_STARTUP_INPUT = {
        .GdiplusVersion = 1,
        .SuppressExternalCodecs = FALSE,
        .SuppressBackgroundThread = FALSE };

static WNDCLASSEXW WINDOW_CLASS_DEFAULT = (WNDCLASSEXW) {
        sizeof(WNDCLASSEXW),
        CS_HREDRAW|CS_VREDRAW|CS_CLASSDC,
        NULL,
        0,
        16,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        L&quot;MY_CLASS&quot;,
        NULL };

LRESULT CALLBACK
window_callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI
WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        PSTR lpCmdLine,
        int nCmdShow) {
    HWND window;
    if((SCREEN_SIZE_WIDTH=GetSystemMetrics(SM_CXSCREEN))==0
       || (SCREEN_SIZE_HEIGHT=GetSystemMetrics(SM_CYSCREEN))==0) {
        printf(&quot;GetSystemMetrics() failed.\r\n&quot;);
        ExitProcess(EXIT_FAILURE);
    }
    if(GdiplusStartup(&amp;GDI_PLUS_TOKEN, &amp;GDI_PLUS_STARTUP_INPUT, NULL)!=Ok) {
        printf(&quot;GdiplusStartup() failed.\r\n&quot;);
        ExitProcess(EXIT_FAILURE);
    }
    WINDOW_CLASS_DEFAULT.hInstance=hInstance;
    WINDOW_CLASS_DEFAULT.hbrBackground= CreateSolidBrush(RGB(255,255,255));
    WINDOW_CLASS_DEFAULT.hCursor=LoadCursor(NULL, IDC_ARROW);
    WINDOW_CLASS_DEFAULT.lpfnWndProc=window_callback;
    if(!RegisterClassExW(&amp;WINDOW_CLASS_DEFAULT)) {
        printf(&quot;RegisterClassExW() failed.\r\n&quot;);
        ExitProcess(EXIT_FAILURE);
    }
    window=CreateWindowExW(
            0, L&quot;MY_CLASS&quot;,
            L&quot;MY PROJECT&quot;,
            WS_POPUP|WS_OVERLAPPEDWINDOW,
            ((SCREEN_SIZE_WIDTH - 700) / 2), // Center of the screen
            ((SCREEN_SIZE_HEIGHT - 400) / 2), // Center of the screen
            700, 600, NULL,
            NULL, hInstance, NULL);
    if(window==NULL) {
        printf(&quot;CreateWindowExA() failed.\r\n&quot;);
        goto failure;
    }
    ShowWindow(window, SW_NORMAL);

    MSG msg;
    while (GetMessage(&amp;msg, NULL, 0, 0)) {
        TranslateMessage(&amp;msg);
        DispatchMessage(&amp;msg);
    }
    UnregisterClassA(&quot;DRAWPEN&quot;, hInstance);
    ExitProcess(EXIT_SUCCESS);
    failure:
    UnregisterClassA(&quot;DRAWPEN&quot;, hInstance);
    ExitProcess(EXIT_FAILURE);
}

LRESULT CALLBACK
window_callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    HDC hdc;
    PAINTSTRUCT ps;
    static int scroll_value = 0;
    switch (uMsg) {
        case WM_MOUSEWHEEL:
        {
            // On scroll wheel, let&#39;s use ScrollWindowEx() function
            // to scroll vertical only and here is my problem !
            ScrollWindowEx(
                    hwnd, 0, GET_WHEEL_DELTA_WPARAM(wParam),
                    NULL, NULL, NULL,
                    NULL, SW_INVALIDATE);
            UpdateWindow(hwnd);
        }
            break;
        case WM_PAINT:
            printf(&quot;WM_PAINT\r\n&quot;);
            hdc=BeginPaint(hwnd, &amp;ps);
            GpGraphics *gfx;
            GdipCreateFromHDC(hdc, &amp;gfx);
            GpPen *pen;
            GdipCreatePen1(0xFF4c4c4c, 15, UnitPixel, &amp;pen);
            GdipDrawRectangle(gfx, pen, 20, 20, 100, 1000);
            EndPaint(hwnd, &amp;ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

A picture for when the application started.
Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

A picture for when i scroll down (never arrive at the end of rectangle

Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

A picture for when i scroll up

Make own window (GUI) scroll viewer using ScrollWindowEx() wrong content

答案1

得分: 0

根据如何滚动位图

窗口滚动后,其客户区的一部分将变为无效。
处理WM_PAINT消息时,应用程序必须重新绘制客户区底部的无效区域。

请参见滚动位图示例,该示例使用BitBlt函数将位图的适当部分复制到客户区无效部分。

就您的代码而言,第二张图片和第三张图片是客户区底部和顶部无效部分的绘制结果。

英文:

According to How to Scroll a Bitmap,

> After a window is scrolled, part of its client area is made invalid.
> When processing the WM_PAINT message, an application must repaint the
> invalid region at the bottom of the client area.

See the Example of Scrolling a Bitmap which uses the BitBlt function to copy the appropriate portion of the bitmap to the invalid portion of the client area.

As far as your code is concerned, the second picture and the third picture are a result of the painting of the invalid portion, bottom and top, of the client area.

huangapple
  • 本文由 发表于 2023年5月7日 14:34:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定