在bcb里完成像Winamp那樣具有吸附效果的磁性窗口
發(fā)表時(shí)間:2023-08-18 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]相信大家都用過Winamp,一定會(huì)對(duì)她那種具有吸附效果的窗口感到很驚喜吧。其實(shí)要實(shí)現(xiàn)這樣的效果并不難,下面我就用bcb做出這樣的效果。為了將問題簡化,窗口只在屏幕頂端產(chǎn)生吸附效果。 打開...
相信大家都用過Winamp,一定會(huì)對(duì)她那種具有吸附效果的窗口感到很驚喜吧。其實(shí)要實(shí)現(xiàn)這樣的效果并不難,下面我就用bcb做出這樣的效果。為了將問題簡化,窗口只在屏幕頂端產(chǎn)生吸附效果。
打開bcb6.0,新建一工程,將Form1的BorderStyle的屬性改為bsNone,做成一個(gè)無標(biāo)題欄,無邊框的窗體。正常情況下,我們是無法移動(dòng)這樣的窗體的。我們必須自己給窗口發(fā)送一個(gè)移動(dòng)的消息,在Form1的MouseDown的事件中添加如下代碼:
ReleaseCapture();
SendMessage(this->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
其實(shí)道理很簡單,相信大家都會(huì)這個(gè),我也就不多說了,:)
為了窗口在接近屏幕頂端的時(shí)候有一種磁性效果,我們必須在窗口的移動(dòng)之前做一個(gè)判斷,判斷窗口將要到達(dá)的新位置的Top值是否小于一定范圍(這個(gè)范圍我稱之為磁性距離,大小可由自己定義,為方便起見,我在這里定為20)。但是bcb里面并沒有窗體移動(dòng)事件,我們必須自己在程序里面攔截窗體移動(dòng)消息,為此,我們要重載WndProc這個(gè)函數(shù):
void __fastcall TForm1::WndProc(TMessage& Message)
{
switch(Message.Msg)
{
/*在窗口移動(dòng)之前,判斷窗口新位置的Top值是不是在磁性范
圍內(nèi),如果在,讓它歸0,表示不產(chǎn)生窗體移動(dòng),避免在磁性
范圍內(nèi)移動(dòng)窗口的時(shí)候窗口過于閃爍*/
case WM_WINDOWPOSCHANGING:
if ((LPWINDOWPOS(Message.LParam))->y<20)
(LPWINDOWPOS(Message.LParam))->y=0;
break;
default:
break;
}
TForm::WndProc(Message); //自己處理完消息后再讓系統(tǒng)做剩下的事情
}
OK,代碼就這么多,是不是很簡單?運(yùn)行一下程序,看是不是果真如此呢?:)
也許有人會(huì)問為什么不是攔截WM_MOVE這個(gè)消息,其實(shí)只要你試一下就知道了,如果攔截這個(gè)消息,窗口在磁性范圍內(nèi)移動(dòng)的時(shí)候會(huì)很閃爍。原因很簡單,WM_WINDOWPOSCHANGING是在窗口移動(dòng)之前就做出了判斷,如果窗口將要在磁性范圍內(nèi)移動(dòng)(此時(shí)尚未移動(dòng)),則不讓窗口移動(dòng)。而WM_MOVE在窗口移動(dòng)以后才做判斷,這樣的結(jié)果就是不斷讓Top復(fù)位成0,當(dāng)然會(huì)造成窗口閃爍了。
另外,大家都知道,根據(jù)系統(tǒng)本身的設(shè)置不同,窗口在移動(dòng)的過程中,有兩種顯示效果,一種是顯示虛線框,一種是顯示窗口內(nèi)容。細(xì)心的朋友可能已經(jīng)發(fā)現(xiàn),在Winamp中,不管系統(tǒng)的設(shè)置是如何,移動(dòng)Winamp的窗口的過程中總是會(huì)顯示窗口內(nèi)容。其實(shí)這樣做的道理很簡單,因?yàn)樵陲@示虛線框的時(shí)候,磁性窗口的吸附效果不怎么好,大家可以親手試試。
那如何也做成和Winamp一樣呢?其實(shí)只要一個(gè)API函數(shù)就搞定了,:),代碼如下:
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,true,NULL,SPIF_SENDCHANGE);
在窗口移動(dòng)之前,通過調(diào)用上面的函數(shù),就能達(dá)到Winamp一樣的效果了。關(guān)于SystemParametersInfo這個(gè)函數(shù)及參數(shù)的具體用法,請(qǐng)各位參見MSDN,再?zèng)]有比MSDN解釋的更清楚了。
以上代碼在Win2k Professional+bcb6.0下測(cè)試通過。