??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久亚洲精品中文字幕 ,精品国产日韩久久亚洲,久久精品国产亚洲av瑜伽http://www.shnenglu.com/beautykingdom/category/7618.htmlzh-cnSat, 07 Feb 2009 18:27:27 GMTSat, 07 Feb 2009 18:27:27 GMT60在XP下用vc6调试ISAPI Project<转蝲加改?gt;http://www.shnenglu.com/beautykingdom/archive/2008/07/19/56620.htmlchatlerchatlerSat, 19 Jul 2008 10:24:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56620.htmlhttp://www.shnenglu.com/beautykingdom/comments/56620.htmlhttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56620.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/56620.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/56620.html关于ISAPI调试的文章,|上已经有很多。今天之所以还要写q篇文章Q原因有三:一是网上关于调? ISAPI的方法大多数都是在Win2KQ二是网上的例子虽然多,大部分都是{载,大部分作者自׃未亲自试q,q接把别h的东西粘贴过来,往往影响? |上搜烦又误g其他L{案的hQ三是网上的例子有些q不详细Q有些也不正,q样不但不能帮助解决问题Q还Ҏ把h带入歧途?br> 
  
 
    今天得了一点空Ԍ在这里详l写下ISAPI在Xp环境下的调试ҎQ希望初ơ接触到ISAPI的程序员们少一些郁闗?br> 
    首先我的操作pȝ环境是Microsoft Windows Xp Professional。我的编译环境是Virsual C++6.0。VC的补丁主要有SP6?br> 
接下来按照下面的步骤Q?br>1、IIS的目录(根目录、虚拟目录)q行U别改ؓ低(默认ZQ?br>控制面板->理工具->Internet信息服务。在默认站点上单d?>属?>ȝ录(标签Q?>应用E序保护(N)Q将?q)改ؓ?IISq程)。执行权限改?#8220;教本和可执行文g”?br>用同LҎ修改你新建的虚拟目录的运行别?br> 
2、修Ҏ地安全策略属?br>控制面板->理工具->本地安全{略->本地{略->用户权利指派?br>a? 扑ֈ“以操作系l方式操?#8221;Q双L者右键选属性,弹出对话框后Q点“d用户或组”按钮Q在输入文字区域中输入管理员帐户Q又UC用户Q,“查名 U?#8221;Q?#8220;定”d。比如我现在登陆的帐hGuyueQ?#8220;查帐?#8221;之后出现A7B4931A85554A0\GuyueQ? A7B4931A85554A0是我的计机名称QGuyue是当前登陆帐P是除Administrator之外的我的管理员帐户?#8220;定”d?br>b、找?#8220;允许计算机和用户帐户被信M便于委托”Q照a的方法添加管理员帐户?br>注:q里我没有加用户Q直接用的管理员用户?br> 
3、打开VC6.0Q不需要打开M工程?br>菜单栏[Build]->[Start Debug]->Attach To Process
N?#8220;Show System Process”Q找到inetinfo,按OK键添加到该进E?br>在菜单栏[Project]->[Settings]或者直接按快捷键Alt+F7?br>? 看到一个General和一个Debug标签Q选择Debug标签。Category下拉列中有两个选项QGeneral和Additional DLLsQ选择Additional DLLs。在Modules中加入你要调试的DLLQ勾选Try to locate others DLLsQ按OK定保存?br>
4、打开你的ISAPI工程中的一个CPP文gQ看能不能设|断点,如果不能Q按shift+F5键退试状态。进 入下一步。如果退Z后l[Build]->[Start Debug]->Attach To ProcessQ这个时候会提示Q该工程不包含Q何调试信息。如果能讄断点Q则直接q入W六步?br>注:q一步没有成功,无法attach to processQ点了按钮以后process listq是I的。我是用
msdev -p <process ID>生成的一个VC6环境Q在q行IE后会在异常抛Z|停止?br> 
5、打开你的ISAPI工程中,定你的~译状态ؓDebug状态,定你LinkQ输出)的DLL和你在第三步Modules中保存的DLL为同一个文件。Rebuild一下?br> 
6、菜单栏[Build]->[Start Debug]->Attach To Process
? ?#8220;Show System Process”Q找到inetinfo,按OK键附加到inetinfoq程。打开ISAPI工程中的一个CPP文gQ最好是E序的入口文Ӟ在程序的 入口处设|断点,比如我设|的是CIsapiWtExtension::InitInstance(...)和DWORD CIsapiWtExtension::HttpExtensionProc(...)E序一旦开始运行,马上可以在q里截获?br>注:既然步骤4里看不到process listQ断点设|自然也׃用了?
 
7、打开IEQ打开你调用该DLL的站点,发出IEhQVC应该׃在你讄断点的地Ҏ截到q个h对当前DLL的操作了?/font>
注:正如我在步骤4中讲到的那样Q程序在异常位置会停住,可以看到函数的调用顺序;再就是有个小trickQ可以加个ASSERT在异帔Rq位|,q样E序可以停止在那儿Q这样也可以用断点了?



chatler 2008-07-19 18:24 发表评论
]]>
仿真VC++提供的关键字__uuidof<?gt;http://www.shnenglu.com/beautykingdom/archive/2008/07/19/56604.htmlchatlerchatlerSat, 19 Jul 2008 08:01:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56604.htmlhttp://www.shnenglu.com/beautykingdom/comments/56604.htmlhttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56604.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/56604.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/56604.html
    class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Class;   
struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Interface;

void test()
{
CLSID clsid=__uuidof(Class);
IID iid=__uuidof(Interface);
...
}


  q比起你以前定义uuid的方法简单多了吧Q可惜,q样好用的东西,它只在VC++中提供。不q没有关p,我们q里介绍一个技巧,可以 让你在几乎所有C++~译器中都可以这h便的使用__uuidof。这里没有说是所有,是因为我们用了模板特化技术,可能存在一些比?#8220;古?#8221;? C++~译器,不支持该Ҏ?

  也许你已l迫不及待了。好Q让我们来看看:

    #include <string>   
#include <cassert>

inline STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz)
{
HRESULT hr;
GUID guid;
if (lpsz[0]=='{')
{
hr=CLSIDFromString(lpsz,&guid);
}
else
{
std::basic_string<OLECHAR> strGuid;
strGuid.append(1,'{');
strGuid.append(lpsz);
strGuid.append(1,'}');
hr = CLSIDFromString((LPOLESTR)strGuid.c_str(),&guid);
}
assert(hr==S_OK);
return guid;
}

template <class Class>
struct _UuidTraits {
};

#define _DEFINE_UUID(Class,uuid) \
template <> \
struct _UuidTraits<Class>{ \
static const GUID& Guid(){ \
static GUID guid=GUIDFromString(L## uuid); \
return guid; \
} \
}

#define __uuidof(Class) _UuidTraits<Class>::Guid()

#define DEFINE_CLSID(Class,guid) \
class Class; \
_DEFINE_UUID(Class,guid)

#define DEFINE_IID(Interface,iid) \
struct Interface; \
_DEFINE_UUID(Interface,iid)


  q样一来,已l模拟出一个__uuidof关键字。我们可以很方便q行uuid的定义。D例如下:
    void test()   
{
CLSID clsid=__uuidof(Class);
IID iid=__uuidof(Interface);
...
}  


  在VC++中,Z与其他编译器以相同的方式来进行uuid的定义,我们不直接用__declspec(uuid)Q而是也定义DEFINE_CLSID, DEFINE_IID宏:

    #define DEFINE_CLSID(Class,clsid)           \   
class __declspec(uuid(clsid)) Class

#define DEFINE_IID(Interface,iid) \
struct __declspec(uuid(iid)) Interface


  q样一来,我们已经在所有包含VC++在内的支持模板特化技术的~译器中Q提供了__uuidof关键字。通过它可以进一步简化你在C++语言中实现COMlg的代仗?

  附注Q关于本文用的C++模板的特化技术,详细请参阅C++文法斚w的书c,例如《C++ Primer》。其实这个技巧在C++标准库——STL中有一个专门的名字QtraitsQ萃取)Q你可以在很多介lSTL的书c中见到相关的介l?

  转注Q因׃后写的文章需要用到类似的技巧,因此先搬q来放这?/p>


chatler 2008-07-19 16:01 发表评论
]]>
更好C真VC++关键字__uuidofhttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56602.htmlchatlerchatlerSat, 19 Jul 2008 06:03:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56602.htmlhttp://www.shnenglu.com/beautykingdom/comments/56602.htmlhttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56602.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/56602.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/56602.htmlhttp://www.shnenglu.com/cexer/archive/2008/07/05/55419.html

世界上有个叫__uuidof的关键字。这是一个家L晓且其被q泛使用的关键字Q几乎可以说Q有COME序员的地方Q就有它 __uuidof的存在。其很好很强大的E度是h所p的,夸张一Ҏ喻:d它的COME序员,像失去了点火器的火,虽然可以人工点火Q但是不安全 且无效率?

  不过很多人ƈ不知道,q其实是一个编译器扩展关键字,提供了此关键字的仅VC一家别无它店。幸q的是,强大的C++让我们能够轻易仿真出q个关键字的大部分功能?

  |上能够扑ֈ一U仿真的ҎQ见许式?《仿真VC++提供的关键字__uuidof?/a>。该Ҏ的实现是Q特化模板类的成员函敎ͼ然后q行时调用函数根据UUID字符串生出UUIDQ由于是生成于运行时Q所以它无可避免地有两个~点Q?

  • 存在q行时消耗?
  • 无法作ؓ非类型模板参C递给模板?

  那些整天着口水q求效率的C++E序员们Q是不能忍受M不必要的q行时消耗的。对于第二点QVC的关键字__uuidof取出来的UUID 是能够作为非cd模板参数传递的QATL中就大量C用了q样的参C递Ş式,所以目前的q种实现功能有限Q仿真度q不够高?

  其实只要能让它能够编译期军_UUID的|那么q两个问题就q刃而解了。而这是肯定可以实现的Qƈ且很单。我曄在自己写的一个COM库里实现q这LҎQ虽焉个库已经不知丢到哪里MQ不q那个方法还记得?

  解决的途径q是M开模板特化。类的成员包括成员函数和成员变量Q函数是q行时作用的Q然而static const的成员变量可以是~译期就军_。所以解决的Ҏ在眼前了:特化模板的成员变量?

  以下是我的实现方法?

  先定义一个类模板Q它有一个static const ,UUIDcd的成员变量:

    template<typename T>   
struct _uuid_of_impl
{
static const UUID id;
};
template<typename T>
const UUID _uuid_of_impl<T>::id=GUID_NULL;

  有了q个单的东西好办了Q只需要针Ҏ个接口特它的成员变量p了,如:

    template<>    
const UUID _uuid_of_impl<IUnknown>::id=IID_IUnknown;

template<>
const UUID _uuid_of_impl<IDispatch>::id=IID_IDispatch;


  然后我们可以这样取得接口的UUIDQ?/p>

    IID IunknownID=_uuid_of_impl<IUnknown>::id;   
IID IdispatchID=_uuid_of_impl<IDispatch>::id;


  作ؓ非类型模板参C递:

    template<const IID* t_iid>   
struct __uuid_of_test
{
__uuid_of_test()
{}

void test()
{
t_iid;
}
};

__uuid_of_test<&(_uuid_of_impl<IDispatch>::id) > obj;


  不过现在q种实现q有一些问题,看以下代码:

    IID ITypelibID=_uuid_of_impl<ITypeLib>::id;


  注意我们q没有事先对模板__uuid_of_impl特化ITypeLib的版本。但是以上语句却能够~译通过Q在q行Ӟ __uuid_of_impl<ITypeLib>的值将会是错误的值GUID_NULL。这是因为,我们定义模板的时候,同时在模板外定义 了模板的静态成员变量ƈ赋gؓGUID_NULLQ所以没有用特化的方法定义UUID的接口,都将使用GUID_NULLq个通用倹{这当然不是我们惌 的。所以我们想在没有定义UUID的时候让~译器警告我们,要达到这L效果只需要去掉上面那句:

    template<typename T>   
const UUID _uuid_of_impl<T>::id=GUID_NULL;


  现在再进行编译,~译器会告诉你,有一个无法解析的W号。根据编译器提供的相关信息,很容易就能确定问题所在。这栯够在~译期极大地减小安全隐患?

  最后加上我们定义的几个宏,q是最后的全部实现Q?/p>

    template<typename T>   
struct _uuid_of_impl
{
static const UUID id;
};

#define uuid_of(x) _uuid_of_impl<x>::id
#define DEFINE_UUID(x,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
template<> \
const UUID _uuid_of_impl<x>::id={l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}


  用以下代码测试通过Q?/p>

    struct ITest{};   

DEFINE_UUID(ITest,0x96289151,0xf059,0x4049,0x88,0x19,0x61,0xa6,0xe9,0x79,0xc,0xf1);

template<const IID* t_iid>
struct uuid_of_test
{
uuid_of_test(){}
};

int main()
{
IID xxxxID=uuid_of(ITest);
uuid_of_test<&(uuid_of(ITest))> obj;

return 0;
}


  需要注意的是DEFINE_UUID应该在实现文Ӟ*.cppQ?.cxxQ?#8230;…Q当中用。到q里Q仍有一些用方法与VC的关? 字是不一LQ所以仍没做C真度100%。不q我怿通过预处理元~程Q能够相当程度地D它,只是我对预处理元~程不是很了解,所以就不在q里献丑 了?/p>

chatler 2008-07-19 14:03 发表评论
]]>
C++~译期函?变量技术,仿真VC关键字__if_exists<?gt;http://www.shnenglu.com/beautykingdom/archive/2008/07/19/56601.htmlchatlerchatlerSat, 19 Jul 2008 05:50:00 GMThttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56601.htmlhttp://www.shnenglu.com/beautykingdom/comments/56601.htmlhttp://www.shnenglu.com/beautykingdom/archive/2008/07/19/56601.html#Feedback0http://www.shnenglu.com/beautykingdom/comments/commentRss/56601.htmlhttp://www.shnenglu.com/beautykingdom/services/trackbacks/56601.htmlhttp://www.shnenglu.com/cexer/archive/2008/07/06/55484.html

  VC当中有一个鲜Zh知的关键字,除了微Y自己的代码,我从未在M地方看到有h用过它。虽然它的功能很强大Q不q除非设计上的问题或是一些无法排除的困难Q否则几乎从不会需要用到它的功能。但是有时候,它确实能作ؓ一个最单的解决Ҏ而让某些设计q程事半功倍?

  借用 CCTV10《走q科学》的语气Q那么这个神U的关键关键字到底是什么呢Q它又实C什么神奇的功能呢?带着q一q串的疑问,让我们先来看一个具体的例子?/p>

  我在自己曄写的一个GUI框架当中Qؓ了实现消息与处理函数自动映射的,需要求助于q种功能。比如说有一个窗口类Q它包含若干消息处理函数和一个消息与处理函数的映?mapQ(h视当中的 show() ?create() 函数Q与主题无关Q?/p>

    class Window
{
typedef UINT _Message;
typedef LRESULT (Window::*_Handler)(_Message);

map<_Message,_Handler> m_handlerMap;

public:
bool show();
bool create();

public:
LRESULT onEvent( WindowEvent<WM_CREATE> );
LRESULT onEvent( WindowEvent<WM_DESTROY> );
};

  
  我需要利用模板元~程 ?0 ?WM_USER  q行循环,?Window cL否存在该消息对应的处理函数。如果消息对应的处理函数存在Q那么就消息与函数的映放q?m_handlerMap 当中。比如说消息 WM_CREATEQ我类 Window是否存在 LRESULT onEvent( WindowEvent<WM_CREATE> ) 成员函数Q在上例代码中是存在的,于是我将q样一个映放qm_handlerMapQ(真正实现的时候,q要考虑函数的类型。不同类型的函数Q是不能? 接装q?map 当中的。不q在q里h视例子当中涉及的所有类型{换,与主题无养I

    pair<WM_CREATE,&Window::onEvent>


  q样pC消息自动映射的目的。而不用像MFC一h写宏L。(最后通过努力的确辑ֈ了我的目的,我的GUI框架能够q行自动? 息映了Q然而可以预见,׃几千个(0QWM_USERQ@环,~译期的速度受到极大影响。所以最l我q是抛弃了这U自动映实玎ͼ而采用了更高效神? 的方法,q是后话也与本主题无兛_先不提)?/p>

  要实C上的自动映射功能引Zq样一个难题:如何~译期检类的某特定名字的成员是否存在?/p>

  功能不负有心人,l过爬山涉水d岭Q我l于?MSDN 一个偏q角落里扄了传说当中那个神U的关键字:__if_existsQ其实还有一?__if_not_existsQ。MSDN 当中q样说明Q__if_exists Q__if_not_existsQ允怽针对某符L存在与否条g性地执行语句。用语法:Q注意检的?#8220;存在?#8221;Q而不是|

    __if_exists ( /*你要存在性的函数或变量的名字*/ ) { 
 //做些有用的事
}


  MSDN当中的示例代码如?
    // the__if_exists_statement.cpp
// compile with: /EHsc
#include <iostream>

template<typename T>
class X : public T {
public:
void Dump() {
std::cout << "In X<T>::Dump()" << std::endl;

__if_exists(T::Dump) {
T::Dump();
}

__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};

class A {
public:
void Dump() {
std::cout << "In A::Dump()" << std::endl;
}
};

class B {};

bool g_bFlag = true;

class C {
public:
void f(int);
void f(double);
};

int main() {
X<A> x1;
X<B> x2;

x1.Dump();
x2.Dump();

__if_exists(::g_bFlag) {
std::cout << "g_bFlag = " << g_bFlag << std::endl;
}

__if_exists(C::f) {
std::cout << "C::f exists" << std::endl;
}

return 0;
}


  以上代码的输出如下:Q未试Q此输出为MSDN的说明文当中的Q?/p>

    In X<T>::Dump()
In A::Dump()
In X<T>::Dump()
T::Dump does not exist
g_bFlag = 1
C::f exists


  大概很少q这个关键字吧。虽然它们的功能与我的需求是如此的接q,但是面对如此强憾的关键字Q我q是只能摇头Ҏ。我伤心地在文 里看到说明,__if_existsQ__if_not_existsQ关键字用于函数的时候,只能Ҏ函数名字q行,而会忽略对参数列表的,? 此没有对重蝲函数的分辨能力,而正是我需要的。比如类 Window 有一个函敎ͼ

    LRESULT Window::onEvent( WindowEvent<WM_DESTROY> )
{
//做些有用的事
}


  我用以下代码来检?WM_CREATE 消息是否存在处理函数Q?/p>

    __if_exists(Window::onEvent)
  {
      //d消息映射
   }


  即 Window cd中不存在 LRESULT onEvent ( WindowEvent<WM_CREATE> )Q以上测试也能通过。这是因?__if_exists 关键字是不管函数重蝲的,如果存在一?onEvent Q那么所有的都能通过。这不是我想要的。我需要比 __if_exists 更强憄功能,强憾到能够针对不同参数列表的同名函数Q重载函敎ͼ做出正确的存在性测试?/p>

  于是我l翻p岭地LQ从 CSDN ?MSDNQ从 SourceForge ?CodeProject。要怿那句老话Q?#8220;有心人天不负”。最后我?CodeProject 上面看到一让我醍醐灌的文章Q?/p>

  Interface Detection by Alexandre Courpron

  q篇文章从原理到实现Q很详细地说明地一U编译期技术,先说明一下,׃VC7.1数千个bug当中的一个,以下技术不能在VC++7.1或更低版本上使用。具体的实现在那文章当中说得很详尽了,q是在这儿赘qC下?/p>

  Alexandre Courpron的实现方式基于C++的这样一个规则:Substitution Failure Is Not An Error Q简USFINAEQ。它的含义我也理解得比较含糊Q不q它作用于重载函数的时候,可以q样理解Q对于一个函数调用,在匹配函数的q程当中Q如果最l能? 有一个函数匹配成功,那么对其余函数的匚w如果p|Q编译器也不会视为错误。听h有些ȝQ看Alexandre Courpronl出的例子:

    struct Test 
{
typedef int Type;
};

template < typename T >
void f(typename T::Type) {} // definition #1

template<typename T>
void f(T){} // definition #2

f<Test>(10); //call #1

f<int>(10); //call #2

  
  对于 call#1 ~译器直接匹?definition#1 成功。对?call#2Q编译器先用 definition#1 匚w 如下Q?/p>

    void f( typename int::Type ) {}


  q显然是不正的。不q编译器q没有编译失败报告错误,因ؓ下面?definition#2 匚w成功Q根?SFINAE?规则Q编译器有权保持沉默 ?/p>

  虽然是个小的规则,在^时几乎不会注意它。然而在q儿Q我们却可以利用它实现编译期的强大功能了,一个最单的CZQ?/p>

    #include <iostream>
using namespace std;
//
struct TestClass
{
void testFun();
};

struct Exists { char x;};
struct NotExists { char x[2]; };

template <void (TestClass::*)()>
struct Param ;

template <class T>
Exists isExists( Param<&T::testFun>* );

template <class T>
NotExists isExists( ... );
//
int main()
{
cout<<sizeof(isExists<TestClass>(0))<<endl;
}


  上面的代码会输出 Q。说明一下检的q程Q?/p>

  1. ~译器遇?isExists<TestClass>(0) q一句,会去匚w isExists 的两个重载函数。不定长的参C先更低Q因此先匚wW一个函数?
  2. W一个函数参数类型ؓ Param<&T::testFun>*Q在q里?Param<&TestClass::testFun>Q编译器在匹配这个参数类型的时候会试实例化模板类 Param?
  3. ~? 译器试?&TestClass::testFun d例化 ParamQ因?TestClass 实存在一?void (TestClass::*)() cdQ且名ؓ testFun 的成员函数。所?Param 的实例化成功Q因此参数匹配成功?
  4. 匚wW一个函数成功。编译器军_ isExists<TestClass>(0) q一句调用就是调用的W一个函数?
  5. 因ؓW一个函数返回的cd?ExistsQ用 sizeof 取大就?1?

  如果是我们把 TestClass 的定义修改ؓQ(仅把函数的参数类型改?int Q?/p>

    struct TestClass
{
void testFun(int);
};


  q一ơ代码会输出 Q。因为在W3步的时候,׃ TestClass 没有cd?void (TestClass::*)()Q且名ؓ testFun 的函敎ͼ所以实例化 Param 会失败,因此匚wW一个函数失败。然后编译器d配第二个函数。因为其参数cd是Q意的Q自然会匚w成功。结果会输出 2?/p>

  当然q只是个最单的CZQ通过模板包装cR可以实现更灉|更强大的功能。比如回到那个自动消息映的例子Q用以下代码p够实CQ?/p>

//c++std
#include <iostream>
using namespace std;




//windows
#include <windows.h>



//detector
template<typename TWindow,UINT t_msg>
struct MessageHandlerDetector
{
typedef WindowEvent<t_msg> _Event;

struct Exists {char x;};
struct NotExists {char x[2];};

template<LRESULT (TWindow::*)(_Event)>
struct Param;

template<typename T>
static Exists detect( Param<&T::onEvent>* );

template<typename T>
static NotExists detect( ... );

public:
enum{isExists=sizeof(detect<TWindow>(0))==sizeof(Exists)};
};

//test classes
struct Window
{
LRESULT onEvent( WindowEvent<WM_CREATE> );
};

struct Button
{
LRESULT onEvent( WindowEvent<WM_DESTROY> );
};

//main
int main()
{
cout<<MessageHandlerDetector<Window,WM_CREATE>::isExists<<endl;
cout<<MessageHandlerDetector<Window,WM_DESTROY>::isExists<<endl;
cout<<MessageHandlerDetector<Button,WM_CREATE>::isExists<<endl;
cout<<MessageHandlerDetector<Button,WM_DESTROY>::isExists<<endl;

return 0;
}




  以上代码会输出:

    1
0
0
1


  以上的示例代码再加上模板元编E,可以很轻易地实现消息的自动映,具体实现q个已不在本贴的讨论范围q且q种自动映射的实玎ͼ太过复杂Q在~译期没有效率,且不够灵zR不q在消息映射机制上来_已称得上是一U革命性的试?/p>

  在说完了q所有一切之后,再告诉你一个我最q才知道的秘密(不准W我孤陋寡闻Q:其实 boost 库当中已有相兛_能的 MPL  工具存在Q叫?has_xxx?/p>

  源文Ӟ<boost\mpl\has_xxx.hpp>

  文档Q?a target="_blank">http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/refmanual/has-xxx-trait-def.html?/p>

chatler 2008-07-19 13:50 发表评论
]]>
޾Ʒ99þþþĻ| ƷþþþþþþþӰԺ | þó˹Ʒ| þ޴ɫĻþþ| þþƷ77777| 91Ʒ91þþþþ| ɫƾþþþþþۺ | 91Ʒ91þþþþ| ƷŮþþþavˬ | պþþþþ| ŷþۺŷ| þþƷһ99| 99þþƷѿһ | AVһȾþ| ھƷþþþþþcoent| þAAAƬ69| ݺɫۺϾþþþ| ɫþþۺ| ɫ͵͵91þۺ| ž99Ʒþþþþ| ƷëٸAVѾþ| 91Ʒպþò| 뾫Ʒþþþ..| Ժձһձþ | AëƬþþþƷëƬ| Ʒþþþù3d| 99þ99þþƷƬ| ŷһþ| þþžžƷ99Ʒ| 777ҹƷþav| þùֱ| ƷþþþĻһ| ɫۺϾþۺ| 91þþһȫ| ٸþĻ| ŷƷһþĻ| þav߳avav紵| þþ뾫Ʒҹ| þþ޾Ʒһ| ޾Ʒþò| þþƵ|