寫treelistview控制項的那個人的確很牛x,看他的**的確學到了不少東西。。。看後想自己也寫個控制項玩玩,看到有人要三態的treeview,於是花了三天時間學習了一下treeview控制項,寫了一些**,初步達到效果。現將自己的方法介紹如下:
首先說說我用的資料:
反編譯器reflector:看看ms的treeview的架構和寫法
msdn的tree-view control reference:了解每個message和結構的定義和用途
安裝vs下的***mctrl.h檔案:了解message和一些列舉的實際值
做法如下:
step1.定義apisenums.cs檔案,參照***mctrl.h給出
#region treeviewmessages / tvm
///
/// treeview messages / tvm
///
public enum treeviewmessages : int
#endregion
等結構,由於比較多,這裡就不一一枚舉了。。但我主要用到的就這個,其他的比較常用的像什麼nmhdr
的就不寫出來了。。
step3 .定義apisuser32.cs檔案,給出了
//hittest
[dllimport("user32.dll", charset=charset.auto)]
public static extern intptr sendmessage(intptr hwnd, apisenums.treeviewmessages msg, int wparam, ref apisstructs.hittestinfo lparam);
//getrec
[dllimport("user32.dll", charset=charset.auto)]
public static extern bool sendmessage(intptr hwnd, apisenums.treeviewmessages msg, bool wparam, ref apisstructs.rect rc);
等。。。。
step4.開始寫extreenode:treenode了,在這裡,我 修改了如下屬性:
#region checked
private checkstates checkedstate = checkstates.unchecked;
[defaultvalue(typeof(checkstates), "unchecked")]
public new checkstates checked
set
if((this.checkeddirection & checkdirection.downwards) == checkdirection.downwards)
}break;
#endregion
case checkstates.checked:
if((this.checkeddirection & checkdirection.all) != checkdirection.all)
if((this.checkeddirection & checkdirection.downwards) == checkdirection.downwards)
}#endregion
#region parent
///
/// get the parent of this item
///
new public extreenode parent
}#endregion
#region treeview
public new extreeview treeview
}#endregion
加入了乙個屬性
#region checkeddirection
private checkdirection checkdirection = checkdirection.none;
public checkdirection checkeddirection
set}
#endregion
其中checkdirection和treelistview的一樣。
step5.開始寫extreeview : treeview了,新增了私有變數
private extreenode _clickednode = null;
重寫了checkboxes屬性。。
#region checkboxes
private checkboxestypes checkboxes = checkboxestypes.none;
[category("modified properties")]
[defaultvalue(typeof(checkboxestypes), "none")]
[browsable(true)]
new public checkboxestypes checkboxes
set
}#endregion
step6開始重寫訊息處理部分了
由於我準備只用click來重繪,而暫時不從customdraw裡擷取,所以**如下
#region lbuttondown
case apisenums.windowmessages.lbuttondown:
apisstructs.hittestinfo hittestinfo = new apisstructs.hittestinfo();
hittestinfo.pt.x = (short) ((int) m.lparam);
hittestinfo.pt.y = ((int) m.lparam) >> 0x10;
intptr hitem = apisuser32.sendmessage(this.handle,apisenums.treeviewmessages.hittest,0,ref hittestinfo);
if((hittestinfo.flags & (uint32)apisenums.tvhtflags.onitemstateicon) != 0 )
switch(checkednode.checked)
this._clickednode = checkednode;
}break;
#endregion
然後重寫onclick及其對應的方法如下
protected override void onclick(eventargs e)
if(temp.parent.checked == checkstates.checked)
temp = temp.parent;
}break;
case checkstates.halfchecked:
break;
case checkstates.checked:
while(temp.parent!=null)
if(temp.parent.checked == checkstates.checked)
temp = temp.parent;
}break;}}
}private void drawhalfchecked(extreenode node)
}private void drawchecked(extreenode node)
}由於我沒有那個打勾的icon,這裡先用乙個咖啡色的東西先表示那個勾,放在drawchecked裡。
到這裡基本實現了外觀的三態,其實更標準的是截獲customdraw對每次重繪的item進行指定,但最近專案也忙,還沒有那麼多時間,等過段時間再來完成,實現真正的三態。。像那個extreenode對應的editor都沒有寫,還有drawhalfchecked裡沒有計算用image時的大小,如果用了還要再-16。。。還有。。。很多很多沒做,這只是一種嘗試。。過幾天再來完善。。。
呵呵,謝謝各位看管,歡迎各位批評指正。。。
程序的三態模型
程序一般有3種基本狀態 執行 就緒和阻塞。1 執行 當乙個程序在處理機上執行時,則稱該程序處於執行狀態。處於此狀態的程序的數目小於等於處理器的數目,對於單處理機系統,處於執行狀態的程序只有乙個。在沒有其他程序可以執行時 如所有程序都在阻塞狀態 通常會自動執行系統的空閒程序。2 就緒 當乙個程序獲得了...
三態門(三態緩衝器)的工作原理
於 為減少資訊傳輸線的數目,大多數計算機中的資訊傳輸線均採用匯流排形式,即凡要傳輸的同類資訊都走同一組傳輸線,且資訊是分時傳送的。在計算機中一般有三組匯流排,即資料匯流排 位址匯流排和控制匯流排。為防止資訊相互干擾,要求凡掛在匯流排上的暫存器或儲存器等,它的傳輸端不僅能呈現0 1兩個資訊狀態,而且還...
三態門有乙個訊號控制端en 三態門輸出的三種狀態
三態指其輸出既可以是一般二值邏輯電路,即正常的高電平 邏輯1 或低電平 邏輯0 又可以保持特有的高阻抗狀態,那麼三態門輸出的三種狀態是什麼呢?三態門輸出的三種狀態 三態門的三種狀態為 高電平,低電平,高阻態 就是高阻抗,電阻很大,相當於開路 1 處於高阻抗狀態時,輸出電阻很大,相當於開路,沒有任何邏...