• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 創建任意形狀的窗口

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    北京市 崔英善 在Windows 系統中窗口的默認形狀是矩形, 在實際應用中絕大多數窗口都是標準矩形窗口。如果一個窗口有著與眾不同的形狀, 則會非常引人注目, 如何創建非標準窗口呢? 在Windows, 可以通過調用SetWindowRgn ( 在MFC 類庫中對應的函數為CWnd::SetWin
    北京市 崔英善

      在Windows 系統中窗口的默認形狀是矩形, 在實際應用中絕大多數窗口都是標準矩形窗口。如果一個窗口有著與眾不同的形狀, 則會非常引人注目, 如何創建非標準窗口呢?

      在Windows, 可以通過調用SetWindowRgn ( 在MFC 類庫中對應的函數為CWnd::SetWindowRgn) 來設置窗口的形狀, 函數的定義如下:

      int SetWindowRgn( HWND hWnd, HRGN hRgn, BOOL bRedrawflag);

      窗口的形狀由參數hRgn 所標志的的區域(region) 決定。通過創建不同的區域就可以創建不同形狀的窗口。下面的代碼, 可以產生圓角矩形的窗口。

    CRgn trgn ;
    trgn.CreateRoundRectRgn( 0 , 0 , 200 , 200 , 30 , 30 ) ;
    SetWindowRgn( trgn , TRUE ) ;
      效果如下圖所示:
    http://www.kjueaiud.com/uploads/2007/07/1_200707042009144.jpg (8834 字節)
      Windows 還支持由路徑( Path ) 創建區域( Region ), 通過這個途徑我們還可以創建文字形狀的窗口。

      下面的代碼可以創建形狀為“計算機世界" 五個字的窗口。

    +CDC *pDC = GetDC() ;
    CFont rfont , *pOldFont ;
    CRgn m_rgn ;

    rfont.CreatePointFont( 1000 , "隸書" ) ;
    pOldFont = pDC ->SelectObject( &rfont ) ;

    pDC ->BeginPath() ;
    pDC ->SetBkMode( TRANSPARENT ) ;
    CString stxt = "計算機世界" ;
    pDC ->TextOut( 0 , 0 , stxt ) ;
    pDC ->EndPath() ;

    m_rgn.CreateFromPath( pDC ) ;

    pDC ->SelectObject( pOldFont ) ;
    ReleaseDC( pDC ) ;
       SetWindowRgn( m_rgn , TRUE ) ;
      效果如下圖所示:
    http://www.kjueaiud.com/uploads/2007/07/1_200707042009145.jpg (5856 字節)
      那么我們能不能創建任意形狀的窗口呢? 也就是創建任意形狀的區域呢? 答案是肯定的。大家請看下面這個圓號形狀的窗口。
    http://www.kjueaiud.com/uploads/2007/07/1_200707042009146.jpg (38260 字節)
      創建這樣的一個區域是調用SDK 的ExtCreateRegion 來實現( MFC 中的對應函數為CRgn::CreateFromData)。這個函數是通過提供一個矩形數組, 來創建一個由這些矩形組成的區域。而創建圓號區域的過程就是由一個圓號的位圖生成矩形數組, 再由這個矩形數組生成區域的過程。

      下面是由圓號位圖創建區域的函數代碼。

    CDib m_dib ;
    CRgn m_rgn ;
    COLORREF m_dwColorKey = 0x0000ff; // 透明色, 純藍

    BOOL CAswDlg::CreateRegionFromBmp( LPCSTR lpsFName )
    {
    // 讀入位圖 
    if( !m_dib.Open( lpsFName ) )
       return FALSE ;

    SIZE dibsize ;

    // 獲取位圖尺寸
    dibsize = m_dib.GetSize( ) ;

    int i , j ;
    BOOL bkey ;
    int iCount = 0 ;

    // 統計需要的矩形個數
    for( i = 0 ; i < dibsize.cy ; i ++)
    {
      bkey = TRUE ;
      for( j = 0 ; j < dibsize.cx ; j ++)
      {
      if( m_dib.GetPixel( j , i ) == m_dwColorKey )
         {
            bkey = TRUE ;
         }
         else
         {
            if( bkey )
            {
              iCount ++;
            }
            bkey = FALSE ;
         }
      }
    }
    BYTE *pData ;
    RGNDATA *pRgnData ;
    RECT *pRect ;
    int iIndex = 0 ;

    pData = new BYTE[ sizeof
    ( RGNDATAHEADER ) +sizeof( RECT ) *iCount ] ;
    pRgnData = ( RGNDATA *)pData ;
    pRect = ( RECT *)( pData +sizeof( RGNDATAHEADER ) ) ;
    pRgnData ->rdh.dwSize =sizeo(RGNDATAHEADER ) ;
    pRgnData ->rdh.iType   =RDH_RECTANGLES ;
    pRgnData ->rdh.nCount  = iCount ;
    pRgnData ->rdh.nRgnSize = sizeof( RECT ) *iCount ;
    pRgnData ->rdh.rcBound.left     = 0 ;
    pRgnData ->rdh.rcBound.top     = 0 ;
    pRgnData ->rdh.rcBound.right    =dibsize.cx ;
    pRgnData ->rdh.rcBound.bottom = dibsize.cy ;
       
    int iLeft = 0 ;
    for( i = dibsize.cy -1 ; i >= 0 ; i --)
    // 因為Bitmap 位圖在Y 方向是顛倒
     的所以要從底部開始
    {
        bkey = TRUE ;
        iLeft = -1 ;
        for( j = 0 ; j < dibsize.cx ; j ++)
        {
        if( m_dib.GetPixel( j , i ) == m_dwColorKey )
        {
          if( !bkey )
          {
          pRect[ iIndex ].left = iLeft ;
          pRect[ iIndex ].right = j ;
          pRect[ iIndex ].top = dibsize.cy -i -1 ;
          pRect[iIndex].bottom = dibsize.cy -i;
          bkey = TRUE ;
          iIndex ++;
          iLeft = -1 ;
          }
        }
           else
           {
              if( bkey )
              {
                iLeft = j ;
                bkey = FALSE ;
              }
           }
        }

        if( iLeft >= 0 )
        {
          pRect[ iIndex ].left = iLeft ;
          pRect[ iIndex ].right = dibsize.cx ;
          pRect[ iIndex ].top = i ;
          pRect[ iIndex ].bottom = i ;
          iIndex ++;
        }
    }
       BOOL br = m_rgn.CreateFromData
    ( NULL , sizeof( RGNDATAHEADER ) +sizeof
    ( RECT ) *iCount , pRgnData ) ;
       return br ;
    }
      有了這個方法, 任意形狀的窗口都可以被創建, 只要先畫出想要的形狀位圖即可。

      這里還要談到一個問題, 任意形狀的窗口沒有標題欄, 那么用戶如何拖動窗口呢? 其實只要在響應左鍵點擊消息時調用SendMessage( WM_SYSCOMMAND , SC_MOVE | HTCLIENT , 0 ) 即可。  

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>