学习windows编程 day3 之滚动条完善

时间:2022-04-20 23:05:13

1.不再使用setscrollrange,setscrollpos,getscrollrange,getscrollpos这些函数,这只是有助于理解其中运行原理

2.改用setscrollinfo,getscrollinfo函数和结构体scrollinfo去改变和获取滚动条信息,相对于上面会更加灵活,方便扩展

3.scrollwindow:滚动窗口客户区的内容,只滚动当前显示的内容,要显示其他内容,需要重绘失效的窗口,但是相对于重绘整个窗口是一个很节省内存的方法

#include <windows.h>
#include "Sysmet.h"
#include <strsafe.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//声明全局数据:类名
static TCHAR szClassName[] = TEXT("MyWindows");
HWND hwnd;
MSG msg; //注册窗口类
WNDCLASS wndclass; wndclass.hInstance = hInstance;
wndclass.lpszClassName = szClassName;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszMenuName = NULL;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.style = CS_HREDRAW; if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("this program must run in Windows NT!"), szClassName, MB_ICONERROR);
return ;
} hwnd = CreateWindow(
szClassName,
TEXT("MyFirstPractice"),
WS_OVERLAPPEDWINDOW|WS_VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
); ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd); while (GetMessage(&msg, NULL, , ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
//获取字体大小,初始化数据
static int cxChar, cyChar, cxCaps;
//获取每次重绘窗口后的大小尺寸
static int cxClient, cyClient;
//获取总行数和当前行数
static numCount, curCount; static int y;
int FirstLine, LastLine; TEXTMETRIC tm;
TCHAR szBuffer[];
size_t st;
SCROLLINFO si; switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
//获取字体大小,初始化数据
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
cxCaps = (tm.tmPitchAndFamily & ? : )*cxChar / ; //初始化总行数和当前行数
numCount = NUMLINES;
curCount = ; //初始化滚动条位置
SetScrollRange(hwnd, SB_VERT, , numCount, FALSE);
SetScrollPos(hwnd, SB_VERT, , TRUE); ReleaseDC(hwnd, &hdc); break;
case WM_SIZE:
//获取每次重绘后的屏幕大小
cxClient = LOWORD(lParam); //这是获取当前窗口的大小
cyClient = HIWORD(lParam); //设置垂直滚动条的范围和页面大小
si.cbSize = sizeof(si); //为了更好的兼容版本
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = ;
si.nMax = numCount - ;
si.nPage = cyClient / cyChar; //页面的大小设置 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
break;
case WM_VSCROLL:
//获得垂直滚动条的信息
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si); //保存当前滑块的位置
curCount = si.nPos; switch (LOWORD(wParam))
{
case SB_LINEUP:
si.nPos -= ;
break;
case SB_LINEDOWN:
si.nPos += ;
break;
case SB_PAGEUP:
//先获取当前页面有几行
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN:
//先获取当前页面的行数
si.nPos += si.nPage;
break; case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
//在si.nTrackPos中存放着SB_THUMBTRACK和SB_THUMBPOSITION的位置信息
case SB_THUMBPOSITION:
si.nPos = si.nTrackPos;
break;
default:
break;
} //设置滚动滑块的新位置
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE); //再次获得滚动滑块的位置,由于窗口调整,他可能不是同一个值
GetScrollInfo(hwnd, SB_VERT, &si);
//curCount是前面未滚动的数据,si.nPos是刚刚滚动后的数据(除非是在顶部或者底部,不然由于窗口调整,两种一定不是同一个值)
if (si.nPos != curCount)
{
ScrollWindow(hwnd, , cyChar*(curCount-si.nPos), NULL, NULL);
/*
hwnd :窗口句柄
0 :水平滚动的数量
cyChar*(curCount-si.nPos):垂直滚动的距离
NULL(lpRect) :为NULL时,当前整个客户区将被滚动
NULL(lpClipRect) :与上一个参数有关,当上一个设置区域后,该参数在其区域中裁剪区域进行滚动
*/
UpdateWindow(hwnd);
//不进入消息队列,直接发送WM_PAINT消息进行处理
}
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); //获取垂直滚动条的位置
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(hwnd,SB_VERT, &si);
curCount = si.nPos; //计算需要重绘的区域
FirstLine = max(, curCount + ps.rcPaint.top / cyChar);
LastLine = min(numCount - , curCount + ps.rcPaint.bottom / cyChar);
/*
ps是结构体,ps.rcPaint是指需要重绘的部分窗口矩形,ps.rcPaint.top是该矩形的上部
*/ for (int i = FirstLine; i < LastLine;i++)
{
y = cyChar*(i - curCount); //相当于将这个重绘区域看着新窗口,重这个区域的顶部开始重新绘制 StringCchLength(sysmetrics[i].szLabel, , &st);
TextOut(hdc, , y, sysmetrics[i].szLabel, st); StringCchLength(sysmetrics[i].szDesc, , &st);
TextOut(hdc, * cxChar, y, sysmetrics[i].szDesc, st); SetTextAlign(hdc, TA_RIGHT | TA_TOP); StringCchPrintf(szBuffer, , L"%5d", GetSystemMetrics(sysmetrics[i].iIndex));
StringCchLength(szBuffer, , &st);
TextOut(hdc, * cxChar + * cxCaps, y, szBuffer, st); SetTextAlign(hdc, TA_LEFT);
} EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage();
return ;
} return DefWindowProc(hwnd, message, wParam, lParam);
}

学习windows编程 day3 之滚动条完善的更多相关文章

  1. 学习windows编程 day2 之滚动条使用

    相关函数: setscrollrange,setscrollpos,getscrollrange,getscrollpos 使用滚动条时我们需要进行的操作: 1.初始化滚动条范围和位置 在窗口创建时W ...

  2. 学习windows编程 day3 之窗口绘画二:边框绘制函数

    #include <windows.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l ...

  3. 学习windows编程 day3 之窗口绘画一:点线绘制

    #include <windows.h> #include <math.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT message, ...

  4. 学习windows编程 day3 之 设置当前的背景颜色

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRU ...

  5. 学习windows编程 day3 之 自定义画笔的两种方法

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRU ...

  6. 有一定基础的 C&plus;&plus; 学习者该怎样学习 Windows 编程?

    人的心理有个奇异的特性:一项知识一旦学会之后,学习过程中面临的困惑和不解非常快就会忘得干干净净,似乎一切都是自然而然,本来就该这种.因此,关于「怎样入门」这类问题,找顶尖高手来回答,未必能比一个刚入门 ...

  7. 我为什么学习Windows编程

    前一段时间在看TCP/IP,在图书馆里面找了不少的书,其中有几本书还是不错的.比如: <Windows网络与通信程序设计(第二版)> 王艳平著 <WinSock网络编程经络> ...

  8. 学习windows编程 day1

    #include <windows.h> #include <strsafe.h> /* 任务:去掉标题栏和边框 */ //#define LineHeight 15 这是自己 ...

  9. 学习windows编程 day6 之处理鼠标移动

    #define POINT_MAX 1000 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPara ...

随机推荐

  1. ABAP 销售范围

    *&---------------------------------------------------------------------* *& Report  ZSDR008 ...

  2. W3C对DOM2&period;0定义的标准事件

    DOM2.0模型将事件处理流程分为三个阶段: 一.事件捕获阶段, 二.事件目标阶段, 三.事件起泡阶段. 具体如图(图片来源于网络,侵删) 事件捕获:当某个元素触发某个事件(如onclick),顶层对 ...

  3. 团队冲刺the first day

    2014年5月5号晚上我们团队小组一起做了团队项目.在此期间我们确定了项目的详细计划,,界面的安排,主界面,还有实现的具体功能,在这我就不做赘述了. 本次晚上我们做主界面,把界面和界面之间的调转实现了 ...

  4. 浅谈网络爬虫爬js动态加载网页(二)

    没错,最后我还是使用了Selenium,去实现上一篇我所说的问题,别的没有试,只试了一下firefox的引擎,总体效果对我来说还是可以接受的. 继续昨天的话题,既然要实现上篇所说的问题,那么就需要一个 ...

  5. java&period;lang&period;IllegalArgumentException&colon; Requested window android&period;os&period;BinderProxy&commat;450b2f48 异常处理

    晕死的错误,改了半天也没想到是这样的原因,基础正要呀... 先看一下警告信息: 07-07 08:32:19.540: WARN/WindowManager(74): Failed looking u ...

  6. IsPostBack是什么意思,如何运用?

    IsPostBack是Page类的一个属性,返回值为一个布尔值.一般放在Page_Load事件中.当页面是第一次打开时其值为False,若当前页面为一个提交后的页面其值为True. if (!IsPo ...

  7. 将默认首页设置成index&period;do的方法

    变态欺骗法,今天csdn一个前辈的,学习了,公司服务器是weblogic的,也可以欺骗. 但是我又非常迫切.非常盼望.非常渴望使用index.do做首页,怎么办? Tomcat中用一段注释: When ...

  8. wxPython中基本控件学习

    wxPython工具包提供了多种不同的窗口部件,包括了本章所提到的基本控件.我们涉及静态文本.可编辑的文本.按钮.微调.滑块.复选框.单选按钮.选择器.列表框.组合框和标尺.对于每种窗口部件,我们将提 ...

  9. centos7初上手1-安装mysql数据库

    随着云服务器的普及,购入云服务器的门槛越来越低,对一个程序员来说,很多人会购买一款云服务器.以前买过两年windows服务器(没有什么实际用途,就是为了玩),最近有机会接触一下linux服务器,选择了 ...

  10. 我的书单&lpar;Book List&rpar;

    code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...