自定义右键弹出菜单

Mr_MAO 1小时前 15

aardio中,win.ui.menu库调用的是User32.dll中Windows 标准菜单,它底层基于GDI实现所以不支持 Alpha 通道,这就导致win.ui.menu库生成的菜单不支持背景透明的png或者gif图片。

下面演示一种方法:利用mode="popup"的winform和plus控件模拟弹出菜单,使用plus控件来显示透明背景的png图标。

( 演示示例中,因加载网络图片导致程序启动较慢,实际生产环境可加载资源文件夹中的图片,不会有任何启动速度问题 )

//自定义弹出菜单 @Mr_MAO
import win.ui;
import fonts.fontAwesome;
import inet.http;
import gdip.bitmap;

class customPopMenu {
	ctor(parent){
    	this._parent = parent;
    	this.items = {};
    	this.itemHeight = 32;
    	this.width = 135;
    	this.fontSize = 12;
    	this.iconSize = 16;
    	this.backgroundColor = 0xFFf0f0f0;
	};
	
	// 添加菜单项
	add = function(text, callback, icon){
    	..table.push(this.items, { text = text; callback = callback; icon = icon });
	};

	// 添加分隔线
	addSeparator = function(){
    	..table.push(this.items, { isSeparator = true });
	};

	// 弹出菜单
	popup = function(x, y){
    	if( !(x && y) ){
        	x, y = ..win.getMessagePos();
    	}
	
    	var totalH = 6;
    	for(i, item in this.items){
        	totalH += item.isSeparator ? 6 : this.itemHeight;
    	}
	
    	// 创建弹出窗体
    	var frm = ..win.form(
        	parent = this._parent;
        	title  = false;
        	right  = this.width; bottom = totalH;
        	border = "dialog frame"; exmode="toolwindow"; mode="popup";
        	bgcolor = this.backgroundColor;
    	)

    	var currentY = 3;
    	var ctrlList = {};
	
    	for(i, item in this.items){
        	if(item.isSeparator){
            	frm.add({
                	["sep"+i] = { 
                    	cls = "plus"; left = 8; top = currentY + 2; right = this.width - 8; 
                    	bottom = currentY + 3; bgcolor = 0xE0E0E0; z = i 
                	}
            	});
            	currentY += 6;
            	continue;
        	}
	
        	var ctrlArgs = {
            	cls = "plus"; left = 0; top = currentY; right = this.width; bottom = currentY + this.itemHeight;
            	text = item.text;
            	align = "left";
            	font = LOGFONT(h = -this.fontSize); color = 0x333333;
            	textPadding = { left = 35 }; 
            	notify = 1; z = i;
        	};
	
        	if(item.icon){
            	if(type(item.icon) == type.string && #item.icon <= 8){
                	ctrlArgs.iconText = item.icon;
                	ctrlArgs.iconStyle = { 
                    	font = LOGFONT(h = -this.iconSize; name = 'FontAwesome');
                    	align = "left"; padding = { left = 7 };
                	};
            	}
            	else {
                	ctrlArgs.foreground = item.icon;
                	ctrlArgs.foreRepeat = "point";
                	ctrlArgs.foreAlign = "left";
                	ctrlArgs.x = 8;
                	ctrlArgs.y = 8;
            	}
        	}
	
        	var ctrl = frm.add({ ["item"+i] = ctrlArgs })["item"+i];
        	..table.push(ctrlList, ctrl);
	
        	ctrl.skin({
            	background = { default = this.backgroundColor; hover = 0xFFE8F0FE; active = 0xFFD0E0FC };
            	color = { default = 0xFF333333; hover = 0xFF0078D4 };
        	});
	
        	var callback = item.callback;
        	ctrl.onMouseClick = function(){
            	frm.close();
            	if(callback) callback();
        	}
	
        	currentY += this.itemHeight;
    	}
	
    	frm.wndproc = function(hwnd, message, wParam, lParam){
        	if(message == 0x6/*_WM_ACTIVATE*/){
            	if((wParam & 0xFFFF) == 0){
                	::PostMessage(hwnd, 0x400, 0, 0);
            	}
        	}
        	if(message == 0x400){
            	frm.close();
        	}
    	}
		
    	frm.setPos(x+20, y+20);
    	..win.setForeground(frm.hwnd);
    	frm.show();
	}; 
}

// 准备3张png图标
var imgPath1 = "https://cdn-icons-png.flaticon.com/512/609/609803.png"; //home-icon
var bmpIcon1 = gdip.bitmap(imgPath1).resize(18,18);

var imgPath2 = "https://cdn-icons-png.flaticon.com/512/724/724713.png";	//chat-icon
var bmpIcon2 = gdip.bitmap(imgPath2).resize(18,18);

var imgPath3 = "https://cdn-icons-png.flaticon.com/512/9451/9451615.png"; //security-icon
var bmpIcon3 = gdip.bitmap(imgPath3).resize(18,18);

/*DSG{{*/
var winform = win.form(text="自定义弹出菜单 - (支持fontAwesome图标和背景透明的png图标)";right=759;bottom=469)
winform.add(
hint={cls="bk";text="右键点击窗口,弹出自定义菜单";left=192;top=178;right=551;bottom=266;color=0x999999;db=1;dl=1;dr=1;dt=1;font=LOGFONT(h=-16);z=1}
)
/*}}*/

winform.wndproc = function(hwnd, message, wParam, lParam) {
    if(message == 0x205/*_WM_RBUTTONUP*/){

        // 创建菜单实例
        var menu = customPopMenu(winform);  
        menu.backgroundColor = 0xFFFFFFFF;
        
        // 添加字体图标项
        menu.add("账户信息", 
            function(){
                winform.msgbox("点击了: 账户信息","提示");
            }, 
            '\uF007'
        );
        menu.add("搜索查找", 
            function(){
                winform.msgbox("点击了: 搜索查找","提示");
            }, 
            '\uF002'
        );
        menu.add("系统设置", 
            function(){
                winform.msgbox("点击了: 系统设置","提示");
            }, 
            '\uF013'
        );
        
        menu.addSeparator();
        
        // 添加位图图标项
        menu.add("返回主页", function(){
            winform.msgbox("点击了: 返回主页","提示");
        }, bmpIcon1);

        menu.add("反馈与交流", function(){
            winform.msgbox("点击了: 反馈与交流","提示");
        }, bmpIcon2);
        
        menu.add("隐私与安全", function(){
            winform.msgbox("点击了: 隐私与安全","提示");
        }, bmpIcon3);        
        menu.addSeparator();

        // 添加一个'退出'项
        menu.add("退出程序", function(){
            winform.close();
        }, '\uF011');

        // 弹出菜单
        menu.popup();
    }
}

winform.show();
win.loopMessage();


最新回复 (0)
返回