VC 如何定义一个类,可以处理消息,而且有 HWND 的?最好有 MFC 与 WTL 的方法?本人初学,还不会,谢谢指教

解决方案 »

  1.   

    《com本质论》第一章有讲到,你可以好好看看,这里也可以大概说一下,你要能处理消息的,一般是导出窗口类,大同小异: 关于导出类   
        
      如何在VC中导出类,下面以一个简单的例子来说明这个问题:     
        
      首先使用Wizard创建一个Win32   Dynamic-Link   Library工程,然后定义一个简单的C++类CInDLL。由于该类会被工程之外的文件所引用,所以需要对这个类进行引出。因为只有引出后所生成的DLL中才带有供足够的信息以在连接和运行时被正确引入到进程空间中。有两种方法可以引出类,使用__declspec(dllexport)定义和使用定义文件。     
        
      下面先讲使用__declspec(dllexport)的方法:将类定义改为:class   __declspec(dllexport)   CInDLL   就可以了。(译者:你也许不相信会有这么简单,我也不相信。:-)   这样产生的工程在编译时是正确的但是在使用时会产生错误,因为你包含的头文件中也是使用__declspec(dllexport),而使用这个DLL的工程中并没有引出这个类,而是需要引入这个类)在使用时需要将类定义改为class   __declspec(dllimport)   CInDLL就可以了。     
        
      使用定义文件可以有效的避免这个问题,这种方法是利用宏定义在不同的地方产生不同的编译代码:在头文件中加入如下的代码:   
        
      #ifdef   _CLASSINDLL   
            #define   CLASSINDLL_CLASS_DECL           __declspec(dllexport)   
      #else   
            #define   CLASSINDLL_CLASS_DECL           __declspec(dllimport)   
      #endif   
        
      #endif   //   ClassInDLL_H   
      //将class   __declspec(dllexport)   CInDLL改为   
      class   CLASSINDLL_CLASS_DECL   CInDLL   
      {   
      CInDLL();   
      ...   
      }   
        
      在实现这个类的CPP文件的顶部加入#define   _CLASSINDLL语句。     
      #define   _CLASSINDLL   
      CInDLL::CInDLL()   
      {   
      }   
      ...   
        
      这样一来在使用这个类时就可以不做任何改动了。DownLoad   Demo   Source   
        
      (注意:这种方法在没有使用MFC时可以使用,如果你使用MFC生成MFC   DLL那么只要做如下定义就可以了class   AFX_EXT_CLASS   yourClass)   
        
      -----------------------------------------------------------------------   
      要输出整个的类,对类使用_declspec(_dllexpot);要输出类的成员函数,则对该函数使用_declspec(_dllexport)。如:   
        
      class   AFX_EXT_CLASS   CTextDoc   :   public   CDocument   
      {   
      …   
      }   
        
      extern   "C"   AFX_EXT_API   void   WINAPI   InitMYDLL();   
        
        
      新建两个工程,其中一个是dll工程(我的示例程序中这个工程名为DllClass),另一个是测试和使用dll的工程(名字为DllClassTest)   
        
         
      注意点:   
      1.   Dll工程编译完成后,将.lib和.dll文件拷贝到测试和使用dll的工程的适当目录下(我的程序是release目录),然后将Dll工程中的导出类的头文件(以下简称头文件)拷贝到测试和使用dll的工程的适当目录下(在我的程序中是拷贝到此工程文件所在目录),然后把这个拷贝过来的头文件通过下面2和3进行修改。   
        
      2.   在Dll工程中的头文件使用的是   #define   DLLCLASS_API   __declspec(dllexport)   表示导出   
      在测试和使用dll的工程中的头文件使用的是   #define   DLLCLASS_API   __declspec(dllimport)   表示导入   
        
      3.   不论Dll工程的头文件如何实现(比如说包括内联函数等等),在测试和使用dll的工程中的头文件中全部都是声明而没有定义(即将类成员函数的实现部分去掉)   
        
      4。在测试和使用dll的工程的那个文件中包含对dll库的引入,分两步:   
        
      首先在是测试和使用dll的工程的setting菜单(按ALT+F7可以调出)中的LINK选项卡中的Object/Librarymodules:下填写对   dll   的连接,比如dll文件名字为DllClass.lib和DllClass.dll,则填写   ../Release/DllClass.lib(注意目录,我的程序中.lib文件是在目录release下)。   
      然后,添加对头文件的包含,比如dll文件名字为DllClass.lib和DllClass.dll,头文件为DllClass.h,则包含头文件为   #include   "DllClass.h"   
         
      由此,就可以使用了。   
        
      相关源码如下:   
        
      dll工程中的DllClass.h   内容:   
        
      //此处在dll的头文件中为   dllexport,在应用文件中为dllimport   
        
      #defineDLLCLASS_API__declspec(dllexport)   
        
      //导出一个类(包括其方法、属性)   
      classDLLCLASS_APICDllClass   
      {   
      public:   
      CDllClass(void);   
      voidMSG(constchar*conststr);   
      };   
        
      dll工程中的DllClass.cpp内容:   
      #include"stdafx.h"   
      #include"DllClass.h"   
        
      BOOL   APIENTRY   DllMain(HANDLE   hModule,DWORD   ul_reason_for_call,LPVOID   lpReserved)   
      {   
      switch(ul_reason_for_call)   
       {   
       case   DLL_PROCESS_ATTACH:   
       case   DLL_THREAD_ATTACH:   
       case   DLL_THREAD_DETACH:   
       case   DLL_PROCESS_DETACH:   
       break;   
      }   
      return   TRUE;   
      }   
        
        
      CDllClass::CDllClass()   
      {   
       return;   
      }   
        
      void   CDllClass::MSG(const   char*   const   str)   
      {   
      MessageBox(NULL,str,"",MB_OK);   
      }   
        
      Dll测试工程中的DllClass.h内容:   
        
      //此处在dll的头文件中为   dllexport,在应用文件中为dllimport   
      #define   DLLCLASS_API   __declspec(dllimport)   
        
      //导出一个类(包括其方法、属性)   
      class   DLLCLASS_API   CDllClass   
      {   
      public:   
       CDllClass(void);   
       void   MSG(const   char*   const   str);   
      };   
      Dll测试工程中DllClassTest.cpp内容:   
      首部:   
      #include   "DllClass.h"   
      class   DllClass;   
        
      代码部分:   
      CDllClass   CTest;   
      CTest.MSG("this   is   a   string   into   dll");
      

  2.   

    对于处理HWND或传HWND,可以这样:
    两种方法(不知是否对您的问题理解有偏差):   
      1、在创建窗口的时候使用SetWindowLong将HANDLE的值设置到窗口相关的GWL_USERDATA中保存,在窗口过程函数中使用GetWindowLong取出和该HWND相关的HANDLE值。   
      2、建立一个HANDLE和HWND对应的关系表,在窗口过程函数中通过HWND查找到对应的HANDLE。