您的位置:首页 > 编程语言 > C语言/C++

WIN32学习——菜单消息

2017-05-15 10:24 176 查看
一、菜单分类:

  窗口菜单

  系统菜单

  右键菜单

二、窗口菜单使用:
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);
}
//TrackPopu
4000
pMenu函数在没有设置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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  win32 MFC c++ c windows