博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WM_PAINT
阅读量:4316 次
发布时间:2019-06-06

本文共 3183 字,大约阅读时间需要 10 分钟。

WM_PAINT:

BeginPaint(hWnd, &ps);

其中: ps 为 

typedef struct tagPAINTSTRUCT

{

  HDC hdc; //设备环境句柄

  BOOL fErase; 

  RECT rcPaint;

  ...

}

主要是前3个参数设置。

bErase大多数情况下被设置为FALSE(默认),意味着Windows在先前的BeginPaint函数中已经擦除了无效区域的背景。

如果想在窗口过程中自定义背景擦除方式,必须自己处理WM_ERASEBKGND消息。

 

InvalidRect函数使一个矩形无效,最后一个参数传FALSE将指定背景是否要被擦除。

FALSE: Windows不会擦除背景。

TRUE: 擦除。

 

调用BeginPaint函数后,PAINTSTRUCT的bErase值将是TRUE。

 

处理WM_PAINT消息时,在调用BeginPaint前调用

InvalidateRect(hWnd, NULL, TRUE);

这个调用将整个客户区无效化,并使其后调用的BeginPaint擦除原有的背景。

最后一个参数设为FALSE,BeginPaint函数将不会擦除背景。

 

GetDC获取的是整个客户区的设备环境句柄,BeginPaint获取的是无效区域的设备环境句柄。

GetDC不会将无效区域有效化,如需有效化整个客户区,ValidateRect(hWnd, NULL);

 

GetWindowDC获取的是整个窗口的设备环境句柄。如需修改窗口的标题栏输出,程序还需处理WM_NCPAINT(非客户区绘制)消息。

---

TextOut(hdc, x, y, psText, Length ); //x,y 在客户区的起始位置。距离左上角的坐标点。

 

文本背景色和窗口类中设定的背景色是不一样的。

 

传给函数的坐标一般称为 "逻辑坐标";

映射方式决定将GDI绘图函数中的逻辑坐标转换成显示器上的物理像素坐标。默认映射方式是MM_TEXT。

MM_TEXT模式下逻辑单位和物理单位都是像素点。

 

GetSystemMetrics函数来获取用户界面的尺寸。

GetTextMetrics获取字体尺寸。//定义变量 TEXTMETRIC tm;

typedef struct tagTEXTMETRIC

{

LONG tmHeight;

LONG tmAscent;

LONG tmDescent;

LONG tmInternalLeading;

LONG tmExternalLeading;

...

}

主要是这5个参数。

Leading(间距)是2行文字之间的空间。tmInternalLeading内部间距,通常用于显示重音符号。

tmExternalLeading不包含在tmHeight内,该字段指在两行文字之间留出的空间大小。

tmHeight = tmAscent + tmDescent;

系统字体的尺寸取决于Windows运行时的分辨率,有时还取决于用户选定的系统字号。

 

tmAscent 包括 tmInternalLeading;

Windows运行时,系统字体不会变化,应用程序只需调用一次GetTextMetrics,最好的时机是在窗口处理WM_CREATE。

定义2个变量来保存字符的平均宽度和总高度:

static int cxChar, cyChar; //变量名中的c 代表 count

示例代码:

GetTextMetrics(hdc, &tm);

cxChar = tm.tmAveCharWidth; //tmAveCharWidth是小写字符的加权平均宽度,tmMaxCharWidth是字体中最宽的字符的宽度。

cyChar = tm.tmHeight + tm.tmExternalLeading; //ExteralLeading 一般为0.

cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2; //大写字符的平均宽度。等宽字体中,cxCaps等于cxChar;变宽字体cxCaps是cxChar的1.5倍。tmPitchAndFamily字段的低位决定字体是否为等宽,1 变宽, 0 等宽。

通常需要显示的是格式化的数字和字符串。用 sprintf函数。

 

WM_SIZE 低位lParam客户区的宽度,wParam客户区的高度。

static int cxClient, cyClient;

cxClient = LWORD(lParam); //cxClient / cxChar 整行能显示的字数。

cyClient = HWORD(wParam); //cyClient 高度

 

滚动条: CreateWindow 第三个参数加上 WS_HSCROLL(水平滚动条) WS_VSCROLL(垂直滚动条)

SetScrollRange(hWnd, iBar, iMin, iMax, bRedraw); //bRedraw = FALSE,不重绘

//iMin~iMax滚动条范围(默认0-100)

//iBar 要么是 SB_VERT, SB_HORZ

如果在调用SetScrollRange函数之后还将调用其他函数来调整滚动条的显示时,最好将bRedraw设为FALSE避免过多的重绘。

SetScrollPos(hWnd, iBar, iPos, bRedraw); //设置滚动条位置。

消息有: SB_LINEDOWN, SB_LINEUP, SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION

SB_THUMBTRACK消息,wParam的高位字是用户拖动滑块的当前位置。

SB_THUMBPOSITION消息,wParam的高位字是用户松开鼠标键时滑块的最终位置。 //这个比较好处理,直接调用SetScrollPos函数。

//部分示例代码

iVscrollPos = max(0, min(iVscrollPos, Max- 1)); //可以防止 iVscrollPos小于0的情况。

if (iVscrollPos != GetScrollPos(hWnd, SB_VERT))

{

  SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE); //bRedraw 为TRUE

  InvalidateRect(hWnd, NULL, TRUE); //使整个窗口无效。

}

如果想立刻更新无效区域,可以在调用InvalidateRect后调用UpdateWindow函数。-》发送WM_PAINT消息。

//新滚动条函数 SetScrollInfo GetScrollInfo

SetScrollInfo(hWnd, iBar, &si, bRedraw);

GetScrollInfo(hWnd, iBar, &si);

typedef struct tagSCROLLINFO

{

UINT cbSize; //设为sizeof(SCROLLINFO)

UINT fMask; //要设置或获取的值

int nMin;

int nMax;

UINT nPage; //页面大小

int nPos; //当前位置

int nTrackPos; //当前追踪位置

}SCROLLINFO

iBar:

1>SIF_RANGE 返回 nMin nMax范围

2>SIF_POS 当前位置。

3>SIF_ALL

 

转载于:https://www.cnblogs.com/sylar-liang/p/5532673.html

你可能感兴趣的文章
MySQL性能优化方法一:缓存参数优化
查看>>
Angular2 - 概述
查看>>
正则表达式tab表示\t
查看>>
NodeJS+Express+MongoDB 简单实现数据录入及回显展示【Study笔记】
查看>>
Highcharts使用指南
查看>>
网络基础(子网划分)
查看>>
Google C++ Style
查看>>
MyBatis总结八:缓存介绍(一级缓存,二级缓存)
查看>>
div+css教程网站建设门户网站和电子商务网站CSS样式表
查看>>
[LeetCode][JavaScript]Candy
查看>>
Mybatis分页插件
查看>>
sk_buff Structure
查看>>
oracle的级联更新、删除
查看>>
多浏览器开发需要注意的问题之一
查看>>
Maven配置
查看>>
HttpServletRequest /HttpServletResponse
查看>>
SAM4E单片机之旅——24、使用DSP库求向量数量积
查看>>
从远程库克隆库
查看>>
codeforces Unusual Product
查看>>
hdu4348 - To the moon 可持久化线段树 区间修改 离线处理
查看>>