• <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>
            隨筆 - 67  文章 - 171  trackbacks - 0
            <2014年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(10)

            隨筆分類

            隨筆檔案

            連接資料

            最新隨筆

            搜索

            •  

            最新隨筆

            最新評論

            用VC++實現異形窗口.大連鐵道學院(116028)李文輝隨著Microsoft憑借Windows在操作系統上取得的巨大成績,Windows用戶界面也日益成為業界標準。統一的界面給廣大用戶對應用軟件的學習與使用帶來了很大方便。但每天都面對同一副面孔,日久天長難免會產生一些厭倦,開發一些“離經叛道”,一改Windows應用程序千篇一律的“標準”界面,一定會給你帶來一種清新的感覺。標準Windows應用程序窗口一般為帶有標題欄的淺灰色矩形外觀,因而“異形”對話框/窗口也主要是顏色與外形上動手腳。改變背景顏色
            改變對話框(窗口)的背景顏色是最簡單的改變Windows應用程序外觀的方法,根據Windows創建與管理機理,一般有兩種方法。一種是處理WM_CTLCOLOR消息,首先創建所選背景顏色的刷子,然后調用SetBkColor()或SetDialogBkColor()以所創建的刷子來繪制窗口或對話框的背景。需要重畫窗口或對話(或對話的子控件)時,Windows向對話發送消息WM_CTLCOLOR,應用程序處理WM_CTLCOLOR消息并返回一個用來繪畫對話背景的刷子句柄。另外一種是響應Windows的WM_ERASEBKGND消息,Windows向窗口發送一個WM_ERASEBKGND消息通知該窗口擦除背景,可以使用VC++的ClassWizard重載該消息的缺省處理程序來擦除背景(實際是用刷子畫),并返回TRUE以防止Windows擦除窗口。2.改變窗口外形通過使用新的SDK函數SetWindowRgn(),可以將繪畫和鼠標消息限定在窗口的一個指定的區域,因此實際上是使窗口成為指定的不規則形狀(區域形狀)。“區域”是Windows GDI中一種強有力的機制,區域是設備上的一塊空間,可以是任意形狀,復雜的區域可以由各個小區域組合而成。Windows內含的區域創建函數有CreateRectRgn()、CreatePolyRgn()、CreatePolygonRgn()、CreateRoundRectRgn()和CreateEllipticRgn(),再通過CombineRgn()來組合區域,即可得到復雜形狀的區域,獲得復雜形狀的窗口外形。通過上面的方法雖然可以得到“異形”窗口,但感覺顏色單調,外形也不夠“COOL”,能否獲得更酷的“異形”對話框/窗口呢?回答是肯定的。下面就介紹利用位圖和蒙板創建“異形”對話框/窗口的方法。3.利用位圖創建異形對話框窗口利用位圖創建異形對話框原理是根據象素的顏色來進行“扣像”處理,對所有非指定顏色象素區域進行區域組合。利用這一技術,實際上就是實現對話框/窗口的位圖背景,并且對指定的顏色區域進行透明處理。下面就以透明位圖為背景的對話框為例來說明:首先用繪圖軟件如PhotoShop繪制編輯一幅擬做對話框背景用的圖片,用BMP格式保存,假設存為Back.Bmp。需要說明的是,雖然Visual C++集成開發環境的資源編輯器只能編輯不超過16色的位圖,但完全我們可以以真彩色方式存儲,不必理會Visual C++的警告。下一步是用Visual C++的AppWizard創建一個基于對話框的應用程序假定命名為Trans。用資源編輯器引入背景圖片Back.Bmp,如果是高彩色,不必理會出現的警告信息,點擊OK確認即可。為了明確,修改默認的資源ID標識IDB_BITMAP1為IDB_BACKBMP。然后修改對話框的Style為Popup,Border為None,如圖1
            。圖1向CTransDlg類添加區域處理功能模塊void CTransDlg::SetupRegion(CDC *pDC /*對話框窗口DC*/, UINT BackBitmapID /*背景位圖資源ID*/, UINT MaskBitmapID /*區域處理位圖資源ID*/, COLORREF TransColor = 0x00000000 /*透明顏色值,默認為黑色*/)。到目前為止,我們暫時認為MaskBitmapID等同于BackBitmapID。其核心工作是根據MaskBitmapID指示位圖的象素顏色進行區域組合。完整的代碼如下:void CTransDlg::SetupRegion(CDC *pDC /*對話框窗口DC*/, UINT BackBitmapID /*背景位圖資源ID*/,UINT MaskBitmapID /*區域處理位圖資源ID*/,COLORREF TransColor /*透明顏色值*/){CDC memDC;CBitmap cBitmap;CBitmap* pOldMemBmp = NULL;COLORREF cl;CRect cRect;UINT x, y;CRgn wndRgn, rgnTemp;//取得窗口大小GetWindowRect(&cRect);//背景位圖資源IDm_BackBitmapID = BackBitmapID//裝載位圖cBitmap.LoadBitmap(MaskBitmapID);memDC.CreateCompatibleDC(pDC);pOldMemBmp = memDC.SelectObject(&cBitmap);//首先創建默認的完整區域為完整的窗口區域wndRgn.CreateRectRgn(0, 0, cRect.Width(), cRect.Height());//下面的兩層循環為檢查背景位圖象素顏色,進行透明區域處理;//當象素顏色為指定的透明值時,即將該點從區域中剪裁掉。//其中用到的幾個成員變量m_MaskLeftOff、m_MaskTopOff、//m_MaskRightOff、m_MaskBottomOff、m_FrameWidth//和m_CaptionHeight,其作用后面再作說明,此時可全部當作0來處理。for(x= m_FrameWidth+m_MaskLeftOff;x<=cRect.Width() - m_FrameWidth-m_MaskRightOff; x++){for(y = m_CaptionHeight+m_MaskTopOff; 


             


             


            y<=cRect.Height() - m_FrameWidth-m_MaskBottomOff; y++){//取得坐標處象素的顏色值cl = memDC.GetPixel(x - m_FrameWidth-m_MaskLeftOff,y - m_CaptionHeight-m_MaskTopOff);if(col == TransColor){//象素顏色為指定的透明色,創建透明“微區域”rgnTemp.CreateRectRgn(x, y, x+1, y+1);//“扣像”,從完整的區域中“扣除”透明的“微區域”wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);//刪除剛創建的透明“微區域”,釋放系統資源rgnTemp.DeleteObject(); }}}if (pOldMemBmp) memDC.SelectObject(pOldMemBmp);//用設定窗口為指定的區域SetWindowRgn((HRGN)wndRgn, TRUE);}重置系統默認的背景擦除操作,即添加WM_ERASEBKGND消息處理過程,這一步可以借助ClassWizard來簡化操作。BOOL CTransDlg::OnEraseBkgnd(CDC* pDC) {// TODO: Add your message handler code here and/or call defaultCRect rect;CDC memDC;CBitmap cBitmap;CBitmap* pOldMemBmp = NULL;GetWindowRect(&rect);//裝載背景位圖cBitmap.LoadBitmap(m_BackBitmapID);memDC.CreateCompatibleDC(pDC);pOldMemBmp = memDC.SelectObject(&cBitmap);//將背景位圖復制到窗口客戶區pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRC/DownloadFiles\a\2001-10-12\COPY);if (pOldMemBmp) memDC.SelectObject( pOldMemBmp );//刪除系統卻省的OnEraseBkgnd功能//return CDialog::OnEraseBkgnd(pDC);return TRUE;}接下來是在WM_PAINT的消息處理函數OnPaint()中添加代碼。由于當背景位圖比較大時,進行區域處理比較耗時,所以只在啟動時進行一次處理。一種方法是OnInitDialog()處理,但這樣會在從啟動程序到窗口出現有相當的延遲,易引起程序尚未啟動的誤解。再一種方法就是在OnPaint()處理,但為了避免重復處理,可以加上一個判斷標志。以下是OnPaint()的代碼,正體為AppWizard生成,粗體為自己添加內容。void CTransDlg::OnPaint() {if (IsIconic()){……}else{if(m_nFirstRun){ //首次運行標志//修改鼠標光標為等待方式BeginWaitCursor();//設置背景區域SetupRegion(GetWindowDC(),
            計算機教程用VC++實現異形窗口.來自www.itwen.comIT WEN計算機教程網

            IDB_BACKBMP,
            IDB_BACKBMP,
            0x00FFFFFF /*白色*/);//恢復鼠標光標為正常模式EndWaitCursor();m_nFirstRun = 0;}CDialog::OnPaint();}}剩下的工作就是根據背景位圖的大小來設置對話框窗口的大小和位置,這可以在OnInitDialog()中通過調用MoveWindow()來實現。再添加一些變量的聲名和初始化,即可編譯運行。圖2為運行結果示例:圖24.進一步的討論前面實現了單一模式的異形對話框,但有些情況下又需要不同的樣式,如有標題欄、邊框等,或者只作局部的處理,這就是前面兩個成員變量m_FrameWidth和m_CaptionHeight作用,通過在OnInitDialog()判斷窗口樣式,使m_FrameWidth和m_CaptionHeight取不同的值。這部分的代碼為:BOOL CTransBmpDlg::OnInitDialog(){……// TODO: Add extra initialization herem_nFirstRun = 1;//數據設置,窗口左上角坐標:m_Left=0,m_Top=0
            //背景位圖寬高:m_Width=535,m_Height=105SetSize(0, 0, 535, 105);//蒙板處理區域與窗口邊框的距離m_MaskLeftOff=m_MaskTopOff=m_MaskRightOff=m_MaskBottomOff=0;//窗口邊框與標題欄象素值m_FrameWidth = m_CaptionHeight = 0;//取得窗口樣式LONG style = ::GetWindowLong(this->m_hWnd, GWL_STYLE);//如保留窗口風格樣式,則根據不同的窗口邊框類型


              

             


            //選取不同的m_FrameWidth和m_CaptionHeight值,
            //也可以根據處理位置的需要進行付值if((style & WS_BORDER) == WS_BORDER)m_FrameWidth = ::GetSystemMetrics(SM_CXBORDER);if((style & WS_THICKFRAME) == WS_THICKFRAME)m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);if((style & DS_MODALFRAME) == DS_MODALFRAME)m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);if((style & WS_CAPTION) == WS_CAPTION){m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);m_CaptionHeight = ::GetSystemMetrics(SM_CYSMCAPTION);}m_CaptionHeight += m_FrameWidth * 2;//重置窗口的位置和大小MoveWindow(m_Left, m_Top,
            m_Width + m_FrameWidth * 2,
            m_Height + m_CaptionHeight, TRUE);……return TRUE; // return TRUE unless you set the focus to a control}另外,為進一步增加靈活性,使窗口樣式不僅僅受背景位圖顏色的控制。通過指定SetupRegion()的MaskBitmapID 為一個我們稱之為“蒙板”的雙色位圖(多色彩也可以,但一般沒有必要),即可實現需要的操作。圖4為在同一背景位圖上,通過圖3的蒙板位圖實現的效果,并且增加了對話框窗體的邊框和標題欄屬性。圖3圖4利用這種蒙板技術,可以創建出任意形狀的窗口,而與背景位圖無關。需要注意的是,對于對話框中的控件如按鈕等,如處在或部分處在通明區域中,則通明區域中部分一并被剪裁掉,是否剪裁和剪裁位置與大小,利用蒙板可以很方便地進行控制。需要特別指出的是,SetWindowRgn()所指定的區域是針對整個窗口的,而Bitblt()/ StretchBlt()的輸出區域是針對于客戶區,兩者在定位上是不同的,編程中應加以注意并靈活應用,這也是前面之所以設置邊框大小等變量的原因。5.結束語這種異形窗口的創建不僅適應于對話框,而且適應于所有的基于CWnd類的派生窗口。采用這一方法,你可以創建出任何只要你能夠畫出的窗體,實現只要可以畫出,就可以做出的目標。本文代碼在Visual C++ 5.0、6.0下調試通過,運行正常,操作系統為Windows98SE。

            posted on 2008-08-04 11:00 cpsprogramer 閱讀(3907) 評論(0)  編輯 收藏 引用 所屬分類: VC++
            精品熟女少妇aⅴ免费久久| 久久久噜噜噜久久中文福利| 99久久人妻无码精品系列| 久久电影网2021| 亚洲午夜久久久| 97精品国产91久久久久久| 久久这里只有精品首页| 亚洲精品乱码久久久久久蜜桃不卡 | 三级片免费观看久久| 久久精品国产亚洲AV大全| 女人香蕉久久**毛片精品| 蜜臀av性久久久久蜜臀aⅴ麻豆| 亚洲国产成人精品91久久久 | 一本色道久久88综合日韩精品 | 国产V亚洲V天堂无码久久久| 久久99精品国产麻豆婷婷| 久久精品国产亚洲AV高清热| 久久亚洲国产最新网站| 久久九九久精品国产免费直播| .精品久久久麻豆国产精品| 久久人人超碰精品CAOPOREN| 久久性精品| 国产亚州精品女人久久久久久 | 影音先锋女人AV鲁色资源网久久| 欧美亚洲国产精品久久| 日本久久久久久中文字幕| 亚洲精品美女久久777777| 国产欧美久久久精品影院| 久久夜色撩人精品国产小说| 久久er国产精品免费观看2| 久久66热人妻偷产精品9| 日韩精品久久久久久免费| 亚洲日本久久久午夜精品| 亚洲国产成人精品女人久久久 | 漂亮人妻被中出中文字幕久久| 久久婷婷国产麻豆91天堂| 久久电影网2021| 久久综合久久久| 久久国产高清一区二区三区| 久久国产综合精品五月天| 久久人妻少妇嫩草AV无码蜜桃|