web browser控件在对话框程序中不会闪烁, 而在CWnd中, 当窗口缩放的时候就会闪.一个web browser控件由3层窗口组成:
Shell Embedding
Shell DocObject View
Internet Explorer_Server
而Internet Explorer_Server这层窗口可能只有在显示网页后才出现. 刚创建的时候并没有这层窗口. 闪烁的原因就是Internet Explorer_Server在显示的时候总是先画背景在画前景, 交替刷新导致的.
所以我们只要在Internet Explorer_Server这层窗口的WM_ERASEBKGND消息中直接返回TRUE就可以, 采用的方法就是从CWnd派生一个类, 处理WM_ERASEBKGND消息, 然后用这个窗口类来子类化Internet Explorer_Server这层窗口.
由于Internet Explorer_Server是在显示网页的时候才会出现(调用Navigate2后并不一定马上就出现), 所以1是可以在网页加载完后子类化(有消息可以得到), 2是在父窗口OnSize的时候处理, 由于网页加载过程中可能就会缩放窗口引起闪烁,所以我们在父窗口的OnSize中处理.
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CUIWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (m_wndSubclass.GetSafeHwnd() == NULL) // m_wndSubclass是CWnd的派生类, 处理了WM_ERASEBKGND消息
{
CWnd *pWnd = GetWindow(GW_CHILD);
while (pWnd != NULL)
{
char szClass[MAX_PATH] = {0};
GetClassName(pWnd-> GetSafeHwnd(), szClass, MAX_PATH-1);
if (strcmp(szClass, "Shell Embedding ") == 0)
{
pWnd = pWnd-> GetWindow(GW_CHILD);
while (pWnd != NULL)
{
GetClassName(pWnd-> GetSafeHwnd(), szClass, MAX_PATH-1);
if (strcmp(szClass, "Internet Explorer_Server ") == 0)
{
m_wndSubclass.SubclassWindow(pWnd-> GetSafeHwnd());
break;
}
pWnd = pWnd-> GetWindow(GW_CHILD);
}
break;
}
pWnd = pWnd-> GetWindow(GW_HWNDNEXT);
}
}
if (m_IE.GetSafeHwnd() != NULL) // m_IE是一个Web browser控件
{
m_IE.SetWindowPos(NULL, 0, 0, cx-20, cy-20, SWP_NOMOVE);
}
}
也可以不用窗口类子类化IE控件, 而是用窗口过程子类化它(推荐)
WNDPROC wpOrigIEProc = NULL; // 最好定义成类成员
LRESULT APIENTRY IESubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_ERASEBKGND)
return TRUE;
return CallWindowProc(wpOrigIEProc, hwnd, uMsg, wParam, lParam);
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CUIWnd::OnSize(nType, cx, cy);
if (wpOrigIEProc == NULL)
{
CWnd *pWnd = GetWindow(GW_CHILD);
while (pWnd != NULL)
{
char szClass[MAX_PATH] = {0};
GetClassName(pWnd-> GetSafeHwnd(), szClass, MAX_PATH-1);
if (strcmp(szClass, "Shell Embedding ") == 0)
{
pWnd = pWnd-> GetWindow(GW_CHILD);
while (pWnd != NULL)
{
GetClassName(pWnd-> GetSafeHwnd(), szClass, MAX_PATH-1);
if (strcmp(szClass, "Internet Explorer_Server ") == 0)
{
wpOrigIEProc = (WNDPROC)SetWindowLong(pWnd-> GetSafeHwnd(), GWL_WNDPROC, (LONG)IESubclassProc);
break;
}
pWnd = pWnd-> GetWindow(GW_CHILD);
}
break;
}
pWnd = pWnd-> GetWindow(GW_HWNDNEXT);
}
}
WINDOWPLACEMENT wp;
pWnd-> GetWindowPlacement(&wp);
if (m_IE.GetSafeHwnd())
m_IE.SetWindowPlacement(&wp);
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
if(wpOrigIEProc==NULL)
{
TCHAR class_name[MAX_PATH+1];
bool found;
found=false;
CWnd * child;
for(child=GetWindow(GW_CHILD);child!=NULL;child=child->GetWindow(GW_HWNDNEXT))
{
//GetClassName(pWnd->GetSafeHwnd(),szClass,MAX_PATH);
//if(strcmp(szClass,"ShellEmbedding")==0)
{
CWnd * grand_child;
for(grand_child=child->GetWindow(GW_CHILD);grand_child!=NULL;grand_child=grand_child->GetWindow(GW_HWNDNEXT))
{
GetClassName(grand_child->GetSafeHwnd(),class_name,MAX_PATH);
if(class_name==CString("Internet Explorer_Server"))
{
found=true;
wpOrigIEProc=(WNDPROC)SetWindowLong(grand_child->GetSafeHwnd(),GWL_WNDPROC,(LONG)IESubclassProc);
break;
}
CWnd * great_grand_child;
for(great_grand_child=grand_child->GetWindow(GW_CHILD);great_grand_child!=NULL;great_grand_child=great_grand_child->GetWindow(GW_HWNDNEXT))
{
GetClassName(great_grand_child->GetSafeHwnd(),class_name,MAX_PATH);
if(class_name==CString("Internet Explorer_Server"))
{
found=true;
wpOrigIEProc=(WNDPROC)SetWindowLong(great_grand_child->GetSafeHwnd(),GWL_WNDPROC,(LONG)IESubclassProc);
break;
}
CWnd * great_great_grand_child;
for(great_great_grand_child=great_grand_child->GetWindow(GW_CHILD);great_great_grand_child!=NULL;great_great_grand_child=great_great_grand_child->GetWindow(GW_HWNDNEXT))
{
GetClassName(great_great_grand_child->GetSafeHwnd(),class_name,MAX_PATH);
if(class_name==CString("Internet Explorer_Server"))
{
found=true;
wpOrigIEProc=(WNDPROC)SetWindowLong(great_great_grand_child->GetSafeHwnd(),GWL_WNDPROC,(LONG)IESubclassProc);
break;
}
}
if(found)
break;
}
if(found)
break;
}//end of for grand child
}
if(found)
break;
}//end of for child
}
}