关于 CDialog::CreateIndirect,高手帮忙,谢谢!

gudyn 2009-09-21 05:24:15
使用 CreateIndirect 创建非模态对框,只有一个LPCDLGTEMPLATE类型变量
我的创建方式是:CreateIndirect(m_lpDialogTemplate, pParentWnd); pParentWnd是父窗口指针,没有指定第三个参数 :lpDialogInit 因为我的程序中无法获得这个值(不知道能不能只直接通过m_lpDialogTemplate获得?)。
我创建非模态对话框成功了,能够正常显示。但是窗口中有一个按钮控件,只要一点按钮整个窗口就没有反应了,也无法调到相应的单击事件处理函数,请问这是怎么回事儿?

...全文
678 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
MoXiaoRab 2009-12-15
  • 打赏
  • 举报
回复
CDialog的Create会调用CreateIndirect弄出窗口,但是创建消息循环不在其中的

范例

BOOL CCTestDlg::Create(CWnd* pParentWnd, LPCTSTR lpszTemplateName)
{
ASSERT(HIWORD(lpszTemplateName) == 0 ||
AfxIsValidString(lpszTemplateName));

m_lpszTemplateName = lpszTemplateName; // used for help
if (HIWORD(m_lpszTemplateName) == 0 && m_nIDHelp == 0)
m_nIDHelp = LOWORD((DWORD)m_lpszTemplateName);

#ifdef _DEBUG
if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE))
{
ASSERT(FALSE); // invalid dialog template name
PostNcDestroy(); // cleanup if Create fails too soon
return FALSE;
}
#endif //_DEBUG

HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);
HGLOBAL hTemplate = LoadResource(hInst, hResource);


// BOOL bResult = CreateIndirect(hTemplate, pParentWnd, hInst);
// write own CreateIndirect
ASSERT(hTemplate != NULL);

LPCDLGTEMPLATE lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hTemplate);
// BOOL bResult = CreateIndirect(lpDialogTemplate, pParentWnd, NULL, hInst);
ASSERT(lpDialogTemplate != NULL);

if (pParentWnd == NULL)
pParentWnd = AfxGetMainWnd();
m_lpDialogInit = NULL;

AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState);
CreateDlgIndirect(lpDialogTemplate, pParentWnd, hInst);

UnlockResource(hTemplate);

FreeResource(hTemplate);
// ASSERT(pParentWnd != NULL);
ASSERT(lpszTemplateName != NULL);



return TRUE;
}


你还是用Create创建好了
wutaihua 2009-12-15
  • 打赏
  • 举报
回复
mark/
gudyn 2009-09-23
  • 打赏
  • 举报
回复
按钮不是我有代码创建的。是用资源编辑器加上去的。
gudyn 2009-09-23
  • 打赏
  • 举报
回复
大概的代码是这样的:
Hook 第一个参数为UINT类型CDialog::Create函数
BOOL CDialogEx::MyCreateByID(UINT nIDTemplate, CWnd* pParentWnd )
{
///////////////////////////////////////////////////////////////////////////
//这部分加载XML文件中的资源 创建dialog template,会保存在m_lpDialogTemplate中
CResourceMgrImpl* pResource = CResourceMgrImpl::GetInstance();
ASSERT(pResource);
HRESULT hr = pResource->LoadDialogDirect(nIDTemplate, this);

if (hr == S_OK) m_lpszTemplateName = ATL_MAKEINTRESOURCE(nIDTemplate);
///////////////////////////////////////////////////////////////////////////

BOOL ret = (this->*oldCreateByID)(hr == S_OK? 0 : nIDTemplate, pParentWnd);
if(hr == S_OK)
SetTemplate(NULL);
return FALSE;
}
Hook 第一个参数为字符串类型CDialog::Create函数
BOOL CDialogEx::MyCreateByName(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
{
///////////////////////////////////////////////////////////////////////////
//这部分加载XML文件中的资源 创建dialog template,会保存在m_lpDialogTemplate中
BOOL bInXml = FALSE;
if(!lpszTemplateName)
{
bInXml = TRUE;
lpszTemplateName = m_lpszTemplateName;
}

HRESULT hr = S_FALSE;
if(lpszTemplateName)
{
CResourceMgrImpl* pResource = CResourceMgrImpl::GetInstance();
ASSERT(pResource);
hr = pResource->LoadDialogDirect(lpszTemplateName, this);
}
///////////////////////////////////////////////////////////////////////////
BOOL ret = FALSE;
if (bInXml)
{
ret = CreateIndirect(m_lpDialogTemplate, pParentWnd);
//ret =(this->*oldCreateByName)(lpszTemplateName, pParentWnd);
//SendMessage(WM_INITDIALOG, NULL, NULL);
}
else
ret =(this->*oldCreateByName)(lpszTemplateName, pParentWnd);
if(hr == S_OK)
SetTemplate(NULL);
return ret;
}
在创建的时候调用m_Dialog.Create(IDD_DIALOG1, pParentWnd);
创建成功了,窗口可以正确显示,消息函数也指定了,但是一点按钮窗口就没有反应了。帮忙看看,谢谢!
gudyn 2009-09-22
  • 打赏
  • 举报
回复
那篇文章不能解决我的问题。他使用的是InitModalIndirect 创建模式对话框,创建模式对话框时只要m_lpDialogTemplate值是正确的那么DoModal就会成功,但是非模式对话框要使用Create函数,好像不太一样。仅仅是m_lpDialogTemplate的值是正确的好像不行。比如说重载CDialog如果将m_lpDialogTemplate设置正确,然后调用domodal就可以了,但是调用Create函数却不行。 我是这么理解的,也不知道对不对,再帮帮忙,谢谢。
gudyn 2009-09-22
  • 打赏
  • 举报
回复
谢谢。刚来上网,我的cdit值设置了,我的代码很多,没法往出贴,我并不是只是调用create创建对话框的,中间还有Hook Create函数的部分,相关的东西太多了。我先看一下你给我的这篇文章。谢谢!
Ghost90 2009-09-22
  • 打赏
  • 举报
回复
1。DLGTEMPLATE::cdit(控件项数目)。设置了吗?
2.看看这篇文章 http://www.vckbase.com/document/viewdoc/?id=1524
3.你的代码贴出来

gudyn 2009-09-22
  • 打赏
  • 举报
回复
高手帮帮忙,谢谢了。
oyljerry 2009-09-22
  • 打赏
  • 举报
回复
按钮如何创建的,是否创建成功,消息响应是否建立
gudyn 2009-09-22
  • 打赏
  • 举报
回复
不是Create不行,ShowWindow也调用了,我的窗口已经正确显示了,但是只要一点窗口中的按钮就出问题了。
Ghost90 2009-09-22
  • 打赏
  • 举报
回复
Create不行?调用 ShowWindow(SW_SHOW);了吗?
  • 打赏
  • 举报
回复
halleluia007 2009-09-21
  • 打赏
  • 举报
回复
一般不用CreateIndirect,用create
wuflyer 2009-09-21
  • 打赏
  • 举报
回复
你那太麻烦了吧。我创建无模对话框有更简单的。我把代码贴出来。楼主给分哦。我弄了好久。也是刚学会的,你看对你有用不,以下是代码:
CPIDSET * dlg; //CPIDSET型指针对象dlg
dlg = new CPIDSET; // 创建dlg并分配内存
dlg->Create(IDD_PIDSET,this); //创建dlg对象
dlg->ShowWindow(SW_SHOW); //显示dlg无模对话框
fishion 2009-09-21
  • 打赏
  • 举报
回复
所以想问你那个对话框有消息处理函数体没
gudyn 2009-09-21
  • 打赏
  • 举报
回复
这样不行,这样创建出来之后,可以显示,但是上面的按钮不能响应事件,而且一点整个窗口就没有反应了,只能通过结束任务来结束程序了。
fishion 2009-09-21
  • 打赏
  • 举报
回复
直接用CreateIndirect(m_lpDialogTemplate)怎么样了?
还有就是你是这样用CMyDlg m_Dlg;
m_Dlg.CreateIndirect(m_lpDialogTemplate),这样用的吗
gudyn 2009-09-21
  • 打赏
  • 举报
回复
up
gudyn 2009-09-21
  • 打赏
  • 举报
回复
因为我的资源不是以普通的方式在资源文件中的。而是通过解析字符串生成的Dialog Template,所以不能通过create创建。
fishion 2009-09-21
  • 打赏
  • 举报
回复
创建非模态对话框我都一般是用Create,没用过这个
加载更多回复(1)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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