




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MFC一些调用的步骤 1、第一步,全局对象“theApp”的构造函数;2、真正的main函数隐藏在框架内,IDE下 按F11可以进入Main函数3、跳转到AfxWinMain函数,看到调用了“InitInstace”虚函数,另外CWinAPP原来是从CWinThread派生的,是一个线程,以前没注意4、最后进入了CWinThread:Run函数,也就是进入了消息泵 AfxMessageBox引起死机1、在CListCtrl右键菜单的执行中;2、AfxMessageBox的数据量4K左右;结论:不要用AfxMessageBox显示大量的数据设置树的节点高度Window控件里面,树的节点高度是可以设置的,如下:tvis.hParent = hItem;tvis.itemex.mask = TVIF_TEXT|TVIF_INTEGRAL;tvis.itemex.pszText = TEXT(3倍高度节点);tvis.itemex.iIntegral = 3;m_wndTree.InsertItem(&tvis);iIntegral 表示是普通节点的3倍高度。一个小技巧,发现网上提及较少,故这里列出。VC+ 6.0的小花招Visual Studio系列中产品中,Visual Studio 6.0是最经典的一个版本,虽然后来有Visual Studio .NET 2003,以及2005,也确实添加了很多让我觉得激动的特性,但是从使用细节的细腻程度上来看,VS 6.0无疑是最棒的。我们一些同事甚至试图把2005的C+编译器独立的拿到Visual Studio 6.0中来用,也不愿意升级到.NET上来用,可见其魅力。和VS 6.0这个产品的成熟相比,VC+ 6.0的编译器的的确确相对来说有些糟糕,其中最被诟病的是对模板技术支持很不好。下面我想做的一件事情,就是向那些继续留恋VC+ 6.0的朋友,介绍一些小花招,来避开VC+ 6.0的一些编译器缺陷。1)for (type var=expression;) 中变量var的作用域问题。按照C+标准,这里定义的变量var出了for循环应该被销毁。也就是说下面这段代码是有效的: for (int i = 0; i 100; +i) func(); for (int i = 0; i 100; +i) func2();而下面这段代码应该编译不过: for (int i = 0; i 100; +i) if (has_found_it() handle_find_result(); break; if (i = 100) do_not_found();然而VC+ 6.0对于第一段代码会报变量i重复定义错误,而第二段代码编译通过。为了让VC+ 6.0的for语句看起来符合C+标准,你可以这样做: #define for if (0); else for你会发现很有趣,这样define一下后,VC+ 6.0的for语句完全符合C+标准了!而且由于编译器的优化,Release版本不会增加任何额外的开销。喜欢“钻牛角尖”的朋友可能会说:嗯,不错的主意。但是为什么不这样做: #define for if (1) for嗯?看起来也可以。还是让我们看一个用例: if (cond) for (int i = 0; i 100; +i) func1(); else func2();进行宏代码展开后,成为: if (cond) if (1) for (int i = 0; i 100; +i) func1(); else func2();这个结果显然不能符合我们的原意。这里func2();语句永远得不到执行机会。2)模板参数类型如果不出现在参数列表中,则不能作为返回值类型。由于编译器的缺陷,VC+ 6.0不支持以下这种用法: template T1 func(T2 arg) T1 var; . / 处理var过程 return var; void test() int result1 = func(1); double result2 = func(2); ;很抱歉,这种用法VC+ 6.0不支持。让人恼火的是,VC+ 6.0编译时不会提示错误,但是生成的执行代码却很成问题。究其原因,是因为VC+ 6.0的template技术是在编译器的较高层次做的,真正的编译器核心并不考虑模板。以上面的代码为例,对编译器核心来说,只是有两个重载函数而已: int func(int arg); double func(int arg);如果是普通情况,只是返回值不同的函数,是不能同时存在的,编译器应该认为这是一个错误。但是很在模板情况下,这两个函数被简单认为是同一个函数。因为VC+ 6.0会为每个函数根据它的: 1)所在的namespace; 2)所在的类的类名(如果是成员函数); 3)函数名; 4)函数调用方式(cdecl、stdcall还是fastcall); 5)所有参数的类型;而生成一个唯一标识该函数的函数名。这个过程叫Name Mangling,是所有C+编译器都要进行的工作。而另一个背景是,很多C+编译器生成的目标文件(.obj文件)有一些和模板相关的特殊信息,包括也标识了某个函数是否模板函数。这是因为一个模板函数在多个源文件(.cpp文件)中被调用的话,这个模板函数就会在这些源文件编译生成的目标文件(.obj文件)中都定义(definition)一份。为了支持模板,link程序显然必须知道这个函数是模板函数,从而随意选择一个定义(丢弃其余的定义),而不是报符号重复定义错误。因为函数名、参数列表等完全一致,所以这两个函数Name Mangling后生成的名字是一样的,并且,它们都被标识为这是模板函数。从而,link程序在工作的时候,简单地将其中一个函数定义给抛弃了。那么,如果我们非要提供上述的func函数,怎么办?我们来点花招:template class funcprivate: T1 var;public: template func(T2 arg) . / 处理var过程 operator T1() const return var; ;我们再来使用func这个“函数”: void test() int result1 = func(1); double result2 = func(2); ;呵呵,你会发现,它还真象是你期望的正常工作。3)仿真VC+提供的关键字_uuidof。这个技巧不是针对VC+ 6.0缺陷的,而是针对VC+扩展语法的。这个技巧的来由,是为了某些希望有一天有可能要脱离Visual C+环境进行开发的人员。为了脱离VC+,你需要谨慎使用它的所有扩展语法。例如本文讨论的_uuidof。我们先来看看一个例子:class _declspec(uuid(B372C9F6-1959-4650-960D-73F20CD479BA) Class;struct _declspec(uuid(B372C9F6-1959-4650-960D-73F20CD479BB) Interface;void test() CLSID clsid = _uuidof(Class); IID iid = _uuidof(Interface); .这比起你以前定义uuid的方法简单多了吧?可惜,这样好用的东西,它只在VC+中提供。不过没有关系,我们这里介绍一个技巧,可以让你在几乎所有C+编译器中都可以这样方便的使用_uuidof。这里没有说是所有,是因为我们使用了模板特化技术,可能存在一些比较“古老”的C+编译器,不支持该特性。也许你已经迫不及待了。好,让我们来看看:#include #include inlineSTDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz) HRESULT hr; GUID guid; if (lpsz0 = ) hr = CLSIDFromString(lpsz, &guid); else std:basic_string strGuid; strGuid.append(1, ); strGuid.append(lpsz); strGuid.append(1, ); hr = CLSIDFromString(LPOLESTR)strGuid.c_str(), &guid); assert(hr = S_OK); return guid;template struct _UuidTraits ;#define _DEFINE_UUID(Class, uuid) template struct _UuidTraits static const GUID& Guid() static GUID guid = GUIDFromString(L # uuid); return guid; #define _uuidof(Class) _UuidTraits:Guid()#define DEFINE_CLSID(Class, guid) class Class; _DEFINE_UUID(Class, guid)#define DEFINE_IID(Interface, iid) struct Interface; _DEFINE_UUID(Interface, iid)这样一来,就已经模拟出一个_uuidof关键字。我们可以很方便进行uuid的定义。举例如下:DEFINE_CLSID(Class, B372C9F6-1959-4650-960D-73F20CD479BA);DEFINE_IID(Interface, B372C9F6-1959-4650-960D-73F20CD479BB);void test() CLSID clsid = _uuidof(Class); IID iid = _uuidof(Interface); .在VC+中,为了与其他编译器以相同的方式来进行uuid的定义,我们不直接使用_declspec(uuid),而是也定义DEFINE_CLSID, DEFINE_IID宏:#define DEFINE_CLSID(Class, clsid) class _declspec(uuid(clsid) Class#define DEFINE_IID(Interfac
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 重庆秀山非遗课件
- 新解读《GB-T 30748-2014旋转式压片机》
- 人教版八年级英语上册单元同步知识点与语法训练 unit3 section A (学生版)
- 新解读《GB-T 12022-2014工业六氟化硫》
- 重庆宠物蚂蚁吃西瓜课件
- 建筑施工-安全培训课件-建筑施工消防安全
- 世界地理选择题专项训练(一)-2023年中考地理高频考点复习(原卷版)
- 老年人自救互救知识培训课件
- 重力除尘工作原理
- 《英语小说选读》课程介绍与教学大纲
- 2025年秋季小学四年级上册语文教学计划及教学进度表
- 北京市西城区2024-2025学年七年级下学期期末道德与法治试题(解析版)
- 2025年广东省高考化学试题(含答案解析)
- 【2025秋新版】三年级上册语文生字组词
- 《智能建造概论》高职完整全套教学课件
- 2025年中小学教师师德师风考试题库及答案
- 小学生情绪调适心理课件
- 节能环保供货保证措施
- GB/T 23806-2025精细陶瓷断裂韧性试验方法单边预裂纹梁(SEPB)法
- 第2课 第二次鸦片战争 课件 部编版2024八年级上册历史
- 2025电化学储能生产指标管理办法
评论
0/150
提交评论