• <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>
            隨筆-159  評論-223  文章-30  trackbacks-0
              1/***************************************************************************************
              2  鄰接矩陣----用來表示所有窗口之間的鄰接關系,值1表示兩個窗口間相交或相切,值0表示
              3              兩個窗口間相離,實際存儲的是若干窗口組成的非連通無向圖結構
              4  粘合窗口----由鄰接矩陣生成的包含老板窗口的集合,當鼠標按在老板窗口上移動時,整個
              5              粘合窗口跟隨移動,實際存儲的是含有老板窗口的一個連通分量
              6  老板窗口----只有當鼠標左鍵按在此窗口時,才能移動整個粘合窗口,僅允許有一個老板窗口
              7
              8  2009-12-11  當新建客口時,能正確構建鄰接矩陣和粘合窗口列表; 當關閉窗口時,能正確重組鄰接矩陣
              9                          和粘合窗口列表當大小改變時(如最大化,最小化時),能更新鄰接矩陣和粘合窗口列表
             10  2009-12-30  改進了矩形相切條件的精確判斷
             11  2009-12-31  支持老板窗口能連續獨立移動
             12****************************************************************************************/

             13
             14CWndMagnet::CWndMagnet():
             15m_hLead(0)
             16{
             17}

             18
             19CWndMagnet::~CWndMagnet()
             20{
             21}

             22
             23/*
             24  @brief 增加磁性窗口
             25  @param hWnd  需要組合分離的窗口
             26  * 一般在窗口初始化或創建時調用此方法,加入待組合分離的窗口,注意窗口句柄有效性
             27*/

             28void CWndMagnet::AddMagnetWnd(HWND hWnd)
             29{
             30    if (!hWnd || !IsWindow(hWnd)) return;
             31    int uIndex = m_map_magWnd.size();
             32    pair<map<HWND,int>::iterator,bool> pr = m_map_magWnd.insert(make_pair(hWnd, uIndex));
             33    if (!pr.second) return
             34    Add2DMatrix();
             35}

             36
             37/*
             38  @brief 移除磁性窗口
             39  @param hWnd 需要移除的窗口句柄
             40  * 一般在窗口關閉或銷毀時調用此方法,移除不組合分離的窗口,注意窗口句柄有效性
             41*/

             42void CWndMagnet::RemoveMagnetWnd(HWND hWnd)
             43{
             44    if (!hWnd || !IsWindow(hWnd)) return;
             45    m_map_leadWnd.erase(hWnd);
             46    Delete2DMatrix(hWnd);
             47    DeleteMagWnd(hWnd);
             48    UpdateLeadWndSet(hWnd);
             49}

             50
             51/*******************************************************************************************
             52 以下為消息映射處理方法,在窗口對應消息處理中調用
             53(1) 在OnLButtonDown調用::SendMessage(m_hWnd,WM_SYSCOMMAND,0xF012,0)來實現按客戶區移動時
             54    經測試發現: 當鼠標左鍵按在標題欄移動窗口時,而后釋放鼠標左鍵,卻收不到WM_NCLBUTTONUP消息,但收到了
             55    WM_NCLBUTTONDOWN消息.同理當鼠標左鍵按在客戶區移動窗口時,,而后釋放鼠標左鍵,卻收不了WM_LBUTTONUP
             56    消息,但收到了WM_LBUTTONDOWN消息.這是移動窗口時發現的規律,本質上是當鼠標左鍵釋放時來更新粘合窗口列表,
             57    但鑒于此規律,正好符合調用來更新粘合窗口列表
             58(2) 如果應用程序調用了OnLButtonDown或OnNcLButtonDown則在點擊窗體時就會粘在一起,否則只有移動時
             59    才粘在一起
             60********************************************************************************************/

             61
             62/*
             63  @brief 鼠標左鍵在老板窗口客戶區按下事件處理方法
             64  @param hWnd  窗口句柄
             65  * 這是為了使老板窗口有機會能獨立連續移動調用的方法
             66*/

             67void CWndMagnet::OnLButtonDown(HWND hWnd)
             68{
             69    if (!hWnd || !IsWindow(hWnd))  return;
             70    if (hWnd != m_hLead)           return;
             71 //   Update2DMatrix(hWnd);
             72    UpdateLeadWndSet(hWnd);
             73}

             74
             75/*
             76  @brief 鼠標左鍵在老板窗口非客戶區按下事件處理方法
             77  @param hWnd  窗口句柄
             78  * 這是為了使老板窗口有機會能獨立連續移動調用的方法
             79*/

             80void CWndMagnet::OnNcLButtonDown(HWND hWnd)
             81{
             82    if (!hWnd || !IsWindow(hWnd))  return;
             83    if (hWnd != m_hLead)           return;
             84    UpdateLeadWndSet(hWnd);
             85}

             86
             87/*
             88  @brief 鼠標移動事件處理方法
             89  @param hWnd  窗口句柄
             90  @param lpRect  窗口矩形區域
             91*/

             92void CWndMagnet::OnMoving(HWND hWnd, LPRECT lpRect)
             93{
             94    if (!m_map_leadWnd.empty()&&hWnd==m_hLead) // return;
             95    {
             96        MoveLeadWndSet(hWnd, lpRect);
             97    }

             98    else
             99    {
            100    Update2DMatrix(hWnd, lpRect);
            101        //移動老板窗口時,使其有機會能獨立連續移動
            102        if (hWnd!=m_hLead) 
            103        {
            104            UpdateLeadWndSet(hWnd, lpRect);
            105        }

            106    }

            107}

            108
            109/*
            110  @brief 窗口大小改變后事件處理方法 
            111  @param hWnd  窗口句柄
            112  @param uType 大小變化類型
            113  * 當大小改變時更新鄰接矩陣
            114*/

            115void CWndMagnet::OnSize(HWND hWnd, UINT uType)
            116{
            117    if (!hWnd || !IsWindow(hWnd))  return;
            118    switch (uType)
            119    {
            120    case SIZE_RESTORED:
            121    case SIZE_MINIMIZED:
            122    case SIZE_MAXIMIZED:
            123        {
            124            Update2DMatrix(hWnd);
            125            UpdateLeadWndSet(hWnd);
            126        }

            127        break;
            128
            129    case SIZE_MAXSHOW:
            130        {
            131        }

            132        break;
            133    }

            134}

            135
            136/**************************************************************************
            137   以下為實現方法,在類內部調用以實現公有方法的功能
            138**************************************************************************/

            139void CWndMagnet::DeleteMagWnd(HWND hWnd)
            140{
            141    map<HWND,int>::iterator iter = m_map_magWnd.find(hWnd);
            142    if (iter==m_map_magWnd.end())  return;
            143 
            144    int index = (*iter).second;
            145    m_map_magWnd.erase(iter);
            146    for (iter = m_map_magWnd.begin(); iter != m_map_magWnd.end(); ++iter)
            147    {
            148        int& indexTemp = (*iter).second;
            149        if ( indexTemp > index) --indexTemp;
            150    }

            151}

            152//當新建窗口時要調用此函數來增加對應的鄰接矩陣值
            153void CWndMagnet::Add2DMatrix()
            154{
            155    int uColCount = m_map_magWnd.size();
            156    int uRowCount = m_vec_2DMatrix.size();
            157    for (int row = 0; row < uRowCount; ++row)
            158    {
            159        for (int col = uRowCount; col < uColCount; ++col)
            160        {
            161            m_vec_2DMatrix[row].push_back(false);
            162        }

            163    }

            164    vector<bool> vec_bool; 
            165    vec_bool.resize(uColCount);
            166    m_vec_2DMatrix.push_back(vec_bool);
            167}

            168//當窗口銷毀時要調用此函數來刪除對應的鄰接矩陣值
            169void CWndMagnet::Delete2DMatrix(HWND hWnd)
            170{
            171    map<HWND,int>::iterator mapIter = m_map_magWnd.find(hWnd);
            172    if (mapIter==m_map_magWnd.end())  return;
            173
            174    int index = (*mapIter).second, row, col;
            175    vector<vector<bool> >::iterator iter;
            176    for (vector<vector<bool> >::iterator iter1 = m_vec_2DMatrix.begin(); iter1 != m_vec_2DMatrix.end(); ++iter1)
            177    {
            178        row = distance(m_vec_2DMatrix.begin(), iter1);
            179        if (row == index) 
            180        {
            181            iter = iter1;
            182        }

            183        for (vector<bool>::iterator iter2 = m_vec_2DMatrix[row].begin(); iter2 != m_vec_2DMatrix[row].end(); ++iter2)
            184        {
            185            if (distance(m_vec_2DMatrix[row].begin(),iter2)==index) 
            186            {
            187               m_vec_2DMatrix[row].erase(iter2); break;
            188            }

            189        }

            190    }

            191    m_vec_2DMatrix.erase(iter);
            192}

            193//當窗口移動或大小改變時要調用此函數來更新鄰接矩陣的值
            194//當大小改變時lpRect為0
            195void CWndMagnet::Update2DMatrix(HWND hWnd, LPRECT lpRect)
            196{
            197    map<HWND,int>::iterator iter = m_map_magWnd.find(hWnd);
            198    if (iter == m_map_magWnd.end())  return;
            199
            200    UINT  uRow = (*iter).second, uCol;
            201    HWND  hWndTemp;
            202    RECT  rcWnd,rcTemp;   GetWindowRect(hWnd,&rcWnd);
            203    for (iter = m_map_magWnd.begin(); iter != m_map_magWnd.end(); ++iter)
            204    {
            205        hWndTemp = (*iter).first;  uCol = (*iter).second;
            206        if (hWnd != hWndTemp)
            207        {
            208            GetWindowRect(hWndTemp, &rcTemp);
            209            if (0 == lpRect)
            210            {
            211                RECT rcInter;
            212                if (IntersectRect(&rcInter,&rcWnd,&rcTemp)
            213                    ||rcWnd.left==rcTemp.right||rcWnd.right==rcTemp.left
            214                    ||rcWnd.top==rcTemp.bottom||rcWnd.bottom==rcTemp.top
            215                    )
            216                    m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            217                else
            218                    m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            219            }

            220            else
            221            {
            222                long  lWidth = lpRect->right-lpRect->left, lHeight = lpRect->bottom-lpRect->top;
            223                long  lOffX  = lWidth/2, lOffY = lHeight/2;
            224                POINT ptCenter = { lpRect->left + lOffX, lpRect->top + lOffY };
            225                RECT  rcLeft, rcTop, rcRight, rcBottom, rcCenter;
            226
            227                SetRect(&rcLeft, rcTemp.left-s_c_iThreshold-lOffX, rcTemp.top-lOffY, 
            228                    rcTemp.left-lOffX, rcTemp.bottom+lOffY);
            229                SetRect(&rcTop, rcTemp.left-lOffX, rcTemp.top-s_c_iThreshold-lOffY, 
            230                    rcTemp.right+lOffX, rcTemp.top-lOffY);
            231                SetRect(&rcRight, rcTemp.right+lOffX, rcTemp.top-lOffY, 
            232                    rcTemp.right+s_c_iThreshold+lOffX, rcTemp.bottom+lOffY);
            233                SetRect(&rcBottom, rcTemp.left-lOffX, rcTemp.bottom+lOffY, 
            234                    rcTemp.right+lOffX, rcTemp.bottom+s_c_iThreshold+lOffY);
            235                SetRect(&rcCenter, rcTemp.left-lOffX, rcTemp.top-lOffY, 
            236                    rcTemp.right+lOffX, rcTemp.bottom+lOffY);
            237
            238              /************************************************************************
            239                  nOffset指示組合或分離時的矩形偏移值,默認為0   
            240                  PtInRect判斷一個點是否在指定矩形內,意味著不包含底邊和右邊
            241                ************************************************************************/

            242                int nOffset = 0;  
            243                if(!m_vec_2DMatrix[uRow][uCol])
            244                {
            245                    if (PtInRect(&rcLeft, ptCenter))
            246                    {
            247                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            248                        lpRect->right = rcTemp.left - nOffset;
            249                        lpRect->left = lpRect->right - lWidth;
            250                    }

            251                    else if (PtInRect(&rcTop, ptCenter))
            252                    {
            253                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            254                        lpRect->bottom = rcTemp.top - nOffset;
            255                        lpRect->top = lpRect->bottom - lHeight;
            256                    }

            257                    else if (PtInRect(&rcRight, ptCenter))
            258                    {
            259                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            260                        lpRect->left = rcTemp.right + nOffset;
            261                        lpRect->right = lpRect->left + lWidth;
            262                    }

            263                    else if (PtInRect(&rcBottom, ptCenter))
            264                    {
            265                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            266                        lpRect->top = rcTemp.bottom + nOffset;
            267                        lpRect->bottom = lpRect->top + lHeight;
            268                    }

            269                    else if (PtInRect(&rcCenter, ptCenter))
            270                    {
            271                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = true;
            272                    }

            273                    
            274                }

            275                else
            276                {
            277                    if (!PtInRect(&rcLeft, ptCenter)&&!PtInRect(&rcTop, ptCenter)&&!PtInRect(&rcRight, ptCenter)
            278                        &&!PtInRect(&rcBottom, ptCenter)&&!PtInRect(&rcCenter, ptCenter))
            279                    {
            280                        m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            281                    }

            282                    else
            283                    {
            284                        ++nOffset;
            285                        OffsetRect(&rcLeft, -nOffset, 0);  OffsetRect(&rcRight, nOffset, 0);
            286                        OffsetRect(&rcTop, 0-nOffset);   OffsetRect(&rcBottom, 0, nOffset); 
            287                        if (PtInRect(&rcLeft, ptCenter))
            288                        {
            289                            lpRect->right = rcTemp.left - s_c_iThreshold;
            290                            lpRect->left = lpRect->right - lWidth;
            291                            m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            292                        }

            293                        else if (PtInRect(&rcTop, ptCenter))
            294                        {
            295                            lpRect->bottom = rcTemp.top - s_c_iThreshold;
            296                            lpRect->top = lpRect->bottom - lHeight;
            297                            m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            298                        }

            299                        else if (PtInRect(&rcRight, ptCenter))
            300                        {
            301                            lpRect->left  = rcTemp.right + s_c_iThreshold;
            302                            lpRect->right = lpRect->left + lWidth;
            303                            m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            304                        }

            305                        else if (PtInRect(&rcBottom, ptCenter))
            306                        {
            307                            lpRect->top    = rcTemp.bottom + s_c_iThreshold;
            308                            lpRect->bottom = lpRect->top + lHeight;
            309                            m_vec_2DMatrix[uRow][uCol] = m_vec_2DMatrix[uCol][uRow] = false;
            310                        }

            311                    }

            312                }

            313            }

            314        }

            315    }

            316}

            317//當移動或擊點窗口時調用此函數更新粘合窗口列表
            318//當點擊窗口時,lpRect為0
            319void CWndMagnet::UpdateLeadWndSet(HWND hWnd, LPCRECT lpRect /*=0*/)
            320{
            321    if (m_vec_2DMatrix.empty())  return;
            322
            323    map<HWND,int>::iterator iter = m_map_magWnd.find(m_hLead);
            324    if (iter == m_map_magWnd.end())  return;
            325        
            326    m_map_leadWnd.clear();
            327    int lead_wnd_index = (*iter).second;
            328    int rows = m_vec_2DMatrix.size(), cols = m_vec_2DMatrix[0].size();
            329    assert(rows == cols);
            330    
            331    vector<int> vecCol;
            332    vector<bool> vecVisited(rows);
            333    DFS(lead_wnd_index, vecVisited, vecCol);
            334
            335    RECT rcLead; GetWindowRect(m_hLead, &rcLead);
            336    for (vector<int>::iterator vecIter = vecCol.begin()+1; vecIter!=vecCol.end();++vecIter)
            337    {
            338        int index = *vecIter;
            339        for (iter = m_map_magWnd.begin(); iter != m_map_magWnd.end(); ++iter)
            340        {
            341            if ((*iter).second==index) 
            342            {
            343                HWND hTemp = (*iter).first; RECT rcTemp; 
            344                GetWindowRect(hTemp, &rcTemp);
            345                LPCRECT pRect = 0;
            346                if (0==lpRect||hWnd!=m_hLead) 
            347                    pRect = &rcLead;
            348                else 
            349                    pRect = lpRect;
            350                POINT pt = {rcTemp.left-pRect->left, rcTemp.top-pRect->top};
            351                m_map_leadWnd[hTemp] = pt; 
            352                break;
            353            }

            354        }

            355    }

            356}

            357//當移動老板窗口時調用此函數來移動整個粘合窗口
            358void CWndMagnet::MoveLeadWndSet(HWND hWnd, LPCRECT lpRect)
            359{
            360    if (hWnd != m_hLead) return;
            361
            362    HWND hTemp;    RECT rcTemp; 
            363    long lNewLeft, lNewTop;
            364    for (map<HWND,POINT>::iterator Iter = m_map_leadWnd.begin(); Iter != m_map_leadWnd.end();++Iter)
            365    {
            366        lNewLeft = lpRect->left + (*Iter).second.x; 
            367        lNewTop  = lpRect->top  + (*Iter).second.y;
            368        hTemp = (*Iter).first; GetWindowRect(hTemp,&rcTemp);
            369        if (rcTemp.left != lNewLeft || rcTemp.top != lNewTop)
            370        {
            371          /***********************************************************************************
            372               如果不考慮隱藏窗口,已最小化和最大化窗口,則加上以下代碼
            373           if ((IsWindowVisible(hTemp))&&!IsIconic(hTemp) && !IsZoomed(hTemp))
            374          ************************************************************************************/

            375            SetWindowPos(hTemp, 0, lNewLeft, lNewTop, 00, SWP_NOSIZE|SWP_NOZORDER);
            376        }

            377    }

            378}

            379
            380/*****************************************************************************************
            381 下面為實現圖深度搜索遍歷算法的函數
            382 DFS:復雜度為O(N*N),N為無向圖的頂點個數,可考慮用鄰接表存儲圖來實現,
            383 其復雜度為N+E,N為頂點個數,E為邊數
            384******************************************************************************************/

            385//找到頂點v的第一個鄰接點
            386int CWndMagnet::GetFirstNeighbor(int v)
            387{
            388    if (-1==v)  return -1;
            389    int  num = m_vec_2DMatrix.size();
            390    assert(v < num);
            391    for (int col = 0; col < num; ++col)
            392    {
            393        if (m_vec_2DMatrix[v][col]) return col;
            394    }

            395    return -1;
            396}

            397//找到頂點V的鄰接點W的下一個鄰接點
            398int CWndMagnet::GetNextNeighbor(int v, int w)
            399{
            400    if (-1==|| -1==w)  return -1;
            401    int num = m_vec_2DMatrix.size();
            402    for (int col = w + 1; col < num; ++col)
            403    {
            404        if (m_vec_2DMatrix[v][col])  return col;
            405    }

            406    return -1;
            407}

            408
            409void CWndMagnet::DFS(int v, vector<bool>& vecVisited, vector<int>& vecNeighbor)
            410{
            411   vecVisited[v] = true;
            412   vecNeighbor.push_back(v);
            413   int w = GetFirstNeighbor(v); 
            414   for (; w !=-1 ;)
            415   {
            416       if (!vecVisited[w]) DFS(w, vecVisited, vecNeighbor);
            417       w = GetNextNeighbor(v, w);
            418   }

            419}
            posted on 2011-08-27 15:12 春秋十二月 閱讀(2633) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
            国产精品久久国产精麻豆99网站| 久久中文字幕视频、最近更新| 久久中文字幕精品| 热久久国产欧美一区二区精品| 中文精品久久久久国产网址| 久久综合久久综合久久综合| 国产精品99久久久久久宅男| 久久精品国产一区二区| 综合久久精品色| 久久精品国产亚洲AV不卡| 久久99精品国产麻豆宅宅| 亚州日韩精品专区久久久| 久久久久国产一区二区| 久久久久国产亚洲AV麻豆| 精品久久久久久无码国产| 四虎国产精品成人免费久久| 2020久久精品国产免费| 国产精品免费看久久久| 日本精品久久久久久久久免费| 91精品国产91久久久久久青草| 亚洲国产成人久久精品动漫| 国产三级精品久久| 久久综合九色综合欧美就去吻| 欧美日韩成人精品久久久免费看| 欧洲国产伦久久久久久久| 国产精品99久久久久久宅男小说| 一本色综合网久久| 品成人欧美大片久久国产欧美| 99久久国产主播综合精品| 久久精品国产一区二区三区不卡| 久久精品二区| 国产亚洲精久久久久久无码77777| 亚洲国产美女精品久久久久∴| 久久青青国产| 久久中文字幕人妻丝袜| 久久精品国产99久久久| 无码八A片人妻少妇久久| 国产精品九九九久久九九| 精品综合久久久久久88小说| 亚洲精品无码久久久久AV麻豆| 久久水蜜桃亚洲av无码精品麻豆|