flash显示方式:网上抄了一个OleContainer模板,
template <class TObject>
class COleContainer :
public IOleClientSite,
public IOleInPlaceSiteWindowless,
public IOleInPlaceFrame,
public IStorage,
public IDispatch
调用IOleObject::DoVerb(OLEIVERB_SHOW...)函数,会触发调用IOleInPlaceSiteWindowless::InvalidateRect,该函数实现如下:
template <class TObject>
HRESULT STDMETHODCALLTYPE COleContainer<TObject>::InvalidateRect(
/* [in] */ LPCRECT pRect,
/* [in] */ BOOL fErase)
{
Draw(pRect, fErase);
return S_OK;
}
其中,Draw函数中用OleDraw函数将flash画到memeory DC上,再调用UpdateLayeredWindow就可以半透明显示在layered window上。但是,WebBrowser控件时调用DoVerb也成功返回S_OK,却不会触发InvalidateRect调用,所以画不出来。
做不出来,估计要被炒鱿鱼,才毕业半年呀,求高手指导,
16 个解决方案
#1
据我目前所知道的,flash是支持 Windowless 的,而 WebBrowser 还没见有人用Windowless实现了,都是将WebBrowser放在另一个Popup Window中,然后与主窗口一起移动。
你可以将这个Popup Window设置为WS_EX_LAYERED,然后调用SetLayeredWindowAttributes设置一下透明度,应该也能达到你的目的。
你可以将这个Popup Window设置为WS_EX_LAYERED,然后调用SetLayeredWindowAttributes设置一下透明度,应该也能达到你的目的。
#2
谢谢。
但是,如果创建个layered window,那它将不能是子窗口,不是子窗口就有跟随问题,好麻烦呀。。。
#3
难道就不能像flash一样将WebBrowser画到memory DC上么?
#4
将WebBrowser画到memory DC上
就会出现如何与上层窗口进行混合问题!
就会出现如何与上层窗口进行混合问题!
#5
类似下面这种效果吗?
这种效果还是可行的,2011年已经实现了,但是实现原理很特别,而且不同IE的版本处理方式也不同,REDUI源码里有实现(很多人有源码,但恐怕愿意看的人没几个),不过暂时只针对IE9,其它版本IE会崩溃,知道原因,懒得改。
以前写的帖子在这里: 带浏览器控件的透明窗口演示
这种效果还是可行的,2011年已经实现了,但是实现原理很特别,而且不同IE的版本处理方式也不同,REDUI源码里有实现(很多人有源码,但恐怕愿意看的人没几个),不过暂时只针对IE9,其它版本IE会崩溃,知道原因,懒得改。
以前写的帖子在这里: 带浏览器控件的透明窗口演示
#6
赞一个~
#7
对内存块进行操作,然后调用UpdateLayeredWindow就可以混合了,
flash画到memory DC上后,也是这样跟上层窗口混合的,OK的,
关键是不知道怎么将WebBrowser画到memory DC上。
#8
同求!
#9
之前看到过这个例子,它的浏览器控件是子窗口,不能半透明,只能显示或者隐藏。
我现在想要的效果是,上层layered窗口全透明,WebBrowser可半透明显示。
依然谢谢。
#10
真是长见识了,居然能想到这样的解决方案
粗略的看了下你的源代码,不知道我说的对不对:
BOOL iGdiTexture::__IsPaintMsg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
{
if (!m_device->IsLayeredWindow() || !m_msgHooks.HasMessage(uMsg))
return FALSE;
HDC hdc = m_alpha ? getDC() : getTexDC();
lResult = ::CallWindowProcW(m_oldProc, hWnd, uMsg, wParam, lParam);
if (m_renderType==5 && m_oleObject) // Ole
{
// 浏览器控件的典型样式:
// <object progid="Shell.Explorer" 浏览器控件的PROGID
// bind-class="Internet Explorer_Server" 改变到HOOK这个类名的窗口
// bind-type="5" 绑定方式
// bind-messages="0x0118 timer" HOOK这些消息
// style="width:100%;height:180;"
// location="www.baidu.com" 初始化打开的网址
// title="WebBrowser">haha</object>
CComQIPtr<IViewObject> vo = m_oleObject;
if (vo.p)
{
RECTL rc = {0,0,(LONG)m_width,(LONG)m_height};
HRESULT hr = vo.p->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, (RECTL*) &rc, NULL, NULL, NULL);
}
}
else
{
switch (m_renderType)
{
case 0: // WM_PAINT
::CallWindowProcW(m_oldProc, hWnd, WM_PAINT, (WPARAM)hdc, lParam);
break;
case 1: // WM_PRINT
::CallWindowProcW(m_oldProc, hWnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
break;
case 2: // WM_PRINTCLIENT
::CallWindowProcW(m_oldProc, hWnd, WM_PRINTCLIENT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
break;
default:
::CallWindowProcW(m_oldProc, hWnd, WM_PAINT, (WPARAM)hdc, lParam);
}
//::SendMessage(m_pWin->m_hWnd, WM_PAINT, (WPARAM)hdc, 0);
//::SendMessage(hWnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
//::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hdc, (LPARAM)(/*PRF_CHECKVISIBLE|*/PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
}
if (m_alpha)
releaseDC(hdc);
else
releaseTexDC(hdc);
m_dirty = FALSE;
m_device->render();
return TRUE;
}
通过拦截相就窗口的WM_PAINT消息,通过替换HDC,将窗口内容绘制在自己的DC上面。
不过这种方案也有很大的限制,就是不通过InvalidateRect进行刷新的控件就无法在分层窗口上面及时更新了,例如:
1. 光标。 它是直接画在窗口DC上的,同样,网页上面的光标也都无法刷新出来
2. EDIT。 将Demo中的class="button"换成edit,刷新不正常,从SPY上没有看到WM_PAINT消息,
3. SCROLLBAR。 它应该也是自己绘制而不通过WM_PAINT
(另外我测试我发现好像没有做裁剪,只在一个按钮上移动时,其它区域也会刷新 )
因此建议LZ还是先分成两个窗口实现,这样说不定能先完成任务,两个窗口的同步其实不难,拦截OnWindowPosChanging消息,再加上 BeginDefWindow...就能搞定
#11
楼上好样的,居然找到关键代码了。确实如楼上所说,这种方案有很多不足:
1、光标显示不出来。在分层窗口下,所有的光标都必须自己实现,但我没有为浏览器控件单独实现光标。
2、EDIT是早期方案,因为很难看,已经废弃不用,改成用Windowless RichEdit了,它的光标和滚动条都是自己实现的。
3、REDUI中的滚动条是用桌面主题自绘的,没有使用滚动条窗口;RICHEDIT中的滚动条也是自绘的;浏览器控件中的滚动条本身就是自绘的,没用窗口,所以都能正常显示。
关于没有做裁剪和刷新的问题,这是设计使然,用DX作为渲染工具时都是全局刷新重绘,不需要设置无效区域(设了也没用)。
到目前为止,最简洁、效果最好的方案还是双窗口解决方案,唯一的麻烦是消息处理得多一点。
1、光标显示不出来。在分层窗口下,所有的光标都必须自己实现,但我没有为浏览器控件单独实现光标。
2、EDIT是早期方案,因为很难看,已经废弃不用,改成用Windowless RichEdit了,它的光标和滚动条都是自己实现的。
3、REDUI中的滚动条是用桌面主题自绘的,没有使用滚动条窗口;RICHEDIT中的滚动条也是自绘的;浏览器控件中的滚动条本身就是自绘的,没用窗口,所以都能正常显示。
关于没有做裁剪和刷新的问题,这是设计使然,用DX作为渲染工具时都是全局刷新重绘,不需要设置无效区域(设了也没用)。
到目前为止,最简洁、效果最好的方案还是双窗口解决方案,唯一的麻烦是消息处理得多一点。
#12
只有先用两个窗口实现了。Thanks~
#13
代码在何里?
求!
求!
#14
给一份代码吧! 3q
#15
http://bbs.csdn.net/topics/380085573
#16
谢谢
#1
据我目前所知道的,flash是支持 Windowless 的,而 WebBrowser 还没见有人用Windowless实现了,都是将WebBrowser放在另一个Popup Window中,然后与主窗口一起移动。
你可以将这个Popup Window设置为WS_EX_LAYERED,然后调用SetLayeredWindowAttributes设置一下透明度,应该也能达到你的目的。
你可以将这个Popup Window设置为WS_EX_LAYERED,然后调用SetLayeredWindowAttributes设置一下透明度,应该也能达到你的目的。
#2
谢谢。
但是,如果创建个layered window,那它将不能是子窗口,不是子窗口就有跟随问题,好麻烦呀。。。
#3
难道就不能像flash一样将WebBrowser画到memory DC上么?
#4
将WebBrowser画到memory DC上
就会出现如何与上层窗口进行混合问题!
就会出现如何与上层窗口进行混合问题!
#5
类似下面这种效果吗?
这种效果还是可行的,2011年已经实现了,但是实现原理很特别,而且不同IE的版本处理方式也不同,REDUI源码里有实现(很多人有源码,但恐怕愿意看的人没几个),不过暂时只针对IE9,其它版本IE会崩溃,知道原因,懒得改。
以前写的帖子在这里: 带浏览器控件的透明窗口演示
这种效果还是可行的,2011年已经实现了,但是实现原理很特别,而且不同IE的版本处理方式也不同,REDUI源码里有实现(很多人有源码,但恐怕愿意看的人没几个),不过暂时只针对IE9,其它版本IE会崩溃,知道原因,懒得改。
以前写的帖子在这里: 带浏览器控件的透明窗口演示
#6
赞一个~
#7
对内存块进行操作,然后调用UpdateLayeredWindow就可以混合了,
flash画到memory DC上后,也是这样跟上层窗口混合的,OK的,
关键是不知道怎么将WebBrowser画到memory DC上。
#8
同求!
#9
之前看到过这个例子,它的浏览器控件是子窗口,不能半透明,只能显示或者隐藏。
我现在想要的效果是,上层layered窗口全透明,WebBrowser可半透明显示。
依然谢谢。
#10
真是长见识了,居然能想到这样的解决方案
粗略的看了下你的源代码,不知道我说的对不对:
BOOL iGdiTexture::__IsPaintMsg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
{
if (!m_device->IsLayeredWindow() || !m_msgHooks.HasMessage(uMsg))
return FALSE;
HDC hdc = m_alpha ? getDC() : getTexDC();
lResult = ::CallWindowProcW(m_oldProc, hWnd, uMsg, wParam, lParam);
if (m_renderType==5 && m_oleObject) // Ole
{
// 浏览器控件的典型样式:
// <object progid="Shell.Explorer" 浏览器控件的PROGID
// bind-class="Internet Explorer_Server" 改变到HOOK这个类名的窗口
// bind-type="5" 绑定方式
// bind-messages="0x0118 timer" HOOK这些消息
// style="width:100%;height:180;"
// location="www.baidu.com" 初始化打开的网址
// title="WebBrowser">haha</object>
CComQIPtr<IViewObject> vo = m_oleObject;
if (vo.p)
{
RECTL rc = {0,0,(LONG)m_width,(LONG)m_height};
HRESULT hr = vo.p->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, (RECTL*) &rc, NULL, NULL, NULL);
}
}
else
{
switch (m_renderType)
{
case 0: // WM_PAINT
::CallWindowProcW(m_oldProc, hWnd, WM_PAINT, (WPARAM)hdc, lParam);
break;
case 1: // WM_PRINT
::CallWindowProcW(m_oldProc, hWnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
break;
case 2: // WM_PRINTCLIENT
::CallWindowProcW(m_oldProc, hWnd, WM_PRINTCLIENT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
break;
default:
::CallWindowProcW(m_oldProc, hWnd, WM_PAINT, (WPARAM)hdc, lParam);
}
//::SendMessage(m_pWin->m_hWnd, WM_PAINT, (WPARAM)hdc, 0);
//::SendMessage(hWnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(PRF_CHECKVISIBLE|PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
//::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hdc, (LPARAM)(/*PRF_CHECKVISIBLE|*/PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN|PRF_OWNED));
}
if (m_alpha)
releaseDC(hdc);
else
releaseTexDC(hdc);
m_dirty = FALSE;
m_device->render();
return TRUE;
}
通过拦截相就窗口的WM_PAINT消息,通过替换HDC,将窗口内容绘制在自己的DC上面。
不过这种方案也有很大的限制,就是不通过InvalidateRect进行刷新的控件就无法在分层窗口上面及时更新了,例如:
1. 光标。 它是直接画在窗口DC上的,同样,网页上面的光标也都无法刷新出来
2. EDIT。 将Demo中的class="button"换成edit,刷新不正常,从SPY上没有看到WM_PAINT消息,
3. SCROLLBAR。 它应该也是自己绘制而不通过WM_PAINT
(另外我测试我发现好像没有做裁剪,只在一个按钮上移动时,其它区域也会刷新 )
因此建议LZ还是先分成两个窗口实现,这样说不定能先完成任务,两个窗口的同步其实不难,拦截OnWindowPosChanging消息,再加上 BeginDefWindow...就能搞定
#11
楼上好样的,居然找到关键代码了。确实如楼上所说,这种方案有很多不足:
1、光标显示不出来。在分层窗口下,所有的光标都必须自己实现,但我没有为浏览器控件单独实现光标。
2、EDIT是早期方案,因为很难看,已经废弃不用,改成用Windowless RichEdit了,它的光标和滚动条都是自己实现的。
3、REDUI中的滚动条是用桌面主题自绘的,没有使用滚动条窗口;RICHEDIT中的滚动条也是自绘的;浏览器控件中的滚动条本身就是自绘的,没用窗口,所以都能正常显示。
关于没有做裁剪和刷新的问题,这是设计使然,用DX作为渲染工具时都是全局刷新重绘,不需要设置无效区域(设了也没用)。
到目前为止,最简洁、效果最好的方案还是双窗口解决方案,唯一的麻烦是消息处理得多一点。
1、光标显示不出来。在分层窗口下,所有的光标都必须自己实现,但我没有为浏览器控件单独实现光标。
2、EDIT是早期方案,因为很难看,已经废弃不用,改成用Windowless RichEdit了,它的光标和滚动条都是自己实现的。
3、REDUI中的滚动条是用桌面主题自绘的,没有使用滚动条窗口;RICHEDIT中的滚动条也是自绘的;浏览器控件中的滚动条本身就是自绘的,没用窗口,所以都能正常显示。
关于没有做裁剪和刷新的问题,这是设计使然,用DX作为渲染工具时都是全局刷新重绘,不需要设置无效区域(设了也没用)。
到目前为止,最简洁、效果最好的方案还是双窗口解决方案,唯一的麻烦是消息处理得多一点。
#12
只有先用两个窗口实现了。Thanks~
#13
代码在何里?
求!
求!
#14
给一份代码吧! 3q
#15
http://bbs.csdn.net/topics/380085573
#16
谢谢