1. 不规则窗口和背景。用SetWindowRgn将窗口变成任意形状。源码网上很多地方都有。这里就不列出了。最好是配合背景图像,例如,在OnEraseBkgnd中作如下处理:
CRect rt;
GetClientRect(&rt);
pDC->DrawState(rt.TopLeft(),rt.Size(),hBkImg,DST_BITMAP);//hBkImg是背景位图句柄
return TRUE;
这样位图就拉伸到窗口客户区大小。如果要平铺,可用其它函数。
2.自定义非客户区的大小。只要响应WM_NCCALCSIZE消息,给出大小即可,如
void CXXDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
lpncsp->rgrc[0].top+=16; // add title bar by 16 pixels
CDialog::OnNcCalcSize(bCalcValidRects, lpncsp);
}
本功能配合下面的自定义窗口框架功能效果更好。
3.自定义窗口框架。在窗口非客户区重画的时候,自己绘制。如在WindowProc里做如下处理
if(message==WM_CAPTURECHANGED||message==WM_NCACTIVATE||message==WM_NCPAINT||
message==WM_INITMENUPOPUP){
CDialog::WindowProc(message,wParam,lParam);
DrawFrame();//画框架
bPressed=FALSE;
return 0;
}
当然,还有其它处理,如系统菜单和按钮的事件处理,只需要响应对应消息即可。另外,在有些系统中,当刚开始用鼠标拖动标题栏的时候,系统会自己重新绘制标题栏,这样破坏了自己绘制的样子。这时候只要处理wParam为0xF012的WM_SYSCOMMAND的消息,重新绘制即可。
4.让控件不遮住主窗口的背景。响应WM_CTLCOLOR,设置背景透明即可
HBRUSH CXXWinDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return ( HBRUSH )::GetStockObject( NULL_BRUSH );
}
当然,部分控件的背景不能简单的这样处理,需要自定义控件,如ListBox。
5.自定义不同控件或区域上的光标形状。响应WM_SETCURSOR,判断控件id并设置光标,如
BOOL CXXWinDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(pWnd->GetDlgCtrlID()==IDC_SENT){
HCURSOR ret=::SetCursor(m_hCursor);//m_Cursor为自定义的光标
return TRUE;
}
else if(nHitTest==HTSYSMENU||nHitTest==HTCLOSE){
HCURSOR ret=::SetCursor(m_hCursor);
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
附图是例子: