luowei010101

 

    新建一个MFC单文档应用程序,工程名为Graphic.

1.画点、直线、矩形、椭圆

在菜单上添加一个绘图弹出菜单,并添加点、直线、矩形、椭圆菜单项,ID分别为:IDM_POINTIDM_LINEIDM_RECTANGLEIDM_ELLIPS,并分别添加命令消息响应,

编辑:

void CGraphicView::OnPoint()  

    // TODO: Add your command handler code here 
    m_nDrawType=1; 

 void CGraphicView::OnLine()  

    // TODO: Add your command handler code here 
    m_nDrawType=2; 

 void CGraphicView::OnRectangle()  

    // TODO: Add your command handler code here 
    m_nDrawType=3; 

 void CGraphicView::OnEllpse()  

    // TODO: Add your command handler code here 
    m_nDrawType=4; 
}

 

CGraphicView类中添加私有的成员变量:

private
    CPoint m_ptOrigin; 
    UINT m_nDrawType;
 

 

并在构造函数中初始化:

CGraphicView::CGraphicView() 

    // TODO: add construction code here 
    m_nDrawType=0;//
初始化为
    m_ptOrigin=0;//
将原点设置成(00 
}

 

再在CGraphicView类上添加两个消息处理函数,WM_LBUTTONDOWN,WM_LBUTTONUP,编辑:

void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    m_ptOrigin=point;//
当鼠标左键按下时,将当前点保存到成员变量当中 
    CView::OnLButtonDown(nFlags, point); 

 
void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 

    CPen pen(PS_SOLID,1,RGB(255,0,0));//创建画笔

    dc.SelectObject(&pen);//将画笔选到设备描述表当中

    CBrush *pBrush=CBrush::FromHandle

         ((HBRUSH)GetStockObject(NULL_BRUSH));//创建透明的画刷

    dc.SelectObject(pBrush);//将画刷选到设备描环境当中
    switch(m_nDrawType) 
    { 
    case 1
        dc.SetPixel(point,RGB(255,0,0)); 
        break
    case 2
        dc.MoveTo(m_ptOrigin); 
        dc.LineTo(point); 
        break
    case 3
        dc.Rectangle(CRect(m_ptOrigin,point)); 
        break
    case 4
        dc.Ellipse(CRect(m_ptOrigin,point)); 
        break
    default
        break
    }
 
    CView::OnLButtonUp(nFlags, point); 
}

运行,OK !

 

2.给程序添加设置对话框

在对话框资源中新建一个对话框,ID: IDD_DIALOG_SETTING ,标题:Setting ,并添加一个静态文本控件(标题:线宽)和一个编辑框控件(ID: IDC_LINE_WIDTH),双击新建一对话框控件,给它新增一个类(类名:CSettingDlg),由于VC6.0本身的问题,这里要删除工程目录下的Graphic.clw文件,然后再打开class wizard…. 重新根据源文件建立一个类向导文件,取名仍就为Grahpic.clw。再给编辑框控件添加一个关联的UINT类型的成员变量m_nLineWidth.

再给CGraphicView类添加一个UINT类型的私有成员变量(取名也叫m_nLineWidth),并在其构造方法中初始化:m_nLineWidth=0;

然后在CGraphicView类当中对话框IDM_SETTING添加一个COMMAND消息响应函数, 编辑:

void CGraphicView::OnSettiing()

{

    // TODO: Add your command handler code here

    CSettingDlg dlg;//设置一个CSettingDlg对象

    dlg.m_nLineWidth=m_nLineWidth;

    //View类中先前保存的值传回到对话框变量

    if(IDOK==dlg.DoModal())//如果选择是的OK按钮

    {

        m_nLineWidth=dlg.m_nLineWidth;//将用户输入的线宽保存到m_nLineWidth

    }

 

}

并在CGraphicView::OnLButtonUp函数中把线宽改成m_nLineWidth替代:

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
    CPen pen(PS_SOLID,m_nLineWidth,RGB(255,0,0));//
创建画笔  
    ……………

    ………….

    ………….

OK ^_^ !!!

 

3.添加线型设置选项

在对话框中建一个组框(标题:线型),并在组框内加三个单选按钮,标题分别为:实线虚线点线。并选中实线单选按钮的属性,并给它添加一个int类型的成员变量m_nStyle

然后在CGraphicView::OnSettiing函数中编辑:

void CGraphicView::OnSettiing()  

    // TODO: Add your command handler code here 
    CSettingDlg dlg;//
设置一个CSettingDlg对象 
    dlg.m_nLineWidth=m_nLineWidth; 
    dlg.m_nLineStyle=m_nLineStyle; 
    //
View类中先前保存的值传回到对话框变量 
    if(IDOK==dlg.DoModal())//
如果选择是的OK按钮 
    { 
        m_nLineWidth=dlg.m_nLineWidth;//
将用户输入的线宽保存到m_nLineWidth 
        m_nLineStyle=dlg.m_nLineStyle; 
    } 
}

CGraphicView::OnLButtonU函数中修改:

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
    CPen pen(m_nLineStyle,m_nLineWidth,RGB(255,0,0));//
创建画笔  
    //
为组中的单选按实线,虚线,点线的值恰好是0,1,2,所以不需要作switch语句 

    .............. 
    .............. 
    .............. 
    CView::OnLButtonUp(nFlags, point); 
}

 

4.创建一个颜色对话框

    在资源的绘图菜单下,添加一个颜色菜单选项,并在CGrahpicView类中给它添加一个命令消息响应函数OnColor. 然后再在CGrahpicView类中添加一个COLORREF类型的私有的成员变量m_clr

并在构造函数中将其初始化:

m_clr=RGB(255,0,0);//将颜色初始化为红色

CGraphicView::OnColor函数中编辑:

void CGraphicView::OnColor()  

    // TODO: Add your command handler code here 
    CColorDialog Dlg;//
创建一个颜色对话框对象 
    Dlg.m_cc.Flags|=CC_RGBINIT|CC_FULLOPEN;//
设置Dlg的标记,与它先前的标记组合起来 
    //CC_FULLOPEN
是把颜色对话框完全展开 
    Dlg.m_cc.rgbResult=m_clr;//
View类的颜色值设置回颜色对话框去 

    if(IDOK==Dlg.DoModal()) 
    { 
        m_clr=Dlg.m_cc.rgbResult; 
    } 
    //DoModal:Call this function to display the Windows common color dialog box and allow the user to select a color.
 
}

CGraphicView::OnLButtonUp中修改:

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
    CPen pen(m_nLineStyle,m_nLineWidth,m_clr);//
创建画笔  
    //
因为组中的单选按实线,虚线,点线的值恰好是0,1,2,所以不需要作switch语句 
    dc.SelectObject(&pen);//
将画笔选到设备描述表当中 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//
创建透明的画刷 
    dc.SelectObject(pBrush);//
将画刷选到设备描环境当中 
    switch(m_nDrawType) 
    { 
    case 1
        dc.SetPixel(point,m_clr); 
        break
        .......... 
        .......... 
        .......... 
    } 
    CView::OnLButtonUp(nFlags, point); 
}

OK !! ^_^

 

5.创建字体对话框

在资源的绘图菜单下,添加一个字体菜单选项,并在CGrahpicView类中给它添加一个命令消息响应函数OnFont. 然后再在CGrahpicView类中添加一个CFont类型的私有的成员变量m_font,和一个CString类型的私有成员变量m_strFontName,并在构造函数中将其初始化:m_strFontName="";

CGraphicView::OnFont函数中编辑:

void CGraphicView::OnFont()  

    // TODO: Add your command handler code here 
    CFontDialog dlg; 
    if(IDOK==dlg.DoModal()) 
    { 
        if(m_font.m_hObject)//
如果字体资源对象已存在 
        { 
            m_font.DeleteObject();//
就释放这种字体资源对象 
        } 
        m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);//
再创建一种字体资源,并与之相关联 
        //CreateFontIndirect:This method initializes a CFont object with the characteristicsgiven in a LOGFONT structure pointed to by lpLogFont. 
        m_strFontName=dlg.m_cf.lpLogFont->lfFaceName;//
将字体的名字保存下来 
        Invalidate();//
使窗口无效,下次WM_PAINT消息发送时,窗口就进行重绘 

    }
 
}

将选择的字体的名字显示出来,在CGraphicView::OnDraw函数中编辑:

void CGraphicView::OnDraw(CDC* pDC) 

    CGraphicDoc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    // TODO: add draw code for native data here 
    CFont *pOldFont=pDC->SelectObject(&m_font);//
保存原来的字体 
    pDC->TextOut(0,0,m_strFontName);//
将选择的字体的名字输出 
    pDC->SelectObject(pOldFont);//
将原来的字体选择回去 

运行, OK !!

 

6.在设置对话框中做示例

    IDD_DIALOG_SETTING对话框中,拖入一个组框(ID: IDC_SAMPLE,标题:示例),然后再给IDC_LINE_WIDTH(编辑框)IDC_RADIO1(实线单选按钮)IDC_RADIO2IDC_RADIO3分别添加EN_CHANGEBN_CLICKEDBN_CLICKEDBN_CLICKED消息响应函数,并在这四个消息响应函数中都添加一句:Invalidate();使窗口无效,这样下次发送WM_PAINT消息,窗口便会重绘。这样就只需要在OnPaint函数中编写一处代码就行了。

接着,在CSettingDlg类上添加一个成员变量:

public:

    COLORREF m_clr;//用来保存颜色值

并在构造函数中初始化:

m_clr=RGB(255,0,0);//初始化红色

同样,在CGraphicView::OnSettiing函数中也要修改:

void CGraphicView::OnSettiing()  

    // TODO: Add your command handler code here 
    CSettingDlg dlg;//
设置一个CSettingDlg对象 
    dlg.m_nLineWidth=m_nLineWidth; 
    dlg.m_nLineStyle=m_nLineStyle; 
    dlg.m_clr=m_clr; 
    //
View类中先前保存的值传回到对话框变量 
     
    if(IDOK==dlg.DoModal())//
如果选择是的OK按钮 
    { 
        m_nLineWidth=dlg.m_nLineWidth;//
将用户输入的线宽保存到m_nLineWidth 
        m_nLineStyle=dlg.m_nLineStyle; 
    } 
}

 

CSettingDlg类上添加一个WM_PAINT消息响应函数,编辑:

void CSettingDlg::OnPaint()  

    CPaintDC dc(this); // device context for painting 
     
    // TODO: Add your message handler code here 
    //
在这里完成示例线条的绘制 
    UpdateData();//
将控件上的值反应到成员变量当中 
    CPen pen(m_nLineStyle,m_nLineWidth,m_clr); 
    dc.SelectObject(&pen); 
 
    CRect rect; 
    GetDlgItem(IDC_SAMPLE)->GetWindowRect(&rect);//
得到静态文本控件矩形区域的大小 
    ScreenToClient(rect);//
将屏幕坐标转换成客户区坐标 
    dc.MoveTo(rect.left+12,rect.top+rect.Height()/2+3);//
示例线条初始位置的坐标 
    dc.LineTo(rect.right-12,rect.top+rect.Height()/2+3);//
示例线条末端坐标,加3是为了调整坐标 

    // Do not call CDialog::OnPaint() for painting messages 
}

 

7.改变对话框控件的背景色及文字颜色

修改整个对话框及其控件的背景色

设置对话框控件的背景色,在CSettingDlg类下添加一个WM_CTLCOLOR消息处理函数,并添加一个私有的成员变量:CBrush m_brush; 并在构造函数中初始化:

m_brush.CreateSolidBrush(RGB(0,0,255));//对画刷进行初始化,蓝色

然后在CSettingDlg::OnCtlColor函数中修改:

HBRUSH CSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)  

    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 
     // TODO: Change any attributes of the DC here 
     
     // TODO: Return a different brush if the default is not desired 
    //return hbr; 
    return m_brush; 

修改某一个控件的背景色

对线型组框修改,首先将线型组框的ID改为:IDC_LINE_STYLE,并在CSettingDlg::OnCtlColor中编辑:

HBRUSH CSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)  

    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 
     
    // TODO: Change any attributes of the DC here 
    if(pWnd->GetDlgCtrlID()==IDC_LINE_STYLE)//
匹配是否是线型组框 
    { 
        pDC->SetTextColor(RGB(255,0,0));//
设置组框文字颜色为红色  
        pDC->SetBkMode(TRANSPARENT);    //
设置文字的背景色为透明 
        return m_brush;                    //
设置相匹配的控件的背景色 
    } 
    if(pWnd->GetDlgCtrlID()==IDC_LINE_WIDTH)//
匹配编辑框 
    { 
        pDC->SetTextColor(RGB(255,0,0));//
设置编辑框文字颜色为红色  
        pDC->SetBkMode(TRANSPARENT);    //
设置文字的背景色为透明 
        //pDC->SetBkColor(RGB(255,0,0));//
设置文字背景色为蓝色 
        return m_brush; 
    }
 
    // TODO: Return a different brush if the default is not desired 
    return hbr; 
    //return m_brush; 
}

 

8.修改控件的字体

在对话框中插入一个静态文本控件(ID:IDC_TEXT,标题:程序员),再给CStringDlg类添加一个私有的成员变量m_font,并在构造函数中初始化:

m_font.CreatePointFont(200,"华文行楷");

CSettingDlg::OnCtlColor添加:

if(pWnd->GetDlgCtrlID()==IDC_TEXT)    //匹配程序员静态文本控件

    {

        pDC->SelectObject(&m_font);    //设置字体

    }

 

9.修改Button控件的背景色和文本颜色

修改OK按钮的文字颜色

先创建一个Button类,然后将CSetttingDlg这个对话框上的按钮控件与它关联。Insert -> new class -> (class type:MFC Class,name:CTestBtn,Base Class:CButton)如果这里出现问题了,可以重新建立那个Class wizard数据库文件。然后可以在CTestBtn上增加一个DrawItem虚函数,并添加以下代码:

void CTestBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  

    // TODO: Add your code to draw the specified item 
    UINT uStyle = DFCS_BUTTONPUSH; 
 
   // This code only works with buttons. 
   ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON); 
 
   // If drawing selected, add the pushed style to DrawFrameControl. 
   if (lpDrawItemStruct->itemState & ODS_SELECTED) 
      uStyle |= DFCS_PUSHED; 
 
   // Draw the button frame. 
   ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem,  
      DFC_BUTTON, uStyle); 
 
   // Get the button\'s text. 
   CString strText; 
   GetWindowText(strText); 
 
   // Draw the button text using the text color red. 
   COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255,0,0)); 
   ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),  
      &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 
   ::SetTextColor(lpDrawItemStruct->hDC, crOldColor);
     
}

接下来,给OK按钮关联一个成员变量(variable name:m_bntTesm,Category:Control,Variable type:CTestBtn),并在CSettingDlg.h头文件中包含:#include "TestBtn.h" 头文件。并将OK按钮的属性中的stylesown draw选项选中。运行,OK!

修改cancle按钮的背景色

创建一个基于CButton的类叫CSXBtn,并在这个类里插入一个DrawItem消息处理,编辑:

void CSXBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 

    UINT uStyle = BS_DEFPUSHBUTTON ;//DFCS_BUTTONPUSH; 
     
    // This code only works with buttons. 
    ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON); 
     
    // If drawing selected, add the pushed style to DrawFrameControl. 
    if (lpDrawItemStruct->itemState & ODS_SELECTED) 
        uStyle |= DFCS_PUSHED; 
     
    // Draw the button frame. 
    ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem ,DFC_BUTTON, uStyle); 
     
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
     
    // Get the button\'s text. 
    CString strText; 
    GetWindowText(strText); 
     
    // Draw the button text using the text color red. 
    CBrush B; 
    CRect rect; 
    CRect focusRect; 
    focusRect.CopyRect(&lpDrawItemStruct->rcItem);  
    DrawFocusRect(lpDrawItemStruct->hDC, (LPRECT)&focusRect); 
    focusRect.left += 4
    focusRect.right -= 4
    focusRect.top += 4
    focusRect.bottom -= 4
     
    rect.CopyRect(&lpDrawItemStruct->rcItem);  
    pDC->Draw3dRect(rect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT)); 
    B.CreateSolidBrush(RGB(0,255,0)); 
    ::FillRect(lpDrawItemStruct->hDC,&rect, (HBRUSH)B.m_hObject); 
    ::SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT); 
    COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255,0,0)); 
    ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),  
        &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 
    ::SetTextColor(lpDrawItemStruct->hDC, crOldColor);
 

 

10.在窗口中贴图

    步骤:1.创建位图

            CBitmap bitmap;

            Bitmap.LoadBitmap(IDB_BITMAP);

         2.创建兼容DC

            CDC dcCompatible;

            dcCompatible.CreateCompatibleDC(pDC);

         3.将位图选到兼容DC

            dcCompatible.SelectObject(&bitmap);

         4.将兼容DC中的位图贴到当前DC

            pDC->BitBlt(rect.left,rect.top,rect.Weight(),

rect.Height(),&dcCompatible,0,0,SRCCOPY);

BitBllt: Copies a bitmap from the source device context to this current device context.

Insert -> 资源 -> Bitmap -> 引入一张位图,然后在CGraphicView类上添加一个WM_ERASEBKGND消息处理,

编辑:

BOOL CGraphicView::OnEraseBkgnd(CDC* pDC) //探除窗口 

    // TODO: Add your message handler code here and/or call default 
    CBitmap bitmap; 
    bitmap.LoadBitmap(IDB_BITMAP1);//
加载位图 
 
    BITMAP bmp;//
定义一个BITMAP结构体变量 
    bitmap.GetBitmap(&bmp); 
    //GetBitmap:to retrieve information about a CBitmap object.  
    //This information is returned in the BITMAP structure referred to by pBitmap.  
 
    CDC dcCompatible; 
    dcCompatible.CreateCompatibleDC(pDC);//
创建兼容DC 
 
    dcCompatible.SelectObject(&bitmap);//
将位图选到兼容DC 
 
    CRect rect; 
    GetClientRect(&rect); 
    //pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY); 
    //
将兼容DC中的位图贴到当前DC 
     
    pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcCompatible, 
        0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);     
 
//
以上的代码也可以移到OnDraw函数当中,也可以实现这个功能 
//OnEraseBkgnd
函数:
Nonzero if it erases the background; otherwise, it is zero. 
//return CView::OnEraseBkgnd(pDC);//
不能再调用基类的擦除背景函数 
      return TRUE;
 
}

OK, ^_^ !

 

练习:

创建一个CDialogBar,然后在CDialogBar上排放一些控件,如放置一个编辑框和列表框,改变编辑框的背景颜色和文字的颜色以及DialogBar本身的背景色;另外要求在列表当中显示一张位图。

分类:

技术点:

相关文章: