WIN32学习——菜单消息

一、菜单分类:
  窗口菜单
  系统菜单
  右键菜单
二、窗口菜单使用:
1 创建菜单
      HMENU  CreateMenu(void); //创建成功返回菜单句柄。
      HMENU  CreatePopupMenu(void); //创建弹出式菜单
  2 增加菜单项
      BOOL AppendMenu(
HMENU    hMenu,//菜单句柄
UINT     uFlags,//菜单项增加选项,MF_POPUP
UINT_PTR uIDNewItem,//菜单项ID
LPCTSTR  lpNewItem//菜单项的名称
      );
  3 设置到窗口
      BOOL SetMenu(
HWND  hWnd, //窗口句柄
HMENU hMenu //菜单句柄
      );
  菜单响应的是WM_COMMAND消息,其中,WPARAM的LOWORD表示的是菜单的ID,LPARAM对于菜单为NULL

三、右键菜单的使用:
    CreatePopupMenu(void);
    AppendMenu
    显示右键菜单
       BOOL  TrackPopupMenu(
HMENU hMenu, //菜单句柄
UINT  uFlags, //显示方式
int   x, //水平位置,屏幕坐标系
int   y, //垂直位置,屏幕坐标系
int   nReserved,//保留,为0
HWND  hWnd, //处理菜单消息的窗口句柄
const RECT  *prcRect//NULL
       );TrackPopupMenu是一个阻塞函数
    注意:显示方式中,可以设定TPM_RETURNCMD来用返回值取得菜单的选择项,如果不设定TPM_RETURNCMD选项,则通过WM_COMMAND消息来获取菜单的选择项
四、右键菜单相关消息:
      1 WM_COMMAND,与窗口菜单一致
        如果TrackPopupMenu设置了TPM_RETURNCMD选项,那么点击的菜单项ID通过函数的返回值获取
      2 显示右键菜单的消息:
        WM_RBUTTONUP - 鼠标右键消息,该消息为窗口坐标系坐标,要使用需要转换成屏幕坐标系
  ClientToScreen
  ScreenToClient
WM_CONTEXTMENU - (专门为右键菜单设计,建议使用)
  WPARAM - 右键点击的窗口句柄

  LPARAM - LOWORD X坐标,屏幕坐标系
      HIWORD Y坐标,屏幕坐标系

       WM_CONTEXTMENU消息是在WM_RBUTTONUP消息产生之后产生


附加定时器消息学习代码:

/*
总结说明:菜单的使用,包括窗口菜单,右键菜单的使用
				点击菜单项相应的是WM_COMMAND消息
				实现了新建、退出、关于菜单项的操作,并在选中"新建"菜单项时,"关于"菜单项可用,未选中"新建"菜单项时,"关于"菜单项不可用。
				**********************************************************************
				右键菜单的使用
				非专业版:响应WM_RBUTTONUP消息
				专业版:WM_CONTEXTMENU消息
*/

#include <Windows.h>

HINSTANCE g_hInstance;
HANDLE  g_hOutputHandle;
BOOL g_State = TRUE;
HMENU hFile;
HMENU hHelp;

void OnCreate(HWND hWnd)
{
	HMENU hMain = CreateMenu();
	hFile = CreatePopupMenu();
	hHelp = CreatePopupMenu();

	AppendMenu(hFile,MF_STRING,1001,__TEXT("新建"));
	AppendMenu(hFile,MF_SEPARATOR,1002,__TEXT("分割线"));
	AppendMenu(hFile,MF_STRING,1003,__TEXT("退出"));
	
	AppendMenu(hHelp,MF_STRING,1004,__TEXT("关于"));

	AppendMenu(hMain,MF_POPUP,(UINT)hFile,__TEXT("文件"));
	AppendMenu(hMain,MF_POPUP,(UINT)hHelp,__TEXT("帮助"));

	SetMenu(hWnd,hMain);
}

void OnCommand(HWND hWnd,WPARAM wParam)
{
	SHORT nMenuID = LOWORD(wParam);
	switch(nMenuID)
	{
	case 1001:
		{
			if (g_State)
			{
				CheckMenuItem(hFile,1001,MF_BYCOMMAND | MF_CHECKED);
				EnableMenuItem(hHelp,1004,MF_BYCOMMAND | MF_ENABLED);
				g_State = FALSE;
			}
			else
			{
				CheckMenuItem(hFile,0,MF_BYPOSITION | MF_UNCHECKED);
				EnableMenuItem(hHelp,1004,MF_BYCOMMAND | MF_DISABLED);
				g_State = TRUE;
			}
			MessageBox(hWnd,__TEXT("点击了新建"),__TEXT("提示"),MB_OK);
		}
		break;
	case 1003:
		{
			PostQuitMessage(0);
		}
		break;
	case  1004:
		{
			MessageBox(hWnd,__TEXT("点击了关于"),__TEXT("提示"),MB_OK);
		}
		break;
// 	case 1005:
// 		MessageBox(hWnd,__TEXT("点击了NEW"),__TEXT("提示"),MB_OK);
// 		break;
	}
}

void OnRButtonUp(HWND hWnd,LPARAM lParam)
{
	//右键菜单创建
	HMENU hPop = CreatePopupMenu();
	//添加菜单项
	AppendMenu(hPop,MF_STRING,1005,__TEXT("NEW"));
	AppendMenu(hPop,MF_STRING,1006,__TEXT("QUIT"));
	//屏幕坐标转换,由客户区坐标转换成屏幕坐标
	POINT pt = {0};
	pt.x = LOWORD(lParam);
	pt.y = HIWORD(lParam);
	ClientToScreen(hWnd,&pt);
	//显示右键菜单,该函数是一个阻塞函数
	int nSelectID = TrackPopupMenu(hPop,TPM_RIGHTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,pt.x,pt.y,0,hWnd,NULL);
	if (1005 == nSelectID)
	{
		MessageBox(hWnd,__TEXT("点击了NEW"),__TEXT("提示"),MB_OK);
	}
	else if(1006 == nSelectID)
	{
		PostQuitMessage(0);
	}
	//TrackPopupMenu函数在没有设置TPM_RETURNCMD参数时,会调用WM_COMMAND来处理所选择的菜单项
	//TrackPopupMenu(hPop,TPM_RIGHTALIGN | TPM_TOPALIGN,pt.x,pt.y,0,hWnd,NULL);
}

void OnContextMenu(HWND hWnd,LPARAM lParam)
{
	HMENU hMenu = CreatePopupMenu();
	AppendMenu(hMenu,MF_STRING,1007,__TEXT("NEW2"));
	AppendMenu(hMenu,MF_STRING,1008,__TEXT("QUIT2"));
	int nSelectID = TrackPopupMenu(hMenu,TPM_RIGHTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,LOWORD(lParam),HIWORD(lParam),0,hWnd,NULL);
	if (1007 == nSelectID)
	{
		MessageBox(hWnd,__TEXT("点击了NEW2"),__TEXT("提示"),MB_OK);
	}
	else if(1008 == nSelectID)
	{
		PostQuitMessage(0);
	}
}

LRESULT CALLBACK MyProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_CONTEXTMENU:
		OnContextMenu(hWnd,lParam);
		break;
// 	case WM_RBUTTONUP:
// 		OnRButtonUp(hWnd,lParam);
// 		break;
	case WM_COMMAND:
		OnCommand(hWnd,wParam);
		break;
	case WM_CREATE:
		OnCreate(hWnd);
		break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE)
		{
			if(IDOK == MessageBox(hWnd,__TEXT("确定要关闭窗口?"),__TEXT("提示"),MB_OKCANCEL))
			{
				PostQuitMessage(0);
			}
			else
				return 0;
		}
	}
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

ATOM Register(LPCWSTR className)
{
	WNDCLASSEX wc = {0};
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hIconSm = NULL;
	wc.hInstance = g_hInstance;
	wc.lpfnWndProc = MyProc;
	wc.lpszClassName = className;
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	return RegisterClassEx(&wc);
}

HWND Create(LPCWSTR className,LPCWSTR windowName)
{
	return CreateWindowEx(0,className,windowName,WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,g_hInstance,NULL);
}

void Show(HWND hWnd)
{
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
}

void Message()
{
	MSG ms = {0};
	while (GetMessage(&ms,NULL,0,0))
	{
		TranslateMessage(&ms);
		DispatchMessage(&ms);
	}
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	AllocConsole();
	g_hOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	g_hInstance = hInstance;
	Register(__TEXT("Main"));
	HWND hWnd = Create(__TEXT("Main"),__TEXT("This is test"));
	Show(hWnd);
	Message();
	return 0;
}


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值