• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-162  評(píng)論-223  文章-30  trackbacks-0
               著名的千千靜聽(tīng)音樂(lè)播放器,其界面簡(jiǎn)潔優(yōu)雅、美觀大方,特別是它那種幾個(gè)窗口像磁石般相互吸引,當(dāng)拖動(dòng)主窗口時(shí),粘在一起的其它窗口會(huì)跟隨著一起移動(dòng),當(dāng)拖動(dòng)其它窗口時(shí),又能脫離不粘在一起,這種窗口效果讓用戶(hù)操作方便,省心省力。為描述方便,本文稱(chēng)這種效果為多窗口的組合分離,它的主要特點(diǎn)是僅用鼠標(biāo)任意移動(dòng)窗口,就可組合或分離,當(dāng)組合在一起時(shí),移動(dòng)某窗口(如主窗口,暫稱(chēng)為老板窗口)能整體移動(dòng),移動(dòng)其口窗口(非老板窗口,暫稱(chēng)為工人窗口)又能將自己脫離出來(lái)。近來(lái)由于工作需要實(shí)現(xiàn)了類(lèi)似于此的窗口效果,經(jīng)過(guò)幾天的測(cè)試,終于穩(wěn)定。在開(kāi)發(fā)過(guò)程中,考慮了以下幾個(gè)問(wèn)題:
                 (1)  組合分離的條件如何決定判斷。
                 (2)  當(dāng)窗口大小改變時(shí),包括最小化,最大化,縮放窗口等,如何保證不影響組合分離,能正常整體移動(dòng)。
                 (3)  窗口個(gè)數(shù)是可變的,當(dāng)新建或銷(xiāo)毀窗口時(shí),如何保證不影響組合分離,能正常整體移動(dòng)(千千靜聽(tīng)窗口個(gè)數(shù)是有限的,而且可能只是隱藏窗口)。
                 (4)  采用什么數(shù)據(jù)結(jié)構(gòu)較好,如何維護(hù)任意兩個(gè)窗口間的距離關(guān)系(相交或相切視為組合,相離視為分離)。
                 (5)  當(dāng)拖動(dòng)老板窗口時(shí),如何拖動(dòng)與其組合的所有窗口,關(guān)鍵是如何得到所有與其組合的窗口列表。
                 (6)  如何針對(duì)這種效果設(shè)計(jì)一個(gè)通用的組件類(lèi),只需調(diào)用幾個(gè)方法便可搞定。
               
               針對(duì)以上問(wèn)題,主要思路是視屏幕上任意多個(gè)窗口為頂點(diǎn),以其窗口矩形中心點(diǎn)來(lái)看待這個(gè)窗口,如果任意兩個(gè)窗口間關(guān)系為組合,則視這兩個(gè)頂點(diǎn)間是相通的,即兩個(gè)頂點(diǎn)存在邊。如果為分離,則視兩頂點(diǎn)間是不通的,即兩頂點(diǎn)不存邊。因此可以用無(wú)向圖來(lái)存儲(chǔ)窗口和關(guān)系,為簡(jiǎn)單起見(jiàn),我用的是鄰接矩陣,問(wèn)題(4)得以解決。既然用鄰接矩陣來(lái)存儲(chǔ),那么如何得到所有與老板窗口相關(guān)的組合窗口呢?由于實(shí)際多個(gè)窗口在移動(dòng)過(guò)程中,會(huì)改變其組合分離關(guān)系,這就會(huì)得到多個(gè)無(wú)向圖的連通分量,而我們需要的是包含老板窗口的那一個(gè)連通分量,因此可以用DFS深度搜索遍歷這個(gè)無(wú)向圖連通分量,起始頂點(diǎn)是老板窗口,遍歷完后就會(huì)得所有與其組合的窗口列表,問(wèn)題(5)得以解決。現(xiàn)在討論問(wèn)題(1),這里有個(gè)細(xì)節(jié)問(wèn)題就是組合分離的條件判斷有兩種情況,一是當(dāng)移動(dòng)窗口時(shí)的條件,稱(chēng)為條件1,因?yàn)閷?shí)際向一個(gè)窗口A移入另一個(gè)窗口B時(shí),要達(dá)到還沒(méi)有接近窗口A時(shí)便一下子靠近A就像被A吸引的效果,當(dāng)移出B時(shí)還沒(méi)完全移到A窗口外面時(shí)便一下子遠(yuǎn)離就像被A排斥的效果。二是當(dāng)大小改變時(shí)的條件,稱(chēng)為條件2,這個(gè)不同于條件1,因?yàn)樗恍枰欠N吸引排斥的效果,也沒(méi)必要,這個(gè)條件2就是簡(jiǎn)單的判斷A和B矩形是否相交,API函數(shù)IntersectRect即可完成這一判斷。條件1的判斷如下圖所示:
                                                                       
               在B向A移入過(guò)程中,當(dāng)B的中心點(diǎn)在矩形left,top,right,bottom范圍內(nèi),可認(rèn)為是發(fā)生組合,實(shí)現(xiàn)吸引效果;當(dāng)在center矩形內(nèi),認(rèn)為是已經(jīng)組合了;同理,B向A移出過(guò)程中,當(dāng)B的中心點(diǎn)在矩形left,top,right,bottom范圍內(nèi),可認(rèn)為是發(fā)生分離,實(shí)現(xiàn)排斥效果。當(dāng)都不在left,top,right,bottom,center矩形范圍時(shí),認(rèn)為是已經(jīng)分離了。至此,問(wèn)題(1)得到解決。當(dāng)窗口大小改變時(shí),需要更新鄰接矩陣反映窗口間關(guān)系的變化,而后更新組合窗口列表,組合窗口列表的計(jì)算依賴(lài)于鄰接矩陣,運(yùn)用DFS算法來(lái)更新,這在WM_SIZE消息事件處理內(nèi)完成,問(wèn)題(2)得到解決。當(dāng)新建窗口時(shí),需要向無(wú)向圖中增加(窗口)頂點(diǎn),擴(kuò)充鄰接矩陣以備存儲(chǔ)與其它窗口的關(guān)系;當(dāng)銷(xiāo)毀窗口時(shí),需要從無(wú)向圖中刪除對(duì)應(yīng)的頂點(diǎn),而后從鄰接矩陣中刪除對(duì)應(yīng)的關(guān)系,問(wèn)題(3)得到解決。
               上述問(wèn)題(1)--(5)都已分析并得到解決,總的來(lái)說(shuō),就是以數(shù)據(jù)結(jié)構(gòu)中無(wú)向圖的觀點(diǎn)和算法來(lái)建模解決這些問(wèn)題的,特別是運(yùn)用到了DFS搜索算法來(lái)重建已組合的所有窗口列表,只有這樣,在移動(dòng)老板窗口過(guò)程中,才能保證其它窗口跟隨著一起移動(dòng)。接下來(lái)就是最后一個(gè)問(wèn)題,也就是怎么封裝設(shè)計(jì)組件類(lèi),以達(dá)到方便應(yīng)用的目的,綜上所述,設(shè)計(jì)接口方法與以下窗口4種消息相關(guān):
               1) 創(chuàng)建窗口發(fā)生的消息,如WM_CREATE,WM_INITDIALOG等。
               2) 關(guān)閉或銷(xiāo)毀窗口發(fā)生的消息,如WM_CLOSE,WM_DESTROY等。
               3) 窗口大小改變后消息,WM_SIZE。
               4) 窗口移動(dòng)中消息,WM_MOVING。
               
               另外提供一個(gè)設(shè)置獲取老板窗口的方法,在應(yīng)用程序中,只需在窗口4種消息處理內(nèi)調(diào)用以上對(duì)應(yīng)4個(gè)方法即可實(shí)現(xiàn)多窗口組合分離的效果,注意該類(lèi)沒(méi)有考慮多線程,因此是非安全的,適用于多窗口屬于同一線程內(nèi)的情況。類(lèi)聲明如下 
             1class CWndMagnet
             2{
             3public:
             4    CWndMagnet();
             5  virtual ~CWndMagnet();
             6
             7public:
             8    void SetLeadWindow(HWND hWnd) { m_hLead = hWnd; }
             9    HWND GetLeadWindow() const return m_hLead; }
            10    
            11    void AddMagnetWnd(HWND hWnd);
            12    void RemoveMagnetWnd(HWND hWnd);
            13    void OnLButtonDown(HWND hWnd);
            14    void OnNcLButtonDown(HWND hWnd);
            15    void OnMoving(HWND hWnd, LPRECT lpRect);
            16    void OnSize(HWND hWnd, UINT uType);
            17
            18protected:
            19    void MoveLeadWndSet(HWND hWnd, LPCRECT lpRect);
            20    void UpdateLeadWndSet(HWND hWnd, LPCRECT lpRect = 0);
            21    void DeleteMagWnd(HWND hWnd);
            22    void Add2DMatrix();
            23    void Delete2DMatrix(HWND hWnd);
            24    void Update2DMatrix(HWND hWnd, LPRECT lpRect = 0);
            25
            26private:
            27    int GetFirstNeighbor(int v);
            28    int GetNextNeighbor(int v, int w);
            29    void DFS(int v, std::vector<bool>& vecVisited, std::vector<int>& vecNeighbor);
            30
            31private:
            32    static const int      s_c_iThreshold = 10///< 偏移閥值
            33    HWND                  m_hLead;        ///< 老板窗口
            34    std::map<HWND,POINT>      m_map_leadWnd;  ///< 粘合窗口列表
            35    std::map<HWND,int>        m_map_magWnd;   ///< 需要組合分離的窗口列表
            36    std::vector<std::vector<bool> > m_vec_2DMatrix; ///< 表示任意兩個(gè)窗口間相交或相切的鄰接矩陣
            37    

            38}
            ;
            posted on 2011-07-04 11:14 春秋十二月 閱讀(2833) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++
            三上悠亚久久精品| 精品久久无码中文字幕| 久久99精品久久久久久不卡 | 久久精品人人做人人爽电影蜜月| 欧美日韩精品久久久免费观看| 亚洲人成电影网站久久| 人妻精品久久久久中文字幕| 久久久精品波多野结衣| 久久久久女教师免费一区| 精品无码久久久久久久动漫| 久久久精品久久久久久 | 99久久99久久精品国产片| 性做久久久久久久久久久| 无码国内精品久久人妻| 久久精品三级视频| 久久人人爽人人爽人人片av高请| 国产高潮国产高潮久久久91 | 中文成人久久久久影院免费观看| 久久精品无码一区二区无码 | 久久综合久久性久99毛片| 国产综合久久久久| 亚洲人成伊人成综合网久久久| 久久人人爽人人爽AV片| 久久久精品2019免费观看| 久久99热这里只频精品6| 99久久精品国产一区二区三区| 伊人久久大香线蕉av不卡| 欧美久久综合九色综合| 婷婷久久综合九色综合98| 亚洲av成人无码久久精品| 7777精品伊人久久久大香线蕉| 91麻精品国产91久久久久| 国产精品久久久久久福利69堂| 久久久亚洲欧洲日产国码是AV| 久久综合色区| 久久免费99精品国产自在现线 | 久久国产高潮流白浆免费观看| 久久精品国产亚洲av麻豆蜜芽| 狠狠色丁香久久婷婷综合_中 | 久久久久99这里有精品10| 久久中文精品无码中文字幕|