小弟正在开发一个供自己使用的辅助工具,是基于对话框的。上面使用了两个控件,一个是自己写的浏览二进制数据的控件,一个是继承了CTreeCtrl的一个树控件(内部想加一些自己的处理函数)。
现在想要解决的问题是:
1.想在两个控件之间互相发送消息给对方,对方收到消息后进行处理。但是我用自定义消息做了之后发现都无法接受到对方发送的消息。
2.我现在采取了折衷的方案,就是两个控件都给父窗口Dialog发消息,然后由dialog调用另一个控件的对象来做响应。
这两种设计我都采用的同样的方法来定义自定义消息,但是第一种不成功,第二种可以实现,但是第二种似乎封装性没有第一种好,所以还是想实现第一种方案,请教各位高手给予指点!!!小弟不胜感激!在此先谢过了!
现在想要解决的问题是:
1.想在两个控件之间互相发送消息给对方,对方收到消息后进行处理。但是我用自定义消息做了之后发现都无法接受到对方发送的消息。
2.我现在采取了折衷的方案,就是两个控件都给父窗口Dialog发消息,然后由dialog调用另一个控件的对象来做响应。
这两种设计我都采用的同样的方法来定义自定义消息,但是第一种不成功,第二种可以实现,但是第二种似乎封装性没有第一种好,所以还是想实现第一种方案,请教各位高手给予指点!!!小弟不胜感激!在此先谢过了!
解决方案 »
- 学习WINDOWS汇编遇到的几个问题???
- 项目之间的功能调用
- Worker Threads 和 User-interface Threads的区别是什么?
- 驱动开发资源收集
- 求助:对文件的复制和删除
- 一个include问题
- 大家来讨论一下类似对战平台之类的软件的原理吧!!
- 告诉我如何显示图片,百分送
- 有没有看Visual C++.NET技术内幕(第6版)这本书的,共同学习
- hook textouta textoutw drawtexta drawtextw extextouta extextoutw
- 有说明,写个函数,简单,马上给分,这个不够,另外再开一个给200,急哦!
- 请问CPropertySheet 是一个控件还是什么?
要想获得更好的效果,建议采用WTL写成COM组件
下面是实现中的部分代码:
// 定义消息
#define WM_NOTIFYDATAPOSITION WM_USER+100(CStructTree继承CTreeCtrl)
类CStructTree的.h文件
//{{AFX_MSG(CStructTree)
afx_msg LRESULT OnNotifyDataPos(WPARAM wParam,LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()类CStructTree的.cpp文件
BEGIN_MESSAGE_MAP(CStructTree, CTreeCtrl)
//{{AFX_MSG_MAP(CStructTree)
ON_MESSAGE(WM_NOTIFYTREEPOSITION, OnNotifyDataPos)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
LRESULT CStructTree::OnNotifyDataPos(WPARAM wParam,LPARAM lParam)
{
....
}
父窗口Dlg的.cpp文件,CSuperEditControl是自己写的一个类,m_ptSuperEdit取控件对应的类对象,在OnInitDialog里面把树控件的句柄传给
BOOL CMemoryReaderDlg::OnInitDialog()
{
CDialog::OnInitDialog(); m_ptSuperEdit= (CSuperEditControl *)GetDlgItem(IDC_MEMORY_SUPEREDIT);
m_ptTreeCtrl = (CStructTree *)GetDlgItem(IDC_STRUCT_TREE); // 将树控件的句柄传给自己写的控件m_ptSuperEdit
if(m_ptSuperEdit != NULL && m_ptTreeCtrl != NULL)
m_ptSuperEdit->SetMsgDestHand(m_ptTreeCtrl->m_hWnd);
return TRUE;
}自定义控件的.cpp文件,响应左键起来的消息,m_hTreeCtrlWnd保存传进来的树控件的句柄
void CSuperEditControl::OnLButtonUp(UINT nFlags, CPoint point)
{
....
::PostMessage(m_hTreeCtrlWnd,WM_NOTIFYDATAPOSITION,m_posStart,m_posEnd);
}
不知道实现方法对不对啊,我用这种方法向Dialog发消息是可以的,但是放到自己继承CTreeCtrl的类里就不行了,请大家指教问题所在!先谢过了!
有几个地方可以考察一下.
一是在PostMessage前::IsWindow(m_hTreeCtrlWnd),
二是看PostMessageBox的值是否为TRUE
1.我之前也左过对::IsWindow(m_hTreeCtrlWnd)的检查了,返回是1。
2.不好意思啊,你说的第二步我没看明白,我猜测是不是说::PostMessage()的返回值呢?我查了下,PostMessage不用等消息响应函数处理就返回了,而用SendMessage需要等消息响应函数处理后才返回是吧?我用PostMessage发消息返回为1,而用SendMessage发消息返回为0。To tomcat_jb:
不知道我理解的对不对啊,我用自己写的控件发消息后,要提交到它的pretranslatemessage这个函数来转发消息是吧!只要消息发送出去了,在pretranslatemessage函数里面就能收到该消息吧!
我的做法:我在里面判断ptMsg->message == 自定义消息宏,但是好像没有收到这个消息啊!感谢楼上大家的指教,但是问题还是没有解决啊,请问还可能是什么方面的问题啊!希望大家能帮帮小弟,再次谢谢啦!
//{{AFX_MSG_MAP(CStructTree)
ON_MESSAGE(WM_NOTIFYTREEPOSITION, OnNotifyDataPos)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()改为BEGIN_MESSAGE_MAP(CStructTree, CTreeCtrl)
//{{AFX_MSG_MAP(CStructTree)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_NOTIFYTREEPOSITION, OnNotifyDataPos)
END_MESSAGE_MAP()
1.我按照你的方法改动了一下,拿到了//}}AFX_MSG_MAP外面.
2.现在我采用了这样的方法,我在三个类的pretranslatemessage函数中都添加了对是否接受到WM_NOTIFYTREEPOSITION消息的判断,分别弹出提示框
类CSuperEditControl中:
BOOL CSuperEditControl::PreTranslateMessage( MSG* pMsg )
{
if(pMsg->message == WM_NOTIFYTREEPOSITION)
{
AfxMessageBox("Edit Ctrl Get Msg OK");
}
// CSuperEditControl这个类是继承CWnd写的一个类
return(CWnd::PreTranslateMessage(pMsg));
}父窗口Dlg中:
BOOL CMemoryReaderDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_NOTIFYTREEPOSITION)
{
AfxMessageBox("Dlg Get Msg OK");
}
return CDialog::PreTranslateMessage(pMsg);
}继承的树控件中:
BOOL CStructTree::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_NOTIFYTREEPOSITION)
{
AfxMessageBox("Tree Get Msg OK");
}
return CTreeCtrl::PreTranslateMessage(pMsg);
}3.然后在自定义的控件中发消息
void CSuperEditControl::OnLButtonUp(UINT nFlags, CPoint point)
{
CWnd::OnLButtonUp(nFlags, point);
BOOL flg = ::IsWindow(m_hTreeCtrlWnd); // 判断是成功的
flg = ::PostMessage(m_hTreeCtrlWnd,WM_NOTIFYTREEPOSITION,m_SelEnd,m_SelEnd);
//flg = ::SendMessage(m_hTreeCtrlWnd,WM_NOTIFYTREEPOSITION,m_SelEnd,m_SelEnd);
....
}结果是我在发消息的地方用PostMessage,返回1。结果只弹出Dlg中收到消息的box,在自定义控件和树控件中都不弹出MessageBox。
若我用SendMessage发消息,返回0。但是没有一个类弹出MessageBox表示接受到消息。
请问这应该怎么处理呢?
十分感谢tomcat_jb耐心的帮助和指导,同时也恳请各位高手不吝赐教啊,帮帮小弟!小弟感谢了!
m_ptSuperEdit= (CSuperEditControl *)GetDlgItem(IDC_MEMORY_SUPEREDIT);
m_ptTreeCtrl = (CStructTree *)GetDlgItem(IDC_STRUCT_TREE);直接在类向导里面定义控件的控制变量,类型选择为你自定义的类
Dlg::OnInitDialog()里面改为
if(::IsWindow(m_myTree.m_hWnd))
m_myEdit.SetMsgDestHand(m_myTree.m_hWnd);
其中
CmyEdit m_myEdit;
CmyTree m_myTree;
这样就OK了.
“我实验过了你的控制变量设置的有问题,不能用”
m_ptSuperEdit= (CSuperEditControl *)GetDlgItem(IDC_MEMORY_SUPEREDIT);
m_ptTreeCtrl = (CStructTree *)GetDlgItem(IDC_STRUCT_TREE);1.请问上面的操作不能取到控制变量吗?我以前也这么取过控制指针的啊,好像和在类向导中定义没有太大区别吧(个人感觉!不知道对否?)!但是我后面的其他操作都是用这两个指针完成的,没有问题啊。2.我实验了下你提供的方法,我在类向导里面可以找到其他的控件,但是找不到我用的那个编辑控件。所以没有办法用类向导生成变量啊!这是什么问题啊?最后我怀疑是不是和控件有关,因为正常情况似乎能够在类向导中看到控件ID的,但是我的工程里看不到那个自定义的控件ID啊。(因为控件不是我写的,是别人写的,他只是告诉我怎么用,我还没完全搞清楚啊!汗...)我下去在研究研究,虽然问题还是没有完全搞清楚,但是仍然感谢你啊!呵呵,还有jasonshark的一直关注!谢谢各位指教!稍后节贴送分啊!十分感谢!
再将CEdit 该成CMyEdit就OK网络上很多那种自己写的控件类,你看看他的类的基类是什么,可能不是控件基类。
我也认为可能是我的控制变量有点问题。但是你说要先new一个变量,我觉得似乎有点问题啊!我用GetDlgItem这个方法取去控制指针的时候就分配了内存啊,如果我new一个在把指针指向用GetDlgItem取得的控件,那我自己new的一块内存不是泄漏了吗?你看看是不是有这个问题啊!你提供的第二种方法应该说是最正规的做法啊!呵呵,一直也没有太注意这个问题,下去好好研究下!