明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

在bcb里完成像Winamp那樣具有吸附效果的磁性窗口

[摘要]相信大家都用過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è)試通過。