vc++创建异性窗体(2)
//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(),
IDB_BACKBMP,
IDB_BACKBMP,
0x00FFFFFF /*白色*/);
//恢復鼠標光標為正常模式
EndWaitCursor();
m_nFirstRun = 0;
}
CDialog::OnPaint();
}
}
剩下的工作就是根據背景位圖的大小來設置對話框窗口的大小和位置,這可以在OnInitDialog()中通過調用MoveWindow()來實現。再添加一些變量的聲名和初始化,即可編譯運行。圖2為運行結果示例:
圖2
4.進一步的討論
前面實現了單一模式的異形對話框,但有些情況下又需要不同的樣式,如有標題欄、邊框等,或者只作局部的處理,這就是前面兩個成員變量m_FrameWidth和m_CaptionHeight作用,通過在OnInitDialog()判斷窗口樣式,使m_FrameWidth和m_CaptionHeight取不同的值。這部分的代碼為:
BOOL CTransBmpDlg::OnInitDialog()
{// TODO: Add extra initialization here
m_nFirstRun = 1;
//數據設置,窗口左上角坐標:m_Left=0,m_Top=0
//背景位圖寬高:m_Width=535,m_Height=105
SetSize(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類的派生窗口。采用這一方法,你可以創建出任何只要你能夠畫出的窗體,實現只要可以畫出,就可以做出的目標。
轉載于:https://www.cnblogs.com/lzjsky/archive/2011/01/13/1934499.html
總結
以上是生活随笔為你收集整理的vc++创建异性窗体(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IntelliJ IDEA编码设置
- 下一篇: 浅尝boost之timer