windows程序设计学习笔记-Unicode,绘图基础

2.Unicode

1.双字节字符集
有些字符由一个字节组成,另一些由两个字节组成。

2.Unicode
一个字符由两个字节组成。
处理器在存储多字节数值时,对单个字符的高低字节可能顺序或逆序存放。

在字符,字符串前加L,如L’H’,L”Hello”,告知编译器对每个字符用两个字节存储。

对C库函数中有字符串参数的需要使用该函数的宽字符版本来处理宽字符。

3.TCHAR

#iddef _UNICODE
    #typedef wchar_t TCHAR;

    #define TEXT(x) L##x
#else
    #typedef char TCHAR

    #define TEXT(x) x
#endif

还有对应的用一种函数名来根据是否采用了Unicode字符集来决定翻译成该函数的宽字符版本还老版本。微软提供的。
常见函数举例:
lstrlen
lstrcpy
lstrcpyn
lstrcat
lstrcmp
lstrcmpi
_stprintf
_sntprintf
MessageBox…

3.窗口与消息

应用程序窗口,对话框,按钮,复选框,滚动条…

Windows程序开始执行时,首先,为该程序创建一个“消息队列”,其中存放应用程序可能创建的所有窗口的消息。有些消息可不经消息队列,直接发给对应的窗口过程。

WNDCLASS wndclass;
wndclass.cbClsExtra:用于在类结构中预留一些额外空间。
wndclass.cbWndExtra:用于在windows内部维护的窗口结构中预留一些额外空间。

TranslateMessage(&msg):将msg结构返还给Windows以进行某些键盘消息的转换。
DiapatchMessage(&msg):Windows将消息发给合适的窗口过程。

在窗口过程中对需要处理的消息捕获处理后返回0,对其他消息都交给DefWindowProc

BeginPaint调用期间Windows可能会擦除客户区背景。
用户单击关闭产生,WM_DESTROY,
PostQuitMessage产生WM_QUIT,会使消息循环结束。

4.文本输出

客户区中有一个无效区域时,Windows在应用程序的消息队列中将放一条WM_PAINT。WM_PAINT同时在消息队列中至多一条。无效矩形包含了客户区所有无效区域。

BeginPaint返回的设备环境句柄的裁剪矩形是无效矩形。
GetDC返回的设备环境句柄的裁剪矩形是整个客户区。且GetDC不会使无效区域有效化。

GetWindowDC返回的是整个窗口的设备环境句柄,包含窗口的客户区和非客户区。

GetTextMetrics(hdc, &tm); // 获取设备环境中与字体相关的信息
tm.tmAscent:字符在基线上的最大高度[包含了tm.tmInternalLeading]
tm.tmDescent:字符在基线下的最大高度
tm.tmHeight = tm.tmAscent + tm.tmDescent
tm.tmExternalLeading:两行字符间距
tm.tmAveCharWidth:小写字符加权平均宽度[大写字符的可按小写的1.5倍算]
tm.tmMaxCharWidth:字体中最宽字符的宽度
tm.tmPitchAndFamily:低位字为1表变宽字体。为0表等宽字体。

GetSystemMetrics

##4.1.滚动条
CreateWindow的第三个参数设置为WS_VSCROLL/WS_HSCROLL可是创建的窗口含垂直或水平滚动条。
滚动条控制函数:
SetScrollRange/GetScrollRange
SetScrollPos/GetScrollPos
对滚动条程序负责如下任务:
1.初始化滚动条范围和位置
2.处理传给窗口过程的滚动条消息
3.更新滑块的位置
4.根据滚动条的变化更新客户区的内容

WM_VSCROLL/WM_HSCROLL
wParam:低位字为通知码。高位字在通知码为SB_THUMBTRACK和SB_THUMBPOSITION时为此时滑块位置。
UpdateWindow:如果客户区存在无效区域,此函数将立刻给窗口过程发一条WM_PAINT消息,处理完后,才返回。

使用新的滚动条控制函数:
SetScrollInfo/GetScrollInfo
滑块大小/滚动条长度 ~页面大小/范围
用到的数据结构:

 typedef struct tagSCROLLINFO 
 {
     UINT cbSize;
     UINT fMask;
     int nMin;
     int nMax;
     UINT nPage;
     int nPos;
     int nTrackPos;
 }SCROLLIFO;

fMask可为:
SIF_RANGE/POS/PAGE/TRACKPOS/DISABLENOSCROLL/ALL

5.绘图基础

GDI包含的函数可分成下面几类:
1.获取/建立 和 释放/销毁 设备环境的函数
2.获取设备环境信息的函数
3.绘图函数
4.设置和获取设备环境属性的函数
5.使用GDI对象的函数

GetDeviceCaps,GetSystemMetrics获取设备环境的一些信息

理论上一个字体的点值= tm.tmHeight - tm.tmInternalLeading
行间距值= tm.tmHeight

当调用GetDC/BeginPaint时,获得的设备环境的所有属性都被设定为默认值。ReleaseDC/EndPaint时,对属性所做的任何改变都会丢失。
若对窗口所属窗口类的style字段指定了CS_OWNDC,则ReleaseDC/EndPaint时,对属性所做的改变不丢失。

crColor = GetPixel(hdc, x, y);
SetPixel(hdc, x, y, crColor)

LineTo
Polyline
PolylineTo
PolyPolyline
Arc
PolyBezier
PolyBezierTo
ArcTo
AngleArc
PolyDraw
Rectangle
Ellipse
RountRect
Pie
Chord

MoveToEx

程序可创建的六种GDI对象:逻辑画笔,画刷,位图,区域,字体,调色板。
对自己创建的GDI对象,用完后要销毁。【创建后无论是否选入设备环境都在内存帮你保存此对象,销毁可释放对应内存】

5.1.画笔

HPEN hPen = GetStockObject(WHITE/BLACK/NULL_PEN);
CreatePen/CreatePenIndirect
HPEN hPenOld = SelectObject(hdc, hPen);

5.2.画刷

HBRUSH hBrush = GetStockObject(WHITE/LTGRAY/GRAY/DKGRAY/BLACK/NULL_BRUSH)

5.3.区域

HRGN hRgn = CreateRectRgn/CreateRectIndirect/CreateEllipticRgn/CreateEllipticRgnIndirect/CreateRoundRectRgn/CreatePolygonRgn

iRgnType = CombineRgn(hRgnDest, hRgnSrc1, hRgnSrc2, iCombine)
iCombine:
RGN_AND/RGN_OR/RGN_XOR/RGN_DIFF/RGN_COPY
iRgnType:
NULLREGION/SIMPLEREGION/COMPLEXREGION/ERROR

FillRgn:填充矩形
FrameRgn:画矩形边框
InvertRgn:翻转矩形颜色
PaintRgn:

5.4.字体

HFONT hFont = GetStockObject(SYSTEM_FONT/SYSTEM_FIXED_FONT/OEM_FIXED_FONT/DEFAULT_GUI_FONT/ANSI_FIXED_FONT/ANSI_VAR_FONT/DEVICE_DEFAULT_FONT)

CreateFont/CreateFontIndirect

InvalidateRgn/ValidateRgn

DeleteObject
GetObject
GetCurrentObject
SetBkColor/GetBkColor
SetBkMode/GetBkMode

绘图模式:
给定画笔的像素色结合目标像素色后得到的颜色
SetROP2/GetROP2

SetPolyFillMode,从封闭区域画射线,对ALTERNATE映射模式,射线穿过奇数条边框时,区域才被填充。对WINDING映射模式,射线穿过奇数条边框时区域被填充,穿过偶数条时,如果不同方向的边框线数目不等,区域也会被填充。

5.3.GDI映射模式

和映射模式相关的四个其他的设备环境属性:窗口原点,视口原点,窗口范围,视口范围。
Windows定义的8中映射模式

映射模式逻辑单位X轴正方向Y轴正方向
MM_TEXT像素
MM_LOMETRIC0.1mm
MM_HIMETRIC0.01mm
MM_LOENGLISH0.01in.
MM_HIENGLISH0.001in.
MM_TWIPS1/1400in.
MM_ISOTROPIC任意x=y可选可选
MM_ANISOTROPIC任意x!=y可选可选

SetMapMode/GetMapMode
Windows对所有消息和所有非GDI函数和部分GDI函数,使用的坐标是设备坐标。【以像素为单位】
使用设备环境句柄作为参数的GDI函数,使用的坐标一般都是逻辑坐标。【单位取决于此时的映射模式】

屏幕坐标:坐标原点是整个屏幕的左上角。
窗口坐标:坐标原点是窗口左上角。
客户区坐标:坐标原点是客户区左上角。

ClientToScreen:把客户区坐标转换到屏幕坐标
ScreenToClient:把屏幕坐标转换到客户区坐标
GetWindowRect:以屏幕坐标形式获取整个窗口的位置和大小。

映射模式确定Windows如何把一些GDI函数中的逻辑坐标映射到设备坐标。

视口坐标系:
坐标原点可能是客户区/屏幕/窗口左上角。【取决于hdc获取方式】
x/y轴单位:像素
x+方向:右
y+方向:下
窗口坐标系:
原点和视口原点在同一位置。
x/y轴单位和方向有具体的映射模式决定

对所有映射模式,windows使用下面公式完成窗口坐标系的坐标与视口坐标系的坐标的相互转换。

xViewport = (xWindow - xWinOrg) * xViewExt / xWinExt + xViewOrg
yViewport = (yWindow - yWinOrg) * yViewExt / xWinExt + yViewOrg

(xWindow, yWindow)是待转换的逻辑点坐标
(xViewport, yViewport)是转换后的设备坐标点坐标
(xViewOrg, yViewOrg)是设备坐标系下视口的原点
(xWinOrg, yWinOrg)是逻辑坐标系下窗口的原点
(xWinExt, yWinExt)是逻辑坐标系下窗口的范围
(xViewExt, yViewExt)是在设备坐标系下视口的范围

DPtoLP:设备坐标转逻辑坐标
LPtoDP:逻辑坐标转设备坐标

5.3.1.MM_TEXT

窗口原点:(0, 0),可改变。SetWindowOrgEx/GetWindowOrgEx。使用的单位是逻辑单位
视口原点:(0, 0),可改变。SetViewportOrgEx/GetViewportOrgEx。使用的单位是设备单位,即像素。
视口范围:(1, 1),不可改变
窗口范围:(1, 1),不可改变

5.3.2.度量映射模式

MM_LOENGLISH
MM_LOMETRIC
MM_HIENGLISH
MM_TWIPS
MM_HIMETRICS

窗口原点:(0, 0) 可改变
视口原点:(0, 0) 可改变
窗口范围:(?, ?) 不可改变
视口范围:(?, ?) 不可改变

5.3.3.自定义的映射模式

MM_IOSTROPIC。Windows自动调整,来让x和y的逻辑单位表示相同的物理尺寸。
MM_ANISOTROPIC

窗口范围:(?, ?) 可改变。SetWindowExtEx
视口范围:(?, ?) 可改变。SetViewportExtEx

5.4.矩形,区域和裁剪

FileRect:填充矩形
FrameRect:用画刷画矩形边框
InvertRect:翻转矩形内所有像素

PeekMessage(&msg, NULL, 0, 0, PM_REMOVE/NOREMOVE):
返回程序中所有窗口的所有消息。
PM_REMOVE:获取后从消息队列中删除消息。
PM_NOREMOVE:获取后不从消息队列中删除消息。

GetMessage:直到从消息队列中拿到消息才返回。
PeekMessage:只对消息队列进行一次查询,有消息就取出一条,没有时,直接返回FALSE。故在PeekMessage取消息时,取到消息后检查下,如果消息是WM_QUIT,就跳出循环。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值