亚洲av色香蕉一区二区三区,十四以下岁毛片带血a级,亚洲 校园 欧美 国产 另类,亚洲av日韩av一区谷露,色欲av无码一区二区三区

  • 相關(guān)軟件
    >Windows 中不規(guī)則窗體的編程實(shí)現(xiàn) 創(chuàng)建者:webmaster 更新時(shí)間:2005-07-02 01:25

    一、序言

      在絕大多數(shù)的Windows應(yīng)用程序中,其窗體都是使用的正規(guī)正矩的矩形窗體,例如我們常用的,“記事本”,“掃雷”,等等。矩形窗體,具有編程實(shí)現(xiàn)簡單,風(fēng)格簡潔的優(yōu)點(diǎn),所以在普通文檔應(yīng)用程序和簡單小游戲中使用足矣。但在某些娛樂游戲程序中使用就略顯呆板些了,這時(shí)若用不規(guī)則窗體替代原先的矩形窗體,將會(huì)使這類程序更添情趣。典型的例子有windows 自代的Media Player,新版本的Media Player有個(gè)控制面板的選項(xiàng),選中這些面板,播放器就以選中的面板形狀出現(xiàn),這時(shí)的播放器比以前版本的Media Player的古老矩形界面要生動(dòng)有趣的多了。 要實(shí)現(xiàn)不規(guī)則窗體不是太難,知道了基本原理后,你也可以創(chuàng)建各種有趣的不規(guī)則窗體。

      二、實(shí)現(xiàn)原理

      所有的 Windows 窗體都位于一個(gè)稱為“region”中,窗體的大小如果超出“region”的范圍,windows 會(huì)自動(dòng)裁剪超出"region"范圍那部分的窗體,使其不可見。所以,要?jiǎng)?chuàng)建不規(guī)則窗體有兩個(gè)步驟:第一步就是創(chuàng)建不規(guī)則"region".第二步就是將窗體放到創(chuàng)建的“region”中。

      其中第二步很簡單就調(diào)用一條語句即可。在SDK中調(diào)用API函數(shù)SetWindowRgn,該函數(shù)原型如下:





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

      其中hWnd為待設(shè)置的窗體句柄,hRgn為已經(jīng)創(chuàng)建的"region"句柄,bRedraw代表是否要重繪窗體。在MFC 中使用窗口類CWnd的成員函數(shù)int CWnd::SetWindowRgn(HRGN hRgn, BOOL bRedraw );該函數(shù)的參數(shù)意義與API中同名函數(shù)相同。

      相對(duì)與第二步,創(chuàng)建不規(guī)則窗體的第一步要復(fù)雜許多,并且不規(guī)則窗體越復(fù)雜,創(chuàng)建其"region"的過程也越復(fù)雜。接下去我們將由淺入深地介紹各種創(chuàng)建”region”的方法。

      在MFC中"region"對(duì)象,由CRgn類實(shí)現(xiàn)。CRgn的幾乎每個(gè)成員函數(shù)都有同名的SDK API函數(shù)對(duì)應(yīng)。

      三、簡單“region”的創(chuàng)建

      類CRgn創(chuàng)建一個(gè)新的"region"的簡單方法有以下幾個(gè)成員函數(shù): BOOL CRgn::CreateRectRgn( int x1, int y1, int x2, int y2 ); 創(chuàng)建矩形的“region”。





    BOOL CRgn::CreateEllipticRgn( int x1, int y1, int x2, int y2 ); 創(chuàng)建圓形或橢圓形“region”。
    BOOL CRgn::CreateRoundRectRgn( int x1, int y1, int x2, int y2, int x3, int y3 ); 創(chuàng)建圓角矩形“region”。
    BOOL CRgn::CreatePolygonRgn( LPPOINT lpPoints, int nCount, int nMode ); 創(chuàng)建多邊形“region”。

      這里以創(chuàng)建橢圓窗體為例,介紹橢圓窗體創(chuàng)建的方法。在創(chuàng)建橢圓“region”的CreateEllipticRgn函數(shù)中,x1,y1指橢圓所在矩形的左上角坐標(biāo),x2,y2指該矩形的右下角坐標(biāo)。

      下面的代碼加入到MFC對(duì)話框程序的OnInitDialog函數(shù)中,可將該對(duì)話框變成橢圓窗體:





    BOOL CTestDlg::OnInitDialog()
    {
    CDialog::OnInitDialog();
    ...
    CRgn rgn;
    rgn. CreateEllipticRgn(0,0,200,100);
    SetWindowRgn(rgn,TRUE);
    }







    圖一 橢圓窗體效果圖

      四、作圖路徑法創(chuàng)建”region”

      使用該方法創(chuàng)建”region”的過程如下:

      第一步繪制所要?jiǎng)?chuàng)建的窗體形狀。
     
      該步驟中使用到CDC類中的一些成員函數(shù)如下:BOOL CDC::BeginPath( );

      調(diào)用該函數(shù)后當(dāng)前設(shè)備環(huán)境(DC)開始追蹤繪圖的過程。





    int CDC::SetBkMode( int nBkMode );

      設(shè)置繪圖時(shí)的背景模式,此應(yīng)用中nBkMode必須取值為TRANSPARENT 。即設(shè)置繪圖時(shí)背景不發(fā)生變化。





    BOOL CDC::EndPath( );

      調(diào)用該函數(shù)后當(dāng)前設(shè)備環(huán)境(DC)結(jié)束追蹤繪圖的過程。

      開始繪圖前,先調(diào)用BeginPath,然后調(diào)用SetBkMode。接下去就可調(diào)用CDC的其他繪圖函數(shù)作圖,例如Arc,AngleArc,LineTo,MoveTo,RoundRect,,Textout等等。繪圖完畢調(diào)用EndPath().

      第二步將繪制的結(jié)果轉(zhuǎn)成”region”.

      此步驟中使用SDK API函數(shù)





    HRGN PathToRegion( HDC hdc );

      Hdc為作圖DC的句柄, CDC類中的m_hDC成員變量可做此參數(shù)傳入。示例,將下面代碼加入某個(gè)按鈕單擊事件中,可以將當(dāng)前窗體變?yōu)樽址県ello”的形狀





    void CTestDlg::OnTest()
    {
     HRGN wndRgn;
     CClientDC dc(this);
     CFont mFont;

     if (dc.m_hDC!=NULL)
     {
      VERIFY(mFont.CreateFont(200, 50, 0, 0, FW_HEAVY, TRUE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
    CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "宋體"));

      //開始記錄窗體輪廓路徑
      dc.BeginPath();

      //設(shè)置背景為透明模式,這句話是必須有的。
      dc.SetBkMode(TRANSPARENT);

      CFont * pOldFont;
      pOldFont = dc.SelectObject( &mFont );
      dc.TextOut(0, 0, "Hello");

      //結(jié)束記錄窗體輪廓路徑
      dc.SelectObject( pOldFont );
      dc.EndPath();

      //把所記錄的路徑轉(zhuǎn)化為窗體輪廓句柄
      wndRgn = ::PathToRegion(dc.m_hDC);

      //賦予窗體指定的輪廓形狀
      this->SetWindowRgn(wndRgn, TRUE);
     }
    }

      CClientDC是CDC的派生類,故此該類具有所有CDC類的成員變量和成員函數(shù)。







    圖二 hello形狀的窗體效果圖

      五、根據(jù)圖像創(chuàng)建”region”

      此法創(chuàng)建不規(guī)則窗體比較復(fù)雜。首先準(zhǔn)備一張含有目標(biāo)窗體形狀的圖片,設(shè)置透明色即將圖片中部不屬于窗體形狀的部分,標(biāo)記成同一種顏色,例如藍(lán)色RGB(0,0,255).程序運(yùn)行后先裝入圖片。然后逐個(gè)掃描圖片的每個(gè)像素,如這個(gè)像素不屬于透明色,則在相應(yīng)位置創(chuàng)建一個(gè)只含一個(gè)像素的“region”然后將這些小”region ”合并起來組成一個(gè)任意形狀的”region”.這里將使用到CRgn的一個(gè)成員函數(shù) :int CRgn::CombineRgn( CRgn* pRgn1, CRgn* pRgn2, int nCombineMode );

      其中pRgn1,pRgn2為要合并的兩個(gè)“region”,nCombineMode為合并的方式,此應(yīng)用中取RGN_OR,即兩”region”全部合并去處重復(fù)部分。代碼實(shí)現(xiàn)如下:





    void SetupRegion(
     CDC *pDC, //窗體的DC指針
     CBitmap &cBitmap, //含有窗體形狀的位圖對(duì)象
     COLORREF TransColor //透明色
    )
    {
     CDC memDC;
     //創(chuàng)建與傳入DC兼容的臨時(shí)DC
     memDC.CreateCompatibleDC(pDC);

     CBitmap *pOldMemBmp=NULL;
     //將位圖選入臨時(shí)DC
     pOldMemBmp=memDC.SelectObject(&cBitmap);

     CRgn wndRgn;
     //創(chuàng)建總的窗體區(qū)域,初始region為0
     wndRgn.CreateRectRgn(0,0,0,0);

     BITMAP bit;
     cBitmap.GetBitmap (&bit);//取得位圖參數(shù),這里要用到位圖的長和寬

     int y;
     for(y=0;y<=bit.bmHeight ;y++)
     {
      CRgn rgnTemp; //保存臨時(shí)region

      int iX = 0;
      do
      {
       //跳過透明色找到下一個(gè)非透明色的點(diǎn).
       while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor)
        iX++;
        //記住這個(gè)起始點(diǎn)
        int iLeftX = iX;

        //尋找下個(gè)透明色的點(diǎn)
        while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor)
         ++iX;

        //創(chuàng)建一個(gè)包含起點(diǎn)與重點(diǎn)間高為1像素的臨時(shí)“region”
        rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);

        //合并到主"region".
        wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);

       //刪除臨時(shí)"region",否則下次創(chuàng)建時(shí)和出錯(cuò)
       rgnTemp.DeleteObject();
      }while(iX GetWindow();
      pWnd->SetWindowRgn(wndRgn,TRUE);
      pWnd->SetForegroundWindow();
     }

      上述代碼創(chuàng)建的不規(guī)則窗體中,在OnEraseBkgnd事件中繪制該位圖,就可得到與該位圖形狀一模一樣的窗體。







    圖三 根據(jù)位圖和位圖中的透明色創(chuàng)建的窗體效果圖

      六、小結(jié)

      三種創(chuàng)建“region”的方法,第一種最簡單,如果所需的窗體形狀是簡單的幾何圖形,這種方法最合適;第二種稍微復(fù)雜些,但是創(chuàng)建的窗體形狀更多些;第三種方法可以創(chuàng)建任何在圖片中畫出的窗體形狀,但是實(shí)現(xiàn)的復(fù)雜度也最高。
    相關(guān)文章
    本頁查看次數(shù):