維尼的蜂巢

RealTime??!! It’s amazing!!!!

不規則視窗 part II 二月 14, 2008

Filed under: VC++/C++/C — kevinlin @ 10:49 上午

之前有一篇不規則視窗六種方法,其實標題不是下的很好,應該是不規則圖形繪製,那一篇主要就是繪製圖形時,將alpha=0的給去除掉。
這一篇才是真正的不規則視窗的實作。

int SetWindowRgn(
  HWND hWnd,     // handle to window 指定的窗口
  HRGN hRgn,     // handle to region 輪廓
  BOOL bRedraw   // window redraw option 呼叫後是否重繪
);

HRGN是由多個點構成的一個資料結構,所以可以做成任何形狀
ex.HRGN rgn = CreateEllpticRgn(0,0,200,100)就有一個橢圓形的region了

先介紹我自己寫的方法:

設計個演算方法取得某張圖的HRGN

假設有一張圖叫做他Image好了

int h = Image.GetHeight();
int w = Image.GetWidth();

  pTempBuffer = new unsigned char[ sizeof( RGNDATAHEADER ) + sizeof( RECT ) * w * h ];
//pTempBuffer是一個unsigned char的AutoPtr
  RGNDATA* pRgnData = ( RGNDATA* )pTempBuffer.Get();
  RECT*pRect = (RECT* )( pTempBuffer.Get() + sizeof( RGNDATAHEADER ) );
  int bKey = true;
  int Left = 0;
  int Index = 0;
  for( int i=h-1;i>=0;i--)
  {
   bKey = true;
   Left = -1;
   MyColorA8R8G8B8*pImageBuffer = (MyColorA8R8G8B8*)Image.GetScanLine(i);
   for( int j=0; j<w; j++)
   {

    if( pImageBuffer->A < 255 )
    {
     if( !bKey )
     {
      pRect&#91;Index&#93;.left = Left ;
      pRect&#91;Index&#93;.right = j  ;
      pRect&#91;Index&#93;.top = i;//h - i -1;
      pRect&#91;Index&#93;.bottom = i+1;//h - i;
      bKey = true;
      Index++;
      Left = -1;
     }
    }
    else if ( bKey )
    {
     Left =j;
     bKey=false;
    }
    pImageBuffer++;
   }
   if( Left>=0 )
   {
    pRect[Index].left = Left;
    pRect[Index].right = w;
    pRect[Index].top = i;
    pRect[Index].bottom = i+1;
    Index++;
   }
  }
  int Count = Index;
  pRgnData->rdh.dwSize= sizeof( RGNDATAHEADER ) ;
  pRgnData->rdh.iType= RDH_RECTANGLES;
  pRgnData->rdh.nCount= Count;
  pRgnData->rdh.nRgnSize = sizeof( RECT ) * Count;
  pRgnData->rdh.rcBound.left = 0;
  pRgnData->rdh.rcBound.top = 0;
  pRgnData->rdh.rcBound.right = w;
  pRgnData->rdh.rcBound.bottom = h;

  HRGN WndRgn = ExtCreateRegion( NULL, sizeof( RGNDATAHEADER )+ sizeof( RECT ) * Count, pRgnData );

ps.MyColorA8R8G8B8跟Image是自己定義的一個資料結構,不過重點在後面的產生WndRgn,產生後就能給SetWindowRgn去用了

這是網路上找的到的方法:
那個CreateRgnFromFile是一個龐大的Function ,不過複製貼上就能用了

// ==================== 建立形狀 ===================== 
// Step 1: 載入影像
   HBITMAP hBmp = (HBITMAP) LoadImage( AfxGetInstanceHandle(), "Rgn.bmp",IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE );
 
// Step 2:建立一個 Region, 令紅色為透明色 (transparent)
    HRGN hRgn = CreateRgnFromFile( hBmp, RGB(255,0,0) );

// Step 3:設定視窗大小與影像大小相同
    SetWindowPos( NULL, 0, 0, m_dwWidth, m_dwHeight, SWP_NOZORDER | SWP_NOMOVE );

// Step 4:設定視窗的形狀
    SetWindowRgn( hRgn, TRUE );
// ==================== End  =====================
 

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s