全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1792
推到 Plurk!
推到 Facebook!

請問一下如何計算出一個元件可以顯示幾行資料?

尚未結案
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-03 11:40:32 IP:211.22.xxx.xxx 未訂閱
包括有Canvas 例如 TStringGrid 和沒有 Canvas 例如 TMemo 我的目的是為了計算Scroll Bar 的座標 我原先是以為只要把 Height / Canvas->TextWidth("w") 結果並不是我所預期的數字 1.以TStringGrid 來說,在Object Inspector 上,DefatltRowHeight = 24 , RowCount = 10,必須設定 Height = 255,才不會出現ScrollBar 可是理論上計算Height 24 * 10 = 240 ,那多的15 難道是每個Row 的邊框嗎? 那我該如何取得邊框大小呢? 2.TMemo 沒有 Canvas ,只有Lines ,不能用Canvas->TextWidth("w") 我就不知道該怎麼利用Height 屬性,在 Design Time 或是 Run Time 去得到TMemo 可以容納幾行資料,才不會出現 ScrollBar? 請大家幫我指點迷津!
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-03 12:53:04 IP:203.75.xxx.xxx 未訂閱
你的算法錯誤, 要除的話是 TextHeight, 而不是 Width, 另外我怎麼樣都想不出為什麼要在 StringGrid 去控制 Scroll Bar, 可否把而求說清楚一些, 應該有其它方法可解. 如果一定要這樣的話, 我等一下作個測試看如何可達到這個要求.    Jesse Chan 發表人 - jessechan 於 2003/04/03 12:56:25 發表人 - jessechan 於 2003/04/03 12:59:22
------
Jesse Chan
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-03 13:13:18 IP:203.75.xxx.xxx 未訂閱
回答你第一個問題, Height = DefaultRowHeight + GridLineWidth * (RowCounts + 1) + Border * 2 這有一些限制, 如果你可以讓使用者改變 Grid 的長寬, 你就要用 RowHeights[row] 去一一取得高度的值, 再者你要檢查 BorderStyle 如果是 bsNone 則不須考慮 border.    Jesse Chan
------
Jesse Chan
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-03 14:08:13 IP:211.22.xxx.xxx 未訂閱
抱歉我打錯了是TextHeight 我是之前問了一個,兩個ScrollBar 同步問題 Okiss 兄,解答了這一題,可惜美中不足的是, 畫面上Memo 的 Thumb Size 與TScrollBar Thumb 沒有一樣 所以我必須先計算Memo 一個畫面上可以容納幾列資料 我才可以藉由此數據,等比例去計算出TScrollBar Thumb size 例如 Memo1->Height = 185 / Form1->Canvas->TextHeight = 14; 可是畫面上卻只有12列資料,然後下面多出了一些空白區域 TStringGrid 因為有 RowCount 屬性,所以比較好計算 至於Height 與 DefaultRowHeight 的關係,只是好奇純研究
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-03 15:02:08 IP:203.75.xxx.xxx 未訂閱
第二題, 我教你一個撇步, 先設定 TMemo 的 VScrollBar 為 true, 在開始時先偷偷加幾行字進 TMemo, 每加一行就用 GetScrollPos 去檢查是否 scrollbar 有移動, 直到開始移動就是你所要的值了, 最後再把一切還原, 辛苦電腦了, 方法雖醜, 可是原理簡單又萬無一失.    Jesse Chan
------
Jesse Chan
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-03 15:14:43 IP:211.22.xxx.xxx 未訂閱
上次我問了一篇,兩個ScrollBar 同步問題 http://delphi.ktop.com.tw/topic.php?topic_id=27548 jessechan 桑,請教一下! 問題一 int wParam = ScrollPos << 16; wParam = wParam (int)LOWORD(ScrollCode); SendMessage(Memo1->Handle, WM_HSCROLL, wParam,NULL); 我查了 Help WM_HSCROLL 有提到,它只能攜帶 16 bits 的 Data postion 最大值 65535 ,可是Okiss 桑卻將 wParam 乘以二的16次方 25536 用 SendMessage 送出去,我一直想不透,你能夠解釋嗎? 問題二 我垂直的 ScrollBar 用以下的方式計算,誤差很小 int max,min; ScrollBar1->Position = GetScrollPos(Memo1->Handle, SB_VERT); GetScrollRange(Memo1->Handle, SB_VERT, &min, &max); ScrollBar1->Min = min; ScrollBar1->Max = max; ScrollBar1->PageSize = max - ( max - (Memo1->Height / Canvas->TextHeight("H") - 1)); // -1 或是 -2 是因為,我無法精確計算,不過誤差不大,我無所謂 但是水平方面,誤差實在太大了! 我的Width = 241 ,Canvas->TextWidth("W") = 11 可是畫面上只能放大約45 個英文字 ScrollBar2->Position = GetScrollPos(Memo1->Handle, SB_HORZ); GetScrollRange(Memo1->Handle, SB_HORZ, &min, &max); ScrollBar2->Min = min; ScrollBar2->Max = max; ScrollBar2->PageSize = max - ( max - (Memo1->Width / Canvas->TextWidth("W") - 2));
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-03 15:58:01 IP:203.75.xxx.xxx 未訂閱
先回答你第二個問題, 第一個問題還要看一下 history, 要計算 TextWidth 比 Height 要麻煩, 除非你把字型設成 Courier, 不然你的字會寬寬窄窄的, 因為每個字寬度不一樣, 你又不知道人家會輸入什麼, 你如何得知一行可放幾個字, 因為根本沒有正確答案, 而且我算出來數值是正確的, 那個寬度 - 2 * border 真的等於可 key 入的 "W" 數, 所以你要用這種方法算, 先把字型設成 Courier 再去算就對了.    Jesse Chan
------
Jesse Chan
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-03 16:03:47 IP:203.75.xxx.xxx 未訂閱
第一個問題請查一下 BCB 的 windows SDK help, HIWORD 放的是 position, wParam 是 int 型態, 共四個 bytes.    Jesse Chan
------
Jesse Chan
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-04-04 12:41:26 IP:211.22.xxx.xxx 未訂閱
jessechan 桑,你提供的方法很不錯, 在Design Time 先打一些字元來得到 Row 的資訊。 至於 int wParam = ScrollPos << 16; 在你的提示之下,我終於懂了,謝謝! 我大概知道問題的癥結點,是在於 GetScrollRange(), 這支 API 不爭氣,算出的 max 值不正確。但是SB_VERT 情況是正確的! GetScrollRange(Memo1->Handle, SB_HORZ, &min, &max); 傳回的 max = 360 ,可是我使用下面的笨方法測試, ShowMessage(GetScrollPos(Memo1->Handle, SB_HORZ)); 每移動一次位置,顯示座標,移到最右邊所得到的值是 142, 和360 實在相差太大了!請問一下,該如何校正?
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-04-05 15:44:17 IP:61.228.xxx.xxx 未訂閱
我沒有去試 VERT 的狀況是如何, 只就你提問的部份作測試, 我得到以下的結果, 基本上 Max 的值是沒有錯的, 因為 Max 的值等於你最大可移動的值加上 Thumb 的寬度, 但是 Thumb 的寬度是會改變的, 所以你要計算可移動量要用 SetScrollPos 移到 Max 再用 GetScrollPos 去得到那時的真正位置, 兩個相減就等於 Thumb 了. 剩下的自己做.    Jesse Chan
------
Jesse Chan
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-04-07 14:47:38 IP:211.22.xxx.xxx 未訂閱
感謝jessechan 桑!問題可以解決了! 我利用假日去買了 BCB&Window API 範例辭典, 以免老是要麻煩jessechan 桑等級的高手幫我解決問題, 不知jessechan 桑,你以前學API 除了看 MSDN 外, 還看了什麼好書?可以介紹一下嗎?
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-04-07 14:58:21 IP:203.75.xxx.xxx 未訂閱
說真的這部份的書不是說去買了一兩本, 然後發奮從頭K到完就能全部了解, 因為東西太多了, 大概看到中間, 前面已經忘了, 我覺得最好還是 project 有碰到再去找相關資料比較好, 不過剛開始可能常有書到用時方恨少的遺憾(我到現在還是常有), 所以高手二字是絶對擔當不起. 說到書, 我昨天剛好去天瓏逛逛, 發現這個 topic 的書快找不到了, 所以目前我還是以 M$DN 為主要的參考資料, 不足再上網找.    Jesse Chan
------
Jesse Chan
系統時間:2024-05-03 13:39:51
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!