ME 6
#define PS_USERSTYLE 7
#define PS_ALTERNATE 8
#define PS_STYLE_MASK 0x0000000F
在这里我们看到,实线、虚线、点线的值和它们所对应的单选按钮的值是一样的,当然这里是故意这么排列的,实际编程中应该先判断值,然后再用相应的画笔样式去构造画笔。
下面要创建一个颜色对话框,样子就是我们在绘图中看到的那个,自己要写的话,很麻烦,MFC为我们提供了一个类:CColorDialog ,可以很方便地创建一个颜色对话框。
在菜单项中添加颜色选项,然后在VIEW类的响应函数中创建该对话框。下面我们要做的事就是保存用户选择的颜色。在CColorDialog类中有一个CHOOSECOLOR结构体类型的成员变量 m_cc
view plain
typedef struct tagCHOOSECOLOR {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
COLORREF *lpCustColors;
DWORD Flags;
LPARAM lCustData;
LPCCHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;
该结构体中COLORREF rgbResult 保存了用户选择的颜色。在VIEW类增加一个COLORREF 变量 m_clr(初始化为红色) 用来保存用户的选择。
就算我们选择了其他颜色进行绘画,但是当我们再次打开时,它的默认颜色还是显示黑色。我们想让它显示用户上次选择的颜色。如果要设置让该对话框满足我们的要求,那么就需要设置该对话框的CC_RGBINIT标志,这个标志可以在创建对话框对象时通过其构造函数的第二个参数来设置,也可以在该对话框对象创建之后,设置其m_cc成员变量中的Flags成员。我们采用后一种方法。在这里设置Flags参数 不可以用直接赋值的方法,因为这样会使得该对话框原来的那些默认的标记都去掉了,我们应该用组合的方式,将新的标准加到已有标准中去,代码如下:
view plain
void CGraphicView::OnColor()
{
CColorDialog dlg;
dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;
dlg.m_cc.rgbResult=m_clr;
if(IDOK==dlg.DoModal())
{
m_clr=dlg.m_cc.rgbResult;
}
}
在VIEW类获得用户的这些设置之后都应该在创建CPEN类时,添加到对应的参数中。上面的代码中 还有一个CC_FULLOPEN标记,这个也是一个常用的标记,使得颜色对话框创建的时候会完全展开。
下面创建一个字体对话框,就和MFC中选择字体的那个一样,和颜色对话框一样,字体对话框也是有一个MFC类与之对应,CFontDialog类。下面我们实现当用户选择了某种字体后,将它的名字用该字体显示出来。
在CFontDialog中有个CHOOSEFONT结构体的成员变量 m_cf
view plain
typedef struct {
DWORD lStructSize;
HWND hwndOwner;
HDC hDC;
LPLOGFONT lpLogFont;
INT iPointSize;
DWORD Flags;
COLORREF rgbColors;
LPARAM lCustData;
LPCFHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
HINSTANCE hInstance;
LPTSTR lpszStyle;
WORD nFontType;
WORD ___MISSING_ALIGNMENT__;
INT nSizeMin;
INT nSizeMax;
} CHOOSEFONT, *LPCHOOSEFONT;
其中有个 lpLogFont成员变量是指向逻辑字体(LOGFONT)的指针。
view plain
typedef struct tagLOGFONT {
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, *PLOGFONT;
在这个结构体中,lfFaceName 就是该字体的名字。
字体对象的创建,首先是利用CFont类构造一个字体对象,然后利用CFont类的CteateFontIndirect函数根据指定特征的逻辑字体来初始化这个字体对象。
view plain
BOOL CreateFontIndirect(const LOGFONT* lpLogFont );
为了保存用户选择的字体,为VIEW类增加一个CString m_strFontName变量来保存,初始化为空。当然要创建字体,所以要为VIEW类增加一个 CFont 类的成员 m_font
view plain
void CGraphicView::OnFont()
{
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();
}
}
在上面代码的最后 调用了Invalidate()函数 使窗口无效,重绘。所以我们就可以在ONPAINT函数中输出该字体了。
view plain
void CGraphicView::OnDraw(CDC* pDC)
{
CGraphicDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
C