本人刚接触MFC不久,句柄、消息传递机制都不太懂,有些地方可能会说的不对,望理解。
最近要编个界面,内容是将GOOGLEEARTH嵌入对话框界面,然后自定义一个右键菜单,在嵌入的GOOGLEEARTH上点击右键,弹出自定义的菜单。
现在问题是在对话框空白部分点击右键可以弹出菜单,但在嵌入的googleearth视图部分点击右键没有弹出菜单。我在OnInitDialog()中添加下面的代码:
ShowWindow(SW_SHOWMAXIMIZED);    //窗口最大化     
ModifyStyle(WS_MAXIMIZEBOX, 0, SWP_FRAMECHANGED);    //显示任务栏
HWND GEHWnd;    //Google地球主窗口句柄  
HWND GEHrender;    //Google地球地图窗口句柄
HWND MainHwnd;    //主窗口句柄
CWinApp *pWinApp=AfxGetApp();
if(pWinApp!=NULL)
{
    CWnd *pWnd=pWinApp->GetMainWnd();
    if(pWnd!=NULL)
    {
MainHwnd=pWnd->m_hWnd;    //获得主窗口句柄
    }
}
::CoInitialize(NULL);    //COM库初始化
if(googleEarth.IsInitialized())
{
    googleEarth.CreateDispatch(CLSID_Application,NULL);   //启动Google地球客户端
}
GEHWnd = (HWND)googleEarth.GetMainHwnd();    //获取Google地球主窗口句柄
::SetWindowPos(GEHWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE + SWP_HIDEWINDOW); //隐藏Google地球界面
GEHrender = (HWND)googleEarth.GetRenderHwnd();    //获取Google地球地图窗口句柄
::SetParent(GEHrender, MainHwnd);  //将Google地图窗口嵌入主窗口
::MoveWindow(GEHrender, 0, 0, 720, 480, true);   //移动并设置地图大小
以上代码可以实现将google地球嵌入到自己的界面中。
然后用WM_CONTEXTMENU消息设置了右键菜单。
此时在对话框界面空白部分点击右键可以弹出我的自定义菜单,但在googleearth上点击右键不行。然后在googleearth进行左键拖动、左键双击、右键双击,均可实现像操纵Google地球客户端一样的操作。以我现阶段的水平只能想到以下原因,请各位朋友指正:
1.由于SetWindowPos的第二个参数设置了Z序,可能造成GEHrender遮挡了右键菜单,以致无法显示。
2.GEHrender没有收到WM_CONTEXTMENU消息。如果是第一种原因,我实在不知道该怎么做。
对第二种原因,我做了以下尝试:
通过各种翻书+百度,知道通过钩子可以拦截消息为己所用,而由于我调用googleearth进程,相当于跨进程,所以用了系统钩子。
我在钩子处理函数中添加以下代码:
if(nCode<0)
return CallNextHookEx(glhHook,nCode,wparam,lparam);
if(wparam==WM_CONTEXTMENU)  
SendMessage(glhHookWnd,WM_CONTEXTMENU,0,0);
return CallNextHookEx(glhHook,nCode,wparam,lparam);
我也尝试过拦截WM_RBUTTONDOWN消息,可都不行。经过这么长时间的折腾啊,感觉我的每一步都有错误,可怎么也找不出原因,希望各位朋友帮忙解决。MFCGoogle Earth界面

解决方案 »

  1.   

    谷歌地图是3D的,MFC套它是可以,不过一般这种用QT去套会更成熟,不知道它是否用OGRE引擎开发的。在3D图里面需要知道其是否屏蔽了你的右键菜单的消息,我感觉这块应该是屏蔽了。引擎里挂的是自已的菜单,不能挂外置菜单。
      

  2.   

    可以试试在PreTranslateMessage中拦截
      

  3.   

    自己搞定了,还是得靠hook。
    在钩子函数中拦截WM_RBUTTONDOWN,然后给主窗口发送WM_CONTEXTMENU消息,其实已经成功了,经过仔细观察,点击右键后右键菜单出现在了程序的左上角位置,并没是没有一点反应的。原因是是鼠标的位置没有传过去,在钩子的MouseProc函数中获取鼠标位置,将相关参数传给TrackPopupMenu函数即可。
    谢谢各位的帮助。