C “第四个参数”之谜;“滚动窗口”;Windows编程中的API函数
我的代码如下所示。当程序运行时,我先单击鼠标右键,然后单击鼠标左键。结果如第一张图所示。根据C “第四个参数”之谜;“滚动窗口”;Windows编程中的API函数,c,windows,winapi,C,Windows,Winapi,我的代码如下所示。当程序运行时,我先单击鼠标右键,然后单击鼠标左键。结果如第一张图所示。根据ScrollWindow函数的帮助文档,如果第四个参数为NULL,则应滚动整个客户端区域。为什么x=30个设备单元时有10个像素的间隙 我想知道为什么结果不像第二张图那样显示 #包括 LRESULT回调WndProc(HWND、UINT、WPARAM、LPARAM); int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、, PS
ScrollWindow
函数的帮助文档,如果第四个参数为NULL
,则应滚动整个客户端区域。为什么x=30个设备单元时有10个像素的间隙
我想知道为什么结果不像第二张图那样显示
#包括
LRESULT回调WndProc(HWND、UINT、WPARAM、LPARAM);
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、,
PSTR szCmdLine,int iCmdShow)
{
静态TCHAR szAppName[]=文本(“HelloWin”);
HWND-HWND;
味精;
WNDCLASS WNDCLASS;
wndclass.style=CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(空,IDI_应用程序);
wndclass.hCursor=LoadCursor(空,IDC_箭头);
wndclass.hbrBackground=(HBRUSH)GetStockObject(白色画笔);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(空,文本(“此程序需要Windows NT!”),
szAppName,MB_i错误);
返回0;
}
hwnd=CreateWindow(szAppName,//窗口类名称
文本(“Hello程序”),//窗口标题
WS\u重叠窗口,//窗口样式
CW_USEDEFAULT,//初始x位置
CW\U USEFAULT,//初始y位置
CW\u usefault,//初始x大小
CW\u usefault,//初始y大小
NULL,//父窗口句柄
NULL,//窗口菜单句柄
hInstance,//程序实例句柄
NULL);//创建参数
显示窗口(hwnd、iCmdShow);
更新窗口(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
返回msg.wParam;
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
HDC-HDC;
PAINTSTRUCT-ps;
RECT-RECT;
开关(信息)
{
案例WM_油漆:
hdc=开始喷漆(hwnd和ps);
端漆(hwnd和ps);
返回0;
案例WM_LBUTTONDOWN:
hdc=GetDC(hwnd);
SetRect(&rect,30,0,70,100);
滚动窗口(hwnd、10、0、NULL和rect);
更新窗口(hwnd);
释放DC(hwnd、hdc);
返回0;
案例WM_RBUTTONDOWN:
hdc=GetDC(hwnd);
椭圆(hdc,0,0,100,100);
释放DC(hwnd、hdc);
返回0;
案例WM_销毁:
PostQuitMessage(0);
返回0;
}
返回DefWindowProc(hwnd、message、wParam、lParam);
}
如果第四个参数为NULL,则应滚动整个客户端区域
您还指定了一个剪切矩形(第5个参数),因此当然不会滚动整个客户端区域。但实际上这与问题无关
为什么x=30个设备单元时有10个像素的间隙
因为当Windows告诉您这样做时,您不会绘制该间隙
发件人:
ScrollWindow未覆盖的区域不会重新绘制,但会合并到窗口的更新区域中。应用程序最终会收到一条WM_PAINT消息,通知它必须重新绘制该区域
您的WM_PAINT
处理程序不。。。除了通过验证更新区域向Windows撒谎之外,什么都没有
通过只在WM\u PAINT
中进行所有绘制来修复代码。在WM_LBUTTONDOWN
中滚动时,还必须增加一个存储滚动位置的变量。将滚动位置添加到在WM_PAINT
中传递到eliple()
的坐标中。现在你应该得到一个像第二张图片一样的结果
我建议找一个关于Win32绘画的好教程,因为这里似乎缺少一些基本知识。了解“更新区域”是什么,以及它如何与绘制周期交互。请提供有关您输入的更多详细信息。你点击一个按钮,即你按下它,在按下时不移动它,然后释放它?然后另一个按钮也一样?你不是在
WM_PAINT
中画画,所以你在屏幕上看到垃圾是正常的。你得到的特定类型的垃圾不是特别有趣。这是常见的绘画代码损坏的情况。右击只会将像素飞溅到窗口上,它们不会存活很长时间。通过将窗口部分拖离屏幕或最小化并恢复窗口,最容易看到。在屏幕截图中可见,ScrollWindow无法将像素移到剪辑矩形之外,并且它生成的后续绘制也不会绘制像素。根据您的回答,我还有两个问题。@user7028什么问题?根据您的回答,我还有两个问题。1.因为第四个参数不起作用。第四个参数存在的必要性是什么?2.您说“来自MSDN:ScrollWindow未覆盖的区域不会重新绘制,但会合并到窗口的更新区域中。应用程序最终会收到WM_PAINT消息,通知它必须重新绘制该区域。”我想知道是否“ScrollWindow未覆盖的区域”
#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) ;
}