<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[缥缈峰]]></title> 
<link>https://www.turbozv.com/index.php</link> 
<description><![CDATA[仁爱、喜乐、和平、忍耐、恩慈、良善、信实、温柔、节制]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[缥缈峰]]></copyright>
<item>
<link>https://www.turbozv.com/read.php/26.htm</link>
<title><![CDATA[记录几篇还不错的P2P文献]]></title> 
<author>turbozv &lt;turbozv@gmail.com&gt;</author>
<category><![CDATA[学习]]></category>
<pubDate>Fri, 10 Mar 2006 19:01:51 +0000</pubDate> 
<guid>https://www.turbozv.com/read.php/26.htm</guid> 
<description>
<![CDATA[ 
	《Peer to Peer ( P2P ) 综述》<br/><a href="http://www.huihoo.com/p2p/1/index.html" target="_blank">http://www.huihoo.com/p2p/1/index.html</a><br/><br/><br/>《P2P 研究领域的综述》<br/><a href="http://net.pku.edu.cn/~shenjian/documents/p2p_report.pdf" target="_blank">http://net.pku.edu.cn/~shenjian/documents/p2p_report.pdf</a><br/><br/><br/>《对等计算研究概论》<br/><a href="http://www.ccf.org.cn/web/resource/newspic/2005/9/20/duideng.pdf" target="_blank">http://www.ccf.org.cn/web/resource/newspic/2005/9/20/duideng.pdf</a>
]]>
</description>
</item><item>
<link>https://www.turbozv.com/read.php/45.htm</link>
<title><![CDATA[開放原始碼理念的開放式課程 原型計畫]]></title> 
<author>turbozv &lt;turbozv@gmail.com&gt;</author>
<category><![CDATA[学习]]></category>
<pubDate>Mon, 30 Jan 2006 15:56:31 +0000</pubDate> 
<guid>https://www.turbozv.com/read.php/45.htm</guid> 
<description>
<![CDATA[ 
	http://www.twocw.net/index.htm<br/><br/> &nbsp; &nbsp; &nbsp;OOPS是Opensource Opencourseware Prototype System，我們的中文名稱叫做開放式課程計畫。簡單地說，這是在奇幻基金會（ <a href="http://www.fantasy.org.tw" target="_blank">http://www.fantasy.org.tw</a> ）之下執行的一個計畫。我們希望能夠用開放原始碼的理想、精神、社群和技術來挑戰開放知識分享的這個新理念，讓更多的人可以分享到知識。
]]>
</description>
</item><item>
<link>https://www.turbozv.com/read.php/51.htm</link>
<title><![CDATA[JobHunting -- 编译器与解释器]]></title> 
<author>turbozv &lt;turbozv@gmail.com&gt;</author>
<category><![CDATA[学习]]></category>
<pubDate>Fri, 20 Jan 2006 10:05:46 +0000</pubDate> 
<guid>https://www.turbozv.com/read.php/51.htm</guid> 
<description>
<![CDATA[ 
	编译器与解释器<br/>作者：Cloud<br/>大家可以通过 zhong335@gmail.com 跟他联系<br/><hr><br/><br/>为了让更多的人能够从本质上理解编译器和解释器的区别，我杜撰了一个小故事<br/><br/>来福与旺财的养牛场<br/><br/>来福和旺财有一个养牛场。本来养牛不是一件太难的事情，但是偏偏他俩养的牛都有特别的怪癖。奶牛阿圆只吃切成圆形的牧草，而奶牛阿方和阿三（印度来的？）分别只吃切成正方形和三角形的牧草。如果来福和旺财拿不和奶牛性格的草去喂食，阿X们不但不产奶而且还会鄙视来福和旺财。<br/><br/>于是来福和旺财分别有了自己的主意<br/><br/>来福的方案：<br/>来福发明了三套大型碾碎机：圆圆碾碎机，方方碾碎机和三三碾碎机。每天收割了牧草，就分别放到这三套机器里碾碎给三头奶牛吃。但是一旦被碾碎了，这堆草就只能给某一头牛吃了。很明显阿方是不会吃给阿圆准备的草的。而且来福每天都要操作这三台机器，觉得比较麻烦。<br/><a href="https://www.turbozv.com/up/image001.png" target="_blank"><img src="https://www.turbozv.com/up/image001.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/> <br/><br/>旺财的方案：<br/>旺财在考察了来福的方案后，发现每天操作三台机器真的很麻烦，而且有时有的牛吃不完，有的牛不够吃时，还不能在奶牛之间调配碾碎了的牧草。所以旺财有了不同的想法：口罩型碾碎机。<br/><a href="https://www.turbozv.com/up/image003.png" target="_blank"><img src="https://www.turbozv.com/up/image003.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a> <br/><br/>就像在图上看到的，旺财给每头奶牛装配了一台口罩碾碎机，所以三头牛完全可以在一个槽里吃草了，在吃之前口罩会自动把牧草碾碎成适合该牛食用的类型。旺财就轻松了，他每天只需要割割草就行了。<br/><br/>但是旺财被鄙视了？？？<br/><br/>是的，被来福鄙视了。来福观察后发现，旺财的口罩碾碎机的效率很低（因为比较小嘛）。阿圆食量大，吃来福的圆圆碾碎机的食物一个小时就饱了，但是戴着口罩吃的时候要吃十个小时！所以来福认为旺财的口罩碾碎机虽然省事，但只能喂喂小牛，完全不适合食量大的牛。<br/><br/>旺财也觉得这样做有问题，但他不想回到来福方案上，他改进了口罩方案：牧草预切割机。<br/><a href="https://www.turbozv.com/up/image005.png" target="_blank"><img src="https://www.turbozv.com/up/image005.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>呵呵，看到预切割做了什么吗？它把牧草割得小了一些，所以需要口罩碾碎机做的事情就少多了。（当然口罩碾碎机也要作适当改进适合预切割后的牧草，所以图上用蓝色表示）阿圆以前用口罩不是要吃十个小时吗，现在两三个小时就可以了。<br/><br/>编译器与解释器<br/><br/>好的，谢谢你有耐心看到这里，经过上面那个不太恰当的例子，相信你已经相当的糊涂了。那么我们试着回到技术方面来。<br/>在上面的例子中<br/>牧草 ＝ 我们的各种编程语言，C/C++/C#, Java, Pascal, PHP, Python, Perl, Java Script等等<br/>切割机 ＝ 各种编译器<br/>奶牛 ＝ 各种CPU（不要告诉我Intel和AMD哦），比如x86，ARM，MIPS等等<br/>那你应该知道了为什么奶牛会有吃不同形状牧草的嗜好了，这个奇怪的比喻是为了表示不同的CPU接受的不同的机器语言。<br/><br/>对应上面的奶牛图，编译器的图是这样的<br/><a href="https://www.turbozv.com/up/image007.png" target="_blank"><img src="https://www.turbozv.com/up/image007.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/> <br/><br/>源代码被编译成机器码，在CPU上运行。<br/><br/>而解释器是这样的<br/><a href="https://www.turbozv.com/up/image009.png" target="_blank"><img src="https://www.turbozv.com/up/image009.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/> <br/><br/>用解释器很方便，只需要直接“运行”就好了，不用像C那样有编译链接的工序。<br/><br/>为什么说这些语言是跨平台的？因为你写了程序以后，如果这个平台上有这种语言的解释器，只需要拿到这个平台上直接运行就可以了。你可以理解为：解释器是在“一边编译，一边运行”，它只是把以前程序员手工做的编译过程放在了运行程序的时候进行。<br/><br/>为什么我们一般说解释器的效率比较低？你也可以想象的是，一段程序在解释器中运行时可能会被编译多次，因为每次运行到这段程序时，都会重新编译一次，这样的开销是很大的。<br/><br/>所以诞生了Java，C#这样的预编译语言：<br/><a href="https://www.turbozv.com/up/image011.png" target="_blank"><img src="https://www.turbozv.com/up/image011.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>在运行之前，需要手动把源代码编译成中间代码（Java里叫字节码），然后在解释器中执行。<br/>这种架构避免了上面纯解释器中编译源代码的开销，所以相对会有效率一些。<br/><br/>但是我不能骗你们，其实我画在纯解释器中的Python，Perl，PHP可能都不会是真的纯解释执行的，这样实在是太没有效率。Python在运行时会生成pyc的二进制临时文件，看起来很像是预编译的结果。只有JavaScript这种真的不会写得太长的语言（Ajax请原谅我）才会采用纯解释的运行方式。
]]>
</description>
</item><item>
<link>https://www.turbozv.com/read.php/55.htm</link>
<title><![CDATA[[转载]简述MFC程序生与死]]></title> 
<author>turbozv &lt;turbozv@gmail.com&gt;</author>
<category><![CDATA[学习]]></category>
<pubDate>Thu, 12 Jan 2006 16:01:54 +0000</pubDate> 
<guid>https://www.turbozv.com/read.php/55.htm</guid> 
<description>
<![CDATA[ 
	原作者姓名 a qing <br/><br/>MFC程序的启动与死亡顺序：<br/><br/><strong>1、创建Application object对象theApp</strong><br/> &nbsp; &nbsp;程序一开始生产一个(且只有一个)Application object对象theApp，也即一个CWinApp对象，这个全局对象一产生，便执行其构造函数，因为并没有定义CMyWinApp构造函数，所以即执行CWinApp类的构造函数。该函数定义于APPCORE.CPP第75行，你可以自己搜出来啃一啃，因此，CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。<br/><br/><strong>2、WinMain登场</strong><br/> &nbsp; &nbsp;用SDK编程序时，程序的入口点是WinMain函数，而在MFC程序里我们并没有看到WinMain函数，哦！~ 原来她是被隐藏在MFC代码里面了。当theApp配置完成后，WinMain登场，慢！细看程序，并没连到WinMain函数的代码啊！这个我也不知道，MFC早已准备好并由链接器直接加到应用程序代码中了，原来她在APPMODUL.CPP里面，好，我们就认为当theApp配置完成后，程序就转到APPMODUL.CPP来了。那执行什么呢？看看下面从APPMODUL.CPP摘出来的代码：<br/><br/> &nbsp; &nbsp;extern \&quot;C\&quot; int WINAPI<br/><br/> &nbsp; &nbsp;_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;// call shared/exported WinMain<br/> &nbsp; &nbsp; &nbsp; &nbsp;return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;_tWinMain函数的“_t”是为了支持Unicode而准备的一个宏。<br/><br/> &nbsp; &nbsp;_tWinMain函数返回值是AfxWinMain函数的返回值，AfxWinMain函数定义于WINMAIN.CPP第21行，稍加整理，去芜存菁，就可以看到这个“程序进入点”主要做些什么事：<br/><br/> &nbsp; &nbsp;int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, &nbsp; &nbsp;LPTSTR lpCmdLine, int nCmdShow)<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;int nReturnCode = -1;<br/> &nbsp; &nbsp; &nbsp; &nbsp;CWinApp* pApp = AfxGetApp();<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;pApp-&gt;InitApplication();<br/> &nbsp; &nbsp; &nbsp; &nbsp;pApp-&gt;InitInstance()<br/> &nbsp; &nbsp; &nbsp; &nbsp;nReturnCode = pApp-&gt;Run();<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;AfxWinTerm();<br/> &nbsp; &nbsp; &nbsp; &nbsp;return nReturnCode;<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;AfxGetApp()函数是取得CMyWinApp对象指针，故上面函数第6至8行相当于调用：<br/><br/> &nbsp; &nbsp;CMyWinApp::InitApplication();<br/> &nbsp; &nbsp;CMyWinApp::InitInstance()<br/> &nbsp; &nbsp;CMyWinApp::Run();<br/><br/> &nbsp; &nbsp;因而导致调用：<br/> &nbsp; &nbsp;CWinApp::InitApplication(); &nbsp;//因为 CMyWinApp 并没有改写 InitApplication<br/> &nbsp; &nbsp;CMyWinApp::InitInstance() &nbsp; &nbsp;//因为 CMyWinApp 改写了 InitInstance<br/> &nbsp; &nbsp;CWinApp::Run(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//因为 CMyWinApp 并没有改写 Run<br/><br/> &nbsp; &nbsp;用过SDK写程序的朋友，现在可能会发出会心的微笑。<br/><br/><strong>3、AfxWinInit——AFX内部初始化操作</strong><br/> &nbsp; &nbsp;AfxWinInit是继CWinApp构造函数之后的第一个操作，主要做的是AFX内部初始化操作，该函数定义于APPINIT.CPP第24行，这里就不掏出来了，你自己搜出来啃吧！<br/><br/><strong>4、执行CWinApp::InitApplication</strong><br/><br/> &nbsp; &nbsp;AfxWinInit之后的操作是pApp-&gt;InitApplication，我们已知道pApp指向CMyWinApp对象，当调用：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;pApp-&gt;InitApplication();<br/><br/> &nbsp; &nbsp;相当于调用：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;CMyWinApp::InitApplication();<br/><br/> &nbsp; &nbsp;但是你要知道，CMyWinApp继承自CWinApp,而InitApplication又是CWinApp的一个虚拟函数，我们并没有改写它(大部分情况下不需改写它)，所以上述操作相当于调用：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;CWinApp::InitApplication();<br/><br/> &nbsp; &nbsp;此函数定义于APPCORE.CPP第125行，你自己搜出来看吧！我就不搬出来了，里面的操作都是MFC为了内部管理而做的(其实我也看不懂，知道有这回事就好了)。<br/><br/><strong>5、执行CWinApp::InitInstance</strong><br/><br/> &nbsp; &nbsp;继InitApplication函数之后，AfxWinMain调用pApp-&gt;InitInstance。当程序调用：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;pApp-&gt;InitInstance();<br/><br/> &nbsp; &nbsp;相当于调用：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;CMyWinApp::InitInstance();<br/><br/> &nbsp; &nbsp;但是你要知道，CMyWinApp继承自CWinApp,而InitInstance又是CWinApp的一个虚拟函数。由于我们改写了它，所以上述操作就是调用我们自己(CMyWinApp)的这个InitInstance函数。<br/><br/><strong>6、CFrameWnd::Create产生主窗口(并先注册窗口类)</strong><br/><br/> &nbsp; &nbsp;现在已经来到CWinApp::InitInstance了，该函数先new一个CMyFrameWnd对象，从而产生主窗口。在创建CMyFrameWnd对之前，要先执行构造函数CMyFrameWnd::CMyFrameWnd()，该函数用Create函数产生窗口：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;CMyFrameWnd::CMyFrameWnd()<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Create(NULL, \&quot;Hello MFC\&quot;, WS_OVERLAPPEDWINDOW, rectDefault, NULL, \&quot;MainMenu\&quot;);<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;其中Create是CFrameWnd的成员函数，它将产生一个窗口，用过SDK编程序的朋友都知道，要创建主窗口时要先注册一个窗口类，规定窗口的属性等，但，这里使用哪一个窗口类呢？Create函数第一个参数(其它参数请参考MSDN或《深出浅出MFC》详解)指定窗口类设为NULL又是什么意思啊？意思是要以MFC内建的空中类产生一个标准的外框窗口，但，我们的程序一般都没有注册任何窗口类呀！噢，Create函数在产生窗口之前会引发窗口类的注册操作。<br/><br/> &nbsp; &nbsp;让我们先挖出Create函数都做了些什么操作，Create函数定义于WINFRM.CPP的第538行(在此我就不把代码Copy过来了，你自己打开出来看吧)，函数在562行调用CreateEx函数，由于CreateEx是CWnd的成员函数，而CFrameWnd是从CWnd继而来，故将调用CWnd::CreateEx。此函数定义于WINCORE.CPP第665行，下面是部分代码：<br/><br/> &nbsp; &nbsp;BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCTSTR lpszWindowName, DWORD dwStyle,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int x, int y, int nWidth, int nHeight,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;// allow modification of several common create parameters<br/> &nbsp; &nbsp; &nbsp; &nbsp;CREATESTRUCT cs;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.dwExStyle = dwExStyle;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.lpszClass = lpszClassName;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.lpszName = lpszWindowName;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.style = dwStyle;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.x = x;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.y = y;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.cx = nWidth;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.cy = nHeight;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.hwndParent = hWndParent;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.hMenu = nIDorHMenu;<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.hInstance = AfxGetInstanceHandle();<br/> &nbsp; &nbsp; &nbsp; &nbsp;cs.lpCreateParams = lpParam;<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;if(PreCreateWindow(cs))<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;PostNcDestroy();<br/> &nbsp; &nbsp; &nbsp; &nbsp;return FALSE;<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;AfxHookWindowCreate(this);<br/> &nbsp; &nbsp;HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);<br/> &nbsp; &nbsp; &nbsp; &nbsp;...<br/>&#125;<br/><br/> &nbsp; &nbsp;用过SDK编程序的朋友，看到上面代码应该有一点感觉了吧，函数中调用的PreCreateWindows是虚拟函数，在CWnd和CFrameWnd之中都有定义。由于this指针所指对象的缘故，这里应该调用的是CFrameWnd::PreCreateWindow。该函数定义于WINFRM.CPP第521行，以下是部分代码：<br/><br/> &nbsp; &nbsp;BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT&amp; cs)<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;if (cs.lpszClass == NULL)<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cs.lpszClass = _afxWndFrameOrView; &nbsp;// COLOR_WINDOW background<br/> &nbsp; &nbsp;&#125;<br/> &nbsp; &nbsp; &nbsp; &nbsp;...<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;其中AfxDeferRegisterClass是一个定义于AFXIMPL.H中的宏。该宏如下：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)<br/><br/> &nbsp; &nbsp;注：这里有宏和《深入浅出MFC》的不一样，以上代码是从Visual C++ 6.0摘取。<br/><br/> &nbsp; &nbsp;AfxEndDeferRegisterClass定义于WINCORE.CPP第3619行，该函数很复杂，主要是注册五个窗口类(哇！终于看到窗口类了，怎么用5个呢？我还不清楚)，不同类的PreCreateWindow成员函数都是在窗口产生之前一刻被调用，准备用来注册窗口类。如果我们指定的窗口类是NULL，那么就使用系统默认类。从CWnd及其各个派生类的PreCreateWindow成员函数可以看出，整个Framework针对不同功能的窗口使用了哪些窗口类。<br/><br/><br/><strong>7、窗口显示与更新</strong><br/><br/> &nbsp; &nbsp;CMyFrameWnd::CMyFrameWnd结束后，窗口已经诞生出来；程序流程又回到CMyWinApp::InitInstance，于是调用ShowWindow函数令窗口显示出来，并调用UpdateWindow函数令程序送出WM_PAINT消息。在SDK程序中，消息是通过窗口函数来处理，而现在窗口函数在哪里、又如何送到窗口函数手中呢？那要从CWinApp::Run说起了。<br/><br/>8、执行CWinApp::Run——程序生命的活水源头<br/><br/> &nbsp; &nbsp;在执行完CMyWinApp::InitInstance函数后，程序的脚步到了AfxWinMain函数的pApp-&gt;Run了，现在我们已知道这将执行CWinApp::Run函数，该函数定义于APPCORE.CPP第391行，下面是程序代码：<br/><br/> &nbsp; &nbsp;int CWinApp::Run()<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;if (m_pMainWnd == NULL &amp;&amp; AfxOleGetUserCtrl())<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Not launched /Embedding or /Automation, but has no main window!<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TRACE0(\&quot;Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n\&quot;);<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AfxPostQuitMessage(0);<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#125;<br/> &nbsp; &nbsp; &nbsp; &nbsp;return CWinThread::Run();<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;函数调用CWinThread::Run函数，该函数定义于THRDCORE.CPP第456行，在这里我就不Copy出来了。函数在第480行调用了PumpMessage函数，该函数定义于THRDCORE.CPP第810行，整理后的部分代码如下：<br/><br/> &nbsp; &nbsp;BOOL CWinThread::PumpMessage()<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp;if (!::GetMessage(&amp;m_msgCur, NULL, NULL, NULL))<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE;<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;// process this message<br/> &nbsp; &nbsp;if (m_msgCur.message != WM_KICKIDLE &amp;&amp; !PreTranslateMessage(&amp;m_msgCur))<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;::TranslateMessage(&amp;m_msgCur);<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;::DispatchMessage(&amp;m_msgCur);<br/> &nbsp; &nbsp; &nbsp; &nbsp;&#125;<br/> &nbsp; &nbsp; &nbsp; &nbsp;return TRUE;<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;该函数主要操作是将消息由::DispatchMessage送到窗口函数(CWnd::DefWindowProc)中，但程序一般没有提供任何窗口函数，但在AfxEndDeferRegisterClass中，在注册五种窗口类之前已经指定窗口函数为：<br/><br/> &nbsp; &nbsp; &nbsp; &nbsp;wndcls.lpfnWndProc = DefWindowProc;<br/><br/> &nbsp; &nbsp;虽然窗口函数被指定为DefWindowProc成员函数(CWnd::DefWindowProc)，但事实上消息并不是被唧往该处，而是一个名为AfxWndProc的全局函数去。<br/><br/><br/><strong>9、把消息与处理函数连接在一起——Message Map机制</strong><br/><br/> &nbsp; &nbsp;到此，主窗口已经产生，等待的就是各种消息了，然后调用相应的处理函数，然而消息和处理函数怎样连接在一起呢？MFC采用了Message Map机制(消息映射机制)，提供给应用程序使用的“很方便的接口”的两组宏，其原理我还不大清楚，在这里也无法讲解，主要用法是：先在类声明中结合DECLARE_MESSAGE_MAP()给出处理函数，如：<br/><br/> &nbsp; &nbsp;class CMyFrameWnd : public CFrameWnd<br/> &nbsp; &nbsp;&#123;<br/> &nbsp; &nbsp;public:<br/> &nbsp; &nbsp; &nbsp; &nbsp;CMyFrameWnd();<br/> &nbsp; &nbsp; &nbsp; &nbsp;afx_msg void OnPaint(); &nbsp; // for WM_PAINT<br/> &nbsp; &nbsp; &nbsp; &nbsp;afx_msg void OnAbout(); &nbsp; // for WM_COMMAND (IDM_ABOUT)<br/> &nbsp; &nbsp; &nbsp; &nbsp;DECLARE_MESSAGE_MAP()<br/> &nbsp; &nbsp;&#125;<br/><br/> &nbsp; &nbsp;再在相应的.CPP文件的任何位置(当然不能在函数之内)使用BEBIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏把相应的消息加入去，如：<br/><br/> &nbsp; &nbsp;BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)<br/> &nbsp; &nbsp; &nbsp; &nbsp;ON_COMMAND(IDM_ABOUT, OnAbout)<br/> &nbsp; &nbsp; &nbsp; &nbsp;ON_WM_PAINT()<br/> &nbsp; &nbsp;END_MESSAGE_MAP()<br/><br/><br/> &nbsp; &nbsp;为什么经过这样的宏之后，消息就会自动流往指定的函数去呢？谜底在于Message Map的结构设计，自己找《深入浅出MFC》第3章的Message Map仿真程序去啃一啃吧！<br/><br/><br/><br/> &nbsp; &nbsp;好了，就写到这了，如果你是刚接触MFC，我想看了之后你可能也有点糊涂，SORRY啦！我是从来没有写过总结的，没事！把侯先生的《深入浅出MFC》拿出来啃几遍就不会了。<br/><br/>
]]>
</description>
</item><item>
<link>https://www.turbozv.com/read.php/58.htm</link>
<title><![CDATA[FDRM阅读笔记]]></title> 
<author>turbozv &lt;turbozv@gmail.com&gt;</author>
<category><![CDATA[学习]]></category>
<pubDate>Tue, 10 Jan 2006 12:58:57 +0000</pubDate> 
<guid>https://www.turbozv.com/read.php/58.htm</guid> 
<description>
<![CDATA[ 
	&nbsp; &nbsp; &nbsp;FDRM(File-Based Digital Rights Management)是微软指定的一套DRM接口规范，包含13个API接口。<br/><br/><br/><br/>1、FileDrmIsDRM 判断一个文件是否是是DRM对象<br/>HRESULT FileDrmIsDRM (LPCTSTR pszFile, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PBOOL pfDRM);<br/><br/><br/>2、FileDrmCreateFile 创建一个FDRM的内容文件<br/>HRESULT FileDrmCreateFile (LPCTSTR pszFileName,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwDesiredAccess,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwShareMode,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPSECURITY_ATTRIBUTES lpSecurityAttributes,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwCreationDisposition,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwFlagsAndAttributes,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HANDLE hTemplateFile,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PHANDLE phFile);<br/>调用方式同CreateFile一样，不过需要注意的是参数里的dwDesiredAccess只能为GENERIC_READ，因为DRM对象都是被保护对象，对应用程序只读。同样，dwCreationDisposition只能为OPEN_EXISTING。<br/><br/><br/>3、FileDrmCreateForwardableContent 创建一个用于转发的DRM文件<br/>HRESULT FileDrmCreateForwardableContent (LPCTSTR pszFileName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwFlags,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCTSTR pszOutputFile);<br/><br/><br/>4、FileDrmNotifyEnable 打开FDRM提醒<br/>HRESULT FileDrmNotifyEnable (LPCTSTR pszFileName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPTSTR pszValueName,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD cchValueNameLen);<br/><br/><br/>5、FileDrmNotifyDisable 关闭FDRM提醒<br/>HRESULT FileDrmNotifyDisable (LPCTSTR pszFileName);<br/><br/><br/>6、FileDrmShowLicenseInfo 显示DRM对象权限信息<br/>HRESULT FileDrmShowLicenseInfo (HWND hwndParent,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCTSTR pszFileName);<br/><br/><br/>7、FileDrmHandleError 显示错误信息<br/>HRESULT FileDrmHandleError (HWND &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hwndParent, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HRESULT &nbsp; &nbsp; &nbsp; &nbsp; hrError, &nbsp; <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCTSTR &nbsp; &nbsp; &nbsp; &nbsp; pszFileName,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PDWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwStatus);<br/><br/><br/>8、FileDrmRenewRights 获取新的DRM对象权限<br/>HRESULT FileDrmRenewRights (HWND hwndParent,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCTSTR pszFileName);<br/>一般情况下会通过网络获取新权限。<br/><br/><br/>9、FileDrmGetMetric 获取度量值<br/>HRESULT FileDrmGetMetric (FDRMMETRIC drmID,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD *pdwMetric);<br/><br/><br/>10、FileDrmVerifyRights 校验DRM对象的权限是否可用<br/>HRESULT FileDrmVerifyRights (HWND &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hwndParent,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCTSTR &nbsp; &nbsp; &nbsp; &nbsp;pszFileName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwRight,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDWORD &nbsp; &nbsp; &nbsp; &nbsp; pdwRightsStatus);<br/>注意，不管是不是已经做了FileDrmGetRights判断，这个函数在使用DRM对象时必须被调用的。<br/><br/><br/>11、FileDrmCommitRights 提交对一个DRM对象进行使用<br/>HRESULT FileDrmCommitRights (HANDLE hFile, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwRight,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwFlags);<br/><br/><br/>12、FileDrmDelete 删除一个DRM对象及其权限<br/>HRESULT FileDrmDeleteFile (LPCTSTR pszFileName);<br/><br/><br/>13、FileDrmStoreContent 将原始的MIME编码的DRM内容保存到本地文件<br/>HRESULT FileDrmStoreContent (LPCTSTR pszInputFileName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCTSTR pszOutputFileName,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPVOID &nbsp;pvReserved,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPTSTR &nbsp;pszMimeType,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp;*pcchMimeTypeLen);<br/><br/><br/>14、FileDrmVerifyRightsEx 校验DRM对象的权限是否可用（多用于文件浏览时）<br/>HRESULT FileDrmVerifyRightsEx (HWND &nbsp; &nbsp; hwndParent,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCTSTR &nbsp;pszFileName, <br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp; &nbsp;dwRight,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp; &nbsp;dwFlags,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDWORD &nbsp; pdwRightsStatus,<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPGUID &nbsp; pguidFilter);<br/><br/><br/><br/>Reference:<br/><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mobilesdk5/html/mob5oriFile-BasedDigitalRightsManagement.asp" target="_blank">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mobilesdk5/html/mob5oriFile-BasedDigitalRightsManagement.asp</a>
]]>
</description>
</item>
</channel>
</rss>