欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Windows 中不規(guī)則窗體的編程實現(xiàn)

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

二、實現(xiàn)原理
所有的 Windows 窗體都位于一個稱為“region”中,窗體的大小如果超出“region”的范圍,windows 會自動裁剪超出"region"范圍那部分的窗體,使其不可見。所以,要創(chuàng)建不規(guī)則窗體有兩個步驟:
第一步就是創(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ù)相同。
相對與第二步,創(chuàng)建不規(guī)則窗體的第一步要復(fù)雜許多,并且不規(guī)則窗體越復(fù)雜,創(chuàng)建其"region"的過程也越復(fù)雜。接下去我們將由淺入深地介紹各種創(chuàng)建”region”的方法。在MFC中"region"對象,由CRgn類實現(xiàn)。CRgn的幾乎每個成員函數(shù)都有同名的SDK API函數(shù)對應(yīng)。

三、簡單“region”的創(chuàng)建
類CRgn創(chuàng)建一個新的"region"的簡單方法有以下幾個成員函數(shù):
?? 1. BOOL CRgn::CreateRectRgn( int x1, int y1, int x2, int y2 ); 創(chuàng)建矩形的“region”。
?? 2. BOOL CRgn::CreateEllipticRgn( int x1, int y1, int x2, int y2 ); 創(chuàng)建圓形或橢圓形“region”。
?? 3. BOOL CRgn::CreateRoundRectRgn( int x1, int y1, int x2, int y2, int x3, int y3 ); 創(chuàng)建圓角矩形“region”。
?? 4. 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對話框程序的OnInitDialog函數(shù)中,可將該對話框變成橢圓窗體:

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


  


Windows 中不規(guī)則窗體的編程實現(xiàn)
圖一 橢圓窗體效果圖


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

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

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

設(shè)置繪圖時的背景模式,此應(yīng)用中nBkMode必須取值為TRANSPARENT 。即設(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ù)傳入。示例,將下面代碼加入某個按鈕單擊事件中,可以將當(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ù)。
Windows 中不規(guī)則窗體的編程實現(xiàn)
圖二 hello形狀的窗體效果圖

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

其中pRgn1,pRgn2為要合并的兩個“region”,nCombineMode為合并的方式,此應(yīng)用中取RGN_OR,即兩”region”全部合并去處重復(fù)部分。代碼實現(xiàn)如下:
    void SetupRegion(
CDC *pDC, //窗體的DC指針
CBitmap &cBitmap, //含有窗體形狀的位圖對象
COLORREF TransColor //透明色
)
{    CDC memDC;
    //創(chuàng)建與傳入DC兼容的臨時DC
    memDC.CreateCompatibleDC(pDC);

    CBitmap *pOldMemBmp=NULL;
    //將位圖選入臨時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; //保存臨時region
            
            int iX = 0;
            do
            {
                //跳過透明色找到下一個非透明色的點.
                while (iX <= bit.bmWidth  && memDC.GetPixel(iX, y) == TransColor)
                    iX++;

                //記住這個起始點
                int iLeftX = iX;

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

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

                //合并到主"region".
                wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);
                
		//刪除臨時"region",否則下次創(chuàng)建時和出錯
                rgnTemp.DeleteObject();
            }while(iX GetWindow();
    pWnd->SetWindowRgn(wndRgn,TRUE);    
    pWnd->SetForegroundWindow();    
}

  

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

Windows 中不規(guī)則窗體的編程實現(xiàn)
圖三 根據(jù)位圖和位圖中的透明色創(chuàng)建的窗體效果圖

六、小結(jié)
三種創(chuàng)建“region”的方法,第一種最簡單,如果所需的窗體形狀是簡單的幾何圖形,這種方法最合適;第二種稍微復(fù)雜些,但是創(chuàng)建的窗體形狀更多些;第三種方法可以創(chuàng)建任何在圖片中畫出的窗體形狀,但是實現(xiàn)的復(fù)雜度也最高。

注:本文的寫作曾參考了“ 形態(tài)各異的不規(guī)則窗體 ”一文。

Windows 中不規(guī)則窗體的編程實現(xiàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产婷婷精品av在线 | 亚洲欧美综合乱码精品成人网 | 成人国内精品久久久久影院 | 免费视频不卡一区二区三区 | 国产精品无码2021在线观看 | 国产精品k | a高清免费毛片久久 | 台湾三级无遮挡在线播放 | 天天爱天天做久久天天狠狼 | 99精品视频免费在线观看 | 人人插人人澡 | 五月婷婷社区 | 亚洲综合在线另类色区奇米 | 亚洲aⅴ天堂 | 精品国产青草久久久久福利 | 香蕉久草在线 | 一区二区视频在线 | 自拍偷拍视频网站 | 亚洲片在线观看 | 四虎永久| 久草免费在线观看 | 日本娇小xxxxhd | 久久久精品久久视频只有精品 | 高清中文字幕视频在线播 | 99热久久国产综合精品久久国产 | 黑人巨大videosjapan高清 婷婷在线免费观看 | 久久精品国产99国产精品澳门 | 一级做a爰片久久毛片唾 | 亚洲网站免费 | 深夜影院破解版免费vip | 97国产精品最新 | 欧美亚洲激情视频 | 狠狠干中文字幕 | 美女用震蛋叫爽的视频95视频 | 国产乱人乱精一区二区视频密 | 成人年鲁鲁在线观看视频 | 香港全黄一级毛片在线播放 | 国产高清在线视频 | 成人片网址 | 欧美aaaaaaaaa | 亚洲 欧美 日韩中文字幕一区二区 |