首先用自己的窗口过程替换掉某个窗口句柄(传入的参数)原来的窗口过程,这样就可以截获该窗口的一些消息现在的问题是,当其他窗口向这个窗口发送鼠标消息时(使用WINAPI发送),在自定义的窗口过程中也可以看到,但是由于MFC窗口类是在消息映射函数中处理鼠标事件的,它不需要传递到窗口过程处理。所以这样一来,其他窗口发送的鼠标消息就无法触发该窗口类中定义的消息映射处理函数了,有办法解决么?前提是,我只知道一个窗口句柄,这个窗口句柄到底对应什么窗口类是不知道的,简单点说就是只允许通过一个窗口句柄,能否完成这种处理?
解决方案 »
- 哪位高手帮帮忙,好像是头文件的问题 不知道怎么加(我用MFC+VC6.0+opencv做一个模态对话框的调用)
- vs2005 如何在C++程序中处理COM事件?
- vc++6.0 directshow 捕捉图像
- dllmain _tmain 问题!
- 点击列表的不同项,对应嵌入主对话框的子对话框界面相应切换
- 招聘vc软件工程师(全职,北京)
- 在VC编程中如何给一个静态文本框加上水平和垂直滚动条?请大家帮帮我!
- cedit如何取得值
- 谁会画表格打印,100分在线等待!!!!!!!!!!!!!!!!!!!!!
- 怎样删除CComboBox中的字符串
- 请问关于CTreeCtrl想通过节点的名称获得这个节点的HTREEITEM
- 关于窗口过程消息处理,重发帖
HHOOK SetWindowsHookEx(
int idHook, // hook type
HOOKPROC lpfn, // hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // thread identifier
);
可以去查查MSDN它的用法,它可以截获所有的消息
2. 在窗口的OnCreate()中return之前SetWindowLong
{
if(m_hTheWnd != NULL)
{
if((lpMsg->hwnd == m_hTheWnd) || ::IsChild(m_hTheWnd, lpMsg->hwnd))
{
if(lpMsg->message == WM_LBUTTONDOWN)
{
//Do you process
}
}
}
}
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID;
// control ID (or 0 for windows messages)
UINT nLastID;
// used for entries specifying a range of control id's
UINT nSig;
// signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};
struct AFX_MSGMAP
{
#ifdef _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
};其中AFX_MSGMAP_ENTRY结构包含了
一个消息的所有相关信息,其中nMessage为Windows消息的ID号
nCode为控制消息的通知码
nID为Windows控制消息的ID
nLastID表示如果是一个指定范围的消息被映射的话,
nLastID用来表示它的范围。
nSig表示消息的动作标识
AFX_PMSG pfn 它实际上是一个指向
和该消息相应的执行函数的指针。AFX_MSGMAP_ENTRY结构实际上定义了消息和处理此消息的动作之间的映射关系。因此静态数组变量_messageEntries[]实际上定义了一张表,表中的每一项指定了相应的对象所要处理的消息和处理此消息的函数的对应关系,因而这张表也称为消息映射表。AFX_MSGMAP定义了一单向链表,链表中每一项的值是一指向消息映射表的指针(实际上就是_messageEntries的值)。你的消息映射中的DECLARE_MESSAGE_MAP 和DECLARE_MESSAGE_MAP之间的定义都将存放在上面的那个消息映射链表中,你可以通过遍历链表实现查找处理函数的指针,然后调用即可要获得这个消息映射实体链表_messageEntries ,可以通过GetMessageMap()这个虚函数
该函数定义:
LRESULT SendMessage(
HWND hWnd, // handle to destination window
UINT Msg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
或者自己去调用那个窗口的消息响应过程
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
if (pWnd != NULL)
{
// call window proc directly since it is a C++ window
AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
}
UserCall(HWND hwnd)
{
// 替换窗口过程
ReplaceWndProc(hwnd, MyWndProc);
...
}// 自定义的窗口过程
MyWndProc(MSG msg....)
{
// 调用原来的窗口过程
CallOrgWndProc(msg...);switch (msg)
{
case WM_LBUTTONDOWN:
break;
...
}
}// 另一个窗口发送鼠标消息到这个窗口
SendMessage(hwnd, msg...)在MyWndProc中是可以看到该消息的,但是这个消息是不会触发应用上MESSAGE_MAP的Cxxxx::OnLButtonDown()处理了,换句话说,APP的鼠标消息在MyWndProc中是看不到的,说明这种消息在之前就被处理了现在的问题不是要截获消息,而是怎样把我在DLL发出的消息触发MESSAGE_MAP中定义的消息映射处理,前提就是我只能通过HWND实现,因为在DLL里面我根本不知道外部它对应的窗口类是什么
给这个窗口发的鼠标消息到底能不能被MyWndProc看到啊?
那是的啊,你已经用MyWndProc替代了mfc封装的窗口过程了啊,而且窗口消息如果被一窗口响应处理了,就不会再被应用类处理了,为啥要在应用类添加鼠标消息的响应函数呢?
我还是不明白你要做什么,既然替换了自己的窗口函数,为何还要应用类去响应处理呢(虽然我知道这个窗口是你写的dll封装的,而调用dll的客户程序是第三方的)
如果是想在你的过程处理完后,还要执行客户程序的消息处理,完全可以定义一个接口,将应用类的鼠标消息
处理函数的指针传进去(也就是回调函数):
typedef void (*PMSGFUNC)(UINT nFlags, CPoint point);
class CYourWnd
{
...
PMSGFUNC m_pLButtonDownFunc;
}MyWndProc(MSG msg....)
{
// 调用原来的窗口过程
// CallOrgWndProc(msg...); //不要这个switch (msg)
{
case WM_LBUTTONDOWN:
{
//Do your process
...
//调用客户程序的消息句柄
if(m_pLButtonDownFunc) m_pLButtonDownFunc(nFlags, point);
}
break;
...
}
}
你既然在用户的窗口上已经覆盖了一个窗口,那么你完全可以不必替代用户的窗口的处理过程啊?直接将你的窗口的处理过程的消息转发就是了(SendMessage即可)。
不替换窗口过程也不行的,似乎从DLL里面SendMessage(hwnd, ...)过去不会触发Cxxx::OnLButtonDown处理
害大家折腾这么久,抱歉!我对不起大家,我对不起组织,我对不起CCAV....