英文:
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>
// 其他代码...
以下是图片链接,显示了应用程序启动时的情况以及向下滚动和向上滚动时的情况:
英文:
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 <stdio.h>
#include <windows.h>
#include <gdiplus.h>
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"MY_CLASS",
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("GetSystemMetrics() failed.\r\n");
ExitProcess(EXIT_FAILURE);
}
if(GdiplusStartup(&GDI_PLUS_TOKEN, &GDI_PLUS_STARTUP_INPUT, NULL)!=Ok) {
printf("GdiplusStartup() failed.\r\n");
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(&WINDOW_CLASS_DEFAULT)) {
printf("RegisterClassExW() failed.\r\n");
ExitProcess(EXIT_FAILURE);
}
window=CreateWindowExW(
0, L"MY_CLASS",
L"MY PROJECT",
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("CreateWindowExA() failed.\r\n");
goto failure;
}
ShowWindow(window, SW_NORMAL);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterClassA("DRAWPEN", hInstance);
ExitProcess(EXIT_SUCCESS);
failure:
UnregisterClassA("DRAWPEN", 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'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("WM_PAINT\r\n");
hdc=BeginPaint(hwnd, &ps);
GpGraphics *gfx;
GdipCreateFromHDC(hdc, &gfx);
GpPen *pen;
GdipCreatePen1(0xFF4c4c4c, 15, UnitPixel, &pen);
GdipDrawRectangle(gfx, pen, 20, 20, 100, 1000);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
return 0;
}
A picture for when the application started.
A picture for when i scroll down (never arrive at the end of rectangle
A picture for when i scroll up
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论