10.3颜色对话框

MFC为我们提供了一个类:CColorDialog类,可以很方便创建一个颜色对话框。
CColorDialog类构造函数:

CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );

第一个参数指定默认颜色选择,默认是黑色。
第二个参数来设置对话框的功能和它的外观。
第三个参数指向父窗口或者拥有者窗口指针。

在绘图子菜单下添加颜色菜单项,ID设置为IDM_COLOR,在视类中为该菜单项添加命令消息响应函数。

void CGraphicView::OnColor() 
{
 // TODO: Add your command handler code here
 CColorDialog dlg;
 dlg.DoModal();
}

运行如图。默认选中颜色为黑色。
在这里插入图片描述
下一步要做的就是将用户选择的颜色保存下来。CColorDialog类有一个CHOOSECOLOR结构体类型的成员变量:m_cc。

typedef struct {   // cc 
    DWORD        lStructSize; 
    HWND         hwndOwner; 
    HWND         hInstance; 
    COLORREF     rgbResult; 
    COLORREF*    lpCustColors; 
    DWORD        Flags; 
    LPARAM       lCustData; 
    LPCCHOOKPROC lpfnHook; 
    LPCTSTR      lpTemplateName; 
} CHOOSECOLOR; 

当用户单击颜色对话框上面的OK之后,颜色就保存到rgbResult变量中了。

接下来为视类添加一个COLORREF类型的私有成员变量:m_clr,,并在视类的构造函数中初始化为红色。

void CGraphicView::OnColor() 
{
 // TODO: Add your command handler code here
 CColorDialog dlg;
 if(IDOK==dlg.DoModal())
 {
  m_clr=dlg.m_cc.rgbResult;
 }
}

在之前创建画笔以及画点中,将代码修改为:

CPen pen(m_nLineStyle,m_nLineWidth,m_clr);
dc.SetPixel(point,m_clr);

运行,但是再次打开颜色对话框时,默认的选择仍然还是黑色。

因此利用之前的方法进行修改:

void CGraphicView::OnColor() 
{
 // TODO: Add your command handler code here
 CColorDialog dlg;
 dlg.m_cc.rgbResult=m_clr;
 if(IDOK==dlg.DoModal())
 {
  m_clr=dlg.m_cc.rgbResult;
 }
}

但是运行,发现问题并没有解决,实际上要想设置颜色对话框初始选择的颜色,需要设计对话框的CC_RGBINIT标记。
dlg.m_cc.rgbResult=m_clr;后面加:

dlg.m_cc.Flags|=CC_RGBINIT;

将CC_RGBINIT与Flags先前的标记组合起来。

dlg.m_cc.Flags|=CC_RGBINIT|CC_FULLOPEN;
运行程序,就会发现颜色对话框处于选中颜色的阶段并且完全展开。如图。
在这里插入图片描述

10.4字体对话框

与颜色对话框一样,字体对话框创建也很简单。MFC提供了一个相应的类:CFontDialog。
CFontDialog类的构造函数:

CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );

第一个参数允许用户设置一些字体的特征;第二个参数设置与字体相关的标记;第三个参数是打印上下文的指针;第四个参数是字体对话框父窗口的指针。

在绘图子菜单中添加一个字体的菜单项,ID为IDM_FONT,接着在视类中为该菜单项添加命令消息响应函数。

void CGraphicView::OnFont() 
{
 // TODO: Add your command handler code here
 CFontDialog dlg;
 dlg.DoModal();
}

当用户通过字体对话框选择某种字体后,应该将其保存起来。CFontDialog类有一个CHOOSEFONT结构体的数据成员:m_cf。

typedef struct {    // cf 
    DWORD        lStructSize; 
    HWND         hwndOwner; 
    HDC          hDC; 
    LPLOGFONT    lpLogFont; 
    INT          iPointSize; 
    DWORD        Flags; 
    DWORD        rgbColors; 
    LPARAM       lCustData; 
    LPCFHOOKPROC lpfnHook; 
    LPCTSTR      lpTemplateName; 
    HINSTANCE    hInstance; 
    LPTSTR       lpszStyle; 
    WORD         nFontType; 
    WORD         ___MISSING_ALIGNMENT__; 
    INT          nSizeMin; 
    INT          nSizeMax; 
} CHOOSEFONT; 

lpLogFont指向逻辑字体(LOGFONT)的指针。

typedef struct tagLOGFONT { // lf 
   LONG lfHeight; 
   LONG lfWidth; 
   LONG lfEscapement; 
   LONG lfOrientation; 
   LONG lfWeight; 
   BYTE lfItalic; 
   BYTE lfUnderline; 
   BYTE lfStrikeOut; 
   BYTE lfCharSet; 
   BYTE lfOutPrecision; 
   BYTE lfClipPrecision; 
   BYTE lfQuality; 
   BYTE lfPitchAndFamily; 
   TCHAR lfFaceName[LF_FACESIZE]; 
} LOGFONT; 

lfFaceName存放的是字体名称。

首先用CFont类构造一个字体对象,然后利用CFont类的CreateFontIndirect成员函数根据指定特征的逻辑字体(LOGFONT)来初始化这个字体对象。
为了保存用户选择的字体,为视类增加一个CFont成员变量:m_font,再增加一个CString类型的成员变量:m_strFontName,用来保存所选字体的名称,并在视类构造函数中初始化为空。

void CGraphicView::OnFont() 
{
 // TODO: Add your command handler code here
 CFontDialog dlg;
 if(IDOK==dlg.DoModal())
 {
  m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);
  m_strFontName=dlg.m_cf.lpLogFont->lfFaceName;
 }
 Invalidate();
}

接下来将用户选择的字体显示出来,可以在视类OnDraw函数中实现。在OnFont函数最后调用Invalidate函数让窗口无效,当下一次发生WM_PAINT消息时,窗口就可以重绘。

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);
}

但是再次选择绘图字体菜单项时,程序就会出现非法操作。原因就是如果一个对象已经和一个字体资源相关联了,首先得切断这种关联,释放该字体资源,才能与新资源相关联。
要释放先前的资源,可以利用CGdiObject类(CPen类,CFon类,CBitmap类,CBrush类都派生于该类)的DeleteObject成员函数来实现。
如果想判断m_font对象是否与某个字体资源相关联,可以利用CGdiObject类对象的数据成员m_hObject来判断,该变量保存了与CGdiObject对象相关联的Windows GDI资源的句柄。

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);
  m_strFontName=dlg.m_cf.lpLogFont->lfFaceName;
 }
 Invalidate();
}

运行如图,一切正常。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值