滚动条函数scrollwindow研究

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

滚动条函数研究

 

下周工作需要,可能用到滚动条,所以在此先研究一下滚动条相关的知识(可怜我接触UI1年多,尽然没有用过滚动条%>_<%)

 

查了下资料,感觉滚动条用法比较简单,实在没有什么可说的,具体资料网上一查一大堆,这里就不再一一列举了;但是感觉网上困惑最多的也没有给出具体答案的是scrollwindow这个函数的最后两个参数的含义,对于初学者来说,初看也是十分的困惑,所以打算花点时间研究下这个,也算是加深印象,^_^

 

下面先上一段代码,也是从网上查抄来的,此公只有代码,却没有任何说明,似乎是嫌说明太累,^_^ ,那我就顺着他的代码来,并说明实验结果,给大家一个完整的答复,也不枉浪费大家的阅读时间!好,下面开始!

 

代码:(总体而言就是一个cpp文件)

 

 

#include "stdafx.h"

#include <windows.h>

#include <stdio.h>

 

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

 

int WINAPIWinMain(HINSTANCEhInstance,HINSTANCEyY,PSTR szCmdLine,int iCmdShow)

{

   static TCHAR szWndClassName[]=TEXT("yy");

   HWND hwnd;

   MSG msg;

   WNDCLASS wndclass;

 

   wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;

   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= CreateSolidBrush( RGB(212,208,200) ) ;

   wndclass.lpszMenuName=NULL;

   wndclass.lpszClassName=szWndClassName;

 

   if(!RegisterClass(&wndclass)){

      MessageBox(NULL,TEXT("Thisprogram requires Windows NT!"),szWndClassName,MB_ICONERROR);

      return 0;

   }

 

   hwnd=CreateWindow(szWndClassName,

      TEXT("ScrollWindow()º¯Êý"),

      WS_OVERLAPPED   |  WS_CAPTION   |  WS_SYSMENU    |  WS_MINIMIZEBOX,

      CW_USEDEFAULT,

      CW_USEDEFAULT,

      300,

      300,

      NULL,

      NULL,

      hInstance,

      NULL);

 

   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;

   static int temp;

   static RECT rectScroll;

   rectScroll.left=50;

   rectScroll.top=50;

   rectScroll.right=220;

   static RECT clipRectScroll;

 

   static int index = 100;

 

   char textme[MAX_PATH] ={0};

 

   TCHAR text[1000];

 

   static LOGFONT lf;  static HFONT hFont;  static int cxText, cyText ;

 

   switch(message){

  case WM_CREATE:

     //×ÖÌ壺

     lf.lfWeight=FW_LIGHT;

     lf.lfCharSet=GB2312_CHARSET;

     lf.lfHeight=13;

     hFont=CreateFontIndirect(&lf);

 

     hdc=GetDC(hwnd);

     SelectObject (hdc, GetStockObject(NULL_BRUSH));

     SelectObject(hdc,hFont);

     SetBkMode (hdc, TRANSPARENT) ;

 

     TEXTMETRIC tm ;

     GetTextMetrics (hdc,&tm) ;

     cxText=tm.tmAveCharWidth ;cyText=tm.tmHeight ;//+ tm.tmExternalLeading ;

     rectScroll.bottom=rectScroll.top+12*cyText;

    

     clipRectScroll.left=rectScroll.left+2*cxText;

     clipRectScroll.top=rectScroll.top+3*cyText;

     clipRectScroll.right=rectScroll.right-2*cxText;

     clipRectScroll.bottom=rectScroll.top+9*cyText;

    

     ReleaseDC(hwnd,hdc);

     return 0;

 

  case WM_CHAR:

    

     sprintf(textme,"index is :  %d", index);

     MessageBox(NULL, textme, textme, MB_OK);

     break;

 

  case WM_KEYUP:

 

     //ScrollWindow (hwnd, 0, -cyText, NULL, NULL) ;//1

 

     //ScrollWindow (hwnd, 0, -cyText, &rectScroll ,0) ;//2

 

     //ScrollWindow (hwnd, 0, -cyText, &rectScroll,&clipRectScroll) ;//3

 

     ScrollWindow (hwnd,0, -cyText, NULL,&clipRectScroll) ;//4

 

     return 0 ;

 

  case WM_PAINT:

     ++index;

     hdc=BeginPaint(hwnd,&ps);

     static int tt,xx,yy,zz;//ScrollWindowµÄÈ·²úÉúÁËWM_PAINTÏûÏ¢£¡

     //if(temp<3)

     //{

     TextOut(hdc,0,0,text,wsprintf (text, TEXT("BOOL ScrollWindow(     //tt:%d´Î"),++tt)  );

     TextOut(hdc,0,cyText,text,wsprintf (text, TEXT (" HWND hWnd,int XAmount,intYAmount," )   )  );

     TextOut(hdc,0,2*cyText,text,wsprintf (text, TEXT (" const RECT *lpRect,const RECT*lpClipRect" )   )  );

     TextOut(hdc,0,3*cyText,text,wsprintf (text, TEXT (");" )   )  );

     //temp++;

     //}

 

     Rectangle(hdc,rectScroll.left-1 ,rectScroll.top-1,rectScroll.right+1,rectScroll.bottom+1);

 

     Rectangle(hdc,clipRectScroll.left-1,clipRectScroll.top-1,clipRectScroll.right+1,clipRectScroll.bottom+1);

 

     DrawText (hdc, text,

        wsprintf (text, TEXT("111111111111%d\n222222222222222222222%d\n333333333333333333333%d\n444444444444444444444%d\n555555555555555555555555\n666666666666666666666666\n777777777777777777777777\n888888888888888888888888\n999999999999999999999999\n1010 10 10 10 10 10 10 \n11 11 11 11 11 11 xx:%d´Î\n12 12 12 12 12 12 yy:%d´Î ²âÊÔÈý:lpRectÊÇÍâ¿ò£¬lpClipRectÊÇÍâ¿ò ÈÎÒâ¼ü²âÊÔ¹ö¶¯Ð§¹û  zz:%d´Î"),index,index, index,index, ++xx,++yy,++zz),

       &rectScroll,DT_NOCLIP);

 

     EndPaint(hwnd,&ps);

     return 0;

 

  case WM_DESTROY:

     PostQuitMessage(0);

     DeleteObject (hFont);

     return 0;

   }

 

   return DefWindowProc(hwnd,message,wParam, lParam) ;

}

 

 

程序运行如下图:

 

代码分析:

 

   关键代码如下:

  case WM_KEYUP:

 

     //ScrollWindow (hwnd, 0, -cyText, NULL, NULL) ;//1

 

     //ScrollWindow (hwnd, 0, -cyText, &rectScroll ,0) ;//2

 

     //ScrollWindow (hwnd, 0, -cyText, &rectScroll,&clipRectScroll) ;//3

 

     ScrollWindow (hwnd,0, -cyText, NULL,&clipRectScroll) ;//4

 

这里一共做了四中情况讨论,我分别按照自己的实验结果给出相关的解释和说明:

主要介绍 最后两个参数  其他参数不做说明,请查阅msdn或者baidu

 

 

条件一:

 

ScrollWindow (hwnd, 0, -cyText, NULL, NULL) ;//1

这个似乎没有什么好说的,大多数运行都是传空  这样的话会滚动整个hwnd客户区,对的,他不会滚动标题栏和菜单 以及状态栏,只会滚动改窗口的客户区,至于怎么找到一个overlapped窗口的客户区,那就是window内部的事情了,到此为止,不在深入。

 

值得说明的是:滚动窗口会收到一个WM_PAINT消息,但是并不会重新绘制一次,从运行结果可以看出来并没有更新程序中onpaint的index变量,但是确实是进入onpaint了,在此,给出一种猜测的实现方式,此方式也适用于后续机种情况:

Scrollwindow的实现逻辑是:现将要滚动的区域保存成一幅内存位图(或者干脆创建内存兼容dc),然后滚动当前窗口到指定的位置,下来再将滚动后新生成的区域(也就是滚出来的区域)发送一个onpaint消息,脏矩形为新生成的区域。

 

条件二:

ScrollWindow (hwnd,0, -cyText, &rectScroll,0) ;//2

 

这里有了rectscroll矩形参数,msdn上解释如下:

lpRect

[in] Pointerto the RECT structure specifying the portion of the client area to be scrolled.If this parameter is NULL, the entire client area is scrolled.

 

大致含义就是指定客户区中将被滚动的区域。

 

带上这个参数之后,就可以看到:只有外面那个大框框里面的东西被滚动了,并且滚动后会超出该框框区域,滚动步骤是:保存内存位图,滚动之,然后向新滚出来的区域发送onpaint消息,脏矩形为该新滚出来的矩形。

 

条件三:

ScrollWindow (hwnd,0, -cyText, &rectScroll,&clipRectScroll) ;//3

 

这里增加了两个参数,即剪裁矩形

lpClipRect

[in] Pointerto the RECT structure containing the coordinates of the clippingrectangle. Only device bits within the clipping rectangle are affected. Bitsscrolled from the outside of the rectangle to the inside are painted; bitsscrolled from the inside of the rectangle to the outside are not painted.

 

这里的剪裁矩形应该和windows onpaint的里面的剪裁矩形和raw区域含义相同,具体请查阅相关图形书籍,在此不详述。大体含义就是  只会更新剪裁区域里面的内容。

 

但是注意:这个和条件二的不同之处在于:条件二会滚动出这个矩形边界,但是条件三不会!!! 这是因为设置了剪裁矩形以后,onpaint更新的区域就是脏矩形和剪裁矩形的交集了,所以还是更新新滚出来的区域,并且滚动后不会超出小矩形边界!!

 

条件四:

ScrollWindow (hwnd,0, -cyText, NULL,&clipRectScroll) ;//4

 

理解了上面几个老大难后,理解4就容易的多了!

 

只设置了剪裁矩形,所以只会在那个小框框里面更新内容!

 

 

最后在做点说明:这个实例中的剪裁矩形和第三个参数的lprect是包含关系,lprect包含了剪裁矩形(大家可以试验一下当剪裁矩形和lprect矩形只相交了一点的情况),最后更新的是剪裁区域里面的内容!那么大家会问:既然只更新剪裁区域里面的内容,为何还要lprect这个外围矩形呢?是不是这个参数就没有用了呢?

 

其实不是,滚动会滚动lprect里面的内容,但是更新只更新剪裁区域里面的内容,这样的话,就给大家提供了方便,可以用两个矩形来控制要滚动的区域!!

MiniGUI编程速查表 前言 自己学习MiniGui也快一年了,粗浅的学习了一下,本文是根据《MINIGUI-PROG-GUIDE-V3.0-C》中的内容整理而来,根据自己的理解做了一些分类,大部分都是一些函数的说明,方便自己以后学习MiniGui时查阅。现在分享出来,供大家一起学习。当然在学习的过程中也遇到过一些坑,像自定义控件,主窗口透明背景,窗口弹出动画啊,控件动画等等,有时间也会分享出来。 1 窗口的创... 阅读详情

相关推荐

MFC:对话窗和滚动条的基情

创建带滚动条窗口的步骤: 以竖直方向的标准滚动条为例(横向方向和滚动条控件也类似): 1.创建一个基于对话框的MFC工程,或新建一个对话框资源,在对话框的属性-->外观 选项中把Vertical Scrollbar选项设为True。 2.在对话框的初始化函数中用SetScrollInfo函数设置滚动条的范围、页面大小、初始位置。 3.捕捉WM_VSCROLL消息,在消息处理函数On

勤能补拙 5260

窗口滚动条scrollwindow

滚动条可以控制窗口里面的控件来回移动,控件可以随着滚动条的移动而移动

[ windows程序设计(programing windows) ] - 窗口滚动条

本次要介绍的控件是ScrollBars滚动条滚动条一般在要现实的东西过多以至于屏幕无法完整呈现时使用。此时,你可以用它来滚动窗口,来显示内容的不同部分。 滚动条这个东西用电脑应该都见得多了,由两个中间包含三角的方块和一个位于两个方块之间的长条组成,一般来说这个长条是可以随着显示内容占总内容的多少来改变长度的这个比例越小,长条越小。

B1aNbian的博客 1261

ScrollWindow()函数

在学习windows编程第五版时,介绍scrollbar时,改进的程序用到了ScrollWindow()函数。按照我的理解,如果使用了UpdateWindow()函数可以 不使用ScrollWindow()函数。因为UpdateWindow()函数会产生一个WM_PAINT消息。为了搞清楚ScrollWindow()函数的作用,我将代码加了些调试 代码/*-------------------

yongan1006的专栏 6038

ScrollWindow函数功能

函数功能:该函数滚动所指定的窗体客户区域内容。函数提供了向后兼容性,新的应用程序应使用ScrollWindowEX。函数原型:BOOL ScrollWindow(HWND hWnd,int XAmount,int YAmount,CONST RECT★IpRect, CONST RECT★lpClipRect);参数:hWnd:客户区域将被滚动的窗体句柄。XAmount:指定水平滚动以设备为单位的

mader的专栏 5251

win32 中关于ScrollWindow函数的应用

1.SetScrollInfo 函数的说明: si.cbSize = sizeof(SCROLLINFO); si.cbMask = SIF_RANGE | SIF_PAGE; si.nMin = 0; si.nMax = NUMLINES - 1; si.nPage = cyClient/cyChar;   SetScrollInfo(hwnd, SB_VERT, &si,

u012513234的专栏 1191

详细解析ScrollWindow()

书籍:《(第五版)》环境:visual studio 2022内容:输出文字->滚动条信息函数说明:以下内容大部分来自腾讯元宝。

felicity_one的博客 703

滚动条详解

对上一天学习的回顾:   1&gt;.&nbsp;&nbsp;TextOut函数的使用     TextOut函数的作用是使用系统当前选择的字体、背景颜色以及正文颜色将一个字符串输出到指定位置,&nbsp;函数原型:   BOOL TextOut(    HDC hdc, //设备环境句柄    int nXStart, //字...

qq_40627648的博客 5153

如何用WINX实现可滚动的窗口(ScrollWindow)

如何用WINX实现可滚动的窗口(ScrollWindow)许式伟 (版权声明)2007-1-29用Windows SDK实现过可滚动的窗口(ScrollWindow)的读者都知道,实现一个ScrollWindow真不是一件容易的事情。你得响应好多好多的滚动条消息,还要处理鼠标滚轮。现在,你用WINX则只需要3步完成: 让你的类从ScrollWindow 实现一个名为

QBox/Golang/CERL/StdExt/TPL/WinxGui - 许式伟的专栏 4833

ScrollWindow滚动窗口,有动态按钮,且主窗口很大,主窗口有滚动条

<br />(1)首先创建主窗口时,在其属性中加上:WS_HSCROLL:<br />hwnd = CreateWindow (szAppName, TEXT ("Button Look"),<br />   WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,//WS_HSCROLL表示有滚动条<br />                          CW_USEDEFAULT, CW_USEDEFAULT,<br />                    

tmljs1988的专栏 2495

中年人学C语言Windows程序设计,6 滚动条SCROLLINFO,SetScrollInfo,GetScrollInfo,ScrollWindow

中年人学C语言Windows程序设计,6 滚动条 如果我们想在 窗口的客户区内输入多行内容就会出现显示不全的情况。 如下: 就会用到滚动条。 在学滚动条前,我们需要先学会获取当前客户区的大小。 LOWORD和HIWORD宏 获取当前客户区的大小可以使用 LOWORD和HIWORD宏 宏功能: 获得指定 32 位数据的低 16 位数据和高 16 位数据。 不要使用 LOWORD 和 HIWORD 宏去获取鼠标的坐标,因为在多显示器的情况下会得到错误的坐标。应该使用 GET_X_LPARAM 和 GET_Y

qq_40922589的博客 986

ScrollBar & ScrollWindow

windows创建的window是默认提供scrollbar功能的.在CreateWindow的时候就可以制定window的属性.WS_VSCROLL 和 WM_HSCROLL.另外windows提供了一些api用于操作scrollbar.主要就是这些APIEnableScrollBarThe EnableScrollBar function enables or disables one or both scroll bar arrows. GetScrollBarInfoThe GetScrollB

Johny的专栏 3336

关于对话框滚动条,

 要点: 使用GetScrollPos() 获取当前滑块位置,使用SetScrollPos()设置滑块位置,使用ScrollWindow()来滚动客户区, 不要使用OnHScroll() 方法中的pScrollBar参数,因为对话框好像m_HWnd变量是空,所以这个参数的方法pScrollBar->GetScrollPos()  / pScrollBar->SetScrollPos

deh_1984的专栏 3612

VC对话框实现添加滚动条实现滚动效果

对话框滚动条及滚动效果实现,用的api主要有: ScrollWindow, SetScrollInfo, GetScrollInfo, SetWindowOrgEx。涉及的数据结构为SCROLLINFO。实现的原理为:设置窗口显示的滚动条;响应滚动条的消息,在其中记录窗口原点的x和y坐标,并滚动窗口;在OnPaint中设置窗口原点,并绘图。SCROLLINFOtypedef struct tagS...

shifouxinyu的博客 3118

C++ 窗口滚动条

1.给窗口添加滚动条 WS_HSCROLL,WS_VSCROLL 2.设定滚动条的范围,位置,页面大小 SetScrollInfo(),SetScrollPOS() 3.使滚动条滑块大小和窗口尺寸同步变化 OnSize() 4.处理滚动条消息 OnHScroll(),OnVScroll() 5.滚动窗口 ScrollWindow() ...

weixin_40806975的博客 2101

windows滚动条

1:滚动条处理方法分类 windows中使用滚动条函数有两类,一种比较古老的,但也是有效的,其调用函数如下: bool SetScrollRange(hwnd,iBar,iMin,iMax,bRedraw); int SetScrollPos(hwnd,iBar,iPos,bRedraw); bool GetScrollRange(hwnd,ibar,lpiMin,lpiMax); int

eskimoer的专栏 1400
上一篇: VS中 宏 的使用,做个小小的总结,以及常见的一些疑问
sunlikerain
博客等级 码龄15年 1粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值