C语言程序设计(郑莉)课后习题答案 下载本文

内容发布更新时间 : 2024/12/23 5:47:37星期一 下面是文章的全部内容请认真阅读。

// 签名类成员函数

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> m_rectBubble[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; iGetListSize(); i++) pDC->Ellipse(pDoc->GetBubble(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