請問如何讓兩個ListView的Scrollbar作同步化 |
尚未結案
|
u8702656
一般會員 發表:2 回覆:5 積分:1 註冊:2003-07-10 發送簡訊給我 |
請教各位前輩
小弟目前在作資料夾中所有檔案的synchronization功能,因此必須使用兩個ListView用vsReport的ViewStyle作比對的列表,讓user方便對照
因為ListView中的ScrollBar為動態產生的所以沒有OnScroll這個Event,所以我是把Scroll的動作寫在OnCustomDrawItem中,並且在程式中判斷滑鼠所在的位置決定由哪一個ListView的OnCustomDrawItem事件來更新Scrollbar的位置,
但是這會造成當我再拖拉時滑鼠不在原本按下的那個ListView時,無法執行更新動作,以下是我的程式碼..
//---------------------------------------------------------------------------
void __fastcall TForm4::ListView2CustomDrawItem(TCustomListView *Sender,TListItem *Item, TCustomDrawState State, bool &DefaultDraw)
{
RECT r;
::GetWindowRect(ListView2->Handle,&r);
//取得滑鼠位置
POINT pd;
GetCursorPos(&pd);
if(::PtInRect(&r,pd))
{
SCROLLINFO scroll; //宣告(ScrollBar)結構
memset(&scroll,0,sizeof(SCROLLINFO));//結構初始化
scroll.fMask = SIF_ALL; //取得ScrollBar全部資料的旗標
scroll.cbSize = sizeof(SCROLLINFO); //配置足夠記憶體
if(GetScrollInfo(ListView3->Handle,SB_VERT,&scroll))//取得垂直
//ScrollBar的資訊
//返回值如果是真的將得到以下各種資訊,否則代表ScrollBar沒有出現
{
if(ListView2->TopItem->Index > ListView3->TopItem->Index)
{
//令垂直ScrollBar向下翻頁 //SB_LINEUP
for(int i = ListView3->TopItem->Index;i
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
u8702656你好:
以下的Code是我用的方式,在bcb6可以運作正常,不知道能否解決你的問題?
//--------------------------------------------------------------------------- void __fastcall TForm1::ListView2CustomDrawItem(TCustomListView *Sender, TListItem *Item, TCustomDrawState State, bool &DefaultDraw) { if(ListView2->VisibleRowCount > ListView2->Items->Count) return; while(ListView2->TopItem->Index != ListView3->TopItem->Index) SendMessage(ListView3->Handle, WM_VSCROLL, (ListView2->TopItem->Index > ListView3->TopItem->Index)? SB_LINEDOWN:SB_LINEUP, 0); } //--------------------------------------------------------------------------- void __fastcall TForm1::ListView3CustomDrawItem(TCustomListView *Sender, TListItem *Item, TCustomDrawState State, bool &DefaultDraw) { if(ListView3->VisibleRowCount > ListView3->Items->Count) return; while(ListView2->TopItem->Index != ListView3->TopItem->Index) SendMessage(ListView2->Handle, WM_VSCROLL, (ListView3->TopItem->Index > ListView2->TopItem->Index)? SB_LINEDOWN:SB_LINEUP, 0); } //--------------------------------------------------------------------------- |
u8702656
一般會員 發表:2 回覆:5 積分:1 註冊:2003-07-10 發送簡訊給我 |
|
m8815010
版主 發表:99 回覆:372 積分:289 註冊:2003-11-13 發送簡訊給我 |
引言: 謝謝pwipwi前輩的幫忙 真的很抱歉先前沒有講清楚,誤導了大家 因為我要避開兩個ListView在OnCustomDrawItem時,互相SendMessage會造成畫面混亂的問題,必須再拖拉時只能由一方發訊息,所以我才用抓滑鼠位置的方式來作分辨,因此造成滑鼠未在ListView中會不work 所以我的問題應該是:如何再拖拉時正確分辨現在到底拖拉的是哪一個ListView 麻煩各位前輩再一次的指導 >>< face="Verdana, Arial, Helvetica">引言: 謝謝pwipwi前輩的幫忙 真的很抱歉先前沒有講清楚,誤導了大家 因為我要避開兩個ListView在OnCustomDrawItem時,互相SendMessage會造成畫面混亂的問題,必須再拖拉時只能由一方發訊息,所以我才用抓滑鼠位置的方式來作分辨,因此造成滑鼠未在ListView中會不work 所以我的問題應該是:如何再拖拉時正確分辨現在到底拖拉的是哪一個ListView 麻煩各位前輩再一次的指導 >>< face="Verdana, Arial, Helvetica"> u8702656你好< >: 你的問題讓我有點困惑< >!因為依照你這樣程式的設計方式是可以達成同步ok,但你的問題: 但是這會造成當我再拖拉時滑鼠不在原本按下的那個ListView時,無法執行更新動作 卻是你自已程式碼中劃地自限造成的不是嗎? 也就是你的這段程式碼: < class="code"> RECT r; ::GetWindowRect(ListView2->Handle,&r); //取得滑鼠位置 POINT pd; GetCursorPos(&pd); if(::PtInRect(&r,pd)) { ~~~ 並沒有意義,因為今天不管滑鼠在那裏,只有我確定ListView2(依你程式中變數名)是onfocus狀態時,我就可以確定在做滑鼠滾輪scroll動作時就是ListView2會接收到,也就是說滑鼠所控制的一定是目前正在onfocus中的那一個元件! 所以那一段程式碼那掉應該就可以滿足你的需求了! 簡單 class="code"> void __fastcall TForm1::ListView1CustomDrawItem(TCustomListView *Sender, TListItem *Item, TCustomDrawState State, bool &DefaultDraw) { if (!ListView1->Focused()) { <--因為ListView1不在onfocus狀態時也有可能會執行 return; 這個drawitem的事件,所以加此段判斷,如果不是 } onfocus的話,後面就不用再做下去了 SCROLLINFO scroll; memset(&scroll,0,sizeof(SCROLLINFO)); scroll.fMask = SIF_ALL; scroll.cbSize = sizeof(SCROLLINFO); if (GetScrollInfo(ListView2->Handle,SB_VERT,&scroll)) { if (ListView1->TopItem->Index>ListView2->TopItem->Index) { for(int i=ListView2->TopItem->Index;i |
u8702656
一般會員 發表:2 回覆:5 積分:1 註冊:2003-07-10 發送簡訊給我 |
|
m8815010
版主 發表:99 回覆:372 積分:289 註冊:2003-11-13 發送簡訊給我 |
引言: 謝謝m8815010前輩提供的方法 可是小弟我去試了一下,發現滑鼠去點選 > >>< face="Verdana, Arial, Helvetica"> u8702656颱風天好< >: 還是不太瞭解你的意思< >!愈看愈霧,呵呵! 首先你說:滑鼠點scroll bar,並不會讓ListView被set focus,只有點選ListView(非scroll bar)處,才可以讓它被focus,這是沒錯的,嗯 另外用滑鼠控制scroll bar有3種方式: 1.用左鍵點選scroll bar的長條,並一直壓者左鍵,同時拖拽長條,達成捲動 2.用滑鼠scroll bar的上、下箭頭 3.直接滾動滑鼠的滾輪 不知道你是怎麼操作,怎麼樣的問題,愈看愈不解,! |
u8702656
一般會員 發表:2 回覆:5 積分:1 註冊:2003-07-10 發送簡訊給我 |
拍謝拍謝拖了這麼久才又上來.
對於這3種操作狀況
1.用左鍵點選scroll bar的長條,並一直壓者左鍵,同時拖拽長條,達成捲動
2.用滑鼠scroll bar的上、下箭頭
3.直接滾動滑鼠的滾輪 以一個例子來說明,比如說我有兩個ListView,分別為ListView1和ListView2,想做到ScrollBar同步;
則在原本的程式中,有這個問題,當我在操作狀況1時,拖拉ListView1的ScrollBar,在拖拉時只要我滑鼠的游標一超出ListView1元件的範圍,就會造成不同步;
而在操作狀況2時,因為滑鼠游標都會在LisView1中,所以不會有問題;
但在操作狀況3中,當Focus在ListView1時,滑鼠游標在ListView1時滾動滑鼠滾輪,一切正常,當滑鼠游標不在ListView1時,就無法做到同步了
以上這些其實也是因為程式中會去判斷滑鼠所在位置,如果不在其範圍內就不發送捲動訊息給另一個ListView的關係 而我會這樣寫的原因有三個
1.主要原因:ListView沒有提供OnScroll的Event,所以我將發送要求同步捲動的Message寫在CustomDrawItem的Event中
2.而CustomDrawItem這個Event是只要你有重繪ListView的動作都會觸發,因此必須加入判斷到底是捲動哪一個ListView的判斷,來避免重複發送Scroll訊息的狀況
3.要判斷現在的focus在哪一個ListView,本來以為只要用
ListView->Focused()來判斷,但是發現
"滑鼠點scroll bar,並不會讓ListView被set focus,只有點選ListView(非scroll bar)處,才可以讓它被focus"的這個問題
所以只好判斷滑鼠游標了;因此我只要找出:
如何在拖拉時正確分辨現在到底拖拉的是哪一個ListView就可以解決我的問題
|
m8815010
版主 發表:99 回覆:372 積分:289 註冊:2003-11-13 發送簡訊給我 |
引言: 拍謝拍謝拖了這麼久才又上來. 對於這3種操作狀況 1.用左鍵點選scroll bar的長條,並一直壓者左鍵,同時拖拽長條,達成捲動 2.用滑鼠scroll bar的上、下箭頭 3.直接滾動滑鼠的滾輪 以一個例子來說明,比如說我有兩個ListView,分別為ListView1和ListView2,想做到ScrollBar同步; 則在原本的程式中,有這個問題,當我在操作狀況1時,拖拉ListView1的ScrollBar,在拖拉時只要我滑鼠的游標一超出ListView1元件的範圍,就會造成不同步; 而在操作狀況2時,因為滑鼠游標都會在LisView1中,所以不會有問題; 但在操作狀況3中,當Focus在ListView1時,滑鼠游標在ListView1時滾動滑鼠滾輪,一切正常,當滑鼠游標不在ListView1時,就無法做到同步了 以上這些其實也是因為程式中會去判斷滑鼠所在位置,如果不在其範圍內就不發送捲動訊息給另一個ListView的關係 而我會這樣寫的原因有三個 1.主要原因:ListView沒有提供OnScroll的Event,所以我將發送要求同步捲動的Message寫在CustomDrawItem的Event中 2.而CustomDrawItem這個Event是只要你有重繪ListView的動作都會觸發,因此必須加入判斷到底是捲動哪一個ListView的判斷,來避免重複發送Scroll訊息的狀況 3.要判斷現在的focus在哪一個ListView,本來以為只要用 ListView->Focused()來判斷,但是發現 "滑鼠點scroll bar,並不會讓ListView被set focus,只有點選ListView(非scroll bar)處,才可以讓它被focus"的這個問題 所以只好判斷滑鼠游標了;因此我只要找出: 如何在拖拉時正確分辨現在到底拖拉的是哪一個ListView就可以解決我的問題u8702656你好: 你的例子中: < class="code"> 1.按滑鼠左鍵點選scroll bar的長條柱,拖拽使scroll bar捲動,你說只要滑鼠一離開Listview 的範圍,就會造成不同步: 這應該不是程式的問題,因為滑鼠離開Listview範圍的時候(左鍵還是一直按著哦),拖拽scroll bar的 長條柱是可以的,只是不太順,會感覺似有似無(這裡要細心感覺一下),這是os(或說builder)design 本身呈現,我們don't care。但是不管滑鼠在不在Listview的範圍上,只要你可以成功捲動Listvew1的 話,listview2就可以跟著動了(用我小修過的版本)! 2.ok 3.你說當滑鼠游標不在Listview1時,就無法同步 因為:1. 你原本的程式限制了,而在我的小修改掉這問題(如前述回應) 2. Listview1跟本沒被setfocus,所以它的scroll bar不會接收到滑鼠的動作,就不會 跟著動,所以Listview1就不會動,所以Listview2也不會跟動! conclusion:1.我還是覺得我前述小修過的程式碼應該可以滿足了 2.以寫在ondraw事件的同步方式,流程一定是死的: Listview1被focus-->才可以接受捲動指令(不管指令怎麼送來)-->被捲動 -->重繪item事件觸發-->送message給Listview2 3.即然問題還不能糎清,還是跳回你一開始想要的做法吧,就是抓scroll事件: 之前post的,精神上應該是一致的,就不劃蛇黏足再寫範例了: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=54792 愈來愈霧,希望有所幫助! |
u8702656
一般會員 發表:2 回覆:5 積分:1 註冊:2003-07-10 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |