windows滚动条

原创 2012年03月28日 17:40:45

今天自己写了《windows程序设计》184页的用键盘控制滚动条显示程序,对滚动条显示有点感悟,留个纪念!

代码如下:

#include <Windows.h>
#include <math.h>
#include "SYSMETS.h"

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
	static TCHAR szAppName[]=TEXT("First Program");
	MSG msg;
	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(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(hwnd,TEXT("Error exists!"),TEXT("Error!"),MB_ICONERROR);
		return 0;
	}

	hwnd=CreateWindow(szAppName,TEXT("Hello World!"),WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
		CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

	ShowWindow(hwnd,iCmdShow);
	UpdateWindow(hwnd);

	while (GetMessage(&msg,hwnd,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	static int cxChar,cyChar,cxCaps,cxClient,cyClient;
	int iVertPos,x,y,i,iPaintBeg,iPaintEnd;
	TCHAR szBuffer[20];
	HDC hdc;
	PAINTSTRUCT ps;
	TEXTMETRIC tm;
	SCROLLINFO si;

	switch(message)
	{
	case WM_CREATE:
		hdc=GetDC(hwnd);

		GetTextMetrics(hdc,&tm);
		cxChar=tm.tmAveCharWidth;
		cyChar=tm.tmHeight+tm.tmExternalLeading;
		cxCaps=(tm.tmPitchAndFamily&1?3:2)*cxChar/2;
		ReleaseDC(hwnd,hdc);
		return 0;

	case WM_SIZE:
		cxClient=LOWORD(lParam);
		cyClient=HIWORD(lParam);
		si.cbSize=sizeof(si);
		si.fMask=SIF_RANGE|SIF_PAGE;
		si.nMin=0;
		si.nMax=NUMLINES-1;
		si.nPage=cyClient/cyChar;
		SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
		return 0;

	case WM_VSCROLL:
		si.cbSize=sizeof(si);
		si.fMask=SIF_ALL;
		GetScrollInfo(hwnd,SB_VERT,&si);
		iVertPos=si.nPos;

		switch(LOWORD(wParam))
		{
		case SB_TOP:
			si.nPos=si.nMin;
			break;

		case SB_BOTTOM:
			si.nPos=si.nMax;
			break;

		case SB_PAGEUP:
			si.nPos-=si.nPage;
			break;

		case SB_PAGEDOWN:
			si.nPos+=si.nPage;
			break;

		case SB_LINEUP:
			si.nPos-=1;
			break;

		case SB_LINEDOWN:
			si.nPos+=1;
			break;

		case SB_THUMBTRACK:
			si.nPos=si.nTrackPos;
			break;

		default:
			break;
		}
		si.cbSize=sizeof(si);
		si.fMask=SIF_POS;
		SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
		GetScrollInfo(hwnd,SB_VERT,&si);
		if (si.nPos!=iVertPos)
		{
			ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);
			UpdateWindow(hwnd);
		}
		return 0;

	case WM_KEYDOWN:
		switch(wParam)
		{
		case VK_UP:
			SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0);
			break;

		case VK_DOWN:
			SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0);
			break;

		case VK_PRIOR:
			SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);
			break;

		case VK_NEXT:
			SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);
			break;

		default:
			break;
		}
		return 0; 
     //关键代码
	case WM_PAINT:
		si.cbSize=sizeof(si);
		si.fMask=SIF_ALL;
		GetScrollInfo(hwnd,SB_VERT,&si);
		iVertPos=si.nPos;
	   
		hdc=BeginPaint(hwnd,&ps);
		iPaintBeg=max(0,si.nPos+ps.rcPaint.top/cyChar);
		iPaintEnd=min(si.nMax,si.nPos+ps.rcPaint.bottom/cyChar);

		for (i=iPaintBeg;i<=iPaintEnd;i++)
		{
			y=cyChar*(i-iVertPos);

			TextOut(hdc,0,y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
			TextOut(hdc,22*cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
			SetTextAlign(hdc,TA_TOP|TA_RIGHT);
			TextOut(hdc,60*cxCaps,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].Index)));
			SetTextAlign(hdc,TA_LEFT|TA_TOP);
		}
		EndPaint(hwnd,&ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}

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

原来我老是有个疑问:

1、iPaintBeg=max(0,si.nPos+ps.rcPaint.top/cyChar);
      iPaintEnd=min(si.nMax,si.nPos+ps.rcPaint.bottom/cyChar);

      这两句是干嘛用的?

2、为什么是for (i=iPaintBeg;i<=iPaintEnd;i++)这样循环?

3、y=cyChar*(i-iVertPos);

     为什么是i-iVertPos?


今天调试了一下,颇有感悟!

调试时滚动条下拉了一行!


首先给出调试时一些参数,是我写的一张图:



得出了一些结论:

1、下拉滚动条时,只更新时新出现的客户区,这个矩形的具体参数存数在ps.rcPaint中。

更新起点iPaintBeg是需更新矩形的顶部所在的行数,iPaintEnd是底部所在的行数。即图中新出现一行的顶部和底部。

2、for循环就是输出这些新出现的文本

3、i-iVerPos就是以新客户区的顶部为起点更新客户区

Windows编程之滚动条—滚动条消息

在用鼠标单击滚动条或者拖动卷动方块时,Windows给窗口消息处理程序发送WM_VSCROLL(供上下移动)和WM_HSCROLL(供左右移动)消息。在滚动条上的每个鼠标动作都至少产生两个消息,一条在...
  • haojingus
  • haojingus
  • 2013年09月23日 12:19
  • 1111

Windows API学习之滚动条系列函数

Windows API学习之滚动条系列函数。
  • clever101
  • clever101
  • 2011年02月17日 18:17
  • 7876

Windows编程之滚动条

Windows编程之滚动条 http://see.xidian.edu.cn/cpp/html/1110.html   滚动条是图形使用者接口中最好的功能之一,它很容易使用,而且提供了很好的视觉...
  • jiangxinyu
  • jiangxinyu
  • 2012年10月24日 16:02
  • 7791

windows程序设计(5)使用滚动条

本文的程序来自《windows程序设计(第五版)》 设计滚动条的初衷,是因为客户区需要显示的东西太多了,在这个头文件中,我们包含了一大堆的系统的信息: //总行数 #define NUMLINES...
  • thefutureisour
  • thefutureisour
  • 2012年05月16日 09:57
  • 2740

windows消息参考大全(vc 去掉水平滚动条)

下是windows消息队列中会出现的所有的消息,在学习win32asm或者windows核心编程、win socket或者VC/VC++的其它的windows程序的时候会很有帮助的。 WM_CREAT...
  • zeng622peng
  • zeng622peng
  • 2010年04月28日 21:26
  • 3984

win32 api 滚动条 处理 WM_VSCROLL消息

scroll.c /* ------------------------------------------------------------------- Author:邱于涵 --------...
  • u012997311
  • u012997311
  • 2016年11月20日 13:59
  • 868

VC/MFC中如何替换自带滚动条控件的图片

 Replace a Window's Internal Scrollbar with a customdraw scrollbar Control flyhigh, 17 Jun ...
  • comwise
  • comwise
  • 2014年11月07日 23:48
  • 1523

WIN32滚动条创建和使用详解

一直对WIN32编程感兴趣,刚开始是从MFC摸索的,总感觉不带劲,新近网上看了一些博客,自己也看了Window程序设计,终于用原版的WIN32写了窗口并处理了滚动条,在这里给大家分享一下。      ...
  • hd770c
  • hd770c
  • 2014年01月08日 00:45
  • 2340

Windows对话框和滚动条

Windows对话框和滚动条cheungmine 2010-1 尽管在Windows平台上编程多年,对滚动条的理解还是很肤浅。尤其给对话框添加滚动条。参考下面的文章: http://www.codep...
  • cheungmine
  • cheungmine
  • 2010年01月11日 23:32
  • 4634

用自建的滚动条代替windows控件内建的滚动条(1)

       最近遇到了这样的问题,使用某个皮肤软件来为界面换皮肤,但必须取得控件的句柄,才能对控件换皮肤。对于标准控件,如CEdit,CRichEdit, CTreeCtrl等控件,内建的滚动条句柄...
  • hjuncheng
  • hjuncheng
  • 2006年01月17日 22:09
  • 1471
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:windows滚动条
举报原因:
原因补充:

(最多只允许输入30个字)