//tab 选项卡
import win.ui.ctrl.metaProperty;//导入控件属性元表支持
namespace win.ui.ctrl; 

//TCM_FIRST 0x1300 // Tab control messages   
class tab{
    ctor(parent,tParam){  
    	if(!tParam)
    		error("该控件不能附加到外部窗口",2)
    	tParam.cls = "SysTabControl32";
    	tParam.style |= 0x40000000/*_WS_CHILD*/ | 0x4000000/*_WS_CLIPSIBLINGS*/ | 0x10000000/*_WS_VISIBLE*/ ;
		if( tParam.multiline ) tParam.style |= 0x0200 //TCS_MULTILINE  
 		this._forms ={}
 		this._history ={};//记录用户切换当前页的历史 
    };
    loadForm = function(code){    
		..win.form=this[["add"]];
		var loopMessage = ..win.loopMessage;
		..win.loopMessage = ..win.hookMessage;
		var func,err = loadcode(code) ;
		if( func ) {
			var ret,wb = func();
			..win.loopMessage  = loopMessage; 
			if( this.lastForm != this.form ){
				this.lastForm.show(false);
			}
			return ret,wb;
		}
		else {
			..win.loopMessage  = loopMessage;
			error( ..string.concat("载入窗体错误:",err),2);
		}  
    };
    loadcode = function(...) {    
		return this.loadForm(...);
    }; 
    add = function(tParam){ 
    	assert(type(tParam)==type.table,"参数必须是table对象");
    	..win.form  = ..win._form; 
    	    
    	var tci = TCITEM();
    	tci.pszText = tParam.text; 
    	tParam.text = null;
    	tParam.parent = this ;
    	tParam.mode="child";
    	tParam.exmode="none";
    	tParam.border="none"
    	tParam.title=false;  
    	if( !(tParam.right && tParam.bottom) ){
    		var rc = this.getClientRect();
    		tParam.right = rc.right;
    		tParam.bottom = rc.bottom;
    	}
    	
    	var wf = ..win.form(tParam);
    	var index = ..table.push(this._forms ,wf)-1;
    	 
    	::SendMessageByStruct(this.hwnd ,4871/*TCM_INSERTITEM*/, index,tci); 
    	::SendMessage(this.hwnd,0x5/*_WM_SIZE*/);
    	
    	this.lastForm = wf; 
    	if(!index){ 
    		this.form = wf;   
    		this.form.show(true);
    		this.adjustRect();
    	}	
    	return wf; 	
    }
    remove = function(i){
    	assert( this._forms[i],"错误的索引")
    	 
    	if( this.form==this._forms[i]){ 
    		this.form = null;
    		..table.pop(this._history)
    		if( #(this._history) ){
    			var form = ..table.pop(this._history);
    			for(i=1;#(this._forms);1){
    				if( this._forms[i] == form ){
    					this.selIndex = i;
    					break ;
    				}
    			} 
    		}
    	}
    	this._forms[i].close();
    	..table.remove(this._forms ,i );
    	::SendMessage(this.hwnd ,4872,topointer(i-1) )
    	
    	if(!this.selIndex)
    			this.selIndex = #this._forms 
    } 
    removeAll = function(){
		for(i=#this._forms;1;-1){ 
			this._forms[i]._closed = true;
			::SendMessage(this._forms[i][["hwnd"]],0x10/*_WM_CLOSE*/);
			..table.remove(this._forms ,i );
		}  
		this.form = null; 
		..table.pop(this._history,#this._history)
    	::SendMessage(this.hwnd ,4873 )  
    } 
    setItem = function(i,tci){
    	::SendMessageByStruct(this.hwnd, 4870,i-1,tci);
    	this._onChange()
    }
    getItem = function(i,tci){
    	tci := TCITEM(); 
    	::SendMessageByStruct(this.hwnd, 4869,i-1,tci);
    	return tci;
    }
    getItemText = function(i,len=100){
    	var tci = TCITEM(); 
    	tci.pszText = ..raw.malloc(len)
    	tci.cchTextMax = len; 
    	return this.getItem(i,tci).pszText; 
    }
    setItemText = function(i,text){ 
    	var tci = this.getItem(i-1);
    	tci.pszText = text;
    	tci.cchTextMax = #text;
    	::SendMessageByStruct(this.hwnd, 4870,i-1,tci); 
    	this._onChange()
    } 
    adjustRect = function(){ 
    	var rc = this.getClientRect();
    	::SendMessageByStruct(this.hwnd, 0x1300+40/*TCM_ADJUSTRECT*/,0,rc);
    	if(this.form){ 
    		var w,h = rc.right - rc.left + 2 ,rc.bottom - rc.top;
    		::MoveWindow(this.form.hwnd, rc.left-2, rc.top, rc.right - rc.left + 2 ,rc.bottom - rc.top ); 
    		::SendMessageInt(this.form.hwnd, 0x5/*_WM_SIZE*/,0,::MAKEWORD(w,h) ); 
    	}
    };
    _adjust = function(){
    	this.adjustRect();
    };
    _onDestroy = function(){ 
    	this.removeAll();
    };
    _prenotify = function(id,code,nmdr){
    	if( code==4294966745/*_TCN_SELCHANGE*/ ){
    		this._onChange();
    	}
    };
    _onChange = function(){
    	var sel = ::SendMessage(this.hwnd,0x1300+11) + 1;
    	sel:=1; 
    	for(i=1;#(this._forms);1){
    		this._forms[i].show(false)
    	}
    	this.form = this._forms[sel];
    	if(this.form){
    		this.adjustRect();
    		this.form.show(true) ;  
    	}
    		
    	..table.push( owner._history,this.form);
    	if(#owner._history > #this._forms ){
    		..table.remove(owner._history);
    	}
    };
	@_metaProperty;
}
 
namespace tab{

	class TCITEM {
 		INT mask = 0x0001|0x0002 ; //TCIF_TEXT | TCIF_IMAGE;
 		INT dwState;
 		INT dwStateMask;
 		string pszText;
 		int cchTextMax;
 		int iImage = -1;
 		int lParam;
	} 
	
	_metaProperty = ..win.ui.ctrl.metaProperty( 
	
		items = {
			_get = function(){ 
				return owner._forms
			} 
		};
		selIndex = {
			_get = function(){ 
				return ::SendMessageInt(owner.hwnd,0x1300+11,0,0) + 1;
			}
			_set = function( v ){
				::SendMessageInt(owner.hwnd,0x1300+12,v-1,0,0 ) ;
				owner._onChange();
			} 	
		};
		getItemRect=function(i){
			var rcTab = ::RECT();
			::SendMessageByStruct( owner.hwnd, 0x130A, i - 1, rcTab);
			return rcTab;
		}
		hitTest = function (x,y,screen=false){
			if( !(x && y) ){
				x,y = ..win.getMessagePos();
				screen = true;
			} 
			if(screen) x,y = ..win.toClient(owner.hwnd,x,y)
			var rcTab;
			for ( i = 1; #owner._forms; 1 ) {
				var rcTab = owner.getItemRect(i)
				if ( ::PtInRect(rcTab, x, y) ) {
					return i;
				}
			} 
		}
	)
	with  _metaProperty {
		fromPoint = hitTest;
	}
}





/***intellisense()
!ui_tab.cls = 设计时类名
!ui_tab.className = 运行时类名
!ui_tab.loadForm("__/*请输入aau文件路径*/") = 加载外部窗体文件并添加到tab页.\n请注意保存外部窗体文件以后测试运行.
!ui_tab.hwnd = 控件句柄
!ui_tab.id = 控件ID
!ui_tab._parentForm = 控件所在的父窗口(指win.form对象)\n!winform.
!ui_tab.getParent() = 返回父窗口\n!static.
!ui_tab.setParent(__/*控件对象*/) = 改变父窗口 
!ui_tab.disabled = 是否禁用
!ui_tab.left = 左侧坐标
!ui_tab.right = 右侧坐标
!ui_tab.top = 顶部坐标
!ui_tab.bottom = 底部坐标 
!ui_tab.width = 宽度
!ui_tab.height = 高度
!ui_tab.redraw() = 刷新
!ui_tab.show(true__) = 显示控件
!ui_tab.getRect() = 控件区块位置(::RECT结构体)
!ui_tab.getRect(true) = 控件屏幕区块位置(::RECT结构体)  
!ui_tab.setRect(rc) = 设置控件区块位置(::RECT结构体)  
!ui_tab.setRect(rc,true) = 设置控件屏幕区块位置(::RECT结构体)
!ui_tab.getClientRect() =  控件客户区块位置(::RECT结构体)\n!rect.
!ui_tab.getFont() = 控件字体(::LOGFONT结构体)\n!logfont.
!ui_tab.setFont(__/*指定字体*/) = 指定LOGFONT字体对象,或逻辑字体句柄 
!ui_tab.setFont(混入字体属性) = @.setFont(point=10;name="宋体");
!ui_tab.clientRect =  获取控件客户区块位置(::RECT结构体)
!ui_tab.theme = 外观主题,例如\nwinform.button.theme = "Explorer"\nwinform.button.theme = false
!ui_tab.remove(__) = 参数为数值，移除指定索引的选项页
!ui_tab.removeAll() = 移除所有选项卡
!ui_tab.items = 返回子窗口列表，只读属性
!ui_tab.items[] = !winform.
!ui_tab.adjustRect() = 调整子窗口大小以适应客户区
!ui_tab.selIndex = 读取或设置当前选项索引\n起始索引为1
!ui_tab.add(__) = 请先用窗体设计器生成创建窗体代码，\n然后将创建窗体的win.form函数替换为此函数。\n函数参数即是win.form的参数(text参数表示选项卡标题)。
!ui_tab.modifyStyle(.(remove,add) = 如果指定第三个参数，则使用此参数调用::SetWidnowPos 
!ui_tab.modifyStyleEx(.(remove,add) = 如果指定第三个参数，则使用此参数调用::SetWidnowPos
!ui_tab.capture = 是否捕获全局鼠标消息
!ui_tab.hitTest(.(x坐标,y坐标,是否屏幕坐标) = 返回坐标指向的选项索引\n参数三可省略,默认为false.\n如果不指定任何参数，则自动调用 win.getMessagePos() 获取消息坐标
!ui_tab.close() = 关闭控件窗口
!ui_tab.setItem(__/*索引*/,"") = 设置选项结构体
!ui_tab.getItem(__/*索引*/) = 读取选项结构体
!ui_tab.setItemText(__/*索引*/,"") = 设置选项卡标题
!ui_tab.getItemText(__/*索引*/) = 读取选项卡标题 
!ui_tab.getItemRect(__/*索引*/) = 读取选项卡区块位置
!ui_tab.invalidate(__/*可选使用::RECT()对象指定客户区*/) = 使窗口绘图区无效
!ui_tab.invalidate(__/*可选使用::RECT()对象指定客户区*/,0) = 使窗口绘图区无效\n不刷新背景
!ui_tab.update() = 重绘invalidate函数指定的区块
!ui_tab.setFocus() = 设置焦点 
!ui_tab.setPos(.(x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序
!ui_tab.getPos() = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
!ui_tab.form = !winform.
win.ui.ctrl.tab.TCITEM() = 选项结构体
win.ui.ctrl.tab() = 选项卡控件\n!ui_tab.
?win.ui.ctrl.tab  =!ui_tab.
end intellisense***/