内容发布更新时间 : 2024/12/23 0:31:13星期一 下面是文章的全部内容请认真阅读。
// 签名类成员函数
void CSignal::SetValue(CString signal, CPoint point, COLORREF color,
int escapement, LOGFONT *pfont) {
m_strSignal = signal; m_pointSignal = point; m_colorSignal = color;
memcpy(&m_fontSignal, pfont, sizeof(LOGFONT)); m_fontSignal.lfEscapement = escapement; }
// 显示签名
void CSignal::ShowSignal(CDC *pDC) {
CFont font, *pOldFont;
font.CreateFontIndirect(&m_fontSignal); pOldFont = pDC->SelectObject(&font); pDC->SetTextColor(m_colorSignal); pDC->TextOut(m_pointSignal.x, m_pointSignal.y,
m_strSignal);
pDC->SelectObject(pOldFont); }
// 框架窗口类 #define MAX_NAME 250
class CMyWnd: public CFrameWnd {
CSignal m_signalList[MAX_NAME]; // 签名数组 int m_nCount; // 签名数量
LOGFONT m_fontSignal; // 签名字体 COLORREF m_colorSignal; // 签名颜色 public: CMyWnd(); protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() };
// 消息映射
BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd) ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_WM_PAINT() END_MESSAGE_MAP() // 框架窗口类的成员函数 CMyWnd::CMyWnd() {
m_nCount = 0;
m_colorSignal = RGB(0, 0, 0); m_fontSignal.lfHeight = 40; m_fontSignal.lfWidth = 0; m_fontSignal.lfEscapement = 0; m_fontSignal.lfOrientation = 0; m_fontSignal.lfWeight = 400; m_fontSignal.lfItalic = FALSE; m_fontSignal.lfUnderline = FALSE; m_fontSignal.lfStrikeOut = 0;
m_fontSignal.lfCharSet = OEM_CHARSET;
m_fontSignal.lfOutPrecision = OUT_DEFAULT_PRECIS; m_fontSignal.lfClipPrecision = CLIP_DEFAULT_PRECIS; m_fontSignal.lfQuality = DEFAULT_QUALITY; m_fontSignal.lfPitchAndFamily = DEFAULT_PITCH; strcpy(m_fontSignal.lfFaceName, \}
// 鼠标右键消息响应函数
void CMyWnd::OnLButtonDown(UINT nFlags, CPoint point) {
if(m_nCount < MAX_NAME) {
CNameDlg dlg;
dlg.m_pointTopLeft = point; if(dlg.DoModal() == IDOK) {
LONG escapement = dlg.m_lEscapement; CString name = dlg.m_strNameEdit; m_signalList[m_nCount].SetValue(name, point,
m_colorSignal,
escapement, &m_fontSignal); m_nCount++; Invalidate(); } } }
// 鼠标右键消息响应函数
void CMyWnd::OnRButtonDown(UINT nFlags, CPoint point) {
CFontDialog dlg(&m_fontSignal); if(dlg.DoModal() == IDOK) {
dlg.GetCurrentFont(&m_fontSignal); m_colorSignal = dlg.GetColor(); } }
// 绘制框架窗口客户区函数 void CMyWnd::OnPaint() {
41 CPaintDC dc(this);
for(int i=0; i // 应用程序类 class CMyApp: public CWinApp { public: BOOL InitInstance(); }; // 应用程序类的成员函数 BOOL CMyApp::InitInstance() { CMyWnd *pFrame = new CMyWnd; pFrame->Create(0,_T(\签字留念簿程序\pFrame->ShowWindow(SW_SHOWMAXIMIZED); this->m_pMainWnd = pFrame; return TRUE; } // 全局应用程序对象 CMyApp ThisApp; 7-16 为例9-3的吹泡泡程序添加颜色选择对话框,使其可以绘出五颜六色的泡泡。 程 序:在例9-3的程序基础上作如下修改: 1.在程序首部添加文件包含命令: #include 2.在框架窗口类声明中添加一个COLORREF类型的数组,存放各泡泡的颜色: COLORREF m_colorBubble [MAX_BUBBLE]; 3.修改鼠标左键消息映射函数,添加使用颜色选择公用对话框的代码: void CMyWnd::OnLButtonDown ( UINT nFlags, CPoint point ) { if(m_nBubbleCount < MAX_BUBBLE) { m_colorBubble[m_nBubbleCount] = RGB(200, 200, 200); CColorDialog dlg(m_colorBubble[m_nBubbleCount]); if(dlg.DoModal() == IDOK) m_colorBubble[m_nBubbleCount] = dlg.GetColor(); int r = rand()P+10; CRect rect(point.x-r, point.y-r, point.x+r, point.y+r); m_rectBubble[m_nBubbleCount] = rect; m_nBubbleCount++; InvalidateRect(rect, FALSE); } } 4.修改OnPaint()成员函数,添加根据泡泡颜色使用画刷的代码: void CMyWnd::OnPaint() { CPaintDC dc(this); CBrush brushNew, *pbrushOld; for(int i=0; i brushNew.CreateSolidBrush(m_colorBubble[i]); pbrushOld = dc.SelectObject(&brushNew); dc.Ellipse(m_rectBubble[i]); dc.SelectObject(pbrushOld); brushNew.DeleteObject(); } } 7-17 序列化。如果例12-1的吹泡泡程序使用一般的数组存放泡泡数据(参看例9-1的程序): CRect m_rectBubble[MAX_BUBBLE]; int m_nBubbleCount; 为其文档类重新设计Serialize()函数。 说 明:按例12-1的方法建立项目和输入源代码,但将文档类中的泡泡数据改为以上两行的形式。修改文档类的Serialize()函数,代码如下。 程 序: // 序列化函数 void CMyDoc::Serialze(CArchive& ar) { if(ar.IsStoring()) { ar << m_nBubbleCount; for(int i=0; i ar >> m_nBubbleCount; for(int i=0; i 42 7-18 修改例12-1的程序并观察其打印结果。 程 序: 在例12-1程序的视图类CMyView类的成员函数OnDraw()中,添加代码沿窗口客户区轮廓画一矩形: void CMyView::OnDraw(CDC* pDC) { CRect rect; GetClientRect(&rect); pDC->Rectangle(rect); CMyDoc* pDoc = GetDocument(); // 取文档指针 ASSERT_VALID(pDoc); pDC->SelectStockObject(LTGRAY_BRUSH); // 在视图上显示文档数据 for(int i=0; i 7-19 改进吹泡泡程序,使之打印输出与屏幕显示的比例相近。 程 序: 在例12-1基础上修改。首先在CMyView类中重载虚函数OnPrepareDC()。在CMyView类的声明中增加一行: virtual void OnPrepareDC(CDC *pDC, CPrintInfo *pInfo=NULL); 然后添加该函数的定义,设置映射模式为MM_LOMETRIC: // 设置映射模式 void CMyView::OnPrepareDC(CDC *pDC, CPrintInfo *pInfo) { pDC->SetMapMode(MM_LOMETRIC); CView::OnPrepareDC(pDC, pInfo); } 然后修改消息映射函数OnLButtonDown(),将物理坐标转换为逻辑坐标: // 响应点击鼠标左键消息 void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { CMyDoc* pDoc = GetDocument(); // 取文档指针 ASSERT_VALID(pDoc); CClientDC dc(this); // 设置设备环境 OnPrepareDC(&dc); int r = rand()P+5; // 生成泡泡 CRect rect(point.x-r, point.y-r, point.x+r, point.y+r); InvalidateRect(rect, FALSE); // 更新视图 dc.DPtoLP(rect); // 转换物理坐标为逻辑坐标 pDoc->AddBubble(rect); // 修改文档数据 pDoc->SetModifiedFlag(); // 设置修改标志 } 7-20 声明一个Person类,并使之支持序列化。 程 序: class CPerson: public CObject { DECLARE_SERIAL( CPerson) LONG m_IDnumber; // 身份证号码 CString m_strName; // 姓名 CString m_strNation; // 民族 int m_nSex; // 性别 int m_nAge; // 年龄 BOOL m_bMarried; // 婚否 public: CEmployee(){}; CPerson& operator = (CPerson& person); void Serialize(CArchive& ar); }; IMPLEMENT_SERIAL( CPerson, CObject, 1 ) CPerson& CPerson::operator = (CPerson& person) { m_IDnumber = person.m_IDnumber; m_strName = person.m_strName; m_strNation = person.m_strNation; m_nSex = person.m_nSex; m_nAge = person.m_nAge; m_bMarried = person.m_bMarried; return *this; } void CPerson::Serialize(CArchive& ar) { CObject::Serialize( ar); // 首先调用基类的Serialize()方法 if(ar.IsStoring()) { ar << m_IDnumber; ar << m_strName; ar << m_strNation; 43 ar << m_nSex; ar << m_nAge; ar << (int)m_bMarried; } else { ar >> m_IDnumber; ar >> m_strName; ar >> m_strNation; ar >> m_nSex; CFont *pOldFont = (CFont *)(pDC->SelectObject(&font)); CRect rectPaper = pInfo->m_rectDraw; // 取页面打印矩形 // 页眉: 页面顶端中央打印文档名称 CMyDoc *pDoc = GetDocument(); ASSERT_VALID(pDoc); CString str; str.Format(\ (LPCSTR)pDoc->GetTitle()); CSize sizeText = pDC->GetTextExtent(str); CPoint point((rectPaper.Width()-sizeText.cx)/2, 0); Report: %s\ ar >> m_nAge; ar >> (int)m_bMarried; } } 7-21 修改例13-3的吹泡泡程序,使其打印每个泡泡的数据值。打印格式为每页40行,页眉为文档名,页脚为页号。 说 明:首先为视图类添加一个数据成员m_nLinePerPage,用来存放每页行数,并在视图类CMyView的构造函数中将m_nLinePerPage初始化为40。 修改视图类成员函数OnPrepareDC(),设置映射模式为MM_TWIPS。该模式为每英寸1440点,很适合打印机输出。 程 序: 重载视图类的成员函数OnPreparePrinting(),在其中添加计算打印页数的代码: BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo) { CMyDoc *pDoc = GetDocument(); int nPageCount = pDoc->GetListSize()/m_nLinePerPage; if(pDoc->GetListSize() % m_nLinePerPage) nPageCount ++; pInfo->SetMaxPage(nPageCount); return DoPreparePrinting(pInfo); } 最后重载视图类的OnPrint()函数并添加打印代码: void CMyView::OnPrint( CDC* pDC, CPrintInfo* pInfo ) { int nPage = pInfo->m_nCurPage; // 当前页号 int nStart = (nPage-1)*m_nLinePerPage; // 本页第一行 int nEnd = nStart+m_nLinePerPage; // 本页最后一行 CFont font; // 设置字体 font.CreateFont(-280, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_MODERN, \ pDC->TextOut(point.x, point.y, str); point.x = rectPaper.left; // 打印页眉下划线 point.y = rectPaper.top-sizeText.cy; pDC->MoveTo(point); point.x = rectPaper.right; pDC->LineTo(point); // 打印表头 str.Format(\\point.x = 720; point.y -= 720; pDC->TextOut(point.x, point.y, str); TEXTMETRIC tm; // 取当前字体有关信息 pDC->GetTextMetrics(&tm); int nHeight = tm.tmHeight+tm.tmExternalLeading; point.y -= 360; // 下移 1/4 英寸 for(int i=nStart; i if(i >= pDoc->GetListSize()) break; str.Format(\pDoc->GetBubble(i).left, pDoc->GetBubble(i).top, pDoc->GetBubble(i).right, pDoc->GetBubble(i).bottom); point.y -= nHeight; pDC->TextOut(point.x, point.y, str); } // 在页面底部中央打印页号 str.Format(\sizeText = pDC->GetTextExtent(str); point.x = (rectPaper.Width()-sizeText.cx)/2; point.y = rectPaper.Height()+sizeText.cy; pDC->TextOut(point.x, point.y, str); // 释放字体对象 pDC->SelectObject(pOldFont); } 44