WIN 下的超動態菜單(二)用法

来源:http://www.cnblogs.com/tomview/archive/2016/05/25/5521431.html
-Advertisement-
Play Games

WIN 下的超動態菜單(一)簡介 WIN 下的超動態菜單(二)用法 作者:黃山松,發表於博客園:http://www.cnblogs.com/tomview/ auto_dynamenu 是一個動態生成WINDOWS菜單的c++封裝庫,設計思路是要儘量簡化動態菜單的生成代碼,在程式界面任何地方想要顯... ...


WIN 下的超動態菜單(一)簡介

WIN 下的超動態菜單(二)用法

作者:黃山松,發表於博客園:http://www.cnblogs.com/tomview/

        auto_dynamenu 是一個動態生成WINDOWS菜單的c++封裝庫,設計思路是要儘量簡化動態菜單的生成代碼,在程式界面任何地方想要顯示菜單(特別是右鍵菜單)的時候,可以方便生成菜單,特別可以根據程式當時的內部數據,內部狀態來生成不同的動態菜單。

        auto_dynamenu 只封裝了一個靜態的介面函數,這樣處理的目的是把類的實現代碼可以放在頭文件的類的聲明裡面,這樣使用的時候只要包含頭文件就可以直接調用了,不需要把實現文件加入工程,簡化操作。

類的介面函數定義

/**************************************************************************************************\
* static int           :    返回值,表明選擇了哪個菜單項或者被更新的 nDefaultValue
* dynamenu             :    
* HWND hWnd            :    當前視窗句柄
* LPPOINT pPoint       :    顯示菜單的位置,通常為0即可,自動確定顯示的菜單位置
* char* pszMenu        :    表明動態菜單內容的菜單字元串
* int nDefaultMode     :    自動更新菜單選擇標記的模式,0 無,1 等於模式,2 位模式
* int nDefaultValue    :    預設值,根據這個值,按照 nDefaultMode 來顯示菜單項的選擇標記
\**************************************************************************************************/
class auto_dynamenu
{
public:
static int dynamenu(HWND hWnd, LPPOINT pPoint, char* pszMenu, int nDefaultMode, int nDefaultValue);
};

參數:pszMenu

        介面用一個格式化的字元串 pszMenu 來表示動態菜單,具體格式規則如下:

(1)每個菜單項為一個以 \n 結束的字元串

(2)菜單項的字元串通常以等號 = 分割為兩部分,等號前面為要顯示的菜單內容,等號後面為選擇這個菜單後的取值

(3)菜單項的字元串裡面如果沒有等號,表明選擇菜單返回的時候,返回的是菜單項字元串

(3)每個菜單項字元串前面可以加如下的修飾符:

[a] *(星號):表示這個菜單項前面有點的選擇標記

[b] ^:表示這個菜單項前面有對勾的選擇標記

[c] #:表示這個菜單項是灰色的

[d] -(減號):表明這個菜單項和下一個菜單項之間分為不同的列(多列的菜單)

[e] `(鍵盤左上角的按鍵):表示一個沒有意義的占位符

[f] ~:表明是一個菜單分割線

(4)可以用單獨一行的 ~ 表示一個菜單分割橫線,“~\n”

(5)菜單項字元串等號前面部分的豎線字元”|“ 把菜單分割為父菜單和子菜單

(6)把不同的菜單項的字元串連接為一個完整的字元串就可以描述這個整個菜單了

例如:

char szMenu[] = 
        "選項1=20\n"                       //選項1對應數值20,選擇這個函數返回20
        "選項2=0x20\n"                     //選擇2對應數值0x20,選擇這個函數返回0x20
        "選項3=0\n"                        //選項3對應數值0,選擇這個函數返回 INT_MAX(因為函數返回0代表沒有選擇菜單項,所以0用INT_MAX返回值表示)
         "~\n"                             //這個代表一個菜單分割橫線
         "錄像|通用格式|avi格式=-1\n"        //多級子菜單,選擇這個返回-1
        "錄像|通用格式|~\n"                //多級子菜單內部的分割橫線
         "錄像|通用格式|mkv格式=-2\n"        //多級子菜單,選擇這個返回-2
        "錄像|~\n"
        "錄像|專用格式|rdv格式=-3\n"        //多級子菜單,選擇這個返回-3
        "~\n"
        "#暫停處理\n"                      //灰色禁用的菜單項,無法選擇,可以用於顯示信息
         "~\n"
        "控制|^開始視頻=10\n"              //顯示選中的視頻開始菜單,選擇返回10
        "控制|結束視頻=11\n"               //顯示沒有選中的菜單,選擇返回11
        "播放當前錄像 1.avi=d:\\1.avi\n"   //返迴文件名字元串指針
        ;

上面的示例菜單字元串顯示出來的菜單如下:

image

參數:hWnd

        雖然菜單的消息不發往任何視窗,但是這個必須指定一個有效的視窗句柄,否則菜單顯示不出來。通常指定對滑鼠右鍵響應要顯示菜單的視窗,或者主視窗。

參數:pPoint

        菜單顯示位置坐標POINT的指針,用於指定菜單的顯示位置,是屏幕坐標。通常可以給0,這時程式自動選擇菜單的顯示位置,通常根據滑鼠當前位置的控制項類型確定,具體如下:

(1)如果是 BUTTON,工具欄上的按鈕,則顯示在這個控制項的下方,左側對齊

(2)如果是TreeView,ListView則顯示在當前滑鼠位置的條目的下方

(3)如果是TabCtrl則顯示在滑鼠當前的Tab頁的頁頭的下方

(4)大小像個按鈕的ActiveX控制項,顯示在下方

(5)其他顯示在滑鼠的當前位置

參數pPoint備註

         在這個參數給0的時候,代碼自動確定菜單顯示位置,但由於作者通常在VC6下編程(參見博文《我是如何把VC6一直用到2016年的》),因此代碼中判斷控制項類型用的 ClassName 沒有包含新版 Visual C 帶的控制項的類,可能需要使用者增加一些代碼中的控制項類名,對不同的控制項確定不同的顯示菜單的位置。具體情況參考文檔《WIN 下超動態菜單(三)代碼》。

參數:nDefaultMode

        預設模式,如果為0,沒有預設模式,菜單項的標記都在菜單字元串中指定。

        如果為1,相等模式,如果某個菜單項的取值等於傳入的nDefaultValue則顯示選中標記。

        如果為2,為與模式,如果某個菜單項的取值與nDefaultValue的位與不為0,則顯示選中標記。

參數:nDefaultValue

        當前的預設值,配合nDefaultValue使用。

返回值:

        程式應該根據返回值來判斷選擇了哪個菜單,根據nDefaultMode不同含義有差別,用法也有差異。

(1)如果nDefaultMode為0

(a)返回值為0的時候,表明沒有選擇任何菜單選項;

(b)返回值為INT_MAX,表明選擇了某個值為0的菜單項;

(c)如果選擇的菜單項字元串裡面有等號,並且等號後面是數字(支持十進位和十六進位寫法),則返回這個數字;

(d)如果選擇的菜單項字元串裡面的等號後面是字元串,則返回這個等號後面的字元串的指針;

(e)如果選擇的菜單項字元串裡面沒有等號,則返回這個菜單項的字元串的指針。

(2)如果 nDefaultMode 為 1 或者 2

        則返回nDefaultValue經過修改後的值,如果沒有選擇任何菜單,返回值等於nDefaultValue。

直接可以這樣寫 :

nDefaultValue = auto_dynamenu::dynamenu(GetSafeHwnd(), 0, pszMenu, nDefaultMode/*1 or 2*/, nDefaultValue);

動態菜單顯示及根據返回值進行處理示例

char szMenu[] = 
        "選項1=20\n"                    //選項1對應數值20,選擇這個函數返回20
        "選項2=0x20\n"                  //選擇2對應數值0x20,選擇這個函數返回20
        "選項3=0\n"                     //選項3對應數值0,選擇這個函數範圍 INT_MAX(因為函數返回0代表沒有選擇菜單項,所以0用INT_MAX返回值表示)
         "~\n"                           //這個代表一個菜單分割橫線
         "錄像|通用格式|avi格式=-1\n"      //多級子菜單,選擇這個返回-1,可以為負值
        "錄像|通用格式|~\n"              //多級子菜單內部的分割橫線
         "錄像|通用格式|mkv格式=-2\n"      //多級子菜單,選擇這個返回-2
        "錄像|~\n"
        "錄像|專用格式|rdv格式=-3\n"      //多級子菜單,選擇這個返回-3
        "~\n"
        "#暫停處理\n"                    //灰色禁用的菜單項,無法選擇,可以用於顯示信息
         "~\n"
        "控制|^開始視頻=10\n"             //顯示選中的視頻開始菜單,選擇返回10
        "控制|結束視頻=11\n"              //顯示沒有選中的菜單,選擇返回11
        "播放當前錄像 1.avi=d:\\1.avi\n"  //返迴文件名字元串指針
        ;

    int index = auto_dynamenu::dynamenu(GetSafeHwnd(), 0, szMenu, 0, 0);
    switch (index)
    {
    case 0:
        //菜單沒有選擇,不做任何處理
        break;
    case 20:
        //選項1
        break;
    case 0x20:
        //選項2
        break;
    case INT_MAX:
        //選項3,這個菜單項的值為0,通常可以避免這樣的情況,就不需要處理這個特殊的值了
        break;
    case -1:
        //avi 錄像
        break;
    case -2:
        //mkv錄像
        break;
    case -3:
        //rdv錄像
        break;
    case 10:
        //開始視頻
        break;
    case 11:
        //停止視頻
        break;
    default:
        {
            char * pfile = (char*)index;
            //選中了最後的文件菜單項,pfile為 “d:\\1.avi” 字元串的指針
        }
        break;
    }

兩點註釋:

        (1)上面的代碼裡面的菜單項的選中標記,都是在菜單字元串裡面手工指定的,這時 nDefaultMode 和 nDefaultValue 指定為0。

        (2)上面代碼中的菜單項是在源代碼中硬編碼的,實際使用的時候可以動態生成,根據程式的狀態來組建菜單字元串,例如:

char szMenu[1024] = {0};
    
    int n = 0;

    if (value == 2)
        n += sprintf(szMenu + n, "^");

    n += sprintf(szMenu + n, "值2=2\n");

    if (value == 4)
        n += sprintf(szMenu + n, "^");

    n += sprintf(szMenu + n, "值4=4\n");

nDefaultMode=1時的示例

(1)模式1為相等模式 ( nDefaultMode = 1 ),當某個菜單項的數值等於輸入的 nDefaultValue 的時候,這個菜單項前面有選中標記

image

    int val = 32;        //nDefaultValue

    char szMenu[] = 
        "整數1=1\n"
        "整數20=20\n"
        "整數32=32\n"
        "整數0x99=0x99\n"
        ;

    //註意上面的菜單字元串裡面沒有選中標記

    //nDeaultMode = 1,當菜單項等於 nDefaultValue的時候顯示選中標記
    
    val = auto_dynamenu::dynamenu(GetSafeHwnd(), 0, szMenu, 1, val);    

    //返回值為當前選中的菜單項對應的值,如果沒有選擇菜單,這個值保持原來的不變

nDefaultMode=2時的示例

        模式2為位模式 ( nDefaultMode = 2 ),當菜單項的數值所對應的位 與nDefaultValue位與的時候不為0,則菜單項前面顯示選中標記。

image

    DWORD flags = 0x82;        //當前的值 nDefaultValue 

    char szMenu[] = 
        "標記1=1\n"
        "標記2=2\n"
        "標記3=4\n"
        "標記4=8\n"
        "標記5=0x10\n"
        "標記6=0x20\n"
        "標記7=0x40\n"
        "標記8=0x80\n"
        ;
    //上面的菜單字元串內沒有選擇標記,程式自動根據 nDefaultValue  把對應的位加上選中標記
    //nDefaultMode = 2

    flags = (DWORD)auto_dynamenu::dynamenu(GetSafeHwnd(), 0, szMenu, 2, flags);
    //返回值就是flags,如果沒有選擇菜單項,那麼這個值不變

待續

        後續還要發表,《WIN 下的超級動態菜單(三)代碼》。

        可以在下麵的鏈接下載代碼和示常式序:

        http://files.cnblogs.com/files/tomview/dynamenu_20160524.rar


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 顯示結果: ID:1 ParentID: 0 TreeLevel: 0 Name:中國ID:2 ParentID: 1 TreeLevel: 1 Name:江西ID:5 ParentID: 2 TreeLevel: 2 Name:南昌ID:6 ParentID: 5 TreeLevel: 3 Nam ...
  • 直接在vs2013里的App_Data目錄創建資料庫,在伺服器資源管理器中查看時報錯: 未能載入包“Microsoft SQL Server Data Tools” 英文: 以下是右擊表的效果。 解決方案: 1.去https://msdn.microsoft.com/zh-cn/dn864412 下 ...
  • 今天在ASP.NET MVC項目中,實現一個小功能,就是記錄瀏覽者客戶端的一些信息。比如瀏覽者的IP,訪問了哪些頁面,以及瀏覽器相關的信息。在資料庫中創建一張表[VisitData]: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI ...
  • ...
  • 本文是Linux Shell系列教程的第(四)篇,更多shell教程請看:Linux Shell系列教程 與許多的編程語言一樣,Shell中也有註釋符號,今天就為大家來介紹下Shell中的註釋的語法及用法。 Shell中的註釋以“#”號開頭,所有以“#”號開頭的代碼都會被解釋器所忽略。 比如下麵的代 ...
  • 官方文檔給出了兩種Yii2的安裝方式。一種是通過歸檔文件安裝,另一種則是通過composer進行安裝。兩種方式具體有什麼不同呢?我們這裡不討論,安裝完了你自然也就明白了。 相信很多小伙伴想學Yii2,但是大部分都死在了開頭。所謂萬事開頭難,Yii2無疑更好的證實了這一點,還沒開始就先給你一棒槌。 安 ...
  • 利用介面做參數,寫個計算器,能完成+-*/運算 (1)定義一個介面Compute含有一個方法int computer(int n,int m); (2)設計四個類分別實現此介面,完成+-*/運算 (3)設計一個類UseCompute,含有方法:public void useCom(Compute c ...
  • 概述 GenEvent 是事件處理的通用部分的抽象。 通過 GenEvent ,我們給已有的服務 動態 的添加 事件處理。 GenEevent 和 GenServer 的區別 之前已經介紹了 GenServer ,GenServer 和 GenEvent 的主要區別在於: GenServer 是服務 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...