我的代码如下所示。当程序运行时,我先单击鼠标右键,然后单击鼠标左键。结果如第一张图所示。根据ScrollWindow
函数的帮助文档,如果第四个参数为NULL
,则整个客户区都应该滚动。为什么 x = 30 设备单位处有 10 像素间隙?
我想知道为什么结果不像第二张图那样显示。
#include <windows.h>
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;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_LBUTTONDOWN:
hdc = GetDC(hwnd);
SetRect(&rect, 30, 0, 70, 100);
ScrollWindow(hwnd, 10, 0, NULL, &rect);
UpdateWindow(hwnd);
ReleaseDC(hwnd, hdc);
return 0;
case WM_RBUTTONDOWN:
hdc = GetDC(hwnd);
Ellipse(hdc, 0, 0, 100, 100);
ReleaseDC(hwnd, hdc);
return 0;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
最佳答案
if the fourth parameter is NULL, the entire client area should be scrolled.
您还指定了一个剪切矩形(第5个参数),因此当然不会滚动整个客户区域。但实际上这与问题无关。
Why is there a 10 pixels gap at x = 30 device units?
因为当 Windows 要求您这样做时,您没有绘制该间隙。
来自MSDN :
The area uncovered by ScrollWindow is not repainted, but it is combined into the window's update region. The application eventually receives a WM_PAINT message notifying it that the region must be repainted.
您的 WM_PAINT
处理程序除了通过验证更新区域向 Windows 撒谎之外什么也不做。
通过仅在 WM_PAINT
中进行所有绘制来修复您的代码。当您在 WM_LBUTTONDOWN
中滚动时,您还必须增加一个存储滚动位置的变量。将滚动位置添加到您传递给 WM_PAINT
中的 Ellipse()
的坐标。现在你应该得到像第二张图这样的结果。
我建议找到一个关于 Win32 绘画的好教程,因为这里似乎缺少一些基本知识。了解什么是“更新区域”以及它如何与绘制周期交互。
关于c - Windows编程中关于 "ScrollWindow"API函数第四个参数的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46020902/