線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2167
推到 Plurk!
推到 Facebook!

請問FileListBox如何在底部加上ScrollBar

尚未結案
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-03-09 14:03:40 IP:220.130.xxx.xxx 未訂閱
大家好,我的程式上面有一個FileListBox元件,我用它來顯示出某個目錄下面 的檔案,但我發現一個問題,當我的檔名很長時它無法顯示出所有的檔名 也就是說這個元件的底部少了一個可以左右移動的ScrollBar,所以想請教一下 大家該如何去解決這一個問題,謝謝大家!!!
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-03-09 19:50:31 IP:140.135.xxx.xxx 未訂閱
aredfish您好: 若是單純讓水平的ScrollBar出現可以使用下面方式
SetScrollRange(FileListBox1->Handle, SB_HORZ, 0, 10, true);
不過實際上是沒有效用的< > 您可以再等前輩們指導< > 發表人 - taishyang 於 2004/03/09 19:51:12
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-03-10 08:46:20 IP:220.130.xxx.xxx 未訂閱
我一直在try這個問題,我覺得它不會自動出現下面的ScrollBar的原因會不會是因為沒有去設定Column 因為在ListView這一個元件裡如果去增加一個Column,且這一個Column 的寬度大於左右邊的長度,那麼下面的ScrollBar就會自動出現. 我在想FileListBox是不是也可以做相同的事情?? 我目前try的情形是沒有辦法 所以想請教一下大家這個辦法是不是可行,另外,如果真的沒辦法,能不能用 ListView來代替FileListBox ??
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-03-10 08:58:59 IP:211.21.xxx.xxx 未訂閱
引言: aredfish您好: 若是單純讓水平的ScrollBar出現可以使用下面方式
SetScrollRange(FileListBox1->Handle, SB_HORZ, 0, 10, true);
不過實際上是沒有效用的< > 您可以再等前輩們指導< > 發表人 - taishyang 於 2004/03/09 19:51:12
try try see ..
//讓ListBox有水平捲軸
       int maxwidth =0;
       const int border = 3;
       for (int ii=0;iiItems->Count;  ii)
           {
             String text = ListBox1->Items->Strings[ii];
             int width = ListBox1->Canvas->TextWidth(text);
             if (width>maxwidth) maxwidth = width;
           }
       maxwidth=maxwidth*1.5;  //我自己加的....因為捲軸寬度不夠
       SendMessage( ListBox1->Handle,LB_SETHORIZONTALEXTENT,maxwidth 2*border,0);  
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-03-10 09:14:09 IP:210.243.xxx.xxx 未訂閱
aredfish您好 提供您一些想法,除非您有要用到FileListBox元件的特殊功能,如果只是單純 要Show的話,使用ListBox就能達到您的要求了,剛嚐試的結果,ListBox增加 Column屬性就會自動產生水平捲軸,FileListBox卻沒有Column屬性... 這也是頗令人百思不解之處,因為它們都繼承於TCustomListBox... 如果一定要用FileListBox的話,小弟之前的做法是使用Hint的方式來補足... 不過這是個消極的做法就是了... 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-03-10 11:53:32 IP:61.63.xxx.xxx 未訂閱
引言: 大家好,我的程式上面有一個FileListBox元件,我用它來顯示出某個目錄下面 的檔案,但我發現一個問題,當我的檔名很長時它無法顯示出所有的檔名 也就是說這個元件的底部少了一個可以左右移動的ScrollBar,所以想請教一下 大家該如何去解決這一個問題,謝謝大家!!!
aredfish你好< >: 這個問題其實很簡單,就觀念上< >! 即: 1. FileListBox沒有水平ScrollBar 2. 想要 3. 自已給一個ScrollBar 4. ScrollBar沒做用(當然) 5. 自已加程式讓它有做用 6. ScrollBar可以做用,FileListBox會跟它水平移動 範例: 1. 右邊是ListBox的範例,因為ListBox有DrawItem事件比較好處理 2. ListBox用DrawItem事件時,要先將style屬性切為lbOwnerDrawVariable 3. 左邊是FileListBox範例,FileListBox沒有DrawItem事件,所以要自已攔訊息(WM_DRAWITEM),比較麻煩 程式碼:
In Unit.h    ~~
class TForm1 : public TForm
{
__published:        // IDE-managed Components
        TListBox *ListBox1;
        TScrollBar *ScrollBar1;
        TFileListBox *FileListBox1;
        TScrollBar *ScrollBar2;
        void __fastcall ListBox1DrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State);
        void __fastcall ScrollBar1Scroll(TObject *Sender,
          TScrollCode ScrollCode, int &ScrollPos);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall ScrollBar2Scroll(TObject *Sender,
          TScrollCode ScrollCode, int &ScrollPos);
private:        // User declarations
        void __fastcall FormWndProc(TMessage&);  <---注意WM_DRAWITEM訊息是要在Form攔
        TWndMethod OldFormWndProc;
public:                // User declarations
        __fastcall TForm1(TComponent* Owner);
};
~~    In Unit.cpp    [green]
~~
TForm1 *Form1;    int ScrollPosition;
int ScrllPos;    //---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 OldFormWndProc=Form1->WindowProc;
 Form1->WindowProc=FormWndProc;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index,
      TRect &Rect, TOwnerDrawState State)
{
 ListBox1->Canvas->FillRect(Rect);
 ListBox1->Canvas->TextOut(Rect.Left-ScrollPosition, Rect.Top+1, ListBox1->Items->Strings[Index].c_str());
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender,
      TScrollCode ScrollCode, int &ScrollPos)
{
 ScrollPosition=ScrollPos;
 ListBox1->Repaint();
}
//---------------------------------------------------------------------------    下面為FileListBox部份    void __fastcall TForm1::FormWndProc(TMessage& Message)
{
 if (Message.Msg==WM_DRAWITEM) {
     DRAWITEMSTRUCT* drawitemstruct;
     drawitemstruct=(LPDRAWITEMSTRUCT)Message.LParam;         if (Message.WParam==(LONG)FileListBox1->Handle) {             RECT rect=drawitemstruct->rcItem;
         FileListBox1->Canvas->FillRect(rect);
         FileListBox1->Canvas->TextOutA(rect.left-ScrllPos,rect.top+1,FileListBox1->Items->Strings[drawitemstruct->itemID].c_str());             return;
     }
 }     OldFormWndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 //注意初始的設定
 FileListBox1->ApplyFilePath("c:\\test");
 ScrollBar2->Max=200;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar2Scroll(TObject *Sender,
      TScrollCode ScrollCode, int &ScrollPos)
{
 ScrllPos=ScrollPos;
 FileListBox1->Repaint();
}
//---------------------------------------------------------------------------

初始狀況: 用ScrollBar拖到可以看到最後的字: 注意ScrollBar的Max屬性的設定,以便可以捲到字串的最後,其它應該沒什麼大問題了!That's all! 發表人 -
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-03-10 13:58:29 IP:140.135.xxx.xxx 未訂閱
bruce0211大哥太帥了 既讓 > > 發表人 -
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-03-10 15:31:13 IP:220.130.xxx.xxx 未訂閱
m8815010大大您好,謝謝您的回答,我試過您的範例 不過不會動,我想是我有些地方寫錯了,我單步執行後發現 每次執行到 >
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-03-10 21:10:06 IP:203.73.xxx.xxx 未訂閱
引言: m8815010大大您好,謝謝您的回答,我試過您的範例 不過不會動,我想是我有些地方寫錯了,我單步執行後發現 每次執行到 > < face="Verdana, Arial, Helvetica"> aredfish你好< >! 首先說明一下我的程式有在我電腦成功執行,才敢>這是一定要的啦< >)! 環境是>> 回到問題,看了一下,我實在抓不出你說的那行有什麼問題,而我的程式碼好像也沒貼錯!所以最直接的方式是你把compile的錯誤訊息借我看,我就知道你的程式是那裡有問題啦< >! <>> 至於>沒惡意< >),明顯的由我的程式碼可以看出這個訊息我是攔>> <>不過借由我的再重看程式,我也發現我的程式有個 >! < class="code"> In Unit1.h ~~~ class TForm1 : public TForm { __published: // IDE-managed Components TFileListBox *FileListBox1; TScrollBar *ScrollBar1; void __fastcall FormCreate(TObject *Sender); void __fastcall ScrollBar1Scroll(TObject *Sender, TScrollCode ScrollCode, int &ScrollPos); private: // User declarations void __fastcall FormWndProc(TMessage&); TWndMethod OldFormWndProc; public: // User declarations __fastcall TForm1(TComponent* Owner); }; ~~~ In Unit.cpp ~~~ TForm1 *Form1; int ScrllPos; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldFormWndProc=Form1->WindowProc; Form1->WindowProc=FormWndProc; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormWndProc(TMessage& Message) { if (Message.Msg==WM_DRAWITEM) { DRAWITEMSTRUCT* drawitemstruct; drawitemstruct=(LPDRAWITEMSTRUCT)Message.LParam; if (Message.WParam==(LONG)FileListBox1->Handle) { OldFormWndProc(Message); RECT rect=drawitemstruct->rcItem; FileListBox1->Canvas->FillRect(rect); FileListBox1->Canvas->TextOutA(rect.left-ScrllPos,rect.top 1,FileListBox1- >Items->Strings[drawitemstruct->itemID].c_str()); return; } } OldFormWndProc(Message); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { FileListBox1->ApplyFilePath("c:\\test"); ScrollBar1->Max=200; } //--------------------------------------------------------------------------- void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender, TScrollCode ScrollCode, int &ScrollPos) { ScrllPos=ScrollPos; FileListBox1->Repaint(); } //--------------------------------------------------------------------------- 請重新撰寫上列程式,不要拿一開始的去該改成這樣,怕改錯! 嗯!這樣應該差不多了,有問題再說吧!
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-03-11 11:16:15 IP:220.130.xxx.xxx 未訂閱
m8815010大大,非常謝謝您的指導,您的程式並沒有問題,Compiler也是正常的 執行途中也不會出現任何錯誤訊息,我想我這裡不能執行的原因可能還是 WM_DRAWITEM訊息的關係,因為我本身並不具備任何有關Windows訊息的知識 甚至常識< >,所以我想可能的原因在於我 >可能是訊息的 問題吧,所以想再請教您一下該怎麼處理呢?? 謝謝!!!< >
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-03-11 12:40:16 IP:61.63.xxx.xxx 未訂閱
引言: 因為我本身並不具備任何有關Windows訊息的知識 甚至常識,所以我想可能的原因在於我>< face="Verdana, Arial, Helvetica"> 嗯,其實我也不是很瞭解啦,只是對於我自已回應的部份,我比較知道一點來龍去脈而已啦! <>< face="Verdana, Arial, Helvetica">引言: 我想我這裡不能執行的原因可能還是 WM_所以我想可能的原因在於我Form的設計上面. 我的Form上面疊了一個TabSheet,然後又疊了一個Panel,最後才是那些 ScrollBar及FileListBox,我試過您的範例是OK的,不過若我將FileListBox 放到TabControl或者是Panel上面,那就失效了,因此我猜< >可能是訊息的 問題吧,所以想再請教您一下該怎麼處理呢?? 謝謝!!!< >
啊呀!aredfish你這樣一講我就瞭解了,原來如此!好險我沒繼續查我的程試! 不過你一開始就說對問題點了!只是你可能沒看到 >,那我幫你 src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=14499425&CC=324275"> Get it? 我的例子FileListBox是長在Form上的,所以我當然去Form攔WM_DRAWITEM訊息,那今天你的FileListBox長在Panel上當然要去Panel攔訊息囉! 嗯,如果攔截的寫法aredfish你還不是那麼ok的話,就彷造範例攔 >!
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-03-11 14:20:14 IP:220.130.xxx.xxx 未訂閱
謝謝m8815010大大的幫忙,所以您的意思是說我必須去找一個訊息 這個訊息是在當FileListBox重畫的時候會被觸發,然後會把這個訊息傳到 Panel去,所以我才能收的到~~~也就因為這樣,所以WM_DRAWITEM不能用 必須要再去找一個WM_xxxx的東西來用...是這樣子嗎??  再問一下喔!! 圖上的那個 > 非常謝謝您的幫忙!!
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-03-11 15:26:50 IP:61.63.xxx.xxx 未訂閱
引言: 謝謝m8815010大大的幫忙,所以您的意思是說我必須去找一個訊息 這個訊息是在當FileListBox重畫的時候會被觸發,然後會把這個訊息傳到 Panel去,所以我才能收的到~~~也就因為這樣,所以WM_DRAWITEM不能用 必須要再去找一個WM_xxxx的東西來用...是這樣子嗎?? 再問一下喔!! 圖上的那個 > 非常謝謝您的幫忙!! < face="Verdana, Arial, Helvetica"> 啊,aredfish……你你…你真的要請我喝飲料了< >! 你一題就問的我耗盡筆墨,掏空我僅會的一些東東< >! 一次給你講清楚! src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=14501303&CC=324317"> 2. WM_DRAWITEM這個訊息不是每個元件都有的,是像有一條一條item這樣類型的元件才有的,如前圖說明。 3. 嚴格說,WM_DRAWITEM觸發是當這個元件,如FileListBox,它的item需要被重繪時,不太能說一個元件需要被"重繪"時觸發,因為元件需要被重繪是觸發WM_PAINT事件。 4. 所有這類的元件,在有item需要重繪時,都是發WM_DRAWITEM這個事件的,no others。 5. 為什麼要做item重繪?for example! 對一個ListBox的垂直ScrollBar做上下拖移,則它必需一直重繪,才能滿足看似item一直跟著動的感覺。 6. 上述過程的實際發生情況: 使用者用滑鼠拖移ScrollBar-->作業系統偵測到-->發出WM_DRAWITEM訊息告訴這個元件的Owner-->這個元件的Owner收到WM_DRAWITEM訊息-->讓這個元件做item重繪 7. 我的範例中: 元件-->FilelistBox1 ----------- 元件的Owner-->Form1 8. 故今天我在Form內攔訊息,當攔到WM_DRAWITEM訊息時,表示Form上面的FileListBox需要重繪item 了。 9. 知道FileListBox要重繪後,就動手腳,讓它動繪的樣子是我們要的。 10. 你可能會問第6點中,使用者用滑鼠拖移FileListBox的ScrollBar,我就已經知道要重繪了呀,為什麼要到Form攔訊息這麼做?因為這樣做比較easy!Most people do it this way! 11. 今天你的FileListBox元件的Owner是一個Panel,所以要在Panel攔WM_DRAWITEM訊息。 12. 直接說,只要把我範例程式中攔WM_DRAWITEM訊息那部份: ---->有關Form的部份全部改成Panel 13. 堅持不幫你直接寫出source code,因為這樣已經沒意義了! That's all,手好酸!
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-03-11 17:29:21 IP:220.130.xxx.xxx 未訂閱
請你台塑小牛排都沒問題~~< >,超感謝您的啦 雖然我現在還沒搞定,不過您老真的幫了很多忙了< >...再感謝您一下 謝謝啦!!!
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-03-11 21:09:42 IP:210.244.xxx.xxx 未訂閱
超級感動的...剛才我把Form1改成Panel1就成功了~~~ >
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-03-15 13:10:00 IP:61.63.xxx.xxx 未訂閱
引言: 超級感動的...剛才我把Form1改成Panel1就成功了~~~ > < face="Verdana, Arial, Helvetica"> 是吧是吧,只要Form物件部份改成Panel物件就ok了! 哦,我彷彿見證一個青年刻苦勤練 >!
系統時間:2024-04-25 23:32:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!