高分!困扰总专家分1w+的csdner的一个很难的问题!关于Windows消息及doc&view问题。高手请进!

gameboy999 2004-01-05 10:27:09
我为这个已经头疼了很多天了。

在MFC向导中,如果你用SDI/MDI生成一个程序,会有doctemplate,document,view和Frame,这个时候可以用ON_COMMAND宏来定制菜单或工具栏消息,可以用ON_COMMAND_UPDATE_UI来定制菜单和工具栏的状态.


我查过很多资料,发现 ON_COMMAND_UPDATE_UI消息是 SDI/MDI app在onIDLE的情况下发送给各个按钮之类的,也就是说Update消息并不是主动发出,而是app在空闲的情况下发送给按钮要求更新的。

然而,问题就出现了!
当我使用默认的SDI/MDI生成文件,当然可以随意使用UPDATE消息宏来定制我的程序,并且,哪怕我不使用SDI/MDI,只要我的App中默认使用frame作为app的m_pMainWnd,再生成我的view之类的,工具栏等一样可以用ON_COMMAND_UPDATE_UI宏来定制消息。

但是!!
如果我修改一下程序,例如改成app先启动一个dialog,然后点击dialog的某个按钮或者菜单再启动这个frame,怪事就发生了,ON_COMMAND消息宏仍然有效,但是ON_COMMAND_UPDATE_UI宏却失效了,frame上面的toolbar和菜单不能响应view里面设置的宏了!!


我重载了app的OnCmdMsg函数让其先访问frame的OnCmdMsg以及修改dialog的OnCmdMsg函数,到后来甚至跟踪到pretranslatemsg,仍然查不到是怎么回事!view定制的Update宏就像没有发生过一样,在庞大的doc&view架构里面消失的无影无踪。



我对docview架构的一些细节实在是有点搞不清楚,请各位大虾指点一下迷津,这个问题已经困扰我很多很多天了!!谢谢啦,200分奉上!
...全文
57 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
gameboy999 2004-01-05
  • 打赏
  • 举报
回复
to 虫子! 我实现了!!多亏你的提示,分全给你


我原来是dialog的domodal!所以死活不行,现在我用create,showwindow,让app启动它的消息泵,然后就成功了!!
BOOL CtesthtmleditctrlApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControls()。否则,将无法创建窗口。
InitCommonControls();

CWinApp::InitInstance();

AfxEnableControlContainer();

// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

CtesthtmleditctrlDlg * dlg;
dlg = new CtesthtmleditctrlDlg();
dlg->Create(IDD_TESTHTMLEDITCTRL_DIALOG);
m_pMainWnd = dlg;
dlg->ShowWindow(SW_SHOW);
dlg->UpdateWindow();

/*
INT_PTR nResponse = dlg.DoModal();
*/
/*
CTestFrame * m_pFrame = new CTestFrame();
RECT r;
r.left = 100;
r.top = 100;
r.right = 400;
r.bottom = 500;
m_pFrame->Create(NULL, "Simple MFC App" );
m_pMainWnd = m_pFrame;
m_pFrame->ShowWindow(TRUE);
m_pFrame->UpdateWindow();
*/


// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return TRUE;
}
gameboy999 2004-01-05
  • 打赏
  • 举报
回复
哦!使用dialog的时候,是不会启动app的消息泵吧?

app。。。
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
kof99th 2004-01-05
  • 打赏
  • 举报
回复
应该重载对话框的WindowProc,把消息路由到frame的WindowProc试试,应该可以的
kof99th 2004-01-05
  • 打赏
  • 举报
回复
OnCmdMsg不相应WM_IDLEUPDATECMDUI的,具体怎么作我还在查。
gameboy999 2004-01-05
  • 打赏
  • 举报
回复
正常的程序(只列出关键部分,其他部分都没有修改过,基本上是向导自动生成

app...
BOOL CtesthtmleditctrlApp::InitInstance()
{
InitCommonControls();
CWinApp::InitInstance();
AfxEnableControlContainer();
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CTestFrame * m_pFrame = new CTestFrame();
RECT r;
r.left = 100;
r.top = 100;
r.right = 400;
r.bottom = 500;
m_pFrame->Create(NULL, "Simple MFC App" );
m_pMainWnd = m_pFrame;
m_pFrame->ShowWindow(TRUE);
m_pFrame->UpdateWindow();
return TRUE;
}

frame...
BOOL CTestFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
CCreateContext context;
pContext = &context;
// Assign custom view.
pContext->m_pNewViewClass = RUNTIME_CLASS(CMyHtmlEditView);
// Create the view.
pview = (CMyHtmlEditView *) CreateView(pContext, AFX_IDW_PANE_FIRST);
if (pview == NULL)
return FALSE;
SetActiveView(pview, FALSE);
return TRUE;
}
view...(我用的是CHtmlEditView,和普通的ON_COMMAND_UPDATE_UI其实差不多)
BEGIN_DHTMLEDITING_CMDMAP(CMyHtmlEditView)
DHTMLEDITING_CMD_ENTRY_TYPE(ID_BUTTON32772, IDM_BOLD, AFX_UI_ELEMTYPE_CHECBOX)
DHTMLEDITING_CMD_ENTRY_TYPE(ID_BUTTON32779, IDM_JUSTIFYCENTER, AFX_UI_ELEMTYPE_CHECBOX)
DHTMLEDITING_CMD_ENTRY_TYPE(ID_BUTTON32773, IDM_ITALIC, AFX_UI_ELEMTYPE_CHECBOX)
DHTMLEDITING_CMD_ENTRY_TYPE(ID_BUTTON32774, IDM_UNDERLINE, AFX_UI_ELEMTYPE_CHECBOX)
END_DHTMLEDITING_CMDMAP()


效果正常。没有任何问题。




而修改过后
app... 修改dialog为默认启动
BOOL CtesthtmleditctrlApp::InitInstance()
{
InitCommonControls();
CWinApp::InitInstance();
AfxEnableControlContainer();

SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

CtesthtmleditctrlDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
/*
CTestFrame * m_pFrame = new CTestFrame();
RECT r;
r.left = 100;
r.top = 100;
r.right = 400;
r.bottom = 500;
m_pFrame->Create(NULL, "Simple MFC App" );
m_pMainWnd = m_pFrame;
m_pFrame->ShowWindow(TRUE);
m_pFrame->UpdateWindow();
*/
return FALSE;
}

dialog...
void CtesthtmleditctrlDlg::OnBnClickedButton1()
{
m_pFrame = new CTestFrame();
RECT r;
r.left = 100;
r.top = 100;
r.right = 400;
r.bottom = 500;
m_pFrame->Create(NULL, "Simple MFC App" );
m_pFrame->ShowWindow(TRUE);
m_pFrame->UpdateWindow();
}

BOOL CtesthtmleditctrlDlg::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
//这句加了和去掉效果一样没有
if(m_pFrame && m_pFrame->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
frame和view和以前写法一摸一样


gameboy999 2004-01-05
  • 打赏
  • 举报
回复
to 小虫:
难道WM_IDLEUPDATECMDUI消息并不在OnCmdMsg里面处理吗?
gameboy999 2004-01-05
  • 打赏
  • 举报
回复
to 小虫:
但是我在dialog的OnCmdMSG里面把消息发送给了pFrame,还是没有响应啊?

BOOL CtesthtmleditctrlDlg::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(pFrame && pFrame->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)
return TRUE;
return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
kof99th 2004-01-05
  • 打赏
  • 举报
回复
检查你的m_pMainWnd设的是不是frame。在idle中,mfc只发消息给主窗口以及它的子窗口。

一下是代码:
BOOL CWinThread::OnIdle(LONG lCount)
{
....
if (lCount <= 0)
{
// send WM_IDLEUPDATECMDUI to the main window
CWnd* pMainWnd = m_pMainWnd;
if (pMainWnd != NULL && pMainWnd->m_hWnd != NULL &&
pMainWnd->IsWindowVisible())
{
AfxCallWndProc(pMainWnd, pMainWnd->m_hWnd,
WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);
pMainWnd->SendMessageToDescendants(WM_IDLEUPDATECMDUI,
(WPARAM)TRUE, 0, TRUE, TRUE);
}
..........
}
gameboy999 2004-01-05
  • 打赏
  • 举报
回复
to lu_zi:
你有VS.net吗,我的例子都是vc7的
lu_zi 2004-01-05
  • 打赏
  • 举报
回复
能不能把例子贴上,或发mail到我的邮件中lu_zi@263.net

16,471

社区成员

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

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

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