您的位置:首页 > 产品设计 > UI/UE

UI设计经验

2010-01-05 14:46 141 查看
1.

Invalidate 只是发送消息 不立即重绘

UpdateWindow 立即重绘

2.双缓冲

如果是一个复杂的画图过程,建议使用双缓冲,首先创建兼容性DC
,即内存
DC,
在其上完成复杂的画图操作,完成后就可以通过
BitBlt
从兼容性
DC
上拷回来。这样就可以避免刷新时闪的可能性。

注意:创建的兼容性DC
是没有画布的,只有通过
CreateCompatibleBitmap()
让后,选择这个兼容性画布,再在这个画布上画图

3.逻辑坐标与设备坐标

简单来说如果是通过GetDC

BeginPaint
则为客户区坐标,如果通过
GetWindowDC

则为窗口坐标。

如果不使用GDI
函数,我们所要面对的只是设备坐标。设备坐标可以分为三种,屏幕,窗口,客户区,这之间的区别仅仅是原点的位置

如果使用GDI
函数就必须理解逻辑坐标,因为
GDI
函数的位置参数都以逻辑坐标为准 如果要画图,就要调用
GDI
函数,那么,画图中的坐标是什么样的,在于调用画图函数所使用的
dc(
即这个
Dc
是怎么获得的
)
,即从一个虚拟界面映射到逻辑界面上。 问题的复杂性在于逻辑坐标并不像设备坐标那样固定不变,它的单位是可变的,
XY
轴增长的方向也是可变的,甚至于逻辑坐标的原点也不一定映射为设备坐标的原点。

逻辑坐标的XY
轴的单位与增长方向由
SetMapMode
决定;逻辑坐标的原点映射到设备坐标什么地方由
SetWindowOrgEx

SetViewportOrgEx
决定。 用不同的映射模式,所得到
XY
轴的单位和增长方向都是不同的,所以,在用
GDI
画图时,需要知道其映射方式是什么,如果不清楚,可以在每次画图前,将其坐标进行相关的从逻辑坐标到设备坐标的转换。

DPtoLP和
LPtoDP

Device Point to Logic Point
) 所以,我可以这样理解,逻辑坐标是不存在的,只是在内存中或者后台的一张虚幻的图片,现在要把这张虚幻的图片移到前台,这就需要其映射的模式是什么样子来决定他的摆放,他的坐标单位,增长方向等。 当我们使用
GDI
函数时,所使用的坐标是逻辑坐标,所以,一般情况下需要将设备坐标转换为逻辑坐标。

而设备坐标的获得是在没有使用GDI
函数时获得的坐标极为设备坐标
::SetWindowOrgEx(hDC, 100, 100, NULL);

理解为:逻辑坐标的(100,100)
映射为设备坐标的
(0,0)
,其他的点以此为依据映射。 映射方式仅仅是某个
DC
的属性,如果这个
DC
释放,则映射方式也没有什么用了,即使存在两个
DC
,他们都对应同一个窗口,映射方式仍然是独立的。

4.GUI对象的创建于销毁

1. 最后必须删除自己创建的所有
GDI
对象。

2. 当
GDI
对象正在一个有效的
DC
中使用时,不要删除它。

3. 不要删除现有对象
(StockObject)



5.
前人控件源码的学习,自己控件的编写


己写控件,应从他人源代码提取精华,所谓精华,就是骨架。他在这个控件上做了些什么操作,对哪些消息进行了响应,以实现相关功能。然后,在我的控件中,实
现相关消息响应。如果有需要在不断完善其消息响应。 写控件函数时的布局: 构造,析构; 消息链 消息响应函数 设置相关参数的函数 成员变量

6.
代码布局

若在一个文件中使用一个全局变量,最好将全局变量放在.cpp
文件中,避免其他文件引用
.h
文件时,出现重复定义这个全局变量而造成编译链接出错。

7._stdcall 与
_cdecl

在跨(开发)平台的调用中,我们都使用__stdcall
(虽然有时是以
WINAPI
的样子出现)。那么为什么还需要
_cdecl
呢?当我们遇到这样的函数如
fprintf()
它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用
_cdecl
。到这里我们有一个结论,如果你的程序中没有涉及可变参数,最好使用
__stdcall
关键字。
_cdecl,__stdcall
是声明的函数调用协议
.
主要是传参和弹栈方面的不同
.
一般
c++
用的是
__cdecl,windows
里大都用的是
__stdcall(API)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: