Windows下C++编程
文章平均质量分 76
C++是我学的第一门面向对象编程语言,也是我下工夫最多的一门编程语言。至今,C++仍然是我最喜欢的编程语言。能成为CSDN博客专家也是因为我关于C++的技术文章。专栏里主要是用C++在Windows开发的文章。
StarLee
欢迎大家访问我的Blog。
主要是C++,设计模式,面向对象设计和.Net方面的技术文章。
展开
-
IT业的未来主导将是软件业
最近比较忙。虽然没有时间写Blog,可是业界的动态还是有了解的。 前一阵子IT业很热闹,动静最大的当然是Google收购了摩托罗拉移动。这样手机行业就出现了三足鼎立的态势:Google的摩托罗拉、苹果以及微软和诺基亚的联盟。这鼎立的三足说白了,其实就是三个操作系原创 2011-09-06 07:12:02 · 12268 阅读 · 59 评论 -
COMMAND模式--《敏捷软件开发》读书笔记(一)
现在几乎每个软件都有Undo和Redo功能,要想实现这个功能就要用到COMMAND模式。所有的操作都应该从类似如下的抽象类CCommand继承:class CCommand{public: virtual ~CCommand(); virtual void Do() = 0; virtual void Undo() = 0;}; 这样就可以在操作的时原创 2006-07-27 08:43:00 · 3544 阅读 · 1 评论 -
DECORATOR模式--《敏捷软件开发》读书笔记(二)
比如现在我们有如下的几个类:class CGShape{public: ~CGShape(); virtual void Draw() = 0;};class CGRectangle : public CGShape{public: void Draw();};class CGSquare : public CGShape{public: void Draw原创 2006-07-28 08:32:00 · 3421 阅读 · 1 评论 -
VISITOR模式--《敏捷软件开发》读书笔记(三)
考虑一下设计一个可以包含长方形、正方形、圆形以及文字的视图类。因为视图中每种元素的显示方式都不一样,所以我们很容易做出如下的设计: 在这里,我使用了COMPOSITE模式。对于COMPOSITE模式,可以参考我那篇《重读《设计模式》之学习笔记(五)--我对COMPOSITE模式的理解》。 现在,我们来分析一下上面的这个设计方案。如果说,由于客户需求的改变,视图中每个元素原创 2006-08-02 10:30:00 · 4685 阅读 · 0 评论 -
消除VISITOR模式中的循环依赖
在我的那篇《VISITOR模式--《敏捷软件开发》读书笔记(三)》中,我用一个C++的小例子说明了设计模式中的VISITOR模式。在例子代码中,我们可以发现:为了使VISITOR类CVisitor通过编译,它就必须知道它要访问的类(CTRectangle,CTSquare,CTCircle, CTText ,CTView )的定义;而这些被访问的类要通过编译,它们必须知道类CVisitor原创 2006-12-19 09:14:00 · 3768 阅读 · 1 评论 -
ADAPTER(适配器)模式
ADAPTER模式可以将一个类的接口转换成另外一个接口,那样就可以使原来不兼容而不能一起工作的那些类可以一起工作。 ADAPTER模式也可以称为WRAPPER模式。 对于ADAPTER模式的简单包装功能,下面以STL中的一个例子来说明: // 下列代码片断摘自VC++ 6.0中的STACK// 可以在..VC98/Include/STACK中找到templateclas原创 2007-01-17 09:14:00 · 5492 阅读 · 7 评论 -
面向对象设计(OOD)中的单一职责原则
我们知道,在面向对象设计中要做到高内聚低耦合。而单一职责原则就是实现高内聚低耦合的最好办法。面向对象设计中单一职责原则是指: 一个类只负责一个功能领域中的相应职责。 如果一个类承担的职责过多,就等于把这些职责耦合在了一起。当其中一个职责变化时,可能影响其他职责的运作。 下面我们用C++的例子来具体说明。 比如我们有如下的设计:class CShape{pub原创 2006-10-18 09:25:00 · 4575 阅读 · 5 评论 -
面向对象设计(OOD)中的替换原则
我们知道,在面向对象语言中,公有继承是IS-A的关系,也就是说子类是一种基类,就像说轿车是一种汽车一样。但是,有时候逻辑上正确的公有继承却会违反替换原则。面向对象设计中的替换原则是: 子类必须能够替换掉它们的基类。 也就是说,代码中基类出现的地方都能用子类来替换,就跟汽车能用的地方都能用轿车一样。但是,如果设计不合理,就会违反这个原则,给开发带来隐患。 下面就以一个C++原创 2006-07-20 09:08:00 · 4922 阅读 · 7 评论 -
在C++中使用C#编写的类
在那篇《在C#中使用C++编写的类》中我介绍了如何在C#中使用C++编写的类。可是由于C#在用户界面设计、数据库存储和XML文件读取等方面的优势,有时候也会出现要在C++中使用C#编写的类的情况。下面就用一个完整的实例来说明怎样在C++中使用C#编写的类。 比如说,现在有一个用C#编写的DLL工程CsharpDll里面有一个Person类://Person.cs原创 2008-09-08 09:57:00 · 10069 阅读 · 47 评论 -
在C#中使用C++编写的类
现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额。因此很多以前搞VC++开发的人都转向用更强大的VS.Net。在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类的问题。下面就用一个完整的实例来详细说明怎样用托管C++封装一个C++类以提供给C#使用。 比如,现在有一个工程名为NativeCppDll的由C++编写的DLL,里面输出了一个CPe原创 2008-09-02 09:14:00 · 48993 阅读 · 101 评论 -
一步一步创建VC2005解决方案
现在软件开发已经告别了“独行侠”的年代,而是以团队开发为主。一般情况下,一个解决方案都会包含多个项目,比如:其中一些是静态库项目,一些是动态库项目,当然还会有应用程序项目。另外,根据需要,还可能会使用一些第三方库。因此为解决方案设置一个合理的目录结构并配合一定的环境变量,不但可以使得代码管理更井井有条,项目成员之间也更容易相互配合,更重要的是能够使得最终应用程序的安装包制作,源代码打包发布原创 2007-09-03 08:51:00 · 17036 阅读 · 30 评论 -
让程序在崩溃时体面的退出之总结
《让程序在崩溃时体面的退出》系列的6篇文章发布完后的总结,但不是终结,还有些东西需要深入研究。原创 2011-08-05 09:48:28 · 8859 阅读 · 10 评论 -
让程序在崩溃时体面的退出之终极解决方案(SEH+Dump+Unhandled Exception Filter)
《让程序在崩溃时体面的退出》系列文章的第六篇,同时使用SEH,Dump和Unhandled Exception Filter,来保证遇到使程序崩溃的异常的时候能得到相应的处理。原创 2011-08-03 09:36:43 · 21682 阅读 · 48 评论 -
让程序在崩溃时体面的退出之SEH+Dump文件
《让程序在崩溃时体面的退出》系列文章的第五篇,在程序中使用SEH捕捉到异常的时候创建Dump文件。原创 2011-08-01 09:31:28 · 7354 阅读 · 4 评论 -
让程序在崩溃时体面的退出之SEH
《让程序在崩溃时体面的退出》系列文章的第四篇,在程序中使用微软提供的Structured Exception Handling。原创 2011-07-27 09:45:58 · 12105 阅读 · 26 评论 -
让程序在崩溃时体面的退出之Dump文件
《让程序在崩溃时体面的退出》系列文章的第三篇,在程序崩溃的时候创建Dump文件。原创 2011-07-25 09:43:40 · 45152 阅读 · 72 评论 -
让程序在崩溃时体面的退出之CallStack
《让程序在崩溃时体面的退出》系列文章的第二篇,在程序崩溃的时候得到CallStack。原创 2011-07-20 09:33:47 · 20469 阅读 · 25 评论 -
让程序在崩溃时体面的退出之Unhandled Exception
《让程序在崩溃时体面的退出》系列文章的第一篇:怎样处理Unhandled Exception。原创 2011-07-18 10:13:18 · 30068 阅读 · 31 评论 -
创建进程后得到该进程的主窗口句柄
最近抽空用VC写了一个小应用程序。主要功能就是创建进程,并到该进程的主窗口句柄,然后再给该窗口发消息。下面把代码共享给大家。HWND CreateMyProcess(){ // 进程启动信息 STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); s原创 2009-11-24 09:31:00 · 16482 阅读 · 8 评论 -
用文件映射(File Mapping)实现进程间内存共享
我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。 如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。 下面就用文件映原创 2007-06-01 09:33:00 · 17784 阅读 · 2 评论 -
《程序只启动一个实例的几种方法》一文的补充
我那篇《程序只启动一个实例的几种方法》发表后被推荐到了CSDN首页,有不少网友看了之后提出了一些很好的建议。其中有个网友说可以用共享变量法,我上网收集了一些资料,又经过代码测试,现在补充一下这种方法: 五,共享变量法 首先,在App类的cpp文件开头加上下面的代码:#pragma data_seg("StarLee") // 自己定义的数据段 char nInst原创 2007-03-27 09:21:00 · 5007 阅读 · 6 评论 -
程序只启动一个实例的几种方法
有些时候,我们要求一个程序在系统中只能启动一个实例。比如,Windows自带的播放软件Windows Medea Player在Windows里就只能启动一个实例。原因很简单,如果同时启动几个实例,却播放不同的文件,那么声音和图像就会引起混乱。在设计模式中,就有一个SINGLETON模式,该模式就是让类只有一个实例。(关于SINGLETON模式,可以看我那篇《重读《设计模式》之学习笔记(三原创 2007-03-20 09:26:00 · 13582 阅读 · 15 评论 -
让你的控件也具有拖拽(drag-and-drop)功能
现在有很多软件都支持拖拽功能,就是用鼠标拖着文件放到软件窗口中某个位置,软件就可以做出相应的反应。比如,Windows自带的播放软件Windows Media Player,你可以拖着一个媒体文件放到它的主窗口中,它就会开始播放这个文件。 怎么让自己的软件也有这个功能呢? 其实,并不是很难,只要让你需要有拖拽功能的控件响应WM_DROPFILES消息就行了。下面以Edit控件和原创 2007-01-03 09:13:00 · 11473 阅读 · 4 评论 -
VC中自动改变控件位置和大小的对话框类
在用VC开发应用程序时,经常会要做一些可以改变大小的对话框,而这个时候就要求对话框上的控件会随着对话框大小的改变而改变自己的位置和大小。如果控件比较少,那可以在对话框的OnSize()事件里面添加代码,通过计算来调整各个控件的位置和大小;但是,如果对话框上的控件比较多的话,那这将是一件非常痛苦的事情!要是程序中又有很多可以改变大小的对话框,那一个一个的OnSize()写下来,那会使程序员崩溃的!原创 2006-04-17 09:21:00 · 14407 阅读 · 31 评论 -
VC中一些控件的小技巧
1.让List Control有Check Box用SetExtendedStyle方法可以设置,看代码:(CListCtrl m_ListCtrl;)DWORD dwStyle = m_ListCtrl.GetStyle();dwStyle |= LVS_EX_CHECKBOXES;m_ListCtrl.SetExtendedStyle(dwStyle);2.让List Box有原创 2005-12-22 13:06:00 · 4726 阅读 · 0 评论 -
在VC中给Slider添加定制的Tooltips
VC中的Slider的Tooltips只能显示表示当前位置的int型值,可是有时候,这种Tooltips并不够用。比如,在一个视频录制的小软件中,可能会需要类似“总共500帧,当前是第13帧”的Tooltips;或者有些时候想在Tooltips中显示float型的值。 在这些时候我们就只能用CToolTipCtrl配合TTN_NEEDTEXT消息来实现我们的定制Tooltips。原创 2005-12-21 10:59:00 · 6610 阅读 · 2 评论 -
在VC中用GDI+绘制角度可变的颜色渐变效果
GDI+ 是GDI(Windows 早期版本提供的图形设备接口)的后续版本,是Microsoft Windows XP作系统即后续版本的图形显示技术。它已经集成到了.Net开发环境中,所以不管你的OS是什么版本,只要安装了.Net框架,就有了GDI+(注意:是.Net框架,而不是.Net开发环境,所以Win98中也可以使用GDI+)。 现在,言归正传。 在头文件中加入下面的代原创 2005-12-21 10:50:00 · 14435 阅读 · 4 评论 -
C++多继承中重写不同基类中相同原型的虚函数
在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数。下面就是一个例子:classCBaseA{public:virtualvoidTestA();};classCBaseB{public:virtualvoidTestB();};classCDerived:publicCBaseA,原创 2008-08-25 09:46:00 · 15561 阅读 · 58 评论 -
小心使用STL中map的[]操作符
一个map就是一个(关键码(key),值(value))对偶的序列,它提供基于关键码的快速提取操作。也就是说,可以用下标运算符[]将关键码作为下标去执行查找,并返回对应的值。因此可以把map的使用方法想象成有特殊下标的数组。在很多时候用下标运算符[]来对map中的元素进行存取是非常方便和简单的;但是,如果map下标运算符[]运用不得当,也会造成意想不到的问题。 我们知道,C++是不检原创 2008-04-07 09:26:00 · 22864 阅读 · 12 评论 -
浅析C++中虚函数的调用及对象的内部布局
在我那篇《浅析C++中的this指针》中,我通过分析C++代码编译后生成的汇编代码来分析this指针的实现方法。这次我依然用分析C++代码编译后生成的汇编代码来说明C++中虚函数调用的实现方法,顺便也说明一下C++中的对象内部布局。下面所有的汇编代码都是用VC2005编译出来的。虽然,不同的编译器可能会编译出不同的结果,对象的内部布局也不尽相同;但是,只要是符合C++标准的编译器,编译结原创 2008-02-13 09:26:00 · 15753 阅读 · 21 评论 -
浅析C++中的this指针
有下面的一个简单的类:class CNullPointCall{public: static void Test1(); void Test2(); void Test3(int iTest); void Test4();private: static int m_iStatic; int m_iTest;};int CNullPointCal原创 2008-01-24 10:00:00 · 60164 阅读 · 57 评论 -
C++中一个容易被忽视的名字查找规则
现在,有下面的代码:namespace lx1{ class Point3d { public: Point3d (double dx, double dy, double dz) : m_dX(dx), m_dY(dy), m_dZ(dz) {} double getX() const { retu原创 2007-12-10 09:12:00 · 7340 阅读 · 29 评论 -
C++中friend对类封装性的强大破坏性
写这篇文章的动机来源于网友purewinter在我的那篇《重读《设计模式》之学习笔记(三)--SINGLETON模式的疑惑》中的评论。 在那篇文章中,我提供了如下一个用C++实现的Singletion模式的小例子:class ClxSingletonMEC{public: friend ClxSingletonMEC& InstanceMEC();private:原创 2007-10-30 09:12:00 · 13353 阅读 · 47 评论 -
用枚举定义有意义的数组下标
在开发中,经常会用到一些数组,它里面存放一定数量(已知,不是太多)的特定元素。在使用数字表示的数组下标访问数组中元素的时候,根本不知道该元素是否是需要的那个元素,而且使代码可读性降低,甚至还会出现下标越界的危险。 比如,现在有如下的继承体系:class CShape;class CSquare : public CShape;class CRectangle : public原创 2007-09-06 08:52:00 · 12730 阅读 · 14 评论 -
让你编写的类也有类型信息
比如说有这样一个类的继承体系:类CDerivedA和CDerivedB都继承自类CBase。如果要写一个函数传入上面类中的一个对象的引用,在函数里面我们要根据对象的类型来进行相应的处理,也就是说对不同类型的对象进行不同的处理。在这种情况下我们就需要类的对象中保存有类型信息。下面就用一个简单的例子来说明怎么让自己编写的类有类型信息。 首先,根据类的继承关系创建类型信息tag:s原创 2007-06-27 08:50:00 · 6698 阅读 · 17 评论 -
引用计数(Reference Counting)和代理(Proxy)的应用
引子 如果让你用C++写一个实用的字符串类,我想下面的方案是很多人最先想到的:class ClxString{public: ClxString(); ClxString(const char *pszStr); ClxString(const ClxString &str); ClxString& operator=(const ClxString &str原创 2007-06-11 09:03:00 · 6894 阅读 · 3 评论 -
STL中bind2nd的用法
比如我们有下面的类:class ClxECS{public: int DoSomething() { // 这里以输出一句话来代替具体的操作 cout "Output from method DoSomething!" endl; return 0; };}; 和下面的一个vector:v原创 2007-01-18 09:21:00 · 17170 阅读 · 3 评论 -
C++中的mutable关键字
mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。 在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。 我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面原创 2006-12-05 09:13:00 · 38910 阅读 · 9 评论 -
C++中重载决议与可访问性检查的顺序
对于如下的类:class ClxECS{public: double Test(double dValue) { return dValue * 13; };private: int Test(int iValue) { return iValue * 13; };}; 下面的函数输出是什么?void ECS_test(){ int iVal原创 2006-11-23 09:13:00 · 4392 阅读 · 3 评论 -
C++中巧用#define访问类的私有成员
我们知道,类的私有成员在类的外部是不能被访问的。 例如有下面的这个简单的类:class ClxECS{private: int iPrivate;}; 那么下面的这个函数是不能通过编译的:void ECS_test(){ ClxECS lx; lx.iPrivate = 13; cout lx.iPrivate endl;}原创 2006-11-22 09:11:00 · 5758 阅读 · 20 评论