15,979
社区成员
发帖
与我相关
我的任务
分享
/****************************************************************************
几大主要问题:
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);