2013-04-30 105 views
1

我有一個模式較少的對話框,我已經使用SetWindowRgn()將形狀更改爲一個圓角。我想用FrameRgn在它周圍畫一個彩色邊框。下面是我使用如何在MFC的非矩形窗口中繪製邊框

BOOL CMyDlg::OnInitDialog() 
{ 
CDialog::OnInitDialog(); m_Brush.CreateSolidBrush(RGB(255,255,255)); 
CRect rcDialog; 
GetClientRect(rcDialog); 

// This Creates area assigned to Dialog: This goes directly below the above in OnInitDialog 
m_rgnShape.CreateRoundRectRgn(rcDialog.TopLeft().x, rcDialog.TopLeft().y,rcDialog.BottomRight().x,rcDialog.BottomRight().y, rcDialog.Width()/8, rcDialog.Height()/8); 
::SetWindowRgn(GetSafeHwnd(), (HRGN)m_rgnShape, TRUE); 

return TRUE; // return TRUE unless you set the focus to a control 
    // EXCEPTION: OCX Property Pages should return FALSE 

}

void CMyDlg::OnPaint() 
{ 
CPaintDC dc(this); // device context for painting 

CBrush brush; 
brush.CreateSolidBrush(RGB(255,0,0)); 

    dc.FrameRgn(&m_rgnShape, &brush, 2, 2); 
} 

任何人都可以解釋爲什麼FrameRgn不工作,也許在這裏提供一些示例代碼 ,這將使它的工作代碼。

回答

1

作爲CWnd::SetWindowRgn文檔中所示:

成功調用後的SetWindowRgn,操作系統擁有所述區域手柄HRGN指定的 區域。操作系統做的是 不能複製該區域,所以不要使用該區域句柄調用任何其他功能 ,並且不要關閉此區域句柄。

這基本上意味着你不能去使用該地區作其他用途,而且你也不能「失去」該地區。因爲它是一個成員變量,所以最後一個問題不是您需要擔心的問題。但關於「不使用它」部分,您會注意到FrameRgn(...)調用很可能返回零,表明嘗試繪製時失敗。

你可以做的是從CRgn對象分離的區域句柄,並用它來設置的窗口區域,那麼你可以重新創建一個新的像以前一樣:

m_rgnShape.CreateRoundRectRgn(...); 
HGDIOBJ hRgn = m_rgnShape.Detach(); 
::SetWindowRgn(GetSafeHwnd(), (HRGN)hRgn, TRUE); 
m_rgnShape.CreateRoundRectRgn(...); 

爲了更好地說明,有看看這篇文章,其中涵蓋Setting a Window Region,使它看起來像一隻貓。


編輯:您的評論中提到,目前,框區域被有效地偏移。金額可能是您的窗口邊框的大小。

當你調用GetClientRect,它返回窗口的客戶區的大小 - 你可以輕而易舉地吸引了一部分,那就是當你在OnPaint()方法做「描述」的設備上下文的一部分。

偏移量的原因是你的窗口有一個邊界,你通常不會繪製(有方法,但我們現在將忽略這些邊界)。所以設備上下文描述了一個偏離窗口的區域。

你的情況最簡單的解決方案可能是修改對話框模板以指定無邊框。這當然會限制調整窗口的大小,但是因爲您已經設置了一個區域,所以我認爲調整大小也不是一個選項。

+0

嗨,我改變了代碼,當我繪製一個多邊形shaped.Now邊界顯示,但只爲多邊形的兩側。你可以告訴我如何控制它。現在,邊界不是來多邊形的所有邊。 – user2336139 2013-05-01 06:21:08

+0

這可能是由於你在對話框上有一個邊框 - 我會在我的答案中添加一些內容來解釋。 – icabod 2013-05-01 15:58:24