rovershen 阅读(838) 评论(5)

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);
}
附图是例子:
 

评论列表
不明白
建议
不错不错,建议美化一下按钮,使用图形填充标题条,附上源码,然后推荐到vckbase的在线杂志,对初学者和懒得在界面上下功夫的朋友会非常有用!

我先期待一下~ :)
rovershen
re: 定制窗口外观的若干技巧
呵呵,我比较懒:)而且按钮有很多现成可以用
YOUYOU
re: 定制窗口外观的若干技巧
我想问一下,怎么改变光标,我一直没有弄好!
ljh
re: 定制窗口外观的若干技巧
能谈谈怎么计算标题行的宽,高,left,top,right bottom等,客户区与screen 之间的关系等
tang
re: 定制窗口外观的若干技巧
OnEraseBkgnd的消息怎么加的?

发表评论
切换编辑模式