创建:CreatePopupMenu
增加:AppendMenu
显示:BOOL TrackPopupMenu
{
HMENU hMenu,//显示的彩带句柄
UINT uFlags,//显示的方式
int x,//菜单的x屏幕坐标
int y,//菜单的y屏幕坐标
int nReseveed,//保留,必须为0
HWND hWnd,//处理菜单命令的窗口句柄
CONST RECT *prcRect);//忽略
命令处理:WM_COMMAND
使用右键菜单的位置
WM_RBUTTONUP消息
在WM_RBUTTONUP中,添加菜单的创建与显示,右键消息坐标,转换成屏幕坐标使用。
ClientToScreen.
WM_CONTEXTMENU消息,用于显示右键菜单的消息
{
WPARAM //右键点击时对应的窗口句柄
LPARAM //右键抬起时鼠标的屏幕坐标位置
LOWORD(lParam)-x屏幕坐标
HIWORD(lParam)-y屏幕坐标
}
WM_RBUTTONUP和WM_CONTEXTMENU对比
坐标系不同,WM_RBUTTONUP客户区坐标
WM_CONTEXTMENU屏幕坐标
先有WM_RBUTTONUP消息,后有WM_CONTEXTMENU消息
#include "stdafx.h"
////2
HINSTANCE g_hInst=NULL;
///b
void OnRButtonUp(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
//创建弹出式菜单
HMENU hPopMenu=CreatePopupMenu();
//增加菜单项
AppendMenu(hPopMenu,MF_STRING,1001,"测试");
AppendMenu(hPopMenu,MF_SEPARATOR,0,NULL);
AppendMenu(hPopMenu,MF_STRING,1002,"退出");
//获取菜单位置
POINT point={0};
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
int nX=LOWORD(lParam);
int nY=HIWORD(lParam);
ClientToScreen(hWnd,&point);
//显示菜单
TrackPopupMenu(hPopMenu,TPM_LEFTALIGN,point.x,point.y,0,hWnd,NULL);
}
void OnCommand(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
int nCmdID=LOWORD(wParam);
switch(nCmdID)
{
case 1001:
MessageBox(NULL,"Hello Popmenu","PopMenu",MB_OK);
break;
case 1002:
PostQuitMessage(0);
break;
}
}
void OnContextMenu(HWND hwnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
//创建弹出式菜单
HMENU hPopMenu=CreatePopupMenu();
//增加菜单项
AppendMenu(hPopMenu,MF_STRING,1001,"测试1");
AppendMenu(hPopMenu,MF_SEPARATOR,0,NULL);
AppendMenu(hPopMenu,MF_STRING,1002,"退出1");
}
////3
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd,//窗口句柄
UINT nMsg,//窗口消息Id
WPARAM wParam,//消息传来的两个参数
LPARAM lParam)
{
switch(nMsg) //消息退出的命令
{
case WM_RBUTTONUP://a当鼠标右键抬起时消息
OnRButtonUp(hWnd,nMsg,wParam,lParam);
break;
case WM_CONTEXTMENU:
OnContextMenu(hWnd,nMsg,wParam,lParam);
break;
case WM_COMMAND:
OnCommand(hWnd,nMsg,wParam,lParam);
break;
case WM_DESTROY:
PostQuitMessage(0); //使窗口退出
return 0;
}
//返回缺省的窗口处理函数
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
////4
//注册窗口-首先使用WNDCLASSEX定义窗口类的各项参数
BOOL RegisterWnd(LPSTR pszClassName)
{
WNDCLASSEX wce ={0};
wce.cbSize =sizeof(wce);
wce.cbClsExtra =0;//窗口类的附加参数
wce.cbWndExtra =0;//窗口的附加参数
wce.hbrBackground =HBRUSH(COLOR_WINDOW);//窗口的背景画刷
wce.hCursor =NULL;//窗口的光标
wce.hIcon =NULL;//窗口的图标
wce.hIconSm =NULL;//窗口的小图标
wce.hInstance =g_hInst;//应用程序的实例句柄
wce.lpfnWndProc =WndProc;//窗口处理函数指针
wce.lpszClassName =pszClassName;//窗口类的名称
wce.lpszMenuName =NULL;//菜单名称
wce.style =CS_HREDRAW|CS_VREDRAW;//窗口风格
//注册窗口用RegisterClassEx,返回用ATOM
ATOM nAtom=RegisterClassEx(&wce);
if(0==nAtom)
{
return FALSE;//窗口注册没有成功
}
return TRUE;
}
////5创建窗口
HWND CreateWnd(LPSTR pszClassName)
{
HWND hWnd=CreateWindowEx(0,//窗口的扩展风格
pszClassName,//窗口类的名称
"MyWnd",//窗口的标题
WS_OVERLAPPEDWINDOW,//窗口的堆叠风格
CW_USEDEFAULT,//窗口的坐标和长宽
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,//窗口的父窗口
NULL,//窗口的菜单
g_hInst,//应用程序句柄
NULL);//窗口创建时的附加参数
return hWnd;
}
////6窗口的显示
void DisplayWnd(HWND hWnd)
{
ShowWindow(hWnd,SW_SHOW);//显示窗口
UpdateWindow(hWnd);//刷新窗口界面
}
////7窗口的消息循环
void Message()
{
MSG msg={0};
while (GetMessage(&msg,NULL,0,0))//获取消息
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//调用窗口处理函数处理消息
}
}
//// 1 新建时自动生成
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
////将程序依次执行
g_hInst=hInstance;
RegisterWnd("MYWND");//注册窗口
HWND hWnd=CreateWnd("MYWND");//创建窗口
DisplayWnd(hWnd);//显示窗口
Message( );//执行消息循环
return 0;
}