我在写一个控件,它的某些部分可能有透明或半透明。基本上这个控制显示一个PNG图像(与alpha通道)。控件的父窗口上有一些图形。因此,要使png控件正确呈现,需要获取父窗口在其下面绘制的图像。父对话框可能会设置WS_CLIPCHILDREN标志,这意味着父窗口不会在png控件下绘制任何东西,在这种情况下,png控件将无法正常工作。 此控件也必须在Windows Mobile上工作,所以它不能有WS_EX_TRANSPARENT透明子控件
透明子控件
回答
有趣的你应该问。我昨天写了代码来做这件事。它位于Project Resistance的代码库中。看看ResistorView(具有透明度的PNG)如何与MainForm(具有背景图像)进行交互。
我没有在做C#,所以我不认为这可能会有所帮助。我试图查看你的代码,即使你完成了和我一样的任务,我也没有看到任何可以解决我的问题的东西。 为了给出更多细节,我的控件还支持gif动画,并且我也使用了与您的项目中相同的来自流的IImage加载。根据我的经验,来自流的IImage加载是令人难以置信的垃圾代码,速度非常慢。我不知道这可能会如此缓慢。加载32x32 gif与31帧需要1.5secods使用垃圾IImage的东西。我写了自己的加载器(使用一些开源的gif库),没有任何优化,整个gif帧的解码/加载需要不到100ms。我正在使用TouchPro2 ......我无法想象这种代码在低端设备上的表现有多糟糕。
作为一个快速替代这里有一个可能的解决我的问题:
在绘制图像(GIF或PNG)的子控件的WM_PAINT处理我做到以下几点:
第一,我称之为SetRedraw (假)在自己和父窗口。 然后我隐藏子控件,并发送WM_PAINT父窗口与可选的HDC(作为wParam)。父窗口将所有内容渲染到离屏位图(通过hdc传递给WM_PAINT),并且在WM_PAINT成功返回后,我获取离屏位图的相关部分。 然后,我启用显示子窗口并在子窗口和父窗口上调用SetRedraw(true)。这个技巧很有效,但有一些明显的缺点(我需要创建一个巨大的离屏位图来捕捉整个屏幕区域,即使我需要父窗口中间的32x32像素)。
的代码如下:
bool pic_control::get_parent_bg(MyBitmap & bg)
{
CWindow parent = GetParent();
CClientDC dc(parent);
bool is_visible = IsWindowVisible() && parent.IsWindowVisible();
if(!is_visible){
return false;
}
parent.SetRedraw(false);
SetRedraw(false);
CRect rect;
parent.GetClientRect(rect);
MyBitmap bmp;
bmp.create(rect.Width(), rect.Height());
ShowWindow(SW_HIDE);
parent.SendMessage(WM_PAINT, (WPARAM)(HDC)bmp.dc());
ShowWindow(SW_SHOW);
GetWindowRect(rect);
parent.ScreenToClient(rect);
bg.create(rect.Width(), rect.Height());
bg.dc().BitBlt(0, 0, rect.Width(), rect.Height(), bmp.dc(), rect.left, rect.top, SRCCOPY);
IF_DEBUG SAL::saveHBITMAPToJpeg(bg.GetBitmap(), "frames/BG.jpg", 100);
SetRedraw(true);
parent.SetRedraw(true);
return true;
}
WS_CLIPCHILDREN被迫在WINCE,你不能切换它。我不知道为什么,也许这是出于性能原因。 从我的经验,我在这种情况下做了什么。 1)如果父窗口bacgkround是动态的(例如包含地图的窗口,它可以被移动),那么它首先被绘制到内存画布上,然后被绘制到屏幕上,内存画布被保存并用于绘制透明的孩子。内存画布不会包含空洞来代替子窗口,所以它可以用于进一步的像素合并。这里的缺点是在内存中保存画布的内存消耗。 2)如果父窗口背景是静态的(对话框,菜单等),那么你可以制作非窗口孩子。
class CImageButton
{
public:
bool IsPointInside(POINT pt);
void OnPaint(HDC canvas);
void OnClick();
void SetRect(RECT& rc);
private:
RECT m_rc;
};
你的父窗口将包含这样的对象的阵列和重定向WM_PAINT和 鼠标点击他们。
该缺点是需要添加到父窗口的附加代码,但是您可以为所有父窗口创建一个基类,这将处理非窗口控件的问题。
- 1. 使控件透明
- 2. 使控件透明
- 3. ASP.net透明编辑控件
- 4. VSTO中的透明控件
- 5. 透明或半透明面板控制
- 6. 透明父母的非透明子女
- 7. wxWidgets具有不透明控件的透明框架
- 8. 使控件“透明”来点击事件
- 9. 通过子控件更改意外不透明蒙版
- 10. 包含控件的不透明度
- 11. 如何创建透明ListView控件
- 12. .NET Compact Framework透明用户控件
- 13. 不重叠的透明控件
- 14. 如何使CStatic控件(MFC)透明?
- 15. .net中的透明用户控件
- 16. 复合控件的透明度?
- 17. C#Panel.BackgroundImage +透明控件=闪烁?
- 18. 在VB6中使.NET控件透明
- 19. Flexgrid VB6中的透明标签控件
- 20. 透明控件放置一个PictureBox
- 21. 绘制表格上的透明控件
- 22. 创建自定义透明控件
- 23. WPF透明用户控件背景
- 24. Winforms:如何在透明表单上获取透明控件的鼠标事件
- 25. ASP.NET图表控制透明
- 26. VB6控件在用户控件框架上显示为透明
- 27. CSS - 摆脱透明盒子
- 28. iPhone子视图透明
- 29. 德尔福:透明控件在上网本上变得不透明
- 30. 形式:透明,窗体上控制:非透明?