VC 如何定义一个类,可以处理消息,而且有 HWND 的?最好有 MFC 与 WTL 的方法? VC 如何定义一个类,可以处理消息,而且有 HWND 的?最好有 MFC 与 WTL 的方法?本人初学,还不会,谢谢指教 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 《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/Librarymodules:下填写对 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 #defineDLLCLASS_API__declspec(dllexport) //导出一个类(包括其方法、属性) classDLLCLASS_APICDllClass { public: CDllClass(void); voidMSG(constchar*conststr); }; 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"); 对于处理HWND或传HWND,可以这样:两种方法(不知是否对您的问题理解有偏差): 1、在创建窗口的时候使用SetWindowLong将HANDLE的值设置到窗口相关的GWL_USERDATA中保存,在窗口过程函数中使用GetWindowLong取出和该HWND相关的HANDLE值。 2、建立一个HANDLE和HWND对应的关系表,在窗口过程函数中通过HWND查找到对应的HANDLE。 哪位用过Google的 Glog,如何设置输出日志输出目录和日志名称 关于MFC工程名和文件名的修改 单文档视图窗口句柄获得方法,高手请指教 求救:MessageBox 不弹出对话框 使自己的软件支持光驱刻录的一个方法 对话框程序能不能这样做?添加框类和视类 我要定义一个BOOL型的全局变量,在我程序的每个类中都可以使用要怎么定义 MFC画的动态图形怎样设置让它停下来? VC如何将串口中的数据存入access中 菜鸟问题,如何用程序移动控件的焦点(vc) 傅立叶反变换 关于GetActiveFrame()的问题
如何在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/Librarymodules:下填写对 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
#defineDLLCLASS_API__declspec(dllexport)
//导出一个类(包括其方法、属性)
classDLLCLASS_APICDllClass
{
public:
CDllClass(void);
voidMSG(constchar*conststr);
};
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");
两种方法(不知是否对您的问题理解有偏差):
1、在创建窗口的时候使用SetWindowLong将HANDLE的值设置到窗口相关的GWL_USERDATA中保存,在窗口过程函数中使用GetWindowLong取出和该HWND相关的HANDLE值。
2、建立一个HANDLE和HWND对应的关系表,在窗口过程函数中通过HWND查找到对应的HANDLE。