import win;
namespace win.util;

var NOTIFYICONDATA  = class {
 INT cbSize;
 int hWnd;
 INT uID;
 int uFlags;
 INT uCallbackMessage;
 pointer hIcon;  
 BYTE szTip[128] ;
 INT dwState=0;
 INT dwStateMask=0;
 BYTE szInfo[256]  ;
 union DUMMYUNIONNAME={
 INT uTimeout;
 INT uVersion; // used with NIM_SETVERSION, values 0, 3 and 4
 };
 BYTE szInfoTitle[64]  ;
 INT dwInfoFlags; 
/*
 struct guidItem=..win.guid(); 
 pointer hBalloonIcon; 
*/
}

class tray{
	
	ctor( hwnd,id = 130/*_IDI_MYICON*/  )begin 
		var tnd = NOTIFYICONDATA(); 
		tnd.cbSize =  ..raw.sizeof(tnd); 
		
		if(type(hwnd)==type.table && hwnd.hwnd){//支持winform.hwnd
			tnd.uCallbackMessage = 0x400+9981/*_WM_TRAYMESSAGE*/
			hwnd=hwnd.hwnd;
		} 
		tnd.hWnd	 =  hwnd;
		
		if( type(id) == type.number ) { 
			//tnd.uID	 = 0;
			if(id >= 0x7F00/*_IDI_APPLICATION*/)
			{ 
				tnd.hIcon  =  ::LoadIcon( null, topointer( id ) );
			}
			else{
				tnd.hIcon  =  ::LoadIcon( ::GetModuleHandle(null), topointer( id ) ); 
			}
		}
		else {
			tnd.hIcon = id;
		}
		 
		   
		tnd.uFlags =  0x2/*_NIF_ICON*/  
 		Shell_NotifyIcon( 0x0/*_NIM_ADD*/, tnd );
		this.m_tnd = tnd
	end; 
	
	pop = function(info,title="",icon=1,timeout=10){
		assert( this.m_tnd ,"托盘图标对象已关闭");
		this.m_tnd.DUMMYUNIONNAME.uTimeout = timeout * 1000 ;//10秒至20秒
		this.m_tnd.szInfoTitle = title ;
		this.m_tnd.szInfo = info  ;
		this.m_tnd.uFlags = this.m_tnd.uFlags | 0x00000010/*_NIF_INFO*/
		this.m_tnd.dwInfoFlags =icon;
		Shell_NotifyIcon( 0x1/*_NIM_MODIFY*/,  this.m_tnd ); 
	}
	delete = function(){ 
		Shell_NotifyIcon( 0x2/*_NIM_DELETE*/,  this.m_tnd ); 
		this.m_tnd = null;
	}	
	@traymeta
}

namespace tray{

	::Shell32 := ..raw.loadDll("shell32")
	Shell_NotifyIcon := Shell32.api("Shell_NotifyIconA","int(int dwMessage, struct lpData)");
	
	pop = function(info,title="",icon=1,timeout=10){ 
		var tray = ..win.util.tray(); //创建托盘图标
		tray.pop(info,title,icon,timeout)
	}
	
	traymeta = {
		_get = function(k,v){
			assert( owner.m_tnd ,"托盘图标对象已关闭");
			
			select(k) {
				case "message" 
				{ 
					return owner.m_tnd.uCallbackMessage;
				}
				case "tip"{
					return owner.m_tnd.szTip;
				}
				
			}
		}
		_set = function(k,v){
			assert( owner.m_tnd ,"托盘图标对象已关闭");
			
			select(k) {
				case "message" 
				{ 
					assert( tonumber(v) and ( v>0x400/*_WM_USER*/) ,"回调消息必须是一个大于0x400/*_WM_USER*/的数值")
					owner.m_tnd.uCallbackMessage =  v;
					if(v)
						owner.m_tnd.uFlags = owner.m_tnd.uFlags | 0x1/*_NIF_MESSAGE*/ 
					else{
						owner.m_tnd.uFlags = owner.m_tnd.uFlags & ~0x1/*_NIF_MESSAGE*/
					}
					
					Shell_NotifyIcon( 0x1/*_NIM_MODIFY*/,  owner.m_tnd ); 
				}
				case "tip"{
					owner.m_tnd.szTip = v 
					owner.m_tnd.uFlags = owner.m_tnd.uFlags | 0x4/*_NIF_TIP*/ 
					Shell_NotifyIcon( 0x1/*_NIM_MODIFY*/,  owner.m_tnd );
				}
				
			}
		}
	
	}

}

/*intellisense()
!tray.delete() = 删除托盘图标
!tray.tip = 设置鼠标提示信息
!tray.pop("__","") = 弹出汽泡提示\n参数(提示信息,标题)
!tray.pop("__","",2) = 弹出汽泡提示\n参数(提示信息,标题,警告图标)
!tray.pop("__","",3) = 弹出汽泡提示\n参数(提示信息,标题,错误图标)
!tray.message = 指定回调消息\n当用户点击托盘图标时、向主窗体发送此消息
win.util.tray(__) = 创建托盘图标，参数为主窗体句柄
win.util.tray(__,130) = 创建托盘图标，参数为(主窗体句柄,图标资源ID)
?win.util.tray = !tray.
win.util.tray.pop("__","") = 弹出汽泡提示\n参数(提示信息,标题)
win.util.tray.pop("__","",2) = 弹出汽泡提示\n参数(提示信息,标题,警告图标)
win.util.tray.pop("__","",3) = 弹出汽泡提示\n参数(提示信息,标题,错误图标)
end intellisense*/
