面向对象编程技术实习报告.doc
面向对象编程技术实验四实验报告班 级:通信2 班学 号:201000800212姓 名: 王煜莹时 间:2012-10-20目录1 实验要求32 实验过程及结果3A、对话框部分:3B、图形绘制函数的使用5C、定时器使用103 问题及解决方案114 实验总结11附件12关键程序代码12A、对话框部分:12B、自定义对话框:151 实验要求 掌握通用对话框和自定义对话框的使用;掌握图形绘制函数的使用;掌握定时器的设置和定时消息响应。2 实验过程及结果A、对话框部分:1. 研究第五章示例程序,理解通用对话框、自定义对话框的使用方式,为本次实验打基础。2. 在自己的工作目录中建立新工程。从已有的示例程序中选取适当的代码,修改形成自己的框架。代码整理过程中要特别注意代码的格式。源文件名后缀必须是.cpp,不可以是.c3. 增加对WM_PAINT消息的处理,在窗口客户区输出文本。case WM_PAINT: hdc = BeginPaint (hWnd, &ps); GetClientRect (hWnd, &rect);DrawText (hdc, TEXT ("欢迎使用"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);EndPaint (hWnd, &ps);return 0; 4. 增加菜单资源,要求至少包含“更改文本颜色”和“更改背景颜色”两个命令。 5. 自定义一个简单的对话框,该对话框内至少有一个“选择背景色”按钮和一个静态文本框(或Edit框)以及确定、取消两个按钮。该简单对话框的处理逻辑为:点击“选择背景色”按钮,弹出通用对话框选择颜色,选择完颜色后,将颜色值显示到静态文本框(或Edit框)中。再点击该对话框的“确定”按钮,可将结果颜色值通过变量交接给外部程序使用。6. 编写上述自定义对话框的处理函数。switch(LOWORD(wParam)case IDM_SET_BKColor:if (DialogBox ( (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG1), hWnd, ColorDlgProc)=IDOK)if (change)hold=(HBRUSH)GetWindowLong(hWnd,GCL_HBRBACKGROUND);SetClassLong(hWnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(g_Color);change=TRUE;if (change) DeleteObject(hold); InvalidateRect(hWnd,NULL,TRUE);case IDM_SET_SCRIPTColor:if (ChooseColor (&cc)crText=cc.rgbResult;InvalidateRect (hWnd, NULL, TRUE);7. 增加响应菜单命令的代码。¨ 在“更改文本颜色”命令的响应中调用通用颜色对话框选择新的颜色。新选定的文本颜色用全局变量或静态变量保存,在主窗口刷新消息(WM_PAINT)处理中用该颜色显示原来输出的文本。case IDC_BUT_SELCOLOR:SetDlgItemInt(hDlg, IDC_COLORVALUE, GetMyColor(hDlg), FALSE); return TRUE; case WM_PAINT: hdc = BeginPaint (hWnd, &ps); GetClientRect (hWnd, &rect);SetTextColor (hdc, crText);DrawText (hdc, TEXT ("欢迎使用"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);EndPaint (hWnd, &ps);return 0;¨ 更改背景颜色命令响应中激活自定义对话框,对话框结束后,根据选择的颜色,结合SetClassLong和CreateSolidBrush函数,创建新的画刷,并替换原来主窗口类使用的画刷。if (change)hold=(HBRUSH)GetWindowLong(hWnd,GCL_HBRBACKGROUND);SetClassLong(hWnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(g_Color);change=TRUE;if (change) DeleteObject(hold); InvalidateRect(hWnd,NULL,TRUE);8. 刷新窗口看显示结果是否符合要求(可在设置完颜色或画刷之后直接用InvalidateRect函数激发WM_PAINT消息)。B、图形绘制函数的使用1. 研习EASYGDI示例程序。查看各个GDI绘制函数的使用方法。2. 在自己的工作目录中建立新工程。要求同2。3. 增加对WM_PAINT消息的处理,在其中使用:PolylinePolyPolylinePolygonPolyPolygon等函数,注意在WM_PAINT消息中对HDC的获取和释放使用的函数是BeginPaint和EndPaint函数。 switch(iSelectionFunc)case IDM_FUNC_POLYLINE:ptDiamond0.x = 0;ptDiamond0.y = rect.bottom / 2;ptDiamond1.x = rect.right / 2;ptDiamond1.y = 0;ptDiamond2.x = rect.right;ptDiamond2.y = rect.bottom / 2;ptDiamond3.x = rect.right / 2;ptDiamond3.y = rect.bottom;ptDiamond4.x = 0;ptDiamond4.y = rect.bottom / 2;Polyline (hdc, ptDiamond, 5);break;case IDM_FUNC_POLYGON:if (GetPolyFillMode(hdc)=WINDING)SetPolyFillMode(hdc, ALTERNATE);elseSetPolyFillMode(hdc, WINDING);ptDiamond0.x = 0;ptDiamond0.y = rect.bottom / 3;ptDiamond1.x = rect.right;ptDiamond1.y = rect.bottom / 3;ptDiamond2.x = rect.right / 4;ptDiamond2.y = rect.bottom;ptDiamond3.x = rect.right / 2;ptDiamond3.y = 0;ptDiamond4.x = 3 * rect.right / 4;ptDiamond4.y = rect.bottom;Polygon (hdc, ptDiamond, 5);break;case IDM_FUNC_POLYPOLYLINE: ptDiamond20.x = 0;ptDiamond20.y = rect.bottom / 4;ptDiamond21.x = rect.right / 4;ptDiamond21.y = 0;ptDiamond22.x = rect.right;ptDiamond22.y = rect.bottom / 4;ptDiamond23.x = rect.right / 4;ptDiamond23.y = rect.bottom;ptDiamond24.x = 0;ptDiamond24.y = rect.bottom / 4; ptDiamond25.x = 0;ptDiamond25.y =3 * rect.bottom / 4;ptDiamond26.x =3 * rect.right / 4;ptDiamond26.y = 0;ptDiamond27.x = rect.right;ptDiamond27.y =3 * rect.bottom / 4;ptDiamond28.x = 3 *rect.right / 4;ptDiamond28.y = rect.bottom;ptDiamond29.x = 0;ptDiamond29.y = 3 *rect.bottom / 4;PolyPolyline (hdc, ptDiamond2, b,2);break;case IDM_FUNC_POLYPOLYGON:if (GetPolyFillMode(hdc)=WINDING)SetPolyFillMode(hdc, ALTERNATE);elseSetPolyFillMode(hdc, WINDING);ptDiamond30.x = 0;ptDiamond30.y = rect.bottom / 6;ptDiamond31.x = rect.right;ptDiamond31.y = rect.bottom /6;ptDiamond32.x = rect.right / 4;ptDiamond32.y = rect.bottom / 2;ptDiamond33.x = rect.right /2;ptDiamond33.y = 0;ptDiamond34.x = 3 * rect.right / 4;ptDiamond34.y = rect.bottom/2; ptDiamond35.x = 0;ptDiamond35.y = 2* rect.bottom / 3;ptDiamond36.x = rect.right;ptDiamond36.y = 2*rect.bottom /3;ptDiamond37.x = rect.right / 4;ptDiamond37.y = rect.bottom;ptDiamond38.x = rect.right /2;ptDiamond38.y = rect.bottom /2;ptDiamond39.x = 3 * rect.right / 4;ptDiamond39.y = rect.bottom;PolyPolygon (hdc, ptDiamond3, c,2);break;4. 按与Polyline相同的函数格式编写自定义的折线绘制函数,新函数命名为MyPolyline(用MoveToEx和LineTo实现),用该函数替换上一步代码(11)中的Polyline,应该获得同样的运行结果。BOOL MyPolyline(HDC hdc,CONST POINT *lppt,int cPoints)MoveToEx(hdc,(*lppt).x,(*lppt).y,NULL);for (int i=1;i<cPoints;i+)LineTo(hdc,(*(lppt+i).x,(*(lppt+i).y);return TRUE;5. 编写MyPolyPolyline和MyPolyPolygon,替换11中相应的库函数,获得同样的运行结果,以此加深对函数编写、指针方式参数传递的理解。BOOL MyPolyPolyline(HDC hdc,CONST POINT *lppt,CONST DWORD *lpdwPolyPoints,int count)int i=0;for (int n=0;n<count;n+)MyPolyline(hdc,lppt+i,*(lpdwPolyPoints+n);i+=*(lpdwPolyPoints+n);return TRUE;BOOL MyPolyPolygon(HDC hdc,CONST POINT*lpPoints,CONST INT*lpPolyCounts,int nCount)PolyPolygon(hdc,lpPoints,lpPolyCounts,nCount);return TRUE;6. 一个工程多个.cpp文件的试验:可尝试将这些自定义函数用单独的.cpp文件管理,并编写相应的头文件,使这些函数可以在其他.cpp文件中被调用。7. 在调试完上述代码的基础上增加绘图函数的使用,尝试绘制椭圆、矩形等图形。case IDM_FUNC_RECTANGLE:Rectangle (hdc, rect.right / 4, rect.bottom / 4, 3 * rect.right / 4, 3 * rect.bottom / 4);break;case IDM_FUNC_ROUNDRECT:RoundRect (hdc, rect.right / 4, rect.bottom / 4, 3 * rect.right / 4, 3 * rect.bottom / 4, rect.right / 4, rect.bottom / 4);break;C、定时器使用8. 在WM_CREATE消息中增加设置定时器的代码(用SetTimer函数);case WM_CREATE: /创建消息SetTimer(hWnd,1,1000,NULL);return 0;9. 在窗口过程的消息处理代码中增加WM_TIMER消息的处理,处理的内容包括:¨ 用SYSTEMTIME结构定义一个时间结构变量¨ 用GetSysteTime函数或GetLocalTime函数取出系统时间或本地时间¨ 将时间值打印成字符串(可以使用wsprintf函数或sprintf函数)¨ 使用GetDC函数获取HDC¨ 用TextOut 或 DrawText函数输出文本¨ 用ReleaseDC函数释放先前获取的HDC上述操作完成后,能够在窗口客户区中看到不断刷新的时间显示。case WM_TIMER:GetLocalTime(&systemtime); InvalidateRect (hWnd, NULL, TRUE);return 0;case WM_PAINT: wsprintf(str, "%s %u/%u/%u %u:%u:%u", day, systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond, systemtime.wMilliseconds); DrawTextA(hdc,str,strlen(str),&rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER); EndPaint (hWnd, &ps);10. 在WM_DESTROY消息中增加删除已创建的定时器的代码(用KillTimer函数)case WM_DESTROY:KillTimer(hWnd,NULL);PostQuitMessage(0);return 0;3 问题及解决方案1 调用通用颜色对话框的时候要先添加到自定义颜色中才可使其变色,为使其更方便,将代码ctText=crCustomColors0;改为ctText=cc.rgbResult;2 编写MyPolyPolyline函数时,出现很多问题,先是在编写函数时总是不能实现特定的功能,调用时忘记申明,最后编写时仔细理解了LineTo和MoveToEx,利用这两个函数先写出了MyPolyline,然后在这基础上编写了MyPolyPolyline;3 MyPolyPolygon编写时也同样出现很多问题,没法实现填充,最后直接调用的PolyPolygon,编写时按照一个在头文件中编写,另一个新建一个cpp,理解函数的调用;#include <windows.h>BOOL MyPolyPolygon(HDC hdc,CONST POINT*lpPoints,CONST INT*lpPolyCounts,int nCount)PolyPolygon(hdc,lpPoints,lpPolyCounts,nCount);return TRUE;4 在定时器的编写时运行无错,却总是出现528528528,无法成功计时,此时#define Time 1;SetTimer(hWnd,1,1000,NULL);确认无错的情况下,将GetSystem(&systemtime);改为GetLocalTime(&systemtime);可成功计时;5 编写时依旧存在括号漏写,未定义等错误,在出现错误很多的情况下检查括号是否漏写,未定义的在定义的类型上要仔细考虑,不能把类型弄错;4 实验总结 这次的实验,总体来说不向以往几次都是赶着上交之前才完成,有了一定的进步吧。初次拿到题目时还是一样的大量的题目,然而仔细的去一点点的研究,去做的时候发现也许有了上几次的练习作为积淀,做起来也不向以前一样刚开始毫无头绪。在仔细的研究完实例程序后,按照特定的步骤和方法都能一步步的做出来。也许是有着实例程序的运用,为我们提供了很多的借鉴及参考。这次的实验中花费时间最长的是函数的编写,因为知道自己的弱点一直在函数这边,所以这次的练习在函数上下了很大的功夫。虽然说是简单的函数编写,但是我还是经过了多次的推敲,尝试,最终顺利的实现时的却十分开心。在一次次的实验中,看着一点点的进步,从不妄想能够一步登天,亦知自己还需努力,于是耐下心来一点点的去做,去积累,去领悟编程的思想。附件关键程序代码A、对话框部分:#include <windows.h>#include <windowsx.h>#include "resource.h"BOOL InitWindow (HINSTANCE hInstance, int nCmdShow);LRESULT CALLBACK MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);COLORREF GetMyColor(HWND hWnd)COLORREF cr = 0;CHOOSECOLOR cc;COLORREF crCustomColors16;/初始化CHOOSECOLOR结构变量 cccc.lStructSize = sizeof (CHOOSECOLOR);cc.hwndOwner = hWnd;cc.hInstance = NULL;cc.rgbResult = RGB (0, 0, 0);cc.lpCustColors = crCustomColors;cc.Flags = CC_RGBINIT | CC_FULLOPEN;cc.lCustData = 0;cc.lpfnHook = NULL;cc.lpTemplateName = NULL;if (ChooseColor (&cc)cr = cc.rgbResult;return cr;COLORREF g_Color;BOOL CALLBACK ColorDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)BOOL b; static int iColor; /用户选择的颜色 switch (message) case WM_INITDIALOG: /先设置为红色 CheckRadioButton (hDlg, IDC_RADIO_RED, IDC_RADIO_GREEN, IDC_RADIO_RED); SetDlgItemInt (hDlg, IDC_COLORVALUE, RGB(255,0,0), FALSE); return FALSE; case WM_COMMAND:/处理对话框中各控件通知消息 switch (LOWORD (wParam) case IDOK: /响应"确认"按钮,改写文本颜色 iCurrentColor 为iColor g_Color = GetDlgItemInt(hDlg, IDC_COLORVALUE, &b, FALSE); /关闭对话框 EndDialog (hDlg, TRUE); /关闭对话框 return TRUE; case IDCANCEL: /响应"取消"按钮,直接关闭对话框 EndDialog (hDlg, FALSE); return TRUE;case IDC_BUT_SELCOLOR:SetDlgItemInt(hDlg, IDC_COLORVALUE, GetMyColor(hDlg), FALSE);return TRUE; case IDC_RADIO_RED: case IDC_RADIO_GREEN: case IDC_RADIO_BLUE: CheckRadioButton (hDlg, IDC_RADIO_RED, IDC_RADIO_BLUE, LOWORD (wParam);switch(LOWORD (wParam)case IDC_RADIO_RED: SetDlgItemInt (hDlg, IDC_COLORVALUE, RGB(255,0,0), FALSE); break;case IDC_RADIO_GREEN: SetDlgItemInt (hDlg, IDC_COLORVALUE, RGB(0,255,0), FALSE); break;case IDC_RADIO_BLUE: SetDlgItemInt (hDlg, IDC_COLORVALUE, RGB(0,0,255), FALSE); break; return TRUE; break; return FALSE;/结束 ColorDlgProcint WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow).LRESULT CALLBACK MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)static HWND hWndEdit;static HMENU hMenuPop;HDC hdc;PAINTSTRUCT ps;RECT rect;static COLORREF crText = RGB (0, 0, 0);static BOOL change=FALSE;HBRUSH hold; static CHOOSECOLOR cc;static COLORREF crCustomColors16;switch (message)case WM_CREATE:/初始化结构 cccc.lStructSize = sizeof (CHOOSECOLOR);cc.hwndOwner = hWnd;cc.hInstance = NULL;cc.rgbResult = RGB (0, 0, 0);cc.lpCustColors = crCustomColors;cc.Flags = CC_RGBINIT | CC_FULLOPEN;cc.lCustData = 0;cc.lpfnHook = NULL;cc.lpTemplateName = NULL; hMenuPop = LoadMenu (LPCREATESTRUCT)lParam)->hInstance, "IDR_MENU1"); hMenuPop = GetSubMenu (hMenuPop, 1);return 0;case WM_SETFOCUS:SetFocus (hWndEdit);return 0;case WM_COMMAND: / 响应编辑控件通知消息if (lParam)WORD w, W1, W2, W3;w = LOWORD (wParam);W1 = HIWORD(wParam);W2 = LOWORD (lParam);W3 = HIWORD(lParam);/编辑控件通知消息if (LOWORD (wParam) = 1) &&(HIWORD(wParam) = EN_ERRSPACE | HIWORD (wParam) = EN_MAXTEXT)MessageBox (hWnd,TEXT ("编辑控件内存溢出"), TEXT ("菜单示例程序"), MB_OK|MB_ICONSTOP);return 0;elseswitch(LOWORD(wParam);case IDM_SET_BKColor:if (DialogBox ( (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG1), hWnd, ColorDlgProc)=IDOK)if (change)hold=(HBRUSH)GetWindowLong(hWnd,GCL_HBRBACKGROUND);SetClassLong(hWnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(g_Color);change=TRUE;if (change) DeleteObject(hold); InvalidateRect(hWnd,NULL,TRUE);case IDM_SET_SCRIPTColor:if (ChooseColor (&cc)crText=cc.rgbResult;InvalidateRect (hWnd, NULL, TRUE);return 0;return 0;case WM_PAINT: hdc = BeginPaint (hWnd, &ps); GetClientRect (hWnd, &rect);SetTextColor (hdc, crText);DrawText (hdc, TEXT ("欢迎使用"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);EndPaint (hWnd, &ps);return 0;case WM_DESTROY: PostQuitMessage (0);return 0;return DefWindowProc (hWnd, message, wParam, lParam); /函数 MainWndProc 结束B、自定义对话框:#include <windows.h>#include <windowsx.h>#include "resource.h"#include "mypolyolygon.h"BOOL InitWindow (HINSTANCE hInstance, int nCmdShow);LRESULT CALLBACK WinProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);BOOL MyPolyline(HDC hdc,CONST POINT *lppt,int cPoints);.LRESULT CALLBACK WinProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)HDC hdc;PAINTSTRUCT ps;RECT rect;LOGPEN logpen;CONST DWORD b2=5,5;int c2=5,5; static HMENU hMenuPop;HMENU hMenu;static int iSelectionFunc=IDM_FUNC_POLYLINE;static int iSelectionPen=IDM_PEN_BLACK;static int iSelectionBrush=IDM_BRUSH_WHITE;static HPEN hRedDashdotPen, hBlueSolidPen;HPEN hOldPen;HBRUSH hNewBrush, hOldBrush;POINT ptDiamond5;POINT ptDiamond210;POINT ptDiamond310, pt;switch (message)case WM_CREATE:hRedDashdotPen = CreatePen (PS_DASHDOT, 1, RGB (255, 0, 0);/创建宽度为3的蓝色画笔logpen.lopnStyle = PS_SOLID;logpen.lopnWidth.x = 3;logpen.lopnColor = RGB (0, 0, 255); hBlueSolidPen = CreatePenIndirect (&logpen); hMenuPop = LoadMenu (LPCREATESTRUCT)lParam)->hInstance, "IDR_MENU1");hMenuPop = GetSubMenu (hMenuPop, 1);return 0;case WM_COMMAND: hMenu = GetMenu (hWnd) ; switch (LOWORD (wParam) case IDM_FUNC_POLYPOLYLINE:case IDM_FUNC_POLYLINE:case IDM_FUNC_