win32 创建右键菜单

一般来说,创建并使用快捷菜单,可以按照以下步骤进行:

1、用资源编辑器创建菜单。

2、当我们在窗口上按下鼠标右键,当系统处理WM_RBUTTONUP时会向我们的应用程序发送一条WM_CONTEXTMENU消息,我们通过响应这条消息来决定是否弹出菜单。

3、计算菜单弹出的位置,一般在我们鼠标指针的右下方,该坐标是基于屏幕的,不是窗口的。

4、调用TrackPopupMenu函数显示快捷菜单。

5、因为这种菜单是不属于某个窗口的,它的内存资源不会在窗口销毁时被回收,因此,在TrackPopupMenu返回后要调用DestroyMenu来销毁菜单的资源,释放内存。

创建菜单资源-并设置ID
win32 创建右键菜单_第1张图片

接下来就是捕捉WM_CONTEXTMENU消息。显示菜单。

case WM_CONTEXTMENU:
    {
                           RECT rect;
                           POINT pt;
                           // 获取鼠标右击是的坐标  
                           pt.x = GET_X_LPARAM(lParam);
                           pt.y = GET_Y_LPARAM(lParam);
                           //获取客户区域大小  
                           GetClientRect((HWND)wParam, &rect);
                           //把屏幕坐标转为客户区坐标  
                           ScreenToClient((HWND)wParam, &pt);
                           //判断点是否位于客户区域内  
                           if (PtInRect(&rect, pt))
                           {
                               //加载菜单资源  
                               HMENU hroot = LoadMenu((HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_CONTEXT));
                               if (hroot)
                               {
                                   // 获取第一个弹出菜单  
                                   HMENU hpop = GetSubMenu(hroot, 0);
                                   // 把客户区坐标还原为屏幕坐标  
                                   ClientToScreen((HWND)wParam, &pt);
                                   //显示快捷菜单  
                                   TrackPopupMenu(hpop,
                                       TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
                                       pt.x,
                                       pt.y,
                                       0,
                                       (HWND)wParam,
                                       NULL);
                                   // 用完后要销毁菜单资源  
                                   DestroyMenu(hroot);
                               }
                           }
    }

点击做出反应效果

        case 32781:
            MessageBox(hWnd, L"哈哈。", L"提示", MB_OK);
            break;
        case 32782:
            MessageBox(hWnd, L"呵呵。", L"提示", MB_OK);
            break;
        case 32783:
            MessageBox(hWnd, L"嘎嘎。", L"提示", MB_OK);
            break;
        }

定义

#define ID_haha                         32781
#define ID_hehe                         32782
#define ID_gaga                         32783

根据MSDN文档的说明,WM_CONTEXTMENU消息的wParam参数指的是弹出菜单的窗口的句柄,lParam参数的低字位是鼠标指针的水平坐标,高字位指的是垂直坐标。

但我们不用自己去转换,我们通过GET_X_LPARAM和GET_Y_LPARAM两个宏可以把lParam中的值转为坐标值,类型为int,要使用这两个宏,需要包含WindowsX.h头文件。接着调用TrackPopupMenu来显示菜单,最后销毁菜单。

现在在窗口的标题栏上右击,快捷菜单不会再出现了,但是,同时,系统菜单也没有出现。因为系统菜单是由系统来处理的,所以,解决这问题很简单,只要我们把WM_CONTEXT消息发回给系统来处理就行了。

方法一:我们判断了如果右击点在窗口的客户区域时显示菜单,那么,如果不在这个区域内,就把消息再传回给系统处理。

else  
{  
    return DefWindowProc(hWnd, message, wParam, lParam);
}  

方法二:在WindowsProc函数的最后,统一把所有消息都返回给操作系统处理。

default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return DefWindowProc(hWnd, message, wParam, lParam);

你可能感兴趣的:(C++)