﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-生客-文章分类-C++/VC</title><link>http://www.blogjava.net/skllb/category/2000.html</link><description>活着就要学习</description><language>zh-cn</language><lastBuildDate>Thu, 08 Mar 2007 02:41:28 GMT</lastBuildDate><pubDate>Thu, 08 Mar 2007 02:41:28 GMT</pubDate><ttl>60</ttl><item><title>[转] MFC应用程序中各类之间的相互引用</title><link>http://www.blogjava.net/skllb/articles/8225.html</link><dc:creator>生客</dc:creator><author>生客</author><pubDate>Fri, 22 Jul 2005 22:53:00 GMT</pubDate><guid>http://www.blogjava.net/skllb/articles/8225.html</guid><wfw:comment>http://www.blogjava.net/skllb/comments/8225.html</wfw:comment><comments>http://www.blogjava.net/skllb/articles/8225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/skllb/comments/commentRss/8225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/skllb/services/trackbacks/8225.html</trackback:ping><description><![CDATA[<P align=center><STRONG>MFC应用程序中各类之间的相互引用<BR></STRONG><BR>作者：<A href="mailto:wang_wang_dogzi@163.com">gouguijia</A></P><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A1">1) 在<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>中获得Doc<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A2">2) 在App中获得MainFrame<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A3">3) 在<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>中获得MainFrame<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A4">4) 获得<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>（已建立）<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A5">5) 获得当前文档<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A6">6) 获得状态栏与工具栏<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A7">7) 获得状态栏与工具栏变量</A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A8">8) 在Mainframe获得菜单<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A9">9) 在任何类中获得应用程序类</A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A0">10) 从文档类取得视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>(1)</A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A10">11) 在App中获得文档模板<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A11">12) 从文档模板获得文档类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A12">13) 在文档类中获得文档模板<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A13">14) 从文档类取得视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>(2)</A><BR><A href="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/winview/mdi/102105505_658.htm#A14">15) 从一个视图类取得另一视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT></A><BR><BR>VC中编程对于刚刚开始学习的同学，最大的障碍和问题就是消息机制和<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>获取与操作。其实这些内容基本上是每本VC学习工具书上必讲的内容，而且通过MSDN很多问题都能解决。<BR>下面文字主要是个人在编程中<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>使用的一些体会，说的不当的地方请指正。<BR>一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架，无论是多文档还是单文档，都存在<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>获取和操作问题。<BR>下面这节内容主要是一般的框架，然后再讲多线程中的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>使用。使用到的类需要包含响应的头文件。首先一般获得本类(视，文档，对话框都支持)实例<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>this，用this的目的，主要可以通过类中的函数向其他类或者函数中发<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，以便于在非本类中操作和使用本类中的功能。<BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A name=A1></A> 1） 在<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>中获得Doc<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CYouSDIDoc *pDoc=GetDocument();一个视只能有一个文档。</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A2 name=A2></A> 2) 在App中获得MainFrame<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT><BR>CWinApp 中的 m_pMainWnd变量就是MainFrame的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT><BR>也可以： <PRE>CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A3 name=A3></A> 3) 在<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>中获得MainFrame<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CMainFrame *pMain=(CmaimFrame *)AfxGetApp()-&gt;m_pMainWnd;</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A4 name=A4></A> 4) 获得<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>（已建立）<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CMainFrame *pMain=(CmaimFrame *)AfxGetApp()-&gt;m_pMainWnd;
CyouView *pView=(CyouView *)pMain-&gt;GetActiveView();</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A5 name=A5></A> 5) 获得当前文档<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd-&gt;GetActiveDocument();</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A6 name=A6></A> 6) 获得状态栏与工具栏<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CStatusBar * pStatusBar＝(CStatusBar *)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_TOOLBAR);
</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A7 name=A7></A> 7) 如果框架中加入工具栏和状态栏变量还可以这样 <PRE>(CMainFrame *)GetParent()-&gt;m_wndToolBar;
(CMainFrame *)GetParent()-&gt;m_wndStatusBar;
</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A8 name=A8></A> 8) 在Mainframe获得菜单<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> <PRE>CMenu *pMenu=m_pMainWnd-&gt;GetMenu();</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A9 name=A9></A> 9) 在任何类中获得应用程序类<BR>用MFC全局函数AfxGetApp()获得。<BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A10 name=A10></A> 10) 从文档类取得视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT><BR>我是从<A href="http://download.cqcnc.com/soft/program/article/vc/vc405.html" target=_blank>http://download.cqcnc.com/soft/program/article/vc/vc405.html</A>学到的，从文档获得视图类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>目的一般为了控制同一文档的多个视图的定位问题，我的体会特别是文字处理CEditView当产生多个视图类时，这个功能是非常需要的。 <BR>CDocument类提供了两个函数用于视图类的定位：<BR>GetFirstViewPosition()和GetNextView() <PRE>virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION&amp; rPosition) const;<BR>
</PRE>注意：GetNextView()括号中的参数用的是引用方式，因此执行后值可能改变。<BR>GetFirstViewPosition()用于返回第一个视图位置（返回的并非视图类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，而是一个POSITION类型值），GetNextView()有两个功能：返回下一个视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>以及用引用调用的方式来改变传入的POSITION类型参数的值。很明显，在Test程序中，只有一个视图类，因此只需将这两个函数调用一次即可得到CTestView的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>如下（需定义一个POSITION结构变量来辅助操作）： <PRE>CTestView* pTestView;
POSITION pos=GetFirstViewPosition();
pTestView=GetNextView(pos);
</PRE>这样，便可到了CTestView类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>pTestView.执行完几句后，变量pos=NULL,因为没有下一个视图类，自然也没有下一个视图类的POSITION.但是这几条语句太简单，不具有太强的通用性和安全特征；当象前面说的那样，当要在多个视图为中返回某个指定类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>时，我们需要遍历所有视图类，直到找到指定类为止。判断一个类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>指向的是否某个类的实例时，可用IsKindOf()成员函数时行检查，如： <PRE>pView-&gt;IsKindOf(RUNTIME_CLASS(CTestView));</PRE>即可检查pView所指是否是CTestView类。<BR><BR>有了以上基础，我们已经可以从文档类取得任何类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>。为了方便，我们将其作为一个文档类的成员函数，它有一个参数，表示要获得哪个类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>。实现如下： <PRE>CView* CTestDoc::GetView(CRuntimeClass* pClass)
{
	CView* pView;
	POSITION pos=GetFirstViewPosition();

	while(pos!=NULL){
		pView=GetNextView(pos);
		if(!pView-&gt;IsKindOf(pClass))
		break;
	}

	if(!pView-&gt;IsKindOf(pClass)){
		AfxMessageBox("Connt Locate the <FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>.\r\n http://www.VCKBASE.com");
		return NULL;
	}

	return pView;
}</PRE><BR>其中用了两次视图类的成员函数IsKindOf()来判断，是因为退出while循环有三种可能：<BR><BR>1.pos为NULL，即已经不存在下一个视图类供操作；<BR>2.pView已符合要求。<BR><BR>1和2同是满足。这是因为GetNextView()的功能是将当前视图<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>改变成一个视图的位置同时返回当前视图<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，因此pos是pView的下一个视图类的POSITION,完全有可能既是pos==NULL又是pView符合需要。当所需的视图是最后一个视图是最后一个视图类时就如引。因此需采用两次判断。<BR>使用该函数应遵循如下格式（以取得CTestView<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>为例）：<PRE>CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));</PRE>RUNTIME_CLASS是一个宏，可以简单地理解它的作用：将类的名字转化为CRuntimeClass为<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>。<BR>至于强制类型转换也是为了安全特性考虑的，因为从同一个基类之间的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>类型是互相兼容的。这种强制类型转换也许并不必要，但能避免一些可能出现的麻烦。<BR><BR>3.从一个视图类取得另一视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT> 综合1和2，很容易得出视图类之间互相获得<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>的方法：就是用文档类作中转，先用1的方法得到文档类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，再用2的方法，以文档类的视图定位函数取得另一个视图类。同样，可以实现成一个函数：<BR>（假设要从CTestAView中取得指向其它视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>）<PRE>CView* CTestAView::GetView(CRuntimeClass* pClass)
{
	CTestDoc* pDoc=(CTestDoc*)GetDocument();
	CView* pView;
	POSITION pos=pDoc-&gt;GetFirstViewPosition();
	while(pos!=NULL){
		pView=pDoc-&gt;GetNextView(pos);
		if(!pView-&gt;IsKindOf(pClass))
		break;
	}
	if(!pView-&gt;IsKindOf(pClass)){
		AfxMessageBox("Connt Locate the <FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>View</FONT>.");
		return NULL;
	}

	return pView;
}</PRE>这个函数和2中的GetView()相比，一是多了第一句以取得文档类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，二是在GetFirstViewPosition()和GetNextView()前加上了文档类<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>，以表示它们是文档类成员函数。<BR>有了此函数；当要从CTestAView中取得CTestBView的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>时，只需如下：<PRE>CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView));</PRE><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A11 name=A11></A> 11）对于单文档中也可以加入多个文档模板，但是一般的开发就使用MDI方式开发多文档模板，其方法与上述视图的获取方法很接近，这里稍做解释，如果不清楚，请查阅MSDN，（以下四个内容（11、12、13、14）来源：<A href="http://sanjianxia.myrice.com/vc/vc45.htm" target=_blank>http://sanjianxia.myrice.com/vc/vc45.htm</A>）<BR><BR>可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板的位置；<BR>利用该值来调用CWinApp::GetNextDocTemplate函数，获得第一个CDocTemplate对象<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>。 <PRE>POSITION GetFirstDocTemplate( ) const; 
CDocTemplate *GetNextDocTemplate( POSITION &amp; pos ) const;
</PRE>第二个函数返回由pos 标识的文档模板。POSITION是MFC定义的一个用于迭代或对象<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>检索的值。通过这两个函数，应用程序可以遍历整个文档模板列表。如果被检索的文档模板是模板列表中的最后一个，则pos参数被置为NULL。<BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A12 name=A12></A> 12）一个文档模板可以有多个文档，每个文档模板都保留并维护了一个所有对应文档的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>列表。 <BR>用CDocTemplate::GetFirstDocPosition函数获得与文档模板相关的文档集合中第一个文档的位置，并用POSITION值作为CDocTemplate::GetNextDoc的参数来重复遍历与模板相关的文档列表。函数原形为： <PRE>viaual POSITION GetFirstDocPosition( ) const = 0; 
visual CDocument *GetNextDoc(POSITION &amp; rPos) const = 0;  
</PRE>如果列表为空，则rPos被置为NULL. <BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A13 name=A13></A> 13）在文档中可以调用CDocument::GetDocTemplate获得指向该文档模板的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>。函数原形如下： <PRE>CDocTemplate * GetDocTemplate ( ) const; </PRE>如果该文档不属于文档模板管理，则返回值为NULL。 <BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A14 name=A14></A> 14)一个文档可以有多个视。每一个文档都保留并维护一个所有相关视的列表。CDocument::AddView将一个视连接到文档上，将该视加入到文档相联系的视的列表中，并将视的文档<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT>指向该文档。当有File/New、File/Open、Windows/New或Window/Split的命令而将一个新创建的视的对象连接到文档上时， MFC会自动调用该函数，框架通过文档/视的结构将文档和视联系起来。当然，程序员也可以根据自己的需要调用该函数。 <PRE>Virtual POSITION GetFirstViewPosition( ) const; 
Virtual CView * GetNextView( POSITION &amp;rPosition) cosnt; 
</PRE>应用程序可以调用CDocument::GetFirstViewPosition返回与调用文档相联系的视的列表中的第一个视的位置，并调用CDocument::GetNextView返回指定位置的视，并将rPositon的值置为列表中下一个视的POSITION值。如果找到的视为列表中的最后一个视，则将rPosition置为NULL. <BR><BR><IMG height=16 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/images/paragraph.gif" width=14><A id=A15 name=A15></A> 15)从一个视图类取得另一视图类的<FONT style="BACKGROUND-COLOR: #0a246a" color=#ffffff>指针</FONT><BR>这个应用在多视的应用程序中很多见，一般如果自己在主程序或者主框架中做好变量记号，也可以获得，还有比较通用的就是用文档类作中转，以文档类的视图遍历定位，取得另一个视图类。这个功能从本文第10项中可以得到。<BR><BR>这些资料大部分都是从网上和MSDN中获得的，写这个文档就是为了让大家不用再寻找，列出标题，可操作性更强。<BR><img src ="http://www.blogjava.net/skllb/aggbug/8225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/skllb/" target="_blank">生客</a> 2005-07-23 06:53 <a href="http://www.blogjava.net/skllb/articles/8225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DLL入门</title><link>http://www.blogjava.net/skllb/articles/8223.html</link><dc:creator>生客</dc:creator><author>生客</author><pubDate>Fri, 22 Jul 2005 22:37:00 GMT</pubDate><guid>http://www.blogjava.net/skllb/articles/8223.html</guid><wfw:comment>http://www.blogjava.net/skllb/comments/8223.html</wfw:comment><comments>http://www.blogjava.net/skllb/articles/8223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/skllb/comments/commentRss/8223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/skllb/services/trackbacks/8223.html</trackback:ping><description><![CDATA[<P>1。 编写DLL时应该在函数前添加<BR>_declspec(dllexport)表明是对外接口函数， 可以被外部使用。<BR>编写DLL时应该提供一个申明源文件，EG：<BR>&nbsp;_declspec(dllimport) 函数申明<BR>技巧：<BR>我们可以通过条件编译定义一个头文件宏：<BR>#ifdef DLLTEST_API<BR>#else<BR>#define DLLTEST_API _declspec(dllimport)<BR>#endif</P>
<P>DLLTEST_API int Add(int a, int b);<BR>DLLTEST_API int Subtract(int a , int b);<BR>在源文件中我们包含这个文件：<BR>#define DLLTEST_API _declspec(dllexport)<BR>#include "dlltest.h"<BR>int Add(int a, int b)<BR>{<BR>&nbsp;return a+b;<BR>}</P>
<P>int Subtract(int a, int b)<BR>{<BR>&nbsp;return a-b;<BR>}<BR>这样我们的调用程序只需要包含头文件就可以了。</P>
<P><BR>2》》》》<BR>导出一个类： 只需在类名和class中间添加_declspec(dllexport)就可以了， 定义在实现文件中。<BR>如果不需要exports整体个类， 我们只需要在成员函数的定义前添加_declspec(dllexport)就可以了， 而不是在类名前添加。<BR>《〈〈“dlltest.h"<BR>class DLLTEST_API Point<BR>{<BR>public:<BR>&nbsp;void Output(int x, int y);<BR>};<BR>&lt;&lt;&lt;dlltest.cpp&gt;&gt;&gt;&gt;<BR>void Point::Output(int x, int y)<BR>{<BR>&nbsp;HWND hWnd = GetForegroundWindow();<BR>&nbsp;HDC hdc = GetDC(hWnd);<BR>&nbsp;char buf[20];<BR>&nbsp;memset(buf, 0, 20);<BR>&nbsp;sprintf(buf, "x=%d, y=%d", x, y);<BR>&nbsp;TextOut(hdc, x, y, buf, strlen(buf));<BR>&nbsp;ReleaseDC(hWnd, hdc);<BR>}<BR>//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH<BR>&nbsp;在dll中得到当前调用文件句柄可以使用API函数: GetForegroundWindow()</P>
<P>&nbsp;</P>
<P>告诉编译器不要做名字改编， 防止名字改编造成的不同编译器和语言下的不兼容：<BR>只需要在_declspec(dllexport)前添加: extern "C"就可以了。”C“必须是大写。<BR>所以我们的头文件变成了：<BR>#ifdef DLLTEST_API<BR>#else<BR>#define DLLTEST_API _declspec(dllimport)<BR>#endif<BR>而CPP文件头部也应该做变成了：#define DLLTEST_API _declspec(dllimport)</P>
<P>〉〉》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》<BR>1， extern "C" 不能exports类， 而只能是全局函数。<BR>2， 如果调用约定为_stdcall（标准调用约定EG： pascl）而不是”C“调用约定时依然会发生名字改编。<BR>&nbsp;_stdcall改编规则： _函数名字@参数字节数大小。</P>
<P><BR>》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》</P>
<P>解决名字改编： 模块定义文件方法：<BR>在dll工程中加入同名文件dllFileName.def<BR>内容：</P>
<P>LIBRARY dllName</P>
<P>EXPORTS<BR>add //导出函数名要求和原函数名相同， 如果需要定义其他的名字我们可以如下定义： name=functionName</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P><BR>调用DLL：<BR>一：隐式连接<BR>1。 使用时可以使用extern 申明DLL函数， 表明函数在外部定义。<BR>也可以使用_declspec(dllimport)申明函数是在外部定义<BR>使用_declspec(dllimport)效率更高</P>
<P>2。 在编译时需要在LINK下添加动态库的lib文件</P>
<P>二：　动态加载<BR>HMODULE LoadLibrary(<BR>&nbsp; LPCTSTR lpFileName<BR>);<BR>FARPROC GetProcAddress(<BR>&nbsp; HMODULE hModule,<BR>&nbsp; LPCSTR lpProcName<BR>);</P>
<P>__<BR>HINSTANCE hInst = LoadLibrary("dlltest.dll");<BR>typedef int (*ADDPROC)(int x, int b);<BR>ADDRPROC Add = (ADDPROC)GetProcAddress(hInst, "add");//如果导出时使用的是_stdcall, 那么这里我们也应该使用(_stdcall ADDPROC)<BR>if(!Add)<BR>{<BR>&nbsp;加载失败.<BR>}<BR>else<BR>&nbsp;Add(5, 3);<BR>FreeLibrary(hInst);//释放DLL<BR>静态连接在启动时将所有的DLL加载到内存, 而动态加载则在使用时才放入内存, 那么我们的程序速度将加快.</P>
<P>ADDRPROC Add = (ADDPROC)GetProcAddress(hInst, "add");<BR>第而个参数也可以使用序号:<BR>MAKEINTRESOURCE(1)代替函数名.</P>
<P>BOOL WINAPI DllMain(<BR>&nbsp; HINSTANCE hinstDLL,//当前模块句柄<BR>&nbsp; DWORD fdwReason, //指示调用原因.<BR>&nbsp; LPVOID lpvReserved //<BR>);//可选函数<BR>无需我们早过多的操作， 申明了就可以了.</P><img src ="http://www.blogjava.net/skllb/aggbug/8223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/skllb/" target="_blank">生客</a> 2005-07-23 06:37 <a href="http://www.blogjava.net/skllb/articles/8223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC注册表操作</title><link>http://www.blogjava.net/skllb/articles/8224.html</link><dc:creator>生客</dc:creator><author>生客</author><pubDate>Fri, 22 Jul 2005 22:37:00 GMT</pubDate><guid>http://www.blogjava.net/skllb/articles/8224.html</guid><wfw:comment>http://www.blogjava.net/skllb/comments/8224.html</wfw:comment><comments>http://www.blogjava.net/skllb/articles/8224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/skllb/comments/commentRss/8224.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/skllb/services/trackbacks/8224.html</trackback:ping><description><![CDATA[<P>void CFileView::OnRegWrite() <BR>{<BR>&nbsp;// TODO: Add your command handler code here<BR>&nbsp;HKEY hKey;<BR>&nbsp;DWORD dWAge = 30;<BR>&nbsp;RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\http://www.bjfu.edu.cn\\admin", &amp;hKey);<BR>&nbsp;RegSetValue(hKey, NULL, REG_SZ, "shengkesky", strlen("shengkesky"));<BR>&nbsp;RegSetValueEx(hKey, "age", 0, REG_DWORD, (CONST BYTE*)&amp;dWAge, 4);<BR>&nbsp;RegCloseKey(hKey);<BR>}</P>
<P>void CFileView::OnRegRead() <BR>{<BR>&nbsp;// TODO: Add your command handler code here<BR>&nbsp;LONG lValue;<BR>&nbsp;RegQueryValue(HKEY_LOCAL_MACHINE, "Software\\http://www.bjfu.edu.cn\\admin", NULL, &amp;lValue);<BR>&nbsp;char *pBuf = new char[lValue];<BR>&nbsp;RegQueryValue(HKEY_LOCAL_MACHINE, "Software\\http://www.bjfu.edu.cn\\admin", <BR>&nbsp;&nbsp;pBuf, &amp;lValue);<BR>&nbsp;MessageBox(pBuf);<BR>&nbsp;<BR>&nbsp;HKEY hKey;<BR>&nbsp;RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\http://www.bjfu.edu.cn\\admin", &amp;hKey);<BR>&nbsp;DWORD dwType;<BR>&nbsp;DWORD dwValue;<BR>&nbsp;DWORD dwAge;<BR>&nbsp;RegQueryValueEx(hKey, "age", 0, &amp;dwType, (LPBYTE)&amp;dwAge, &amp;dwValue);<BR>&nbsp;CString str;<BR>&nbsp;str.Format("age:%d", dwAge);<BR>&nbsp;MessageBox(str);<BR>&nbsp;<BR>}</P><img src ="http://www.blogjava.net/skllb/aggbug/8224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/skllb/" target="_blank">生客</a> 2005-07-23 06:37 <a href="http://www.blogjava.net/skllb/articles/8224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转帖] 深入理解sizeof</title><link>http://www.blogjava.net/skllb/articles/8222.html</link><dc:creator>生客</dc:creator><author>生客</author><pubDate>Fri, 22 Jul 2005 22:35:00 GMT</pubDate><guid>http://www.blogjava.net/skllb/articles/8222.html</guid><wfw:comment>http://www.blogjava.net/skllb/comments/8222.html</wfw:comment><comments>http://www.blogjava.net/skllb/articles/8222.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/skllb/comments/commentRss/8222.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/skllb/services/trackbacks/8222.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR bgColor=#a0d39b>
<TD height=30>&nbsp;<A href="http://www.vckbase.com/" target=_blank><IMG height=13 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/prjconfig/vckcom.gif" width=109 border=0></A></TD>
<TD vAlign=bottom align=right height=30><IMG height=27 src="mk:@MSITStore:E:\VC知识库精华珍藏版\vckbaseBE30.chm::/prjconfig/earch.gif" width=89></TD></TR>
<TR bgColor=#eeeeee>
<TD><FONT class=small color=#333333>::</FONT><A href="http://www.vckbase.com/" target=_blank><FONT color=black>VC知识库在线杂志</FONT></A></TD>
<TD class=small align=right></TD></TR></TBODY></TABLE>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=40></TD>
<TD vAlign=top width=*>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<P align=center><B>深入理解sizeof<BR></B><BR><BR>作者：<A href="mailto:taboy@bit.edu.cn">房秉毅</A></P>
<P><BR>　　最近在论坛里总有人问关于sizeof的问题，并且本人对这个问题也一直没有得到很好的解决，索性今天对它来个较为详细的总结，同时结合strlen进行比较，如果能对大家有点点帮助，这是我最大的欣慰了。<BR><BR>一、好首先看看sizeof和strlen在MSDN上的定义：<BR><BR>首先看一MSDN上如何对sizeof进行定义的：</P><PRE>sizeof Operator

sizeof expression

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type 
(including aggregate types). This keyword returns a value of type size_t.

The expression is either an identifier or a type-cast expression (a type specifier enclosed in 
parentheses).

When applied to a structure type or variable, sizeof returns the actual size, which may include 
padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof 
returns the size of the entire array. The sizeof operator cannot return the size of dynamically 
allocated arrays or external arrays.</PRE>
<P>然后再看一下对strlen是如何定义的： </P><PRE>strlen

Get the length of a string.

Routine Required Header：
strlen &lt;string.h&gt;

size_t strlen( const char *string );
Parameter
string：Null-terminated string 
Libraries
All versions of the C run-time libraries.

Return Value
Each of these functions returns the number of characters in string, excluding the terminal 
NULL. No return value is reserved to indicate an error.

Remarks
Each of these functions returns the number of characters in string, not including the 
terminating null character. wcslen is a wide-character version of strlen; the argument of 
wcslen is a wide-character string. wcslen and strlen behave identically otherwise.
</PRE>二、由几个例子说开去。<BR><BR>第一个例子： <PRE>char* ss = "0123456789";
sizeof(ss) 结果 4 ＝＝＝》ss是指向字符串常量的字符指针
sizeof(*ss) 结果 1 ＝＝＝》*ss是第一个字符

char ss[] = "0123456789";
sizeof(ss) 结果 11 ＝＝＝》ss是数组，计算到\0位置，因此是10＋1
sizeof(*ss) 结果 1 ＝＝＝》*ss是第一个字符

char ss[100] = "0123456789";
sizeof(ss) 结果是100 ＝＝＝》ss表示在内存中的大小 100×1
strlen(ss) 结果是10 ＝＝＝》strlen是个函数内部实现是用一个循环计算到\0为止之前

int ss[100] = "0123456789";
sizeof(ss) 结果 400 ＝＝＝》ss表示再内存中的大小 100×4
strlen(ss) 错误 ＝＝＝》strlen的参数只能是char* 且必须是以''\0''结尾的

char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 4 3 3 2      </PRE>第二个例子：<PRE>class X
{
int i;
int j;
char k;
};
X x;
cout&lt;&lt;sizeof(X)&lt;&lt;endl; 结果 12 ＝＝＝》内存补齐
cout&lt;&lt;sizeof(x)&lt;&lt;endl; 结果 12 同上
</PRE>第三个例子：<PRE>char szPath[MAX_PATH]
</PRE>　　如果在函数内这样定义，那么sizeof(szPath)将会是MAX_PATH，但是将szPath作为虚参声明时（void fun(char szPath[MAX_PATH])）,sizeof(szPath)却会是4(指针大小) <BR><BR>三、sizeof深入理解。 
<UL>
<LI>1.sizeof操作符的结果类型是size_t，它在头文件中typedef为unsigned　int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 
<LI>2.sizeof是算符，strlen是函数。 
<LI>3.sizeof可以用类型做参数，strlen只能用char*做参数，且必须是以''\0''结尾的。sizeof还可以用函数做参数，比如： <PRE>short f();
printf("%d\n", sizeof(f()));
</PRE>输出的结果是sizeof(short)，即2。 
<LI>4.数组做sizeof的参数不退化，传递给strlen就退化为指针了。 
<LI>5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因 <PRE>char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
</PRE>
<LI>6.strlen的结果要在运行的时候才能计算出来，时用来计算字符串的长度，不是类型占内存的大小。 
<LI>7.sizeof后如果是类型必须加括弧，如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。 
<LI>8.当适用了于一个结构类型时或变量， sizeof 返回实际的大小， 当适用一静态地空间数组， sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 
<LI>9.数组作为参数传给函数时传的是指针而不是数组，传递的是数组的首地址，如： <PRE>fun(char [8])
fun(char [])
</PRE>都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针，编译器不知道数组的大小如果想在函数内知道数组的大小， 需要这样做：进入函数后用memcpy拷贝出来，长度由另一个形参传进去 <PRE>fun(unsiged char *p1, int len)
{
  unsigned char* buf = new unsigned char[len+1]
  memcpy(buf, p1, len);
}
</PRE>有关内容见： C++ PRIMER? 
<LI>10.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快（这同CPU取数操作有关，详细的介绍可以参考一些计算机原理方面的书），C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算，这就叫数据对齐（data alignment）。这样做可能会浪费一些内存，但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定，有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储，而不进行数据对齐，可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。 
<LI>11.sizeof操作符不能用于函数类型，不完全类型或位字段。不完全类型指具有未知存储大小的数据类型，如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int　max(),sizeof(char_v)　若此时char_v定义为char　char_v　[MAX]且MAX未知，sizeof(void)都不是正确形式 </LI></UL>四、结束语<BR><BR>sizeof使用场合。 
<UL>
<LI>1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如：　 <PRE>　　void　*malloc（size_t　size）,　
　　size_t　fread(void　*　ptr,size_t　size,size_t　nmemb,FILE　*　stream)。
</PRE>
<LI>2.用它可以看看一类型的对象在内存中所占的单元字节。 <PRE>void　*　memset（void　*　s,int　c,sizeof(s)）
</PRE>
<LI>3.在动态分配一对象时,可以让系统知道要分配多少内存。 
<LI>4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。 
<LI>5.由于操作数的字节数在实现时可能出现变化，建议在涉及到操作数字节大小时用sizeof来代替常量计算。 
<LI>6.如果操作数是函数中的数组形参或函数类型的形参，sizeof给出其指针的大小。 </LI></UL></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P></P>
<TABLE height=1 cellSpacing=0 cellPadding=0 width="100%" background=../../prjconfig/dotline.gif border=0>
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR align=middle>
<TD class=eng>Copyright© 1999-2003 vckbase.com All Rights Reserved.</TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/skllb/aggbug/8222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/skllb/" target="_blank">生客</a> 2005-07-23 06:35 <a href="http://www.blogjava.net/skllb/articles/8222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>昨天碰到个小病毒... ... 谁都能写的那种</title><link>http://www.blogjava.net/skllb/articles/7667.html</link><dc:creator>生客</dc:creator><author>生客</author><pubDate>Wed, 13 Jul 2005 22:52:00 GMT</pubDate><guid>http://www.blogjava.net/skllb/articles/7667.html</guid><wfw:comment>http://www.blogjava.net/skllb/comments/7667.html</wfw:comment><comments>http://www.blogjava.net/skllb/articles/7667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/skllb/comments/commentRss/7667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/skllb/services/trackbacks/7667.html</trackback:ping><description><![CDATA[<P>前天晚上DC发消息， 说园林学院主页上好象有病毒， 自己认为机器补丁打的满全的， 就贸然上去了，查了下源代码， 果然有一段可疑的加密后的代码， 断定可能被人入侵了。也没有太在意， 昨天晚上和人聊天的时候突然弹出个框框， 然后不见了，汗.... 好低级的病毒... ...</P>
<P>查一下进程, 没有什么特殊的， 换了procexp.exe再查一次,显示Rundll32 .exe的图标是rar格式, 有点问题,(procexp.exe是个好工具)..</P>
<P>很快找到了那个文件， %Systemroot%\system\rundll32.exe(system32下有一个同名合法文件), 删了，清理了所有的自启动项, 看了下exe文件关联, 没有问题. 但很奇怪, 再次运行procexp.exe查看进程时出现了两个RAR图标, 一个没有名字， 一个则是rundll32.exe同上, 很快没有名字的图标消失了. 很明了, 应该是没有名字的文件启动了rundll32.exe, 而我没有做任何操作， 且进程已经清理, 猜想可能是注入了DLL文件， 这下麻烦了... ...</P>
<P>&nbsp;&nbsp; 正当郁闷时, 仔细看了下[HKEY_CLASSES_ROOT\exefile\shell\open\command],，感觉有点不对, 编辑, 发现在"%1" %*的前面有三个空格, 高估了写病毒的人了... ...， 可以断定刚才那个没有名字的病毒文件应该是有名字的,只不过名字是两个空格罢了. 而这里关联的时候它没有显示路径名, 那么肯定在环境变量设置好的路径下, 定位到c:\windows\system32找到了这个没有名字的文件， 删除, 并恢复了exe文件关联， 同上， 还找到了一个"notepade .exe", txt文件关联. 病毒全部清理结束........</P>
<P>__</P>
<P>OK, 大家有没有想过怎么设计一个这样的病毒呢? 很简单, 你只需要明白一个道理, 用我们不能几个的C语言就可以搞定了. 无论你打开任何被关联程序, 系统都会打开我们设置好的病毒程序, 那么我们只需要在病毒程序里面打开用户本来希望打开的程序，那么就可以神不知鬼不觉的运行我们的病毒了, 哈.那么怎么打开呢?　这个就是你必须明白的了: 系统在关联打开程序后， 在你双击打开某个文件时会发送一个消息到你设置的病毒文件，我们叫做cmdline("命令行参数"), 在C语言里面就是main(int argc, char* argv[])的参数数组, 这下你知道该怎么做了吧? 呵, 翻开潭教授的&lt;&lt;C语言&gt;&gt;,你就可以写一个很难被发现的病毒了， 至于你写的是病毒或者木马到底要干什么,怎么写，就随便你了， 偷偷的格式化他的硬盘也可以， 大一时不几个的的C语言水平就完全可以实现了... ...记住: 向上面的病毒一样， 把名字用空格, 呵.. ...</P>
<P>有一点可以提示一下: 不及格的C语言水准做上面的事是可以了，但我怎么写一个木马或者别的能够完成我想做的事情的程序呢? 很简单， 用别人的就可以了. 例如我们要给他种个木马， 那么我们把别人的木马拿过来， 再自己写一个上面提到的文件, 只是在后面加一个功能: 在运行完用户提交的任务后， 再运行一下我们希望的木马不就可以了, 这样我们的病毒文件只需要1K左右就够了, 而木马也打可以取个叫muma.txt的名字， 神仙也不会认为一个真正的txt文件是木马了. 实际上, 上面提到的那么病毒就是这么完成的. rundll32.exe是在运行"&nbsp;&nbsp;.exe"后生成的, 但他的"&nbsp;&nbsp;.exe"有32K之大， 应该是把rundll32.exe作为资源文件添加到了里面， 大没有必要这么做了, 木马我们可以利用病毒文件从网上下载或者从本地机其他已经保存好的有迷惑性格式和名字的文件中提取而来的.<BR><BR><BR>____________________补充： 刚又仔细看了看， 发现WINDOWS文件名字不能为空格，但我们可以使用REN TEST.TXT .TXT来生成一个".TXT"文件， 可病毒是"&nbsp;&nbsp;.TXT" , 本来以为是ASCII码做的， 但实验了一下，不是, 在网上找了会没有找到， 以后碰到再研究研究了.另外该病毒会关联QQ, 在QQ目录下也有病毒文件， 替换一下就可以了.<BR><BR><BR>OK, 就到这里， 感觉自己写东西越来越罗嗦了.......</P><img src ="http://www.blogjava.net/skllb/aggbug/7667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/skllb/" target="_blank">生客</a> 2005-07-14 06:52 <a href="http://www.blogjava.net/skllb/articles/7667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>