在vc下调试activex控件.出现了First-chance exception in xxx.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.异常.
实际上在vc下一般利用TSTCON32.EXE调试控件.目前我的程序底层封装成dll.留接口给ocx调用.这里在你按F5调式ocx的时候,一般会选择调试方式.选择TSTCON32.EXE去调试控件.
出现问题最终解决了,是我没有把动态库和ocx放在同一个目录下.导致ocx不能创建成功.
我总以为单步调试dll应该是在和工程的路径在同一个目录下,但是实际上的调试结果让我失望.vc把调试权利给了TSTCON32.EXE,因为编译ocx的时候就已经注册过了.TSTCON32.EXE调用ocx,启动ocx的时候,首先是到其ocx所在的目录去找这个动态库
以上是个人理解,不知道有没有偏差
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/luhuillll/archive/2009/07/07/4328248.aspx
如何调试和使用ActiveX控件。
由于控件并不能单独运行,所以你必须利用另一个程序来装载控件并进行调试,VC中提供了ActiveX容器供使用,在工程/设置菜单(project/setting)中选择Debug页并选择ActiveX Container。
然后开始调试,进入Container时VC会提示Container中是没有调试代码的错误,不用理会并继续。
进入Container后首先要装载你所需要调试的控件,选择菜单Edit/Insert OLE Control...,在弹出的对话框中选择你需要插入的控件。
如果Container 成功创建了控件在屏幕中就会显示出控件,根据上节的内容我们可以看到控件中显示了一串字符,接下来我们需要测试一下控件所提供的方法是否能够正确运行。请 选择菜单Edit/Invoke Methods...,在弹出的对话框上选择你要使用的方法,但你选择了方法后,对话框上的参数输入区会显示输入参数的列表,你输入参数后按下 Invoke按钮就可以执行。
在调试时你可以如同调试其他程序一样在代码中使用TRACE宏,也可以设置断点。
其实你在插入控件时会看见其他在系统中已经注册的控件,如果有兴趣可以自己试试加载几个看看效果。
如果要在VC 的工程中使用已经存在的ActiveX控件,最简单的方法就是利用VC的插入功能,在菜单中选择Project/Add To Project/Component and Control(在不同版本的VC中可能菜单位置不同),然后选择插入的控件,VC会为你生成这个控件的定义文件,当然和你最开始编写的会完全不一样,但 是没有关系。你会在定义文件看见这个控件所实现的方法和属性,这些都可以让你通过函数的方式进行调用。(所以在使用控件时如果没有该控件的说明是很难使用 的)
还有一种方法就是在对话框中插入一个控件。如果该控件的定义文件没有生成VC也可以帮助你生成。
在对话框中的控件是不需要手工创建的,但是如果你希望在其他地方创建窗口就需要调用控件的创建函数,其实这个函数很简单,和CWnd::Create函数定义的区别不大。定义为:
class CATLSam : public CWnd{BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE, BSTR bstrLicKey = NULL)。可以使用如下方式调用:
Create("window
text",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0,0,200,200),this,1001);
由于是CWnd的派生类所以CWnd的相关功能都可以使用。在程序中创建了控件窗口后就可以调用控件的各种方法(对属性的控制也是通过函数调用来实现的,在前面的教程中我们已经认识到这点)。
在控件创建后就可以使用控件的各种属性和方法,由于控件是你自己编写的所以调用起来应该不会有什么问题。
OCX 控件注册
在DOS 或Windows命令行下运行:regsvr32 ocxname.OCX 注册。
示例:
regsvr32 netshare.ocx //注册netshare.ocx控件
regsvr32 /u netshare.ocx //解除netshare.ocx控件的注册
如 果netshare.ocx文件不在system目录时,还必须在文件名前加上完整的路径。除了regsvr32应用程序之外,Microsoft在它的 Web站点上还提供了一个称为regclean.exe的程序,可以检查注册表并去掉丢失的组件在注册表中的条目。regclean.exe除了可以删除 “悬挂”的条目,它还提供一个“undo”文件帮助恢复错误的删除。
用regsvr32.exe注册ActiveX控件虽然简单,但需要 用户手工进行注册,在不用时还需手工解除注册。
方法二:用Install Shield,在里面选“Self-Registered”,安装程序将自动注册。
方法三:API函数注册
此方法的设计 思路是:先将ActiveX控件载入内存,然后验证其有效性,最后直接在内存地址中执行其注册函数(DllRegisterServer、 UnDllregisterServer)。其编程方法是:
1、使用Windows API函数LoadLibrary载入ActiveX控件;
2、使用GetProcAddress函数获取ActiveX控件中 注册函数DllRegisterServer(注销函数为DllUnregisterserver)指针;
3、使用CallWindowProc函数执行已载入内存的 ActiveX控件注册函数(DllRegisterServer、UnDllregisterServer)。
示例:
typedef int (CALLBACK* MYFUNCTION)(void);
MYFUNCTION MyFunction = NULL;
HINSTANCE handle = NULL ;
handle = LoadLibrary("TRDragDropTreeCtrl.ocx");
if( handle != NULL )
{
MyFunction = GetProcAddress(handle,"DllRegisterServer");
if( MyFunction != NULL )
{
MyFunction();
}
}
小 小经验:
1、有时候在程序中使用OCX控件时失 效,检查一下调用之间是否执行了AfxOleInit()。如果使用了容器,还需要保证执行了AfxEnableControlContainer()
2、使用ActiveX Control Test Container可以很方便地测试制作出来的OCX控件(从开始菜单->程序->Microsoft Visual Studio 6.0 -> Microsoft Visual Studio 6.0 tools可以看到该工具)
3、有时候控件制作的没有问题,注册方式也对,但是注册的时候确失 败了,可能时DLL的版本不对,使用Dependencies查看OCX控件依赖DLL是否跟现在使用的DLL版本一致
if (FAILED(OleInitialize(NULL)))
{
AfxMessageBox("OLE initialization failed.Make sure that the OLE libraries are the correct version.") ;
return FALSE ;
}
2.在需使用的对话框及程序开头处加入
#ifdef _WIN32
#define LOADLIBRARY_FAILED(x) (x == 0)
#else
#define LOADLIBRARY_FAILED(x) (x <= HINSTANCE_ERROR)
#endif
//定义函数地址
STDAPI DllRegisterServer(void) ;
STDAPI DllUnregisterServer(void) ;
typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)();
3. 定义注册函数
BOOL CNetMeetDlg::Register(CString strOcx) //strOcx为需注册的OCX名称
{
BOOL bResult = FALSE;
HMODULE hModule = ::LoadLibrary(strOcx) ;
if (LOADLIBRARY_FAILED(hModule)) return FALSE ;
//获得注册函数地址
CTLREGPROC DLLRegisterServer =
(CTLREGPROC)::GetProcAddress(hModule,"DllRegisterServer" ) ;
if (DLLRegisterServer != NULL)
{
HRESULT regResult = DLLRegisterServer() ;
bResult = (regResult == NOERROR) ;
}
::FreeLibrary(hModule) ;
return bResult;
}
4.在需注册的地方加入Register(“name.OCX”);