MFC對話方塊裡利用CHtmlView載入介面(四)————分層視窗設定
在學會了 利用CHtmlView 在MFC對話方塊上顯示網頁,並支援JavaScript 和 MFC 之間的互相通訊後。 當然就想: 我們為什麼不能只用HTML 作為前端介面, 而底層用MFC實現邏輯呢? 這樣就完全不需要用到MFC對話方塊的介面風格了。
本文就講告訴大家如何實現 用HTML代替MFC的對話方塊介面。
首先解決的問題為: 如何使MFC對話方塊完全被HTML介面覆蓋?
答案就在視窗風格設定上。
首先我們消除對話方塊上方的系統選單欄:ModifyStyle(WS_CAPTION , 0);
這裡有必要解釋下ModifyStyle
BOOL ModifyStyle(
DWORD dwRemove,
DWORD dwAdd,
UINT nFlags = 0
);
dwRemove指定在樣式修改時要移除的視窗樣式。 dwAdd 指定在樣式修改時要新增的視窗樣式。
ModifyStyle(WS_CAPTION , 0);相當於將WS_CAPTION風格移除。 此風格為:對話方塊上方的系統選單欄,包含了對話方塊的名稱、關閉、最大化、最小化等按鈕。
我們只需要上述設定,就可以移除整個系統選單欄。
這裡注意到:系統選單框 會佔據 對話方塊客戶區一定區域,具體為寬度 15,高度 20。
而我們的html介面的寬度為962, 高度632, 所以如果在有選單欄的風格中,要想將html全面顯示,則對話方塊寬度,高度至少應設定為977, 652.
消除系統選單欄後,再用ModifyStyleEx( WS_EX_DLGMODALFRAME, 0) 消除對話方塊四邊的雙邊,即上圖的紅色標記部分。
消除後如圖:
這雙邊去除後,可以看到介面上多餘了一部分對話方塊,這是就需要我們設定對話方塊框的大小,剛好為html介面大小。
如下圖,這樣就將html完全覆蓋了對話方塊介面。
但是僅僅這樣做時,我們發現在將介面最小化後再次彈出時,介面會出現閃爍。我分析閃爍的根本原因為:MFC對話方塊要先繪製背景,然後再繪製html,這樣就會出現閃爍。
故,利用windows分層視窗( LayeredWindows)來將背景對話方塊透明化,這樣就能避免閃爍了。
具體的步驟如下:
一:設定視窗風格為分層視窗(WS_EX_LAYERED):
有兩種方法可以設定視窗屬性:
方法一:
ModifyStyleEx(0,WS_EX_LAYERED);
//設定視窗擴充套件風格為:分層視窗
方法二:
SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,WS_EX_LAYERED);
當設定了視窗風格為分層視窗後, 如果你未呼叫SetLayeredWindowAttributes或UpdateLayeredWindow為其設定透明情況,那麼預設將為全透明,不會彈出任何視窗。
二:設定背景透明屬性
::SetLayeredWindowAttributes(GetSafeHwnd(),RGB(255,
0, 255), 255,LWA_COLORKEY); //將背景顏色為RGB(255, 0, 255)透明化
或:
this->SetLayeredWindowAttributes(RGB(255,
0, 255), 255, LWA_COLORKEY );//將背景顏色為RGB(255,
0, 255)透明化
三:設定對話方塊背景顏色
在SetLayeredWindowAttributes中,有一項為設定透明顏色, 表示在繪製對話方塊背景時,如果為透明顏色,則讓其透明。 這就需要我們在背景繪製時,將其繪製為透明顏色,使其透明。
設定對話方塊背景的方式:
在OnPaint函式中:
voidCMFCHtmlTest1Dlg::OnPaint()
{
if (IsIconic())
{
。。。
}
else
{
CPaintDCdc(this);
RECTrect;
GetClientRect(&rect);
dc.FillSolidRect(&rect,RGB(255, 0, 255)); //設定對話方塊背景顏色
CDialogEx::OnPaint();
}
}
未透明 和 透明視窗 效果如圖:
最終這些設定我都在OnInitDialog()完成:
BOOLCMFCHtmlTest1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//將“關於...”選單項新增到系統選單中。
// IDM_ABOUTBOX必須在系統命令範圍內。
ASSERT((IDM_ABOUTBOX & 0xFFF0) ==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu*pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu !=NULL)
{
BOOLbNameValid;
CStringstrAboutMenu;
bNameValid =strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//設定此對話方塊的圖示。 當應用程式主視窗不是對話方塊時,框架將自動
// 執行此操作
SetIcon(m_hIcon,TRUE); // 設定大圖示
SetIcon(m_hIcon,FALSE); // 設定小圖示
// TODO: 在此新增額外的初始化程式碼
ModifyStyle(WS_CAPTION , 0); //移除對話方塊 上方的系統選單欄
ModifyStyleEx(WS_EX_DLGMODALFRAME, 0);//分層視窗,並且不在工作列裡顯示,不帶雙邊
SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,WS_EX_LAYERED);
CRectrtDesk;
GetWindowRect(rtDesk);
MoveWindow(rtDesk.left,rtDesk.top,width, height);
this->SetLayeredWindowAttributes(RGB(255,
0, 255), 255, LWA_COLORKEY );
m_HtmlView.CreateFromStatic(IDC_STATIC1,this);
//載入html
returnTRUE; // 除非將焦點設定到控制元件,否則返回 TRUE
}