由于显示的字符可能会不全,我们很容易想到的一个解决办法是使用滚动条。

先看一下代码,再进行分析:

/*----------------------------------------------------
SYSMETS2.C -- System Metrics Display Program No. 2
(c) Charles Petzold, 1998
----------------------------------------------------*/ #define WINVER 0x0500
#include <windows.h>
#include "sysmets.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("SysMets2") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
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 ;
} hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 2"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL ,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, , ))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
} LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cxCaps, cyChar, cyClient, iVscrollPos ;
HDC hdc ;
int i, y ;
PAINTSTRUCT ps ;
TCHAR szBuffer[] ;
TEXTMETRIC tm ; switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd) ; GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cxCaps = (tm.tmPitchAndFamily & ? : ) * cxChar / ;
cyChar = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; SetScrollRange (hwnd, SB_VERT, , NUMLINES - , FALSE) ;
SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
return ; case WM_SIZE:
cyClient = HIWORD (lParam) ;
return ; case WM_VSCROLL:
switch (LOWORD (wParam))
{
case SB_LINEUP:
iVscrollPos -= ;
break ; case SB_LINEDOWN:
iVscrollPos += ;
break ; case SB_PAGEUP:
iVscrollPos -= cyClient / cyChar ;
break ; case SB_PAGEDOWN:
iVscrollPos += cyClient / cyChar ;
break ; case SB_THUMBPOSITION:
iVscrollPos = HIWORD (wParam) ;
break ; default :
break ;
} iVscrollPos = max (, min (iVscrollPos, NUMLINES - )) ; if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))
{
SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
InvalidateRect (hwnd, NULL, TRUE) ;
}
return ; case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ; for (i = ; i < NUMLINES ; i++)
{
y = cyChar * (i - iVscrollPos) ; TextOut (hdc, , y,
sysmetrics[i].szLabel,
lstrlen (sysmetrics[i].szLabel)) ; TextOut (hdc, * cxCaps, y,
sysmetrics[i].szDesc,
lstrlen (sysmetrics[i].szDesc)) ; SetTextAlign (hdc, TA_RIGHT | TA_TOP) ; TextOut (hdc, * cxCaps + * cxChar, y, szBuffer,
wsprintf (szBuffer, TEXT ("%5d"),
GetSystemMetrics (sysmetrics[i].iIndex))) ; SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
}
EndPaint (hwnd, &ps) ;
return ; case WM_DESTROY:
PostQuitMessage () ;
return ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

我们在CreateWindow函数的第三个参数加上 WS_VSCROLL 即垂直滚动条。

同时在WM_CREATE中加入:

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

SetScrollRange设置滚动条范围,NUMLINES是在头文件中定义的行数,

滚动条的每个位置对应一行文字。

iVscrollPos变量记录这滑块的当前位置。

在鼠标拖动滑块时,会产生WM_VSCROLL消息,对iVscrollPos变量进行赋值操作。

还有更改的一处是Y坐标: y = cyChar * (i - iVscrollPos) ; 这保证了滑动之后,小于当前位置的字符不会输出到屏幕(因为他们Y坐标是负的)

同时在滑动滚动条的时候:

if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))
{
SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
InvalidateRect (hwnd, NULL, TRUE) ;
}

当滚动条位置改变之后我们会用InvalidateRect函数使窗口无效,会生成WM_PAINT消息,重绘窗口。

windows程序设计读书笔记3——字符显示2的更多相关文章

  1. windows程序设计读书笔记2——字符显示1

    本程序使用GetSystemMetrics获取windows各种图像选项,并输出字符到窗口中. #define WINVER 0x0500 #include <windows.h> #in ...

  2. windows程序设计读书笔记4——字符显示3

    在之前的一章里我们使用InvalidateRect函数,生成窗口重绘消息进行重绘,但是并没有在处理滚动条消息时直接绘制,这样的代码效率并不高. 这里作者使用了UpdateWindow函数,直接进行窗口 ...

  3. windows程序设计读书笔记1——创建窗口

    第一个win32程序,简单的创建窗口: #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ...

  4. Windows内核读书笔记——Windows异常分发处理机制

    本篇读书笔记主要参考自<深入解析Windows操作系统>和<软件调试>这两本书. IDT是处理异常,实现操作系统与CPU的交互的关口. 系统在初始化阶段会去填写这个结构. ID ...

  5. Windows程序设计学习笔记(一)Windows内存管理初步

    学习Windows程序设计也有一些时间了,为了记录自己的学习成果,以便以后查看,我希望自己能够坚持写下一系列的学习心得,对自己学习的内容进行总结,同时与大家交流.因为刚学习所以可能有的地方写不不正确, ...

  6. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  7. Windows程序设计学习笔记(1):一个简单的windows程序

    <Windows程序设计>(第五版)(美Charles Petzold著) #include<windows.h> LRESULT CALLBACK WndProc(HWND, ...

  8. AngularJS高级程序设计读书笔记 -- 大纲篇

    零. 初衷 现在 AngularJS 4 已经发布了, 楼主还停留在 1.x 的阶段, 深感自卑. 学习 AngularJS 的初衷是因为, 去年楼主开始尝试使用 Flask 开发自动化程序, 需要用 ...

  9. 关于Lua程序设计{读书笔记}

    1.lua中的标识符可以是由任意字母.数字和下划线构成的字符串,但不能以数字开头.2.lua将通常类似"_VALUE"的标识符作为保留标识符3.lua的保留字 and break ...

随机推荐

  1. tp其他功能

    数据缓存 在ThinkPHP中进行缓存操作,一般情况下并不需要直接操作缓存类,因为系统内置对缓存操作进行了封装,3.1版本推荐的数据缓存方法是cache方法,基本的用法是:(3.1.2版本cache方 ...

  2. BootStrap 模态框禁用空白处点击关闭,手动显示隐藏,垂直居中

    $('#ajax_wait').modal({ backdrop: 'static', keyboard: false }); backdrop:static ,空白处不关闭. keyboard:fa ...

  3. MVC4 Win2008 aspnet_isapi配置问题

    win2008下配置共2步 1.先确保你的应该程序池选择了asp.net 4.0框架 2.添加脚本映射(解决URL不能重写) 3.添加通配符脚本映射(解决图片不能显示) IIS中的Web应用程序有两种 ...

  4. 谈谈我对Java中CallBack的理解

    谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...

  5. NFC介绍

    简介 本文介绍Nokia设备所支持的近场通信技术(NFC)及相关的功能.旨在为使用 Qt/Symbian/Java™ API为Nokia手机开发应用的开发者 刚开始接触NFC开发时提供有用的信息. 什 ...

  6. 把自定义控件集成到Qt Designer中

    要想在Qt Designer中使用自定义控件,必须要使Qt Designer能够知道我们的自定义控件的存在.有两种方法可以把新自定义控件的信息通知给Qt Designer:“升级(promotion) ...

  7. C++之单元测试

    以前编写程序从没有做过单元测试的工作,所以在后期会花很多时间去纠错,这也就是软件工程中的2:8定律.最近要完成一个项目,要求要对系统中的主类和主函数作出单元测试的保证,才去查找了相关方面的资料,看过后 ...

  8. C#中ref和out的使用小结

    ref传递的参数是变量的地址,在传入函数后,函数可以使用这些地址处的值,同时函数执行完后,这些变量被带回了调用者.ref传递的参数既可作传入值,也可作返回值. out传递的参数是变量的地址,在传入函数 ...

  9. Easyui几种布局方式的使用

    1.通过标记创建layout.  记得添加"easyui-layout"样式给div标记. <div id="cc" class="easyui ...

  10. http 中get和post

    1. http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html 浅谈HTTP中Get与Post的区别 2009-03-31 14:51 ...