zoukankan      html  css  js  c++  java
  • 12.菜单(二)

    1.右键菜单(Context Menu,上下文菜单)的使用

      (1)创建菜单

         右键菜单是一个弹出式菜单,使用CreatePopupMenu创建

      (2)显示弹出式菜单

         BOOL TrackPopupMenu( HMENU          hMenu,        //弹出菜单句柄

                                                     UINT             uFlags,         //显示方式

                                                     int                 x,                //水平位置,屏幕坐标系

                                                     int                 y,                //垂直位置,屏幕坐标系

                                                     int                 nRevserved,  //保留,必须为0

                                                     HWND            hWnd,          //处理菜单消息的窗口句柄

                                                     CONST RECT  *prcRect);     //NULL,忽略

         TrackPopupMenu是阻塞函数

         //将客户区坐标系下的坐标转换为屏幕坐标系下的坐标

         BOOL ClientToScreen( HWND    hWnd,       //窗口句柄

                                                  LPPOINT  lpPoint);    //[IN/OUT]

                                                                输入:客户区坐标系下的坐标

                                                                输出:屏幕坐标系下的坐标

      (3)命令处理

         WM_COMMAND消息与窗口菜单一致。如果TrackPopupMenu设置了TPM_RETURNCMD被点击的菜单ID是通过返回值获取。

      (4)菜单项的状态

         WM_INITMENUPOPUP消息,按照弹出式菜单处理。

    2.菜单的处理位置

      (1)鼠标右键抬起

         WM_RBUTTONUP,鼠标右键抬起消息,是窗口坐标系坐标,使用时要转换成屏幕坐标系坐标。

         ClientToScreen

         ScreenToClient

      (2)WM_CONTEXTMENU

         wPARAM:右键点击的窗口句柄

         lPARAM:LOWORD - x坐标,屏幕坐标系

                                HIWORD - y坐标,屏幕坐标系

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

      相关代码:

    #include "stdafx.h"
    
    
    HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄
    
    void OnCreate(HWND hWnd)
    {
        HMENU hSys = GetSystemMenu(hWnd, FALSE);
        //删除系统菜单
        for (int i = 0; i < 6; i++)
        {
            DeleteMenu(hSys, 0, MF_BYPOSITION);  
        }
        //增加系统菜单
        AppendMenu(hSys, MF_SEPARATOR, 0, "");
        AppendMenu(hSys, MF_STRING, 1001, "我的菜单项");
    }
    void OnSysCommand(HWND hWnd, WPARAM wParam)
    {
        switch (LOWORD(wParam))
        {
        case 1001:
            MessageBox(hWnd, "我的菜单项被点击", "Info", MB_OK);
            break;
        }
    }
    void OnRButtonUp(HWND hWnd, LPARAM lParam)
    {
        /*
        HMENU hPopup = CreatePopupMenu();
        AppendMenu(hPopup, MF_STRING, 1002, "新建");
        AppendMenu(hPopup, MF_SEPARATOR, 0, "");
        AppendMenu(hPopup, MF_STRING, 1003, "退出");
        POINT pt = { 0 };
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        ClientToScreen(hWnd, &pt);
        BOOL nRet = TrackPopupMenu(hPopup, TPM_CENTERALIGN | TPM_VCENTERALIGN|TPM_RETURNCMD,
            pt.x, pt.y, 0, hWnd, NULL);
        switch (nRet)
        {
        case 1002:
            MessageBox(hWnd, "没发出WM_COMMAND消息,处理了新建被点击", "Info", MB_OK);
            break;
        case 1003:
            MessageBox(hWnd, "没发出WM_COMMAND消息,处理了退出被点击", "Info", MB_OK);
            break;
        }
        */
    }
    void OnCommand(HWND hWnd, WPARAM wParam)
    {
        switch (LOWORD(wParam))
        {
        case 1002:
            MessageBox(hWnd, "新建被点击", "Info", MB_OK);
            break;
        case 1003:
            MessageBox(hWnd, "退出被点击", "Info", MB_OK);
            break;
        }
    }
    void OnContextMenu(HWND hWnd, LPARAM lParam)
    {
        HMENU hPopup = CreatePopupMenu();
        AppendMenu(hPopup, MF_STRING, 1002, "新建");
        AppendMenu(hPopup, MF_SEPARATOR, 0, "");
        AppendMenu(hPopup, MF_STRING, 1003, "退出");
        POINT pt = { 0 };
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        //ClientToScreen(hWnd, &pt);//无需转换
        BOOL nRet = TrackPopupMenu(hPopup, TPM_CENTERALIGN | TPM_VCENTERALIGN | TPM_RETURNCMD,
            pt.x, pt.y, 0, hWnd, NULL);
        switch (nRet)
        {
        case 1002:
            MessageBox(hWnd, "没发出WM_COMMAND消息,处理了新建被点击", "Info", MB_OK);
            break;
        case 1003:
            MessageBox(hWnd, "没发出WM_COMMAND消息,处理了退出被点击", "Info", MB_OK);
            break;
        }
    }
    //窗口处理函数
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_CONTEXTMENU:
            OnContextMenu(hWnd, lParam);
            break;
        case WM_COMMAND:
            OnCommand(hWnd, wParam);
            break;
        case WM_RBUTTONUP:
            OnRButtonUp(hWnd, lParam);
            break;
        case WM_SYSCOMMAND:
            OnSysCommand(hWnd, wParam);
            break;
        case WM_CREATE:
            OnCreate(hWnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        }
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    //注册窗口类
    BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
    {
        WNDCLASSEX wce = { 0 };
    
        wce.cbSize = sizeof(wce);
        wce.cbClsExtra = 200;
        wce.cbClsExtra = 200;
        wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wce.hCursor = NULL;
        wce.hIcon = NULL;
        wce.hIconSm = NULL;
        wce.hInstance = g_hInstance;
        wce.lpfnWndProc = wndProc;
        wce.lpszClassName = lpClassName;
        wce.lpszMenuName = NULL;
        wce.style = CS_HREDRAW | CS_VREDRAW;
    
        ATOM nAtom = RegisterClassEx(&wce);
        if (0 == nAtom)
        {
            return FALSE;
        }
        return TRUE;
    }
    //创建主窗口
    HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
    {
        HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
            500, 200, 500, 300, NULL, NULL, g_hInstance, NULL);
        return hWnd;
    }
    //显示窗口
    void Display(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    //消息循环
    void Message()
    {
        MSG nMsg = { 0 };
        while (GetMessage(&nMsg, NULL, 0, 0))
        {
            TranslateMessage(&nMsg);
            DispatchMessage(&nMsg);
        }
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        g_hInstance = hInstance;
        Register("Main", WndProc);
        HWND hWnd = CreateMainWindow("Main", "window");
        Display(hWnd);
        Message();
    
        return 0;
    }
    View Code

       运行结果:

      

  • 相关阅读:
    【SQL】182. Duplicate Emails
    【SQL】181. Employees Earning More Than Their Managers
    【SQL】180. Consecutive Numbers
    【SQL】178. Rank Scores
    【SQL】177. Nth Highest Salary
    如何处理postman Self-signed SSL certificate blocked错误
    Radio checked 属性
    转成百分比
    内建函数
    队列
  • 原文地址:https://www.cnblogs.com/csqtech/p/5616133.html
Copyright © 2011-2022 走看看