<?xml version="1.0" encoding="utf-8"?><rss version="2.0">
<channel>
<title><![CDATA[FreeWindow]]></title>
<link>http://blog.pfan.cn/ainterly</link>
<description>编程爱好者博客</description>
<language>zh-cn</language>
			<item>
		<title><![CDATA[Windows消息大全（3）]]></title>
		<link>http://blog.pfan.cn/ainterly/15227.html</link>
		<description><![CDATA[WM_COPY = $0301;
程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板
WM_PASTE = $0302;
程序发送此消息给editcontrol或combobox从剪贴板中得到数据
WM_CLEAR = $0303;
程序发送此消息给editcontrol或combobox清除当前选择的内容；
WM_UNDO = $0304;
程序发送此消息给editcontrol或combobox撤消最后一次操作
WM_RENDERFORMAT = $0305；
WM_RENDERALLFORMATS = $0306;
WM_DESTROYCLIPBOARD = $0307;
当调用ENPTYCLIPBOARD函数时 发送此消息给剪贴板的所有者
WM_DRAWCLIPBOARD = $0308;
当剪贴板的内容变化时发送此消息给剪贴板观察链的第一个窗口；它允许用剪贴板观察窗口来
显示剪贴板的新内容；
WM_PAINTCLIPBOARD = $0309;
当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区需要重画；
WM_VSCROLLCLIPBOARD = $030A;
WM_SIZECLIPBOARD = $030B;
当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区域的大小已经改变是此消息通过剪贴板观察窗口发送给剪贴板的所有者；
WM_ASKCBFORMATNAME = $030C;
通过剪贴板观察窗口发送此消息给剪贴板的所有者来请求一个CF_OWNERDISPLAY格式的剪贴板的名字
WM_CHANGECBCHAIN = $030D;
当一个窗口从剪贴板观察链中移去时发送此消息给剪贴板观察链的第一个窗口；
WM_HSCROLLCLIPBOARD = $030E; 
此消息通过一个剪贴板观察窗口发送给剪贴板的所有者 ；它发生在当剪贴板包含CFOWNERDISPALY格式的数据并且有个事件在剪贴板观察窗的水平滚动条上；所有者应滚动剪贴板图象并更新滚动条的值；
WM_QUERYNEWPALETTE = $030F;
此消息发送给将要收到焦点的窗口，此消息能使窗口在收到焦点时同时有机会实现他的逻辑调色板
WM_PALETTEISCHAN]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-30 17:06:00</pubDate>
		</item>
				<item>
		<title><![CDATA[Windows消息大全（2）]]></title>
		<link>http://blog.pfan.cn/ainterly/15226.html</link>
		<description><![CDATA[WM_INPUTLANGCHANGE = $0051;
当平台现场已经被改变后发送此消息给受影响的最顶级窗口
WM_TCARD = $0052;
当程序已经初始化windows帮助例程时发送此消息给应用程序
WM_HELP = $0053;
此消息显示用户按下了F1，如果某个菜单是激活的，就发送此消息个此窗口关联的菜单，否则就发送给有焦点的窗口，如果当前都没有焦点，就把此消息发送给当前激活的窗口
WM_USERCHANGED = $0054;
当用户已经登入或退出后发送此消息给所有的窗口，当用户登入或退出时系统更新用户的具体
设置信息，在用户更新设置时系统马上发送此消息；
WM_NOTIFYFORMAT = $0055;
公用控件，自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构
在WM_NOTIFY消息，使用此控件能使某个控件与它的父控件之间进行相互通信
WM_CONTEXTMENU = $007B;
当用户某个窗口中点击了一下右键就发送此消息给这个窗口
WM_STYLECHANGING = $007C;
当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口
WM_STYLECHANGED = $007D;
当调用SETWINDOWLONG函数一个或多个 窗口的风格后发送此消息给那个窗口
WM_DISPLAYCHANGE = $007E;
当显示器的分辨率改变后发送此消息给所有的窗口
WM_GETICON = $007F; 此消息发送给某个窗口来返回与某个窗口有关连的大图标或小图标的句柄；
WM_SETICON = $0080;
程序发送此消息让一个新的大图标或小图标与某个窗口关联；
WM_NCCREATE = $0081;
当某个窗口第一次被创建时，此消息在WM_CREATE消息发送前发送；
WM_NCDESTROY = $0082;
此消息通知某个窗口，非客户区正在销毁
WM_NCCALCSIZE = $0083;
当某个窗口的客户区域必须被核算时发送此消息
WM_NCHITTEST = $0084;//移动鼠标，按住或释放鼠标时发生
WM_NCPAINT = $0085;
程序发送此消息给某个窗口当它（窗口）的框架必须被绘制时；]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-30 17:05:00</pubDate>
		</item>
				<item>
		<title><![CDATA[Windows消息大全（1）]]></title>
		<link>http://blog.pfan.cn/ainterly/15225.html</link>
		<description><![CDATA[鼠标位置
end;
消息中有什么？
是否觉得一个消息记录中的信息像希腊语一样？如果是这样，那么看一看下面的解释：
hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象，因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message 用于区别其他消息的常量值，这些常量可以是Windows单元中预定义的常量，也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值，也可能是窗口或控件的句柄。
lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的，因此，它们之间可以相互转换。
WM_NULL = $0000;
WM_CREATE = $0001;
应用程序创建一个窗口
WM_DESTROY = $0002;
一个窗口被销毁
WM_MOVE = $0003;
移动一个窗口
WM_SIZE = $0005;
改变一个窗口的大小
WM_ACTIVATE = $0006;
一个窗口被激活或失去激活状态；
WM_SETFOCUS = $0007;
获得焦点后
WM_KILLFOCUS = $0008;
失去焦点
WM_ENABLE = $000A;
改变enable状态
WM_SETREDRAW = $000B;
设置窗口是否能重画 
WM_SETTEXT = $000C;
应用程序发送此消息来设置一个窗口的文本
WM_GETTEXT = $000D;
应用程序发送此消息来复制对应窗口的文本到缓冲区
WM_GETTEXTLENGTH = $000E;
得到与一个窗口有关的文本的长度（不包含空字符）
WM_PAINT = $000F;
要求一个窗口重画自己
WM_CLOSE = $0010;
当一个窗口或应用程序要关闭时发送一个信号
WM_QUERYENDSESSION = $0011;
当用户选择结束对话框或程序自己调用ExitWindows函数
WM_QUIT = $0012;
用来结束程序运行或当程序调用postquitmessage函数 
WM_QUERYOPEN = $0013;
当用户窗口恢复以前的大小位置时，把此消息发送给某个图标
WM_ERASEBKGND]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-30 17:04:00</pubDate>
		</item>
				<item>
		<title><![CDATA[使用Rundll32.exe和Rundll.exe]]></title>
		<link>http://blog.pfan.cn/ainterly/15224.html</link>
		<description><![CDATA[常用Windows9x的朋友一定对Rundll32.exe和Rundll.exe这两个文件不会陌生吧，不过,由于这两个程序的功能原先只限于在微软内部使用，因而真正知道如何使用它们的朋友想必不多。那么好，如果你还不清楚的话，那么就让我来告诉你吧。　　首先，请你做个小实验（请事先保存好你正在运行的程序的结果，否则...）：点击“开始－程序－Ms－Dos方式”，进入Dos窗口，然后键入"rundll32.exe user.exe,restartwindows"，再按下回车键，这时你将看到，机器被重启了！怎么样，是不是很有趣？　　当然，Rundll的功能绝不仅仅是重启你的机器。其实，Rundll者，顾名思义，运行Dll也，它的功能就是以命令行的方式调用Windows的动态链接库，Rundll32.exe与Rundll.exe的区别就在于前者是调用32位的链接库，而后者是运用于16位的链接库，它们的命令格式是：　　RUNDLL.EXE ，&lt;入口点&gt;，&lt;调用参数&gt;　　这里要注意三点：1.Dll文件名中不能含有空格，比如该文件位于c:\Program Files\目录，你要把这个路径改成c:\Progra～1\；2.Dll文件名与Dll入口点间的逗号不能少，否则程序将出错并且不会给出任何信息！3.这是最重要的一点：Rundll不能用来调用含返回值参数的Dll，例如Win32API中的GetUserName(),GetTextFace()等。在Visual Basic中，提供了一条执行外部程序的指令Shell,格式为：　　Shell “命令行”　　如果能配合Rundll32.exe用好Shell指令，会使您的VB程序拥有用其他方法难以甚至无法实现的效果：仍以重启为例，传统的方法需要你在VB工程中先建立一个模块，然后写入WinAPI的声明，最后才能在程序中调用。而现在只需一句: 　　Shell “rundll32.exe user.exe,restartwindows”就搞定了！是不是方便多了？　　实际上，Rundll32.exe在调用各种Windows控制面板和系统选项方面有着独特的优势。下面，我就将本人在因特网上收集的有关Rundll的指令列举如下（很有用的，能省去你很多调用Windows API的时间！！），供大家在编程中引用：　　命令行: rundll]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-30 17:01:00</pubDate>
		</item>
				<item>
		<title><![CDATA[经典资料及其下载地址]]></title>
		<link>http://blog.pfan.cn/ainterly/14605.html</link>
		<description><![CDATA[C++编程思想——C++的神奇书籍&nbsp;&nbsp;&nbsp;13.82&nbsp;MB&nbsp; ·本书作者根据自己学习C++的亲身体会及多年教学经验，用简单的例子和简练的叙述讲解C++编程，别具特色。&nbsp;全书共分十八章，内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命...&nbsp;&nbsp; &nbsp;钱能C++程序设计教程&nbsp;&nbsp;6.8&nbsp;MB ·钱能C++程序设计教程虽然是很老的书,不过总算是国产书中质量不错中的一本,适合C++初学者....&nbsp;&nbsp; &nbsp;The&nbsp;C++&nbsp;Standard&nbsp;Library&nbsp;&nbsp;4.24&nbsp;MB&nbsp;&nbsp; ·虽然也是老书,但是够经典,:-)&nbsp;Programming&nbsp;with&nbsp;the&nbsp;C++&nbsp;Standard&nbsp;Library&nbsp;can&nbsp;certainly&nbsp;be&nbsp;difficult,&nbsp;but&nbsp;Nicolai&nbsp;Josuttiss&nbsp;The...&nbsp;&nbsp; &nbsp;C++PrimerPlus&nbsp;4thEdition&nbsp;4.34&nbsp;MB&nbsp;&nbsp;&nbsp; ·The&nbsp;fourth&nbsp;edition&nbsp;presents&nbsp;the&nbsp;ANSI&nbsp;C++&nbsp;standard&nbsp;beginning&nbsp;with&nbsp;a&nbsp;discussion&nbsp;of&nbsp;the&nbsp;essential&nbsp;elements&nbsp;of&nbsp;C++&nbsp;program...&nbsp;&nbsp; 　 &nbsp;C++&nbsp;Primer&nbsp;中文版（第三版）完全版&nbsp;&nbsp;&nbsp;3.81&nbsp;MB&nbsp; ·C++&nbsp;Primer的第三版结合了Stanley&nbsp;Lippman的实践经验和J]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-23 13:18:00</pubDate>
		</item>
				<item>
		<title><![CDATA[USB&nbsp;设备的枚举过程&nbsp;]]></title>
		<link>http://blog.pfan.cn/ainterly/14517.html</link>
		<description><![CDATA[USB 设备枚举的数据传输过程 
以下是一个程序枚举数据传输的全过程： 
(1) 主机检测到有设备插上，总线复位 
当设备与主机连接时，主机就会检测到一个连接条件，并且D＋的数据线被拉至Vse以上2.5微秒(30个全速数据比特周期)，主机就开始进行总线复位。 
(2) 主机读取设备描述符 
主机使用默认地址(地址0)读取设备描述符，在这里主机使用地址0对设备的设备描述符进行读取。由于PDIUSBD12的端点0的缓冲区只有16个字节，所以单片机就先发送16个字节的设备描述符。当主机接收到这16个字节的字符后，就认为真正有设备连接了，即发送1个0字节的数据包到设备作为状态应答。 
(3) 地址分配 
在地址分配阶段里，主机分配给设备一个地址。在以后的通信里设备就只对这个地址的信息作出应答。 
(4) 主机从新的地址获取设备描述符 
分配好了设备地址后，主机就从新的地址获取设备描述符。由于受PDIUSBD12芯片的限制，设备分2次把设备描述符经过端点0发送出去，第一次发送16个字节，第2次发送2个字节。最后主机发送0字节的数据包作为状态应答。 
(5) 主机读取配置描述符 
主机读取完设备描述符后就读取设备的配置描述符 
(6) 读取描述符集合 
主机除了读取设备描述符和配置描述符外，还要读取接口描述符和端口描述符。在这里主机使用再次读取配置的方法来读取配置描述符、接口描述符和端点描述符的集合。 
(7) 设置配置 
主机读取完描述符后，就需要对设备进行配置，使得设备从地址状态进入配置状态。 
(8) 读取配置状态 
主机设置完配置以后，设备即可使用。主机有时会对设备的配置状态进行读取。 
(9) 读取接口状态 
在配置完成后，主机会对接口的状态进行读取，这和读取配置一样也是可选的。]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-22 13:34:00</pubDate>
		</item>
				<item>
		<title><![CDATA[USB驱动基础]]></title>
		<link>http://blog.pfan.cn/ainterly/14187.html</link>
		<description><![CDATA[DriverWorks supports development of drivers that are USB clients, i.e., drivers that need to send requests over a USB to some device.
From the client driver's perspective, any USB device is conceptually comprised of three classes of components:


Logical Device. This is the logical component with which the USB bus driver communicates in order to configure and control the device. It corresponds to the default control pipe or "endpoint 0" as described in the USB specification. All USB devices support a common set of functions accessible via commands to the Logical Device layer of the USB protocol stack. These functions include access to the device descriptor and setting the configuration.
Class KUsbLowerDevice abstracts this functionality. By instancing this class, a device driver creates an interface to the upper edge of the system USB bus driver.


Interfaces. All USB devices have one or more interfaces. An interface is a grouping of the device's endpoints which provides a part]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-05-16 15:07:00</pubDate>
		</item>
				<item>
		<title><![CDATA[自己想的问题]]></title>
		<link>http://blog.pfan.cn/ainterly/11256.html</link>
		<description><![CDATA[假设有一张白纸，单面可以写n个字，并且两面都可以写字。
现在提出下面要求：
1、只能在空白的地方写字。
2、只能在向上的那一面上写字。
3、一面写完后，可以通过折叠使没有写字的那一面部分向上。
4、挨着桌子的那一面永远不能有字。
最后，请问这张纸最多可以写多少个字？]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2006-03-21 14:08:00</pubDate>
		</item>
				<item>
		<title><![CDATA[一个关于继承和虚函数的问题]]></title>
		<link>http://blog.pfan.cn/ainterly/8732.html</link>
		<description><![CDATA[首先，看一下这几行简单的代码：
class&nbsp; A
{
int&nbsp; a;
public:
A(int aa):a(aa){};
void funa(){ a++;};
};
class B:public A
{
int b;
public:
B(int aa,int bb):A(aa),b(bb){};
virtual void funb()=0;//pure virtual function
};
class C
{
int c;
public:
C(int cc):c(cc){};
virtual void func()=0;
};
A a(1);//应该正确
C c(1);//应该错误
B&nbsp; b(1,2);//对不对呢？
在C++语言中，拥有纯虚函数的类成为抽象类，该类不能实例化一个对象，必须在进一步继承中实现该函数，然后用派生类定义对象。那么，现在的问题是，基类为非抽象类，从他继承来的类是不是非抽象类呢？如果该继承类有纯虚函数，又属于抽象类还是非抽象类呢？还是先测试一下上面代码，看看结果：
第一次测试：（使用VC++6.0）
int main(int argc, char* argv[]){&nbsp;A a(1);&nbsp;C c(1);&nbsp;B b(1,2);}
看看结果：
F:\work2000\ddd\ddd.cpp(29) : error C2259: 'C' : cannot instantiate abstract class due to following members:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F:\work2000\ddd\ddd.cpp(20) : see declaration of 'C'F:\work2000\ddd\ddd.cpp(29) : warning C4259: 'void __thiscall C::func(void)' : pure virtual function was not defined&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F:\work2000\ddd\ddd.cpp(24) : see declar]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-23 11:53:00</pubDate>
		</item>
				<item>
		<title><![CDATA[Pointers, handles, and null]]></title>
		<link>http://blog.pfan.cn/ainterly/8202.html</link>
		<description><![CDATA[Standard C++ supports pointer types and null pointer constants. C++/CLI adds handle types and null values. 20To help integrate handles, and to have a universal null, C++/CLI defines the keyword nullptr. This 21keyword represents a literal having the null type. nullptr is referred to as the null value constant. (No 22instances of the null type can ever be created, and the only way to obtain a null value constant is via this 23keyword.) 24The definition of null pointer constant (which Standard C++ requires to be a compile-time expression that 25evaluates to zero) has been extended to include nullptr. The null value constant can be implicitly 26converted to any pointer or handle type, in which case it becomes a null pointer value or null value, 27respectively. This allows nullptr to be used in relational, equality, conditional, and assignment 28expressions, among others. 29Object^ obj1 = nullptr; // handle obj1 has the null value 30String^ str1 = nullptr; // handle str1 has the null value]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-14 15:25:00</pubDate>
		</item>
				<item>
		<title><![CDATA[The Common Language Runtime]]></title>
		<link>http://blog.pfan.cn/ainterly/7989.html</link>
		<description><![CDATA[COM led to a lot of great software and some very useful systems over the years. However, during its lifespan, the problems we just discussed emerged time and again (and we haven’t even mentioned the problems with DCOM). The initial impetus behind COM was the question “How can we compose already-compiled binary software that was developed using different languages and tools?” The answer was “Build reliable, predictable bridges between separate components.” COM concentrated on a well-established boundary—the one between the client and the object. COM makes sure the boundary is well-defined and named so there’s no ambiguity between the client and the object.
It eventually became evident that the boundary between the client and the object didn’t necessarily have to exist at all. What if a runtime environment were available that dissolved the boundary between the client and the object? That’s what the common language runtime is all about—erasing the boundaries between components. The commo]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-08 11:05:00</pubDate>
		</item>
				<item>
		<title><![CDATA[关于读书]]></title>
		<link>http://blog.pfan.cn/ainterly/7988.html</link>
		<description><![CDATA[今天突发奇想，其实也算不上什么奇想了，为什么我不把自己每天学习的资料和看过的书籍文章都一起发上来，一方面可以给自己一些充实感；另一方面，也可以在以后适当的时候回过头来查找方便；当然也可以给自己以后留作纪念，或者给其他人留作参考。
呵呵，不错的想法，就从今天开始吧。]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-08 11:04:00</pubDate>
		</item>
				<item>
		<title><![CDATA[Pure C++]]></title>
		<link>http://blog.pfan.cn/ainterly/7919.html</link>
		<description><![CDATA[Visual Studio&reg; 2005 brings the type parameter model of generic programming to the Microsoft&reg; .NET Framework. C++/CLI supports two type parameter mechanisms—common language runtime (CLR) generics and C++ templates. In my last column, I looked at the characteristics that these two mechanisms have in common (see Pure C++: Generic Programming Under .NET). In this column, I'll look at some of the differences—in particular, differences in the parameter list and type constraint model.Parameter List Redux
The parameter list works like the signature of a function: it identifies the number and kind of each parameter, and associates a unique identifier with each one so that each parameter can be uniquely referred to within the template definition.
The parameter serves as a placeholder within the definition of the template or generic type. The user creates object instances of the type by providing actual values to bind to the parameters. The instantiation of a parameterized type is not a]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-07 10:38:00</pubDate>
		</item>
				<item>
		<title><![CDATA[使用 Visual C++ 2005 的现代语言功能编写更快的代码(4)]]></title>
		<link>http://blog.pfan.cn/ainterly/7918.html</link>
		<description><![CDATA[安全性
在 2002 年，Bill Gates 发出了可信任计算 (Trustworthy Computing) 倡议，这对 Microsoft 开发的所有产品都有着不可小视的冲击力。Windows 操作系统的开发人员在安全性培训和代码评审上花费了几个月的时间，这使得 Windows Server 2003 成为该公司曾经发布过的安全性最高的一个操作系统。Microsoft Office 2003 还包含了许多安全功能，例如 Information Rights Management (IRM)、更好的宏安全性和在 Outlook 中阻止 HTML 下载等等。而编译器小组也在大踏步地使他们开发的编译器及其生成的代码变得更安全。
Visual Studio .NET 2002 引入了缓冲区安全检查 /GS 编译器选项。这一标志将导致编译器在决定为有缓冲区溢出攻击嫌疑的函数返回地址之前就预先在堆栈上分配空间。在函数进入时，一个带有已知计算值的安全 Cookie 会被放在这个缓冲区中，而在函数退出时，编译器会对其进行检查，以确保该 Cookie 没有被破坏。对 Cookie 值的更改意味着有重写返回地址的可能性，而这会产生一个错误并导致应用程序终止。
当然，这并不能防止所有的缓冲区溢出攻击。Visual Studio .NET 2003 还增强了 /GS 功能。它通过对堆栈上的局部变量进行排序来将数组分配在高于其余局部变量的内存地址上，从而防止这些局部变量造成溢出。这样会阻止基于 vtable 入侵的攻击和其他基于指针的攻击。

图 7 原来的 /GS

Visual C++ 2005 对这一强大的功能进行了又一次升级。当进行函数调用时，函数的激活记录按照如图 7 所示的方式放置。如果一个局部缓冲区发生了溢出，黑客就有可能重写其堆栈上的所有内容，其中包括异常处理函数记录、安全 cookie、帧指针、返回地址，以及函数的参数。这些值中的大多数都是通过各种机制保护的（例如安全异常处理)，然而，在一个以函数指针作为参数的函数中，利用缓冲区溢出仍有可能。如果一个函数将函数指针（或者一个包含函数指针的结构或类）作为参数，黑客就可能会重写这一指针的值，并使代码执行任何他/她想要运行的函数。为了防止这一点，Visual C++ 2005 编译器会分析所有的函数参数来防止这]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-07 10:32:00</pubDate>
		</item>
				<item>
		<title><![CDATA[使用 Visual C++ 2005 的现代语言功能编写更快的代码(3)]]></title>
		<link>http://blog.pfan.cn/ainterly/7916.html</link>
		<description><![CDATA[在 Visual Studio .NET 2003 中，C++ Interop 技术被称为 IJW 或“正常运行 (It Just Works)”。在即将推出的版本中，这被改为一个更具描述性的名称“Interop 技术”。那么，它是如何“正常运行”的呢？对于每个由应用程序使用的本机方法而言，编译器同时创建了一个托管的入口点和一个非托管的入口点。它们中的一个是实际的方法实现，而另外一个是转发 thunk，它创建适当的转换并进行任何必要的封送处理。托管入口点几乎总是实际的方法实现，唯一的例外是该方法的代码无法用 MSIL 表示或者开发人员使用“#pragma unmanaged”编译器指令来强制要求将入口点实现为本机代码。
当使用一个 IJW 转发 thunk 时（例如，当本机入口点是转发 thunk 时），编译器提供 thunk 的实现，并通过一个偏移量或导入地址表（Import Address Table，IAT）跳转来调入实际的实现。IJW thunk 的合理时间大约在 50 到 300 个周期之间，不过，精心设计的测试用例可以使这个数字减至 10 那么小。当转发 thunk 是 MSIL 时，托管的 P/Invoke 就会派上用场。P/Invoke 仅包含一个声明而没有实际的方法实现；CLR 提供了对 thunk 的运行时支持的功能。这些转发 thunks 通常都会比同等的本机实现稍微慢一点点。
如上所述，使用 IJW 使每个函数都有两个入口点，一个托管的接口和一个非托管的接口。但某些构造需要这些入口点的调用地点在编译时进行填充（例如函数指针和 vtable）。而如果编译器在编译时无法知道运行时调用地点的托管状态，则它应该选择哪一个入口点呢？在 Visual Studio .NET 2003 中，编译器总是会选择非托管入口点。当然，如果调用方确实是托管的，则上述做法就会造成一些麻烦，这称为 Double P/Invoke 问题，如图 4 所示。在这种情形下，托管调用对非托管 thunk 进行的转换刚好又转换回托管代码，这样的操作会导致几个大的不必要的开销。

图 4 Double P/Invoke 问题

Visual C++ 2005 提出了几个解决方案。第一个方案就是使用 __clrcall 关键字，通过这个关键字，可以指定是否基于每个方法发出非]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-07 10:31:00</pubDate>
		</item>
				<item>
		<title><![CDATA[使用 Visual C++ 2005 的现代语言功能编写更快的代码(2)]]></title>
		<link>http://blog.pfan.cn/ainterly/7914.html</link>
		<description><![CDATA[Interop 选择
在 Visual Studio .NET 2003 的所有基于 .NET 框架的语言中，Visual C++ 7.1 提供了最好的 interop 功能。它具有实现实际的 interop 方案所必需的功能，Quake II 到 .NET 框架的移植便是例证，具体细节请访问http://www.vertigosoftware.com/Quake2.htm。Visual C++ 2005 进一步扩展了这一功能。
在托管与本机环境中，使用 .NET Interop 有四种主要途径：COM interop 可以使用 Runtime Callable Wrappers (RCW) 与 COM Callable Wrappers (CCW) 来实现。.通用语言运行库 (CLR) 负责类型封送（除非在极少的情况下使用自定义封送拆收器），并且这些调用的开销很大。您需要非常小心地尽量避免接口往来过于频繁，否则就会出现很严重的性能问题。您还需要保证这些包装一直与其底层的组件保持一致。也就是说，在您因简单的 Interop 场景而试图使用大量的本机 COM 代码时，COM Interop 非常有用。
第二种 Interop 选择是使用 P/Invoke。要达到此目的，可以使用 DLLImport 属性，并且在方法声明中为您想要导入的函数指定属性。封送是按照它在声明中的指定方式来处理的。然而，只有在您有代码需要通过 DLL 导出公开必需的功能时，DLLImport 才是有用的。
当您需要从本机代码调用托管代码时，CLR 宿主也是一种选择。在这种情况下，本机应用程序必须驱动所有的执行：设置主机、绑定到运行库、启动主机、检索适当的 AppDomain、设置调用上下文、查找所需的程序集和类，并调用所需类上的操作。在控制发生什么以及何时发生方面，这无疑是最健壮的解决方案之一，但这也会带来让人难以置信的枯燥，并需要许多自定义代码。
第四种选择，也有可能是最简单并最可行的选择，就是使用 C++ 的 Interop 功能。通过设置 /clr 开关，编译器会生成 MSIL 而不是本机代码。唯一被生成为本机代码的是那些无法被编译成 MSIL 的代码，其中包括带有内联 asm 块的函数，以及使用像 Streaming SIMD Extensions (SSE) 这样一些特定于]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-07 10:29:00</pubDate>
		</item>
				<item>
		<title><![CDATA[使用 Visual C++ 2005 的现代语言功能编写更快的代码(1)]]></title>
		<link>http://blog.pfan.cn/ainterly/7913.html</link>
		<description><![CDATA[Stephen Toub 
本文基于 Microsoft Visual Studio 2005 的预发布版本，它以前的代号为“Whidbey”。此处所包含的任何信息都可能会变更。 
本文讨论：



&#8226;

.NET C++/CLI 语法

&#8226;

Interop 技术

&#8226;

配置文件指导的优化

&#8226;

MSIL 优化

&#8226;

OpenMP 支持

&#8226;

增强的缓冲区安全检查
本文使用了以下技术：
Visual C++ .NET 2003 和 Visual C++ 2005


对于 C++ 语言的爱好者来说，Visual Studio .NET 2003 中 C++ 编译器的引入绝对令人垂涎欲滴。Visual C++ .NET 2003 中有 98% 的部分与 ISO C++ 标准保持一致，这使它比以往任何版本更为靠近这些标准，而且它还加入了对一些功能（如局部模板专用化）的语言支持。它还包括增强的缓冲区安全检查和改进的编译器诊断功能。C++ 开发人员就像 C# 和 Visual Basic .NET 开发人员一样，可以使用拖放窗体设计器来构建健壮的 Windows 窗体应用程序。该编译器还包含了针对 Intel Pentium 4 和 AMD Athlon 处理器的优化。
如果您对 Visual C++ .NET 2003 感到兴奋不已，您将会疯狂地爱上它的下一个版本 Visual C++ 2005。Visual C++ 2005 为 .NET开发提供了既优雅又强大的新语法支持。它使用的新优化技术已经使 Microsoft 产品的运行速度提高了 30%。它通过新的编译模式来确保 Microsoft .NET 框架通用语言基础结构（Common Language Infrastructure，CIL）的一致性和可验证性，并且具有新的 interop 模型，这不仅提供了本机和托管环境的无缝合并，而且还在跨这些边界的情况下提供了完全控制。该编译器增强了前两个版本中提供的缓冲区安全检查选项，并且还包括了 C++ 应用程序普遍使用的以安全性为中心的的库的新版本。它提供了对 OpenMP 标准以及 64 位平台（其中包括 Intel I]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-12-07 10:28:00</pubDate>
		</item>
				<item>
		<title><![CDATA[关于韩国申请端午]]></title>
		<link>http://blog.pfan.cn/ainterly/7388.html</link>
		<description><![CDATA[先看下面一则新闻吧：　
北京晚报消息：由韩国申报的江陵端午祭巴黎时间24日被联合国教科文组织正式确定为“人类传说及无形遗产著作”。一度沸沸扬扬的中韩端午节“申遗”之争以韩国的胜利而告终,对此,今天上午专家在接受记者采访时称:无形遗产属于全人类共享,韩国申报成功并非坏事。 　　据韩国联合通讯今天报道,韩国驻联合国教科文组织代表称,由18名专家组成的联合国教科文组织国际审查委员团21日至24日在巴黎的联合国教科文组织举行审查委员会,并在江陵端午祭等64个申报遗产中选定43个为“人类传说及无形遗产著作”。据悉,“人类传说及无形遗产著作”宣布制度是在认识到无形遗产在人类历史上所占价值和保存必要性后,联合国教科文组织于2001年实行的制度。此次也是联合国教科文组织第三批宣布无形遗产名单。 　　“韩国申遗成功对我们的端午文化不会有什么冲击,无形文化遗产是全人类共享的财富,我们的文化传统被别国认同,我个人认为不是一件坏事,”中国民俗学会理事长、中国社会科学院研究员刘魁立上午在接受记者采访时表示。刘教授介绍,联合国教科文组织对无形遗产申报的要求是每个国家每两年才能申报一项,中国急需保护的无形遗产很多,所以才导致此次韩国抢先申报。 　　“江陵端午祭其实与我们的端午节不是一回事。”中国民俗学会秘书长、北大教授高丙中在接受记者采访时介绍,韩国的端午祭实际上是由舞蹈、萨满祭祀、民间艺术展示等内容构成,这与中国人吃粽子、划龙舟、纪念屈原是两回事,“惟一的相同点是时间框架,都是在中国的端午节期间举行。”高教授表示,韩国申遗成功实际上给我们带来了很好的启示:他们把传统的文化活动注入了现代的元素,成功地实现了现代转型,并得到了国际认同，对于中国文化遗产的保护有借鉴意义。 　　围绕着端午节申遗之争，从去年开始至今，在中国学术界和民间都产生了极大的反响。(记者丁肇文) 
用什么来形容我现在的心情呢？是失望，气氛，怨恨，无奈……都无法尽情的描述，能做的就是将这一股怨恨化成文字，散播于网上，与华夏文化的拥护者共同纪念着一个让人失望的日子，期待能焕发起我们的民族自尊心，在未来的日子里更加努力！
我们并不能责怪韩国的做法，因为人家做的只是自己该做的事情，维护着自己的文化，只不过占用了本该是属于我们的名字，而现在我们深深地明白端午是我们，若干年以后，当端午成为世界认同的名词之后，还会不会记得最初出现端午的]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-11-25 21:28:00</pubDate>
		</item>
				<item>
		<title><![CDATA[Linux安装之经验心得]]></title>
		<link>http://blog.pfan.cn/ainterly/6984.html</link>
		<description><![CDATA[这三天创造了我个人历史上的一个记录——三天安装了八次操作系统！三次linux和五次windows Xp,在其中遇到了很多挫折，最主要的就是分区，最后终于安装成功！
第一次、
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、分区，C: &nbsp; 20（FAT32)、D:&nbsp;&nbsp; 10（NTFS)、E:&nbsp; &nbsp;10（NTFS）、F:&nbsp;&nbsp; 15（NTFS)、G: 5（FAT32)、H: 20(FAT32),可能我的划分有些奇特，为了满足自己的需要嘛，吾见笑。之所以这样分区，是以为Linux和windows采用的是同样的文件格式，并以为最后留两个FAT32的分区，可以用来交换数据，呵呵，想的美！这种想法有很大的问题！
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、安转系统，将windows Xp安装到D盘（扩展分区），一切正常。
第二次、
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、安装Linux,本来以为和Windows安装差不多，想着选个C盘就可以了。进入安装界面，前几步一切顺利，到选择分区时，首先采用手动，无奈，不管怎么搞都是提示挂载点出错，无奈，退回上一步，选择自动分区，此处有三项可选，可是只有格式化整个硬盘的那个可以继续下去，思考再三，为了C++编程，为了Linux，继续。终于，linux安装完成，可是遗憾的是，windows Xp再也找不到了！
第三次、
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、不爽，在这年头，以我的情况，没有Windows还真的很难生活。所以，只能再来一次了，重新安装windows Xp.首先用魔术分区在linux自动分区的硬盘上划分出50G的空间来为Xp服务，然后进入安装过程，选择安装的分区，windows Xp在复制完文件重新启动后，竟然直接显示disk error,无法引导，晕，无奈，有些不知所措，
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5、既然已经出]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-11-15 10:47:00</pubDate>
		</item>
				<item>
		<title><![CDATA[为应用程序添加闪屏（splash)功能]]></title>
		<link>http://blog.pfan.cn/ainterly/6588.html</link>
		<description><![CDATA[创建一个启动窗口，用来显示应用程序的相关信息
为了使该启动窗口再最早时刻被显示，启动窗口最好的位置可以放到InitInstance()中。
步骤：
1、创建一个从CWnd派生的启动窗口类,为方便可以用Class wizard
2、为该类添加Create()成员函数，用来显示相关信息。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CSplashWnd::Create(UINT nID)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_bitmap.LoadBitmapEx(nID,FALSE);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //make the window at center
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int x=(::GetSysytemMetrics(SM_CYSCREEN)-mbitmap.m_Width)/2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int y=(::GetSystemMetrics(SM_CYSCREEN)-m_bitmap.m_Height)/2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRect rect(x,y,x+m_bitmap.m_Width,y+m_bitmap.m_Height);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateEx(0,AfxRegisterWndClass&nbsp; ,0),"",
&nbsp;&nbsp;]]></description>
		<author><![CDATA[freemyself]]></author>
		<pubDate>2005-11-03 10:26:00</pubDate>
		</item>
		</channel>
</rss>