您的位置:首页 > 产品设计 > UI/UE

duilib 尝试解决透明窗体WebBroswer控件无法显示的问题

2016-08-23 09:55 1931 查看
问题描述:
设置Window bktrans="true"时,WebBrowser控件无法正常显示。
https://github.com/redrains/DuiLib_Redrain/issues/9
Redrain的回复里说的,所有子窗体都将无法显示,经过验证确实是这样的。

相关讨论
http://blog.csdn.net/LostSpeed/article/details/21130755
https://github.com/redrains/DuiLib_Redrain/issues/9

方案一:
使用wke控件,这是Redrain给的建议 (7楼回复)
此方法我还没有验证过,既然Redrain建议了,那肯定错不了了,但是此方法有个问题,必须要引入wke.dll, 这个文件有10MB大,还有个插件的DLL, 也将近6MB, 对于某些小型应用程序,可能难以接受。比如我的上司,刚好就不能接受,所以此方案就放弃了。

下面这个链接是Redrain封装的wke控件,代码在他个人Github上
http://www.cnblogs.com/redrainblog/p/3888099.html

方案二:
创建两个窗口,一个窗口是带透明背景的,一个是纯IE控件,第一个窗口trans=true, 第二个trans=false, 然后处理窗口1的WM_MOVE消息,在窗口1移动时,同时移动窗口2。

此方案已经实现了,但是窗口会轻微晃动,完全没办法用,晃的太明显了。

后来打LOG看下WindowProc内,在窗口移动过程中,有以下5个消息都会被触发,于是每一种都试了下,好像WM_WINDOWPOSCHANGING的效果要稍微好一点,但还是不能接受,所以此方案放弃了。

WM_MOVE message:0x0003, wParam:0, lParam:13107657 -- Mon Aug 22 19:42:59 2016
WM_MOVING message:0x0216, wParam:9, lParam:4320328 -- Mon Aug 22 19:42:59 2016
WM_WINDOWPOSCHANGING message:0x0046, wParam:0, lParam:4320312 -- Mon Aug 22 19:42:59 2016
WM_GETMINMAXINFO message:0x0024, wParam:0, lParam:4318644 -- Mon Aug 22 19:42:59 2016
WM_WINDOWPOSCHANGED message:0x0047, wParam:0, lParam:4320312 -- Mon Aug 22 19:42:59 2016

方案三:
Redrain在其Blog内的一篇文章内提到的:
 半透明异形窗体的缺陷还是在于无法嵌入有句柄子控件。解决方法有两个:一是用双层窗体的方法,主窗体主动控制子控件联动(迅雷用这样的方法,只要联动做得够好,效果上还是不错的)。二是在WM_PAINT中用SendMessage发子控件发送WM_PRINT效率得到子控件的位图,具体操作在官方Duilib中已经做好了。不过如果子控件是比较复杂的控件,这样的方法还是会有一些缺陷。所以最好还是用无窗模式的子控件,或者在一些比较复杂的场景里别使用半透明异形功能。
===================
上面说的第一个方法,好像跟我上面方案二提出的方法比较像,只是我做的效果实在不行,子窗口晃的厉害,不知道有没有办法解决?

第二个方法,官方的代码是下面这样的:
if( m_bLayered ) {
for( int i = 0; i < m_aNativeWindow.GetSize(); ) {
HWND hChildWnd = static_cast<HWND>(m_aNativeWindow[i]);
if (!::IsWindow(hChildWnd)) {
m_aNativeWindow.Remove(i);
m_aNativeWindowControl.Remove(i);
continue;
}
++i;
if (!::IsWindowVisible(hChildWnd)) continue;
RECT rcChildWnd = GetNativeWindowRect(hChildWnd);
RECT rcTemp = { 0 };
if( !::IntersectRect(&rcTemp, &rcPaint, &rcChildWnd) ) continue;

COLORREF* pChildBitmapBits = NULL;
HDC hChildMemDC = ::CreateCompatibleDC(m_hDcOffscreen);
HBITMAP hChildBitmap = CRenderEngine::CreateARGB32Bitmap(hChildMemDC, rcChildWnd.right-rcChildWnd.left, rcChildWnd.bottom-rcChildWnd.top, &pChildBitmapBits);
::ZeroMemory(pChildBitmapBits, (rcChildWnd.right - rcChildWnd.left)*(rcChildWnd.bottom - rcChildWnd.top)*4);
HBITMAP hOldChildBitmap = (HBITMAP) ::SelectObject(hChildMemDC, hChildBitmap);
::SendMessage(hChildWnd, WM_PRINT, (WPARAM)hChildMemDC,(LPARAM)(PRF_CHECKVISIBLE|PRF_CHILDREN|PRF_CLIENT|PRF_OWNED));
COLORREF* pChildBitmapBit;
for( LONG y = 0; y < rcChildWnd.bottom-rcChildWnd.top; y++ ) {
for( LONG x = 0; x < rcChildWnd.right-rcChildWnd.left; x++ ) {
pChildBitmapBit = pChildBitmapBits+y*(rcChildWnd.right-rcChildWnd.left) + x;
if (*pChildBitmapBit != 0x00000000) *pChildBitmapBit |= 0xff000000;
}
}
::BitBlt(m_hDcOffscreen, rcChildWnd.left, rcChildWnd.top, rcChildWnd.right - rcChildWnd.left,
rcChildWnd.bottom - rcChildWnd.top, hChildMemDC, 0, 0, SRCCOPY);
::SelectObject(hChildMemDC, hOldChildBitmap);
::DeleteObject(hChildBitmap);
::DeleteDC(hChildMemDC);
}
}


不过我觉得对Web控件来说,这种方式应该也不太靠谱,暂时先到这吧,目前我搞不定,希望能抛砖引玉,看到有人能解决此问题。

如果解决了,一定要在评论里告诉我哦,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐