绘图-图像绘制相关

来源:互联网 发布:raphael min.js 编辑:程序博客网 时间:2024/05/17 06:09

OnCtlColor

每个控件在绘制时,都会向父窗口(通常都是dialog)发送一个WM_CTLCOLOR消息,用来返回一个Cbrush
句柄,用来绘制自己.
HBRUSH CDlgDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
 if (nCtlColor == CTLCOLOR_DLG)
 {
  return m_brush;
 }
 return hbr;
}

pDC是为绘制自己而准备的,pWnd是发送消息的控件窗体的对象指针,nCtlColor代表发送消息的控件的类型,如:
CTLCOLOR_BTN   Button control
CTLCOLOR_DLG   Dialog box
CTLCOLOR_EDIT   Edit control
CTLCOLOR_LISTBOX   List-box control
CTLCOLOR_MSGBOX   Message box
CTLCOLOR_SCROLLBAR   Scroll-bar control
CTLCOLOR_STATIC   Static control
如果用来判断是哪一类控件可以用这个值,如何用来精确控件哪一个控件,可以用
pWnd->GetDlgCtrlID() 返回控件的ID

 if (nCtlColor == CTLCOLOR_DLG)
 {
  return m_brush;
 }

 if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
 {
  m_brush.DeleteObject();
  CBitmap bmp;
  bmp.LoadBitmap(IDB_BITMAP1);
  m_brush.CreatePatternBrush(&bmp);
  return m_brush;
 }

如果改变字体的颜色可以为pDC选择相应的设备对象

DrawItem

在OnCtlColor, CButton是不被控件的。要改变CButton的绘制,要重载CButton类的DrawItem方法,具体可以查看MSDN

OnEraseBkgnd

以上对bitmap的操作,都是作为brush进行刷背景,现在介绍一下如何显示出一副位图
OnEraseBkgnd对应的事件发生在背景重绘时,这是从CWnd继承下来的一个方法。可以在这个事件中将
一幅图显示在CView, CDialog等类的背景上。

OnEraseBkgnd事件可以在Cview的子类上用类向导添加,但vc6中,CDialog中是不能用类向导添加的。可以直接手工添加消息响应函数

BOOL CDlg_DCTest1::OnEraseBkgnd(CDC* pDC)
{
 CDC dc;
 dc.CreateCompatibleDC(pDC);
 CBitmap bmp;
 bmp.LoadBitmap(IDB_BITMAP1);

 dc.SelectObject(&bmp);

 CRect rect;
 GetClientRect(&rect);
 //显示全图
 pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);

 BITMAP bitmap;
 bmp.GetBitmap(&bitmap);
 return true;
}

BitBlt函数说明:参数1,2是目的DC开始粘贴的起始点, 参数6,7是源DC开始拷贝的起始点。参数3,4是拷贝和粘贴的大小

icon绘制

 CClientDC dc(this);
 HICON hIcon = ::LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1));
 //HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
 dc.DrawIcon(8, 8, hIcon);

icon可以通过两种方式加载,然后用dc进行绘制.

sdk中的loadicon第一个参数是指icon所在程序的应用程序实例句柄

绘制不规则窗体

OnInitDialog中实现即可

 //改变窗体形状
 CRect rect;
 GetClientRect(&rect);
 m_rgn.CreateEllipticRgn(0, 0, rect.Width(), rect.Height());
 SetWindowRgn(m_rgn, true);

SetWindowRgn会将CRgn m_rgn;描述的形状显示成窗体形状

绘制随意形状的窗体

下面是一个按钮事件中的方法

 CClientDC dc(this);
 //创建字体
 CFont mFont;
 VERIFY(mFont.CreateFont(
  200, 50, 0, 0, FW_HEAVY, TRUE, FALSE,
  0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,       
  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,            
  DEFAULT_PITCH | FF_SWISS, "宋体"));
 
 dc.BeginPath(); 
  //必须
 dc.SetBkMode(TRANSPARENT);
 CFont *pOldFont = (CFont *)dc.SelectObject(&mFont);
 dc.SelectObject(&mFont); 
 dc.TextOut(0, 0, "中华民族");
 mFont.DeleteObject();
 dc.SelectObject(pOldFont);
 dc.EndPath();
 HRGN  hrgn;
 hrgn=PathToRegion(dc);
 SetWindowRgn(hrgn, true);

根据dc的beginpath  endpath之前,dc画出的路径,可以转化为hrgn,然后设置窗体。

移动没有title bar的窗体(CDialog窗体)

通过响应WM_NCHITTEST来实现
头文件中对消息的声明:

afx_msg UINT OnNcHitTest(CPoint point);

源文件中的定义:

ON_WM_NCHITTEST()

UINT CDlgDlg::OnNcHitTest(CPoint point)
{
 //Let user move window by clickign anywhere on the window .
 UINT nHitTest = CDialog :: OnNcHitTest (point) ;
 return (nHitTest == HTCLIENT)? HTCAPTION: nHitTest ;
}

响应函数是指当鼠标落在窗体上时,变为拖拽模式模式。

对CView这种有控件覆盖在主窗体上的程序,可以在网上查一下具体做法:
http://www.vckbase.com/document/viewdoc/?id=464

设置没有title bar 窗体在状态栏上的文字

OnInitDialog中实现就可以

//此处可以设置没有title bar的窗体在任务栏上的显示标题
 char *str = "abc";
 SendMessage(WM_SETTEXT, 0, (LPARAM)str);

 
原创粉丝点击