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 來表示動態菜單,具體格式規則如下:
(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" //返回文件名字符串指針 ;
上面的示例菜單字符串顯示出來的菜單如下:
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");
(1)模式1為相等模式 ( nDefaultMode = 1 ),當某個菜單項的數值等於輸入的 nDefaultValue 的時候,這個菜單項前面有選中標記
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); //返回值為當前選中的菜單項對應的值,如果沒有選擇菜單,這個值保持原來的不變
模式2為位模式 ( nDefaultMode = 2 ),當菜單項的數值所對應的位 與nDefaultValue位與的時候不為0,則菜單項前面顯示選中標記。
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