/****************************************************************************几大主要问题:1.通过处理WM_MOUSEACTIVATE,并返回MA_NOACTIVATE可以实现点窗口时不激活窗口(父窗口不会失去焦点)2.CreateWindowEx时窗口的样式一定要有 WS_EX_TOPMOST 和 WS_POPUP ,并且设置窗口的父句柄。3.用 ::ShowWindow(hWnd,SW_SHOWNOACTIVATE); 让窗口显示时无焦点4.消息阻塞:用 GetMessage 来阻塞父窗口,不让代码继续往下执行直到菜单窗口消失为止。未解决的问题:1.菜单窗口不处于激活状态,所以未能收到键盘消息2.窗口点击其他程序时,菜单不会自动消失****************************************************************************//****************************************************************************创建窗口 (不需要注册窗口类,只能创建一个)****************************************************************************/class CMyMenu{private: static WNDPROC OldWndProc; static LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);public: static void CreateWnd(int x,int y,HWND PareWnd=NULL) //创建窗口函数 { HWND hWnd = CreateWindowEx(WS_EX_TOPMOST, _T("#32770"), _T("Demo"), WS_POPUP| WS_BORDER, x,y,100,100,PareWnd,NULL,NULL,NULL) ; ::ShowWindow(hWnd,SW_SHOWNOACTIVATE); //把hWnd的默认窗口过程替换为WindowProc,返回默认函数过程的函数指针 OldWndProc=(WNDPROC)SetWindowLong(hWnd,GWL_WNDPROC, (LONG) (WindowProc)); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { //点击的不是菜单窗口就返回 if ( msg.message==WM_LBUTTONDOWN || msg.message==WM_RBUTTONDOWN ) { if ( msg.hwnd != hWnd ) ::PostMessage(hWnd,WM_CLOSE,NULL,NULL); } TranslateMessage(&msg); DispatchMessage(&msg); } }};WNDPROC CMyMenu::OldWndProc=NULL;LRESULT CALLBACK CMyMenu::WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){ switch(message) { case WM_LBUTTONDOWN: { ::PostMessage(hWnd,WM_CLOSE,NULL,NULL); } break; case WM_MOUSEACTIVATE: return MA_NOACTIVATE ; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); //会退出消息循环 GetMessage break; default: return ::CallWindowProc(OldWndProc, hWnd, message, wParam, lParam); //如果我们没有处理的再交给原窗口默认处理 } return 0;}void CDemoDlg::OnRButtonUp(UINT nFlags, CPoint point){ POINT pt; ::GetCursorPos(&pt); CMyMenu::CreateWnd(pt.x,pt.y,m_hWnd) ; CDialog::OnRButtonUp(nFlags, point);