2005年01月
问:如何传递CString中包含的字符串到具有IStream类型参数的函数?
问:如何根据获得的IStream接口指针获得字符串?
答:
MFC7中的未归档类CStreamOnCString实现了IStream接口访问封装的CString类型的m_strStream成员。如果你没有MFC7,可以用CreateStreamOnGlobal创建IStream的内存流实现对象,之后调用IStream::Write将字符串写入内存流对象;或者创建IStream的内存流实现对象,反复调用IStream::Read和IStream::Write复制数据到内存流实现对象,然后调用GetHGlobalFromStream函数直接访问内存流的内存句柄。
上面的一些调用在MFC中被封装到COleStreamFile 类中。
下面的代码把一个内存流读到字节数组。你可以根据字符串的类型把字节数组转化成字符串。
COleStreamFile osfRead;
osfRead.Attach(pStream);
long lLength=osfRead.GetLength();
CByteAr阅读全文>
发表于 @ 2005年01月24日 10:09:00|评论(loading...)|编辑
问:我看到CListView的成员函数GetListCtrl直接把CListView本身的指针转换为CListCtrl指针。我想知道在什么情况下可以安全地把一个类的指针转化为另一个类的指针?
答:只要你访问的数据的内存表示是完全相同的,那么这种转化就是安全的。考虑MFC从CWnd到CEdit的派生过程,是一个纯粹的封装——既没有增加数据成员也没有增加虚函数(隐含的虚函数表的指针实际上是类的一个成员,你可以在VC的监视窗口看到)——所有的代码只是在操作基类的成员。所以你可以在对话框的成员函数中安全地进行如下调用
CEdit* pEdit=GetDlgItem (IDC_EDIT);//把CTempWnd类型的对象的指针转化成CEdit指针
也就是说,你可以安全地把CWnd指针转化为CEdit指针。在CWnd的窗口类为EDIT的情况下,你可以安全地用这个CEdit指针来访问CEdit具有的而CWnd不具有的方法。由于CEditView的窗口类也是EDIT,同时是从CWnd派生下来的,所以你也可以把CEditView指针转化成CEdit指针。MFC的CCtrlView的派生类都可以做这阅读全文>
发表于 @ 2005年01月24日 09:35:00|评论(loading...)|编辑
编译器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全地转化为一个基类的指针。这样删除一个基类的指针的时候,C++不管这个指针指向一个基类对象还是一个派生类的对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么此时会有资源泄漏。
所以建议的方式是将析构函数声明为虚函数。如果你使用MFC,并且以CObject或其派生类为基类,那么MFC已经为你做了这件事情;CObject的析构函数是虚函数。一个函数一旦声明为虚函数,那么不管你是否加上virtual修饰符,它在所有派生类中都成为虚函数。但是为了理解明确起见,建议的方式还是加上virtual 修饰符。
C++不把虚析构函数直接作为默认值的原因是虚函数表的开销以及和C语言的类型的兼容性。有虚函数的对象总是在对象开始或者末尾的位置(具体位置随编译器而异)包含一个隐含的虚函数表指针成员。对于MFC类CPoint和CSize这样的小型类,增加一个指针成员就增加了很多内存占用,而且使得其内存表示和基类POINT和SIZE不一致。如果两个类的内存表示一致,那么你有时可阅读全文>
发表于 @ 2005年01月24日 09:22:00|评论(loading...)|编辑
微软知识库中的文章How To Increment Version Information After Each Build in Visual C++(http://support.microsoft.com/kb/237870/)提供了在VC6中自动增加版本号的方法。在VS.Net中,需要对这个宏进行少许的更改:http://www.thecodeproject.com/macro/IncBuildNrMacro.asp?df=100&forumid=49502&select=1008554#xx1008554xx。
也可以使用VS.NET插件来实现该功能,一个示例在下面的网址可以找到
An Automatic Build Number Incrementer for Visual Studio .NET
http://codeguru.earthweb.com/Csharp/.NET/net_vs_addins/article.php/c5961/
但是宏比插件更加灵活,更稳定,更便于修改和扩展。
阅读全文>
发表于 @ 2005年01月23日 02:22:00|评论(loading...)|编辑
在Windows中拨号上网(包括MODEM和PPPoe),一般都是用Windows平台提供的的Remote Access Service(RAS,远程访问服务):http://msdn.microsoft.com/library/en-us/rras/rras/ras_start_page.asp 。其中的连接操作函数(http://msdn.microsoft.com/library/en-us/rras/rras/ras_connection_operations.asp)可以用于对拨号连接进行操作。比较常用的几个函数是RasDial、RasHangUp、RasEnumConnection和RasGetConnectStatus,以及自定义的通知处理函数(http://msdn.microsoft.com/library/en-us/rras/rras/notification_handlers.asp)。
一个代码示例可以在http://www.pconline.com.cn/pcedu/empolder/gj/vc/10309/221591.html 找到(原始出处搜索半阅读全文>
发表于 @ 2005年01月23日 01:41:00|评论(loading...)|编辑
为了唤醒网络上的计算机,必须发出一种特殊的数据包,该数据包的格式与普通数据包不同,而且还必须使用相应的专用软件才能产生。当前普遍采用的是AMD公司制作的Magic Packedt这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。该数据包包含有连续6个字节的“FF”和连续重复16次的MAC地址。
Magic Packet格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此 许多具有网络唤醒功能的网卡都能与之兼容。
需要更多关于Magic Packet的信息的话,可以参考
http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2481,00.html
一个生成网络唤醒所需要的特殊数据包的示例代码可以在http://staff.aist.go.jp/d.g.fedorov/ether-wake.c 找到。阅读全文>
发表于 @ 2005年01月23日 01:16:00|评论(loading...)|编辑
某些应用程序处理紧缺资源,例如可擦写光驱、串口或者大量内存,通常不希望这种应用程序的多个实例同时运行。
实际上你没有办法限制用户只能启动一次。你可以做到的是在应用程序启动之后查找是否用户启动了另一个实例。如果没有找到现存的实例,应用程序以正常方式启动。否则,通常的处理是退出。阅读全文>
发表于 @ 2005年01月22日 13:46:00|评论(loading...)|编辑
桌面处理和一个例子 (http://www.vckbase.com/vckbase/vckbase10/vc/nonctrls/atlcomocx_02/1002001.htm)讲述了使用IActiveDesktop接口可以做到的事情。活动桌面允许在桌面上显示HTML网页,这也意味着我们可以在桌面上的项目中以在网页中使用ActiveX控件来对网页进行扩展的方式来提供丰富的内容。但是不建议在桌面上使用不安全的控件,例如Windows Media Player。虽然用一段影片作为桌面背景是一件很酷的事情,但是你不得不忍受在每次切换任务或者刷新桌面的时候都弹出安全性提示对话框。你可以在编写自己的控件时利用
http://msdn.microsoft.com/library/CHS/vccore/html/_atl_step_7.3a_.putting_the_control_on_a_web_page.asp中的技术来避免这个烦人的对话框。阅读全文>
发表于 @ 2005年01月22日 13:33:00|评论(loading...)|编辑