如果SOUI的宿主窗口沒有包含子窗口,直接使用窗口的半透明屬性:translucent=1就可以解決了,整個窗口形狀完全由背景圖決定,可以實現完美的圓角。
然后窗口半透明時,窗口中的子窗口(非SWindow)就不能正常顯示,所以有時候不得不使用translucent=0,這時窗口就成了方形。
實際上這個問題已經和SOUI沒有什么關系了,你的問題變成了窗口如何做圓角,還不是在SOUI中窗口如何做圓角。
網上一搜索一大堆,可惜經常有人要問。
給窗口做圓角或者異形好像只有一個辦法:SetWindowRgn,自己創建一個HRGN,再調用這個API就可以了,關鍵問題是在窗口大小變化時注意重新設置。
好人做到底,這里帖一份專業做圓角的代碼:
1 template <class T> 2 class CWHRoundRectFrameHelper 3 { 4 protected: 5 6 SIZE m_sizeWnd; 7 8 void OnSize(UINT nType, CSize size) 9 { 10 T *pT = static_cast<T*>(this); 11 12 if (nType == SIZE_MINIMIZED) 13 return; 14 15 if (size == m_sizeWnd) 16 return; 17 18 CRect rcWindow, rcClient; 19 CRgn rgnWindow, rgnMinus, rgnAdd; 20 21 pT->CSimpleWnd::GetWindowRect(rcWindow); 22 pT->CSimpleWnd::GetClientRect(rcClient); 23 pT->CSimpleWnd::ClientToScreen(rcClient); 24 25 rcClient.OffsetRect(- rcWindow.TopLeft()); 26 27 rgnWindow.CreateRectRgn(rcClient.left, rcClient.top + 2, rcClient.right, rcClient.bottom - 2); 28 rgnAdd.CreateRectRgn(rcClient.left + 2, rcClient.top, rcClient.right - 2, rcClient.top + 1); 29 rgnWindow.CombineRgn(rgnAdd, RGN_OR); 30 rgnAdd.OffsetRgn(0, rcClient.Height() - 1); 31 rgnWindow.CombineRgn(rgnAdd, RGN_OR); 32 rgnAdd.SetRectRgn(rcClient.left + 1, rcClient.top + 1, rcClient.right - 1, rcClient.top + 2); 33 rgnWindow.CombineRgn(rgnAdd, RGN_OR); 34 rgnAdd.OffsetRgn(0, rcClient.Height() - 3); 35 rgnWindow.CombineRgn(rgnAdd, RGN_OR); 36 pT->CSimpleWnd::SetWindowRgn(rgnWindow); 37 pT->SetMsgHandled(FALSE); 38 m_sizeWnd = size; 39 } 40 41 public: 42 43 BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) 44 { 45 BOOL bHandled = TRUE; 46 47 switch(dwMsgMapID) 48 { 49 case 0: 50 if (uMsg == WM_SIZE) 51 { 52 OnSize((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); 53 lResult = 0; 54 } 55 break; 56 } 57 return FALSE; 58 } 59 };
這是一個模板類,下面給一個SOUI中使用的示例代碼:
class CFuckDialog : public SHostDialog , public CWHRoundRectFrameHelper<CFuckDialog> { //xxxxx //HOST消息及響應函數映射表 BEGIN_MSG_MAP_EX(CMainDlg) CHAIN_MSG_MAP(CWHRoundRectFrameHelper<CFuckDialog >)//重要 CHAIN_MSG_MAP(SHostDialog) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP() //xxxx };
這樣你的Dialog就有圓角了。