以下文章載自:【巴蠻子的破新茅屋】
windows程式設計的習慣是直接指定控制項的座標和大小,而unix下面的習慣是在容器裡面堆放,用不同的layout manager來控制布局(j**a,wx等也是這種思想)。這也是為什麼windows程式的對話方塊一般都不讓改變大小(因為這意味著要自己寫很多**逐步調整子控制項的位置),而unix下一般都可以。delphi程式原來有align屬性來控制控制項對那邊靠攏。但如果想要乙個控制項固定離左邊、右邊有多遠,得用d6開始提供anchors屬性。
所以delphi提供3種布局屬性:align, anchor,和 constraint。基本能滿足布局設計的需要。
這樣還是不夠的,比如有七八個按鈕順排或者**式布局,這在d2006裡面可以用新增的tflowpanel和tgridpanel來實現。
tflowpanel和tgridpanel的使用方法:
呵呵,沒找到中文說明的,只能看看e文了。裡面的demo無法down。
其中有乙個事情要注意:任何乙個控制項被放到這兩個布局上後,無法調整位置,delphi提供了一種方法,就是選擇要調整的控制項,在屬性窗體的最下面會出現和布局有關的屬性,進行調整就可以了。tflowpanel有controlindex。tgridpanel有column,row,columnspan,rowspan。
評價
delphi提供的gridpanel貌似很好,但是使用起來實在不方便。我自己用gridpanel準備畫乙個人口資訊的輸入介面,結果畫了一會就覺得煩了,根本沒辦法用。考慮再三,還是自己寫乙個。
至少提供如下功能:
1.能夠在設計狀態用滑鼠調整行的行的寬度和列的高度。
2.panel的寬度和高度應該隨著裡面行和列的高度和寬度的變化而變化。而不應該是像gridpanel,寬度和高度不邊,而讓行和列的值來適應gridpanel。
3.能方便的增加和刪除行和列。
4.放入pane中的控制項的寬度要隨著所在格仔的寬度變化而變化。
開發思路:
1.從tcustomgridpanel繼承。
2.在設計狀態當滑鼠移動到網格線上的時候,cursor變成可crhsplit和crvsplit,(可以通過繼承wmsetcursor來實現)
3.設計狀態,當在網按住滑鼠並移動的時候,修改對應的格仔的大小(可以通過繼承wmlbuttondown,wmlbuttonup,和wmmousemove來實現)
4.當panel上放入乙個控制項的時候,自動設定到對應格仔的寬度(可以通過繼承aligncontrols來實現)。
5.增加rowcount和columncount屬性,可以通過設定這兩個屬性來設定行和列的總數。
效果:
可惜,這個gif無法顯示滑鼠移動到網格中的時候改變滑鼠形狀的情況。
delphi問題
在寫這個panel的時候發現乙個問題,可能是delphi的bug
在extctrls單元第3500行,procedure tcustomgridpanel.aligncontrols(acontrol: tcontrol; var rect: trect);方法中,**如下:
anchorsubset := acontrol.anchors * [akleft, akright];
if anchorsubset = [akleft] then
newbounds.left := cellrect.left
else if anchorsubset = [akright] then
newbounds.left := max(cellrect.left, cellrect.right - acontrol.margins.explicitwidth)
else
newbounds.left := max(cellrect.left, cellrect.left + ((cellrect.right - cellrect.left) - acontrol.margins.controlwidth) div 2);
這個應該是乙個明顯的bug,如果control的anchors同時設定了akleft和akright,則系統就不再處理,也就是前面提到的如果用gridpanel,放到panel上的控制項無法根據格仔的寬度自動調整寬度。
修復方法:增加乙個判斷就可以:
anchorsubset := acontrol.anchors * [akleft, akright];
//hl add 20090415原來控制項沒有提供對 anchors = akleft, akright的處理
if anchorsubset = [akleft, akright] then
begin
newbounds.left := cellrect.left;
newbounds.right := cellrect.right;
endelse begin
if anchorsubset = [akleft] then
newbounds.left := cellrect.left
else if anchorsubset = [akright] then
newbounds.left := max(cellrect.left, cellrect.right - acontrol.margins.explicitwidth)
else
newbounds.left := max(cellrect.left, cellrect.left + ((cellrect.right - cellrect.left) - acontrol.margins.controlwidth) div 2);
newbounds.right := newbounds.left + min(cellrect.right - cellrect.left, acontrol.margins.explicitwidth);
end;
關於delphi指標
大家都認為,c語言之所以強大,以及其自由性,很大部分體現在其靈活的指標運用上。因此,說指標是c語言的靈魂,一點都不為過。同時,這種說法也讓 很多人 產生誤解,似乎只有c語言的指標才能算指標。basic不支援指標,在此不論。其實,pascal語言本身也是支援指標的。從最初的pascal發展至今 的ob...
關於delphi 窯洞的關閉
我的老家在陝西渭北,祖祖輩輩住在窯洞裡,窯洞裡面冬暖夏涼,結實耐用,非常舒服。隨著新農村的改造,新蓋的樓房慢慢替代了古老的窯洞,剩下的窯洞漸漸越來越少人住了,也慢慢的荒涼起來,估計再過幾十年後,窯洞也就成了遺跡了。我從1998年開始建立delphi 窯洞 一直致力於推廣delphi 技術,由當時的個...
Delphi7 IDE布局技巧
玩了五年delphi7,最近才發現一點ide介面布局的小技巧 1.object treeview和object inspector預設在左側上下分布,兩個框都很小,顯示內容有限 其實可以合併成乙個pagecontrol式的大屬性框,同樣的空間,顯示內容更多,兩項也可以方便的切換 只要把其中乙個拖到另...