DLL导出非模态对话框一闪而过是怎么回事呢?

pigpy 2008-07-25 09:36:36
我使用shared MFC DLL导出一个对话框,当使用模态对话框时OK,可是使用非模态对话框时对话框一闪而过(使用EXE程序调用),代码如下:
extern "C" __declspec(dllexport) void ShowLoginDlg(void)
{
HINSTANCE save_Instance=AfxGetResourceHandle(); //保存当前句柄
AfxSetResourceHandle(theApp.m_hInstance);

//模态对话框方式==========这种方式调用OK
/*CLoginDlg loginDlg;
loginDlg.DoModal();
*/

//非模态对话框方式
CLoginDlg *ploginDlg=new CLoginDlg();
ploginDlg->Create(IDD_DIALOG_LOGIN);
ploginDlg->ShowWindow(SW_SHOW);

AfxSetResourceHandle(save_Instance); //恢复句柄
}

希望高手能够指点迷津~~
...全文
594 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuyouzi299 2011-04-12
  • 打赏
  • 举报
回复
smqingk
pigpy 2008-07-26
  • 打赏
  • 举报
回复
SetedMode我给出了三个取值,0,1,2,分别去这三个值时会将对话框caption修改为对应的mode,比如SetedMode=0时,对话框caption为“Demo environment”,然后在OnInitDialog()中根据不同的SetedMode值连接不同的数据库。
现在的问题是:SetedMode的值根本没有被改变,对话框标题还是出事标题“System Login”,而且连接数据库时出现“Unkonwn error”,后边是以串字符。
主要是调用的那个GetLoginMode(int setMode);函数没有起作用。我也试过直接修改SetedMode的值,比如:pLoginDlg->SetedMode=mode;pLoginDlg->UpdateData(FALSE);但是也没有任何作用。
cnzdgs 2008-07-26
  • 打赏
  • 举报
回复
现在是出现什么样的错误?
对话框中是如何根据SetedMode来执行不同操作的?
pigpy 2008-07-26
  • 打赏
  • 举报
回复
不行啊,去掉以后还是不行。
SetedMode是选择用户登录模式,我在EXE对话框上用了三个单选按钮用于选择用户登录模式,用户选择以后就把选择的int值传递给SetedMode,DLL对话框中会根据不同的SetedMode值做不同的操作。
另外,我在DLL对话框的OnCancle()方法中直接调用DestroyWindow();为什么一直有错呢??
cnzdgs 2008-07-26
  • 打赏
  • 举报
回复
ploginDlg->ShowWindow(SW_NORMAL);
这行去掉。
另外,SetedMode有何作用?
pigpy 2008-07-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cnzdgs 的回复:]
创建非模态对话框后要有消息循环。如果程序已有主窗口,在窗口的消息响应函数中创建非模态对话框,创建后直接返回就可以,因为这种情况下是使用CWinThread类的消息循环;如果不使用CWinThread类的消息循环,可以自己写消息循环代码,参考MSDN中的代码:

MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit …
[/Quote]
我添加了消息循环以后,窗口一闪而过的问题解决了。现在又有了新的问题:
我想在EXE中传递一个数据给DLL,使用模态对话框可以,现在使用非模态对话框又不行了。代码很简单,我在DLL中添加了一个函数GetLoginMode(int setMode);当导出DLL非模态对话框时,代码如下:
extern "C" __declspec(dllexport) void ShowLoginDlg(int mode)
{
HINSTANCE save_Instance=AfxGetResourceHandle(); //保存当前句柄
AfxSetResourceHandle(theApp.m_hInstance);
// LoginMode=mode;
/*============================调试用代码=====================
if(mode==1||mode==2)
{
CLoginDlg LoginDlg;
LoginDlg.DoModal();
}
if(mode==3)
{
AfxMessageBox(_T("Engineering Mode"));
}
*/
//使用模态对话框
/*CLoginDlg loginDlg;
loginDlg.GetLoginMode(mode);
loginDlg.DoModal();
*/

//使用非模态对话框
CLoginDlg *ploginDlg=new CLoginDlg();
ploginDlg->Create(IDD_DIALOG_LOGIN,NULL);
ploginDlg->GetLoginMode(mode);
ploginDlg->ShowWindow(SW_NORMAL);
HWND hDlgModeless=ploginDlg->GetSafeHwnd();
ploginDlg->ShowWindow(SW_SHOW);

//消息循环
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
if(hDlgModeless==0 || !IsDialogMessage(hDlgModeless,&msg))
{
if(msg.hwnd==hDlgModeless)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}

AfxSetResourceHandle(save_Instance); //恢复句柄
}
消息传递函数GetLoginMode(int setMode)代码如下:
void CLoginDlg::GetLoginMode(int setMode)
{
SetedMode=setMode;
}
其中,SetedMode是一个CLoginDlg类的公共成员变量。
现在又不知道这么回事了,希望cnzdgs兄或者其他高手帮帮我吧。谢谢~~~
cnzdgs 2008-07-26
  • 打赏
  • 举报
回复
如果要delete this,要重载PostNcDestroy函数来执行。你的代码可以在消息循环的下面delete this。
pigpy 2008-07-26
  • 打赏
  • 举报
回复
哎,照您的方法还是没有解决,不知道怎么回事了。
我的调用顺序:
ShowMainDlg();
DestroyWindow();
这样可以正确调用,但如果把两个位置换一下,就不行了。
WM_DESTROY消息OnDestroy()
void CLoginDlg::OnDestroy()
{
CDialog::DestroyWindow();

PostQuitMessage(1);
delete this;
}
cnzdgs 2008-07-26
  • 打赏
  • 举报
回复
先DestroyWindow,相应WM_DESTROY消息PostQuitMessage。
pigpy 2008-07-26
  • 打赏
  • 举报
回复
先给您加分吧,这个问题还希望您帮我解决一下哦~~
pigpy 2008-07-26
  • 打赏
  • 举报
回复
果然如此。非常感谢,这个问题终于解决了。
还有最后一个问题:我调用了CLoginDlg后需要用户输入用户名和密码,当密码验证成功后需要调用另外一个DLL,而当前的对话框需要销毁,我在OnOK()函数中进行密码验证,验证成功后先调用MainDlg()(这是一个使用模态对话框的DLL)再使用PostQuitMessage(1);退出消息循环,调用DestroyWindow();销毁窗口。调用时没什么问题,可是当我关闭MainDlg后会出现一个“程序出现异常,将会被关闭”的消息框。就不知道怎么回事了。
我估计可能是退出消息循环和销毁窗口的时间不太对,可是我把代码加到调用MainDlg之前根本就不能运行了。
不知道这又是怎么回事呢?
不好意思一直打扰你哈~~~
cnzdgs 2008-07-26
  • 打赏
  • 举报
回复
原来是这样啊。把GetLoginMode放到Create之前,因为你是要在创建对话框的时候使用SetedMode,如果放到Create之后就没有作用了。
xiaojing7 2008-07-25
  • 打赏
  • 举报
回复
up
cnzdgs 2008-07-25
  • 打赏
  • 举报
回复
GetMessage的参数hWnd应改为NULL。
cnzdgs 2008-07-25
  • 打赏
  • 举报
回复
创建非模态对话框后要有消息循环。如果程序已有主窗口,在窗口的消息响应函数中创建非模态对话框,创建后直接返回就可以,因为这种情况下是使用CWinThread类的消息循环;如果不使用CWinThread类的消息循环,可以自己写消息循环代码,参考MSDN中的代码:

MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

另外需要自己响应窗口关闭消息,调用DestroyWindow销毁窗口,并PostQuitMessage使消息循环退出。
pigpy 2008-07-25
  • 打赏
  • 举报
回复
高手帮我解决一下吧,50点相送。谢谢~~

7,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧