我在寫一個控件,它的某些部分可能有透明或半透明。基本上這個控制顯示一個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. 半透明控件上的不透明控件
- 4. 使子控件比父控件更不透明
- 5. VSTO中的透明控件
- 6. ASP.net透明編輯控件
- 7. 透明或半透明面板控制
- 8. 透明父母的非透明子女
- 9. 透明度控制(在透明容器中的非透明控制)
- 10. wxWidgets具有不透明控件的透明框架
- 11. 使控件「透明」來點擊事件
- 12. 通過子控件更改意外不透明蒙版
- 13. 包含控件的不透明度
- 14. 如何使CStatic控件(MFC)透明?
- 15. Picturebox滑塊控件透明度
- 16. .NET Compact Framework透明用戶控件
- 17. 透明背景與多個控件
- 18. 如何創建透明ListView控件
- 19. 複合控件的透明度?
- 20. Flexgrid VB6中的透明標籤控件
- 21. 不重疊的透明控件
- 22. 透明NSWindow具有可見控件
- 23. 在VB6中使.NET控件透明
- 24. C#Panel.BackgroundImage +透明控件=閃爍?
- 25. 繪製表格上的透明控件
- 26. 透明控件放置一個PictureBox
- 27. 半透明的自定義控件
- 28. 創建自定義透明控件
- 29. .net中的透明用戶控件
- 30. WPF透明用戶控件背景