相关函数:

setscrollrange,setscrollpos,getscrollrange,getscrollpos

使用滚动条时我们需要进行的操作:

1.初始化滚动条范围和位置

在窗口创建时WM_CREATE响应时可以完成

SetScrollRange(hwnd, SB_VERT, , NUMLINES,FALSE);
SetScrollPos(hwnd, SB_VERT, , TRUE);

2.处理窗口过程的滚动条消息

在响应WM_VSCROLL时处理

switch(LOWORD(wParam))
{
case SB_LINEUP:
....
break;
case SB_LINEDOWN:
....
break;
case SB_PAGEUP:
....
break;
case SB_PAGEDOWN:
....
break;
case SB_THUMBTRACK:
....
break;
case SB_THUMBPOSITION:
....
break;
}

注意在wParam参数中的低十六位中可以获取鼠标在滚动条上的动作使用LOWORD(wParam)

当滚动条动作为SB_THUMBPOSITION或SB_THUMBTRACK时,可以在wParam参数中的高十六位中获取位置HIWORD(wParam)

3.更新滑块位置

SetScrollPos(hwnd, SB_VERT, XXX, TRUE);

4.根据滚动条变化更新客户端内容

可以在处理滚动条消息是设置全局参数,在WM_PAINT响应时做出响应更新

为了及时更新客户端内容

可以使用

InvalidateRect(hwnd, NULL, TRUE);

向消息队列中发送消息WM_PAINT,此消息会放在消息队列后面,知道其他消息处理完毕才会响应

或者使用

UpdateWindow(hwnd);

非队列化消息,跳过消息循环机制直接处理更新窗口

全部代码:

#include <windows.h>
#include <strsafe.h>
#include "SysMet.h" LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iShowCmd)
{
static TCHAR szClassName[] = TEXT("MyWindow5");
MSG msg;
HWND hwnd; WNDCLASS wndclass;
wndclass.cbClsExtra=;
wndclass.cbWndExtra=;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wndclass.hIcon = LoadIcon(NULL, IDC_ARROW);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW; if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("this program must run in win nt!"), TEXT("ERROR"), MB_OK);
return ;
} hwnd = CreateWindow(szClassName,
TEXT("MyWindowProgram"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
); ShowWindow(hwnd,iShowCmd);
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;
TCHAR szBuffer[];
TEXTMETRIC tm;
static int cxChar, cyChar, cxCaps,iVscrollPos;//大写占1.5倍
size_t st;
int y;
static int cxClient, cyClient;
switch (message)
{
case WM_CREATE:
iVscrollPos = ;
SetScrollRange(hwnd, SB_VERT, , NUMLINES,FALSE);//后面代表是否现在重画窗口
SetScrollPos(hwnd, SB_VERT, , TRUE); hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmExternalLeading + tm.tmHeight;
cxCaps = (tm.tmPitchAndFamily & ? : )*cxChar / ;
ReleaseDC(hwnd,hdc);
break;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam); case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); for (int i = ; i < NUMLINES;i++)
{
y = cyChar*(i - iVscrollPos);
//获取的大量数据
StringCchLength(sysmetrics[i].szLabel, , &st);
TextOut(hdc, , y, sysmetrics[i].szLabel, st); StringCchLength(sysmetrics[i].szDesc, , &st);
TextOut(hdc, * cxCaps, y, sysmetrics[i].szDesc, st); SetTextAlign(hdc,TA_RIGHT|TA_TOP);
StringCchPrintf(szBuffer, , L"%d %d %5d", i + ,iVscrollPos, GetSystemMetrics(sysmetrics[i].iIndex));
StringCchLength(szBuffer, , &st);
TextOut(hdc, * cxCaps + * cxChar, y, szBuffer, st);
SetTextAlign(hdc, TA_LEFT|TA_TOP);
} //获取屏幕分辨率
// cxClient=GetSystemMetrics(SM_CXSCREEN); //水平
// cyClient=GetSystemMetrics(SM_CYSCREEN); //垂直
// StringCchPrintf(szBuffer, 100, L"screen : %d * %d px", cxClient, cyClient);
// //在屏幕中心写字
// GetClientRect(hwnd, &rect);
// DrawText(hdc, szBuffer, -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER); EndPaint(hwnd, &ps);
break;
case WM_VSCROLL:
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rect);
if (LOWORD(wParam) == SB_LINEUP)
{
iVscrollPos -= ;
}
else if (LOWORD(wParam) == SB_LINEDOWN)
{
iVscrollPos += ;
}
else if (LOWORD(wParam) == SB_PAGEUP)
{
iVscrollPos -= cyClient / cyChar;
}
else if (LOWORD(wParam) == SB_PAGEDOWN)
{
iVscrollPos += cyClient / cyChar;
}
else if (LOWORD(wParam) == SB_THUMBTRACK)
{
DrawText(hdc, L"Slider.....", -, &rect, DT_RIGHT | DT_VCENTER);
}
else if (LOWORD(wParam) == SB_THUMBPOSITION)
{
iVscrollPos = HIWORD(wParam);
}
ReleaseDC(hwnd, hdc); iVscrollPos = max(, min(iVscrollPos, NUMLINES));
if (iVscrollPos != GetScrollPos(hwnd, SB_VERT))
{
InvalidateRect(hwnd, NULL, TRUE);
SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
}
break;
case WM_DESTROY:
PostQuitMessage();
break;
case WM_QUIT:
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return ;
}

学习windows编程 day2 之滚动条使用的更多相关文章

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

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

  2. 有一定基础的 C++ 学习者该怎样学习 Windows 编程?

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

  3. 我为什么学习Windows编程

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

  4. 学习windows编程 day1

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

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

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

  6. 学习windows编程 day4 之 绘制随机矩形和peekMessage

    #include <windows.h> #include <strsafe.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT messa ...

  7. 学习windows编程 day4 之 自定义映射

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

  8. 学习windows编程 day4 之视口和窗口

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

  9. 学习windows编程 day4 之 盯裆猫

    写着写着就困了.... 看这些测量数据就算了,是对各种函数的练习 #include <windows.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT ...

随机推荐

  1. mysql外键关联

    主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的.所以说,如果谈到了外键,一定是至少涉及到两张表 ...

  2. [2017BUAA软工]个人项目:数独

    一.项目地址 https://github.com/Slontia/Sudoku 附加作业(GUI):https://github.com/Slontia/SudokuGUI 二.开发时间 PSP2. ...

  3. java.lang.Exception: No tests found matching Method tes(com.bw.test.Testrefiect) from org.junit.vintage.engine.descriptor.RunnerRequest@3bfdc050 at org.junit.internal.requests.FilterRequest.getRunner

    junit   方法  没有加上注解  @Test java.lang.Exception: No tests found matching Method tes(com.bw.test.Testre ...

  4. PHP压力测试使用apache的ab工具和Linux的time命令

    ab工具是apache自带的一个压力测试工具,可以在apache的安装路径下的bin目录下找到,我的环境中是在/usr/local/apache/bin/目录下: ab 压测主要使用两个参数: -n ...

  5. vue的使用1

    Vue.$set(object, key, value); <!-- Alt + C --> <input @keyup.alt.="clear"> < ...

  6. 热修改 MySQL 数据库 pt-online-schema-change 的使用详解

    由于周五公司团建的关系所以此篇推迟了抱歉. 首先不得不在该篇里面梳理一个数据库热增加删除字段表的工具 pt-online-schema-change 这个工具在前面我的博文 <关于utf8mb4 ...

  7. BZOJ3419[POI2013]taxis——贪心

    题目大意: 一条线段有三个点,0为初始位置,d为出租车总部位置,m为家的位置,人要叫车,有n辆车可以提供,每辆车有一个路程上限,并且都从车站出发,叫的车行驶之后不必须回到车站,问最少叫几辆车. 一定能 ...

  8. BZOJ4378[POI2015]Logistyka——树状数组

    题目描述 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作.每次 ...

  9. Java生成数独函数

    突然想写一下生成算法.代码注释的比较多,应该比较好理解 使用了递归 import java.util.ArrayList; public class Sudoku { static int sudok ...

  10. Educational Codeforces Round 8 B. New Skateboard

    题目链接:http://codeforces.com/problemset/problem/628/B 解题思路: 一个数最后两位数能被4整除那么这个数就能被4整除,而且题目还是连续的子序列,这就很简 ...