我使用dll做了个子界面,就是个简单的测试功能,在上面显示了个静态框,其中导出了三个函数
//主要用来在主界面的一个静态框中显示这个子界面
extern "C" __declspec(dllexport) void Show(CRect rc)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
/*CTest test;
test.Create (IDD_DIALOG1);
test.ShowWindow(SW_SHOW);*/
//test.DoModal();
m_test.Create(IDD_DIALOG1);
m_test.ShowWindow(SW_SHOW);
m_test.MoveWindow(rc);
}
//销毁这个子界面
extern "C" __declspec(dllexport) void Rel()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_test.DestroyWindow();
}//对这个子界面进行一个判断
extern "C" __declspec(dllexport) HWND Dec()
{
HWND hwnd;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
hwnd = m_test.GetSafeHwnd();
return hwnd;
}我的主界面做的是一个CTreeCtrl 类,但点击一个叶子节点的时候显示这个子界面,开始的时候我是直接在主程序中创建了一个子界面,一切正常
然后我将子见面的函数换成dll中的创建函数,具体代码如下:
在CTreeCtrl的消息处理函数OnTvnSelchangedTree1(主要是响应其中TVN_SELCHANGED消息)中
typedef void (WINAPI * CCDDLL)(CRect rc);
HINSTANCE hmod;
hmod = ::LoadLibrary ("ChildDlg.dll");
if(hmod==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL lpproc;
lpproc = (CCDDLL)GetProcAddress (hmod,"Show");
if(lpproc==(CCDDLL)NULL)
{
MessageBox("lpproc is error");
}
typedef HWND (WINAPI * CCDDLL2)();
HINSTANCE hmod2;
hmod2 = ::LoadLibrary ("ChildDlg.dll");
if(hmod2==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL2 reoroc;
reoroc = (CCDDLL2)GetProcAddress(hmod,"Rel");
if(reoroc==(CCDDLL2)NULL)
{
MessageBox("reoroc is error");
}
typedef HWND (WINAPI * CCDDLL1)();
HINSTANCE hmod1;
hmod1 = ::LoadLibrary ("ChildDlg.dll");
if(hmod1==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL1 decroc;
decroc = (CCDDLL1)GetProcAddress(hmod,"Dec");
if(decroc==(CCDDLL1)NULL)
{
MessageBox("decroc is error");
}
HWND Cchd = decroc();
然后在switch/case的部分
if (!IsWindow(Cchd))//判断现在子界面的窗口是否为子窗口
{
(*lpproc) (rc);
}
......//深绿部分为如果但前窗口不是子窗口,则关闭现有窗口,
运行的时候弹出储物Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.问中断、继续,我中断了一下,发现错误出现在(*lpproc) (rc);语句后一次,OnTvnSelchangedTree1函数后一次,然后才能显示界面,这是怎么回事呀,我查了一下说是调用错误,可是我有点看不懂那个调用的情况,想请高手指点一下
//主要用来在主界面的一个静态框中显示这个子界面
extern "C" __declspec(dllexport) void Show(CRect rc)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
/*CTest test;
test.Create (IDD_DIALOG1);
test.ShowWindow(SW_SHOW);*/
//test.DoModal();
m_test.Create(IDD_DIALOG1);
m_test.ShowWindow(SW_SHOW);
m_test.MoveWindow(rc);
}
//销毁这个子界面
extern "C" __declspec(dllexport) void Rel()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_test.DestroyWindow();
}//对这个子界面进行一个判断
extern "C" __declspec(dllexport) HWND Dec()
{
HWND hwnd;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
hwnd = m_test.GetSafeHwnd();
return hwnd;
}我的主界面做的是一个CTreeCtrl 类,但点击一个叶子节点的时候显示这个子界面,开始的时候我是直接在主程序中创建了一个子界面,一切正常
然后我将子见面的函数换成dll中的创建函数,具体代码如下:
在CTreeCtrl的消息处理函数OnTvnSelchangedTree1(主要是响应其中TVN_SELCHANGED消息)中
typedef void (WINAPI * CCDDLL)(CRect rc);
HINSTANCE hmod;
hmod = ::LoadLibrary ("ChildDlg.dll");
if(hmod==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL lpproc;
lpproc = (CCDDLL)GetProcAddress (hmod,"Show");
if(lpproc==(CCDDLL)NULL)
{
MessageBox("lpproc is error");
}
typedef HWND (WINAPI * CCDDLL2)();
HINSTANCE hmod2;
hmod2 = ::LoadLibrary ("ChildDlg.dll");
if(hmod2==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL2 reoroc;
reoroc = (CCDDLL2)GetProcAddress(hmod,"Rel");
if(reoroc==(CCDDLL2)NULL)
{
MessageBox("reoroc is error");
}
typedef HWND (WINAPI * CCDDLL1)();
HINSTANCE hmod1;
hmod1 = ::LoadLibrary ("ChildDlg.dll");
if(hmod1==NULL)
{
AfxMessageBox("Fail");
}
CCDDLL1 decroc;
decroc = (CCDDLL1)GetProcAddress(hmod,"Dec");
if(decroc==(CCDDLL1)NULL)
{
MessageBox("decroc is error");
}
HWND Cchd = decroc();
然后在switch/case的部分
if (!IsWindow(Cchd))//判断现在子界面的窗口是否为子窗口
{
(*lpproc) (rc);
}
......//深绿部分为如果但前窗口不是子窗口,则关闭现有窗口,
运行的时候弹出储物Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.问中断、继续,我中断了一下,发现错误出现在(*lpproc) (rc);语句后一次,OnTvnSelchangedTree1函数后一次,然后才能显示界面,这是怎么回事呀,我查了一下说是调用错误,可是我有点看不懂那个调用的情况,想请高手指点一下
{
g_pDlg = new CTestDlg();
g_pDlg->Create...
g_pDlg->ShowWindow..
g_pDlg->UpdateWindow..
}void HideDlg()
{
if(g_pDlg != NULL)
{
delete pDlg;
}
}
//判断IDs是哪个界面
switch(IDs)
{
case 01:
如果当前不是dlg1,则创建并显示
if (!IsWindow(dlg1.GetSafeHwnd()))
{
dlg1.Create(IDD_MAIN_DIALOG2,this);
dlg1.ShowWindow(SW_SHOW);
dlg1.MoveWindow(rc);
}
//如果当前界面是dlg2,关闭dlg2
if (IsWindow(dlg2.GetSafeHwnd()))
{
dlg2.DestroyWindow();
}
...
如上,我想问下,在dll调用子对话框的时候使用前帖中的代码可以吗?
还有hmod1,hmod2,hmod什么时候FreeLibrary才对呀
可以 extern "C" __stdcall也可以extern "C" __declsc
VC默认的是__declsc,所以只写extern "C"的话就不是WINAPI