在SOUI中非半透明窗口如何实现圆角窗口?

如果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就有圆角了。

 

posted @ 2015-12-30 11:12  启程软件  阅读(4342)  评论(0编辑  收藏  举报