博文
Invalidate、UpdateWindow、Z-order、显示顺序(2010-05-17 10:50:00)
摘要: 在一个Dialog的OnPaint按照下面的方法实现:
void CMyDialog::OnPaint()
{
CWnd* pWnd = GetDlgItem(IDC_STATIC1);
CDC* pDC = pWnd->GetDC();
pWnd->Invalidate(); //??????????
pWnd->UpdateWindow(); //????????????
pDC->SelectStockObject(BLACK_BRUSH);
pDC->Rectangle(0,0,10,10);
pWnd->ReleaseDC(pDC);
}
&nbs......
虚拟相机的绘制方法(二)(2010-05-14 17:23:00)
摘要:OpenGL坐标系
上面的代码还是不够的。因为需要对虚拟相机进行模型变换。在OpenGL中,模型变换有三种方式,即glTranslateX, glRotateX, glScaleX. 对于单个变换很容易理解,但是当多种变换组合的时候,初学者就很难分析清楚最后的结果了。
首先我们来讲解一种红宝书上介绍的一种经典情况。即先旋转还是先平移的问题。
glTranslatef(0,0,5);
glRotatef(45, 0,0,1);
显然这段代码如果换个顺序执行结果是不同的。因此红宝书中指出为了方便读者理解,提出了从全局坐标系和局部坐标系来理解这段代码。
如果是全局坐标系理解,那么从下往上执行,结果就应该是先绕z轴旋转45°,紧接着沿着z轴平移5个单位。
如果是局部坐标系理解,那么从上往下执行,结果就应该是先沿z轴平移5个单位,紧接着,建立模型的局部坐标系(第一次局部坐标系与场景的坐标系平行),再绕z轴旋转45°。
这样读者在理解层次上就统一了。
再举上面一例。
glScalef(dPerRatio,1.0,1.0);
glRotatef(45,0,0,1);
这段代码的目标是将一个正方形旋转45°后,x轴方向伸缩dPerRatio倍,变成长方形。
如果从全局坐标系理解是很容易的。但是有人认为,从局部坐标系好像不对劲。因为首先是X轴伸缩了dPerRatio倍。再次旋转45°。显然不是长方形了?
这个理解是有问题的。因为既然从局部坐标系理解,要知道,执行了glScalef之后,局部坐标轴其实也被伸缩了。这样再次旋转45°,结果还是长方形。由于glScalef从局部坐标系一般不容易理解,所以专家建议还是这种变换从全局坐标系理解。
旋转轴
了解了OpenGL中的模型变换之后,我们就要尝试将刚才创建的相机进行变换,即镜头需要从原点移到相机位置,并且使它的轴线与视线方向平行。设变换前轴向量为 AB,变换后轴向量为C......
虚拟相机的绘制方法(一)(2010-05-14 16:49:00)
摘要:
一般,我们经常把看到的三维场景类比于相机拍照(OpenGL编程指南第四版),因此视点变换也称为相机变换。后来有些人总是误解“视点”的概念,因为视点既可以理解为“相机(眼睛)所在的位置”,也可以理解为“相机(眼睛)所看到的地方”。前者是指相机位置,而后者则是场景中心(参见gluLookAt函数)。为了方便起见,本文不采用“视点”的概念,而用相机位置来代替说明。
三维漫游的过程实际上就是相机运动的过程,包括相机位置和相机视线的运动改变。人眼所看到的三维动画就好比看到的DV录像。要知道,相机拍照是不会拍到自己的。(除非有镜子,排除这种情况)。但是有些时候,我们希望从全局看到相机本身的运动过程。因此,我们希望在场景中虚拟出这样一个对象来模拟相机的运动,称为“虚拟相机”(Virtual Camera).这样做有2个优点:一来可以帮助我们更好的宏观上了解和定制漫游路线和漫游效果,比如我们想指定,当相机经过A楼大门前,视线必须经过对面马路的红绿灯;另外,也可以检查漫游效果是否平滑,以及不平滑出现的位置和时间等。
虚拟相机的绘制包括两个部分:视锥体和相机体。(参见下图:3DSMax中的虚拟相机)。其中视锥体为由近裁切面和远裁切面为底面构成的棱锥台,其轴线为视线方向。为方便模拟,一般近裁切面直接表示为一个点,该点位于相机体镜头的中心。而远裁切面由于一般设置很大,我们只需要控制在一定距离内进行示意即可,例如100m,或者在路径漫游时,如果用户设定了相机路径和目标路径,那么可以直接把“远裁切面”中心设置在目标路径上。
图:3DSMax中的虚拟相机
&n......
去除VC map warning C4786(2010-05-12 18:43:00)
摘要:在vc6.0 下面使用stl中的map的时候,会发现报n个warning。看的都觉得烦,虽然不会有大影响。
这是vc的一个bug,就不说原因了,这里只给出具体解决方案:
如果有stdafx.h文件,则在其文件头加入:
#pragma warning(disable: 4786)
.............
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
有其他用到map的头文件或者源文件处,也要加入
#pragma warning(disable: 4786)
......
error C2011: 'DataTypeEnum' (转)(2010-04-23 21:36:00)
摘要:1>------ 已启动生成: 项目: iotser, 配置: Debug Win32 ------
1>正在编译...
1>iotser.cpp
1>f:\c++ pro\iocptser\debug\msado15.tlh(228) : error C2011: “LockTypeEnum”: “enum”类型重定义
1> c:\program files\microsoft sdks\windows\v6.0a\include\dbdaoint.h(109) : 参见“LockTypeEnum”的声明
1>f:\c++ pro\iocptser\debug\msado15.tlh(276) : error C2011: “DataTypeEnum”: “enum”类型重定义
1> c:\program files\microsoft sdks\windows\v6.0a\include\dbdaoint.h(138) : 参见“DataTypeEnum”的声明
1>f:\c++ pro\iocptser\debug\msado15.tlh(321) : error C2011: “FieldAttributeEnum”: “enum”类型重定义
1> c:\program files\microsoft sdks\windows\v6.0a\include\dbdaoint.h(127) : 参见“FieldAttributeEnum”的声明
1>f:\c++ pro\iocptser\debug\msado15.tlh(343) : error C2011: “EditModeEnum”: “enum”类型重定义
1> c:\program files\microsoft sdks\windows\v6.......
PDF文档 一页分成多页打印 多页合成一页打印(2010-04-19 22:29:00)
摘要:今天发现一幅Visual C++ 2008 Poster ,里面是常用的一些快捷键。
http://www.microsoft.com/downloads/details.aspx?familyid=4411BBFC-0E3C-42B3-BD05-AF1D292C986F&displaylang=en
但是单幅打印在A4上面很不清楚(原图打印在A3上最好)于是想分成两页A4打印,查了一下一页分成多页打印的方法。但是网上成堆的都是为了节约纸张的人们在研究如何多页合成一页打印(我个人认为fineprint蛮好用)。不过还是有人碰到了与我一样的问题。与大家分享一下。
原PDF文件是由图片文件制作的,我原来处理的方式是用Adobe Acrobat 7.0 Professional转存为图片,再用PhotoShop CS2裁切,另存为JPG格式的图片,用Adobe Acrobat 7.0 Professional合并回PDF,合并后的文件较大,有1M多,比原来文件增大太多;后看了4楼colaux的方法二,觉得直接用colaux的方法二可能更便捷,试过后发现文件增大更多,达3M多,而且用Adobe Acrobat 7.0 Professional插入页面、裁剪时很难精确定位(大概是我用Adobe Acrobat 7.0 Professional还未到家),常常需要定位在字体中间;记起PDF文件是可以用PhotoShop CS2直接处理的,再试验了一下,最后觉得还是用PhotoShop CS2直接打开PDF文件进行裁剪较好,因PhotoShop CS2可以精确定位,我们都知道A4尺寸是21cmX29.7cm,用PhotoShop CS2直接裁剪PDF、定位时在导航框的信息栏可直接看到定位信息,精确到小数点后两位,可选定最接近A4、同时是两行字之间的位置再松开鼠标左键;另外裁剪后另存为TIF格式较好,我试了JPG和TIF两种格式,用Adobe Acrobat 7.0 Professional合并回PDF时,JPG的仍有1.4M之多,而TIF的则只有300多K,接近原来文件大小,用Adobe Acrobat 7.0 Professional打开前后的PDF比较,两者尺寸一致(JPG格式生成的比原文件的稍大,字体周边发虚)。......
如何删除.svn文件下text-base文件夹(2010-04-19 20:37:00)
摘要:
今天在删除资料时,发现.svn文件下text-base文件夹无论如何也删不掉。
方法一:
只好剪切 .svn文件夹,移到其他地方,然后再删,一切就都OK了。
方法二:
卸载svn。
方法三:
新建文本文件,输入以下内容,改为.reg后缀,双击运行,加入到注册表信息中。右键就会出现Delete SVN folders的选项,可以清除SVN的文件夹。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""
......
使用map和hash_map的效率问题(转)(2010-04-18 10:28:00)
摘要:
这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自
alvin_lee ,codeproject,codeguru.baidu等等!
先看看alvin_lee 朋友做的解析,我觉得还是很正确的,从算法角度阐述了他们之间的问题!
实际上这个问题不光C++会遇到,其他所有语言的标准容器的实现及选择上都是要考虑的。做应用程序你可能觉得影响不大,但是写算法或者核心代码就要小心了。今天改进代码,顺便又来温习基础功课了。
还记得Herb Sutter那极有味道的《C++对话系列》么,在其中《产生真正的hash对象》这个故事里就讲了map的选择。顺便回顾一下,也讲一下我在实用中的理解。
选择map容器,是为了更快的从关键字查找到相关的对象。与使用list这样的线性表容器相比,一可以简化查找的算法,二可以使任意的关键字做索引,并与目标对象配对,优化查找算法。在C++的STL中map是使用树来做查找算法,这种算法差不多相当与list线性容器的折半查找的效率一样,都是O(log2N),而list就没有map这样易定制和操作了。
相比hash_map,hash_map使用hash表来排列配对,hash表是使用关键字来计算表位置。当这个表的大小合适,并且计算算法合适的情况下,hash表的算法复杂度为O(1)的,但是这是理想的情况下的,如果hash表的关键字计算与表位置存在冲突,那么最坏的复杂度为O(n)。
那么有了这样的认识,我们应该怎么样选用算法呢?前两天看Python文章的时候,不知道哪个小子说Python的map比c++的map快,如何如何的。但是他并不知道Python是默认使用的hash_map,而且这些语言特征本质上是使用c/c++写出来的,问题在与算法和手段,而不是在于语言本身的优劣,你熟悉了各种算法,各种语言的细节、设计思想,还能在这偏激的嚷嚷孰好孰坏(片面与偏激的看待事物只能表明愚昧与无知,任何事物都有存在的价值,包括技术)。显然C++的STL默认使用树结构来实现map,是有考究的。
树查找,在总查找效率上比不上hash表,但是它很稳定,它的算法复杂度不会出现......
激活另一个进程的窗口(转载)(2010-04-05 22:10:00)
摘要:问题: 我要在我的系统(假如当前窗口是A)里面用vba 的方法打开word的窗口(B窗口),但是打开后发现Word窗口不是活动的,A窗口依然是活动窗口,但是发现B窗口已经在任务栏上打开了,有时候即使能显示B窗口,但是你只要按键盘,发现活动窗口立即转到了A窗口上,让我无可奈何。
于是我通过FindWindow的方法来获取当前打开的B窗口的句柄(能够正确获取到),但是后面无论用SetActiveWindow、SetFocus、ShowWindow等方法来设置把B窗口设置为活动窗口,但是没有一个能行的,请大家教教我。
解答:
光找到WORD的主窗口不行,还要处理其子窗口。可以这样做:
CWnd *pMainWnd,*pSubWnd;
pMainWnd=CWnd::FindWindow(_T("WORD窗口类型"),"WORD窗口名");
if (pMainWnd)
{
pSubWnd=pMainWnd->GetLastActivePopup();
pMainWnd->ShowWindow(SW_SHOW);
pSubWnd->SetForegroundWindow();
} ......
ShowWindow(转载)(2010-03-31 21:13:00)
摘要: ShowWindow虽然使用简单,但之所以要为它写一篇文章,是因为在做一个非模式对话框是,非模对话框显示的时候抢夺了其顶级框架窗口的焦点(标题栏变暗)。我如何让我的非模对话框在显示的时候不抢夺框架窗口的焦点呢?
使用SW_SHOWNA的显示方式。
函数声明如下:
WINUSERAPI
BOOL
WINAPI
ShowWindow(
__in HWND hWnd,
__in int nCmdShow);
hWnd是窗口的句柄。
nCmdShow是窗口显示的状态。可能设置的值如下:
SW_FORCEMINIMIZE是强制窗口最小化,
主要使用在非窗口主线程的其它线程来操作。
SW_HIDE是显示窗口为隐藏状态。
SW_MAXIMIZE是显示窗口为最大化。
SW_MINIMIZE是显示窗口为最小化。
SW_RESTORE是从任务里恢复窗口显示。
SW_SHOW是激活窗口为当前窗口,并且显示为当前的大小和位置。
SW_SHOWDEFAULT是创建进程时显示窗口的值。
SW_SHOWMAXIMIZED是激活窗口为当前窗口,并且显示最大化。
SW_SHOWMINIMIZED是激活窗口为当前窗口,并且显示最小化。
SW_SHOWMINNOACTIVE是显示窗口为最小化,但不激活它作为当前窗口。
SW_SHOWNA是显示为当前的大小和位置,但不激活它作为当前窗口。
SW_SHOWNOACTIVATE是显示当前窗口,但不激活它作为当前窗口。
SW_SHOWNORMAL是显示当前窗口,但窗口是最小化或
最大化时会恢复窗口为原来的大小和位置。......