win32实现画图小程序

来源:互联网 发布:51单片机毕业设计题库 编辑:程序博客网 时间:2024/05/17 01:06

本周我们的三级项目是用win32完成一个画图软件。今天我们也进行一个总结。如果大家觉得下面表述不清,想直接看代码,可以到我的资源页下载源代码。

该画图软件要求实现功能:颜色选择、工具选择、画笔宽度设置、画图进行保存和打开文件、调色板的停靠、工具栏和调色板的显示和隐藏

功能演示截图如下:

颜色选择


工具选择


画笔宽度设置


画图进行保存和打开文件


调色板的隐藏和显示


工具栏和调色板的停靠


创建了三个窗口,一个是主窗口,完成画板的主要操作;一个是调色板子窗口,用来进行画图颜色的选择和将选择颜色传给主窗口,完成颜色选择操作;另一个是工具栏窗口,用来进行画图工具的选择和将选择工具传给主窗口,完成工具选择操作。

方法一:在画图的同时,将参数存入列表中,重绘、保存、打开文件和清除窗口,都通过对这个列表进行调用来实现。

方法二:在画图时,将参数存入数组中,具体操作与方法一类似。

以下代码中,我两种方法都进行了编辑,但未区分,且方法二只完成了重绘、文件的相关操作未进行编写,还请读者注意。

主窗口的回调函数:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;static TCHAR szFullFileName[300],szFileName[300];static HWND hWndcolorbox,hWndtoolbox;static COLORREF color,col[10];static DRAWSTRU ds;static PDRAWFUN pMouseDown,pMouseMove,pMouseUp;static POINT ptstart,ptend;static POINT pts[10],pte[10];static int shapeindex=0;static int iPenWidth=2;static HMENU hMenu;static bool bMouseDown=FALSE;static bool colorboxdock=false;switch (message){case WM_COMMAND:wmId    = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;case IDM_FILE_NEW:_tcscpy_s(szFullFileName,TEXT(""));case IDM_EDIT_CLEAR:ClearGraphic(ds.g);InvalidateRect(hWnd,NULL,TRUE);break;case IDM_FILE_OPEN:ClearGraphic(ds.g);if(!PopFileOpenDlg(hWnd,szFullFileName,szFileName))break;OpenGraphic(szFullFileName,ds.g);InvalidateRect(hWnd,NULL,TRUE);break;case IDM_FILE_SAVE:if(_tcslen(szFullFileName)==0){if (!PopFileSaveDlg(hWnd,szFullFileName,szFileName))break;}SaveGraphic(szFullFileName,ds.g);break;case IDM_FILE_SAVEAS:if (!PopFileSaveDlg(hWnd,szFullFileName,szFileName))break;SaveGraphic(szFullFileName,ds.g);break;case IDM_EDIT_PENWIDTH:if(DialogBoxParam(hInst, (LPCTSTR)IDD_PENWIDTH,hWnd,(DLGPROC)PenWidth,(LPARAM)&iPenWidth)==IDOK){        SendMessage(hWnd,WM_CHANGEPENWIDTH,(WPARAM)0,(LPARAM)iPenWidth);}break;case IDM_VIEW_COLORBOXDOCK:if(colorboxdock){colorboxdock=false;ShowWindow(hWndcolorbox,SW_HIDE);hWndcolorbox=CreateWindow(szColorBtnClass,L"11",WS_CHILD|WS_BORDER|WS_VISIBLE,0,0,280,40,hWnd,NULL,hInst,(LPVOID)RGB(0,0,0)); CheckMenuItem(hMenu,IDM_VIEW_COLORBOXDOCK,MF_BYCOMMAND|MF_CHECKED);}else{colorboxdock=true;ShowWindow(hWndcolorbox,SW_HIDE);    hWndcolorbox=CreateWindow(szColorBtnClass,L"11",(WS_POPUP |WS_CAPTION|WS_SYSMENU|WS_VISIBLE),0,0,330,90,hWnd,NULL,hInst,(LPVOID)RGB(0,0,0)    CheckMenuItem(hMenu,IDM_VIEW_COLORBOXDOCK,MF_BYCOMMAND|MF_UNCHECKED);}break;case IDM_VIEW_COLORBOXHIDE://ShowWindow(hWndcolorbox,SW_HIDE);{if(IsWindowVisible(hWndcolorbox)){ShowWindow(hWndcolorbox,SW_HIDE);CheckMenuItem(hMenu,IDM_VIEW_COLORBOXHIDE,MF_BYCOMMAND|MF_CHECKED);}else{ShowWindow(hWndcolorbox,SW_SHOWNORMAL);CheckMenuItem(hMenu,IDM_VIEW_COLORBOXHIDE,MF_BYCOMMAND|MF_UNCHECKED);}}break;case IDM_VIEW_TOOLHIDE:if(IsWindowVisible(hWndtoolbox)){ShowWindow(hWndtoolbox,SW_HIDE);CheckMenuItem(hMenu,IDM_VIEW_TOOLHIDE,MF_BYCOMMAND|MF_CHECKED);}else{ShowWindow(hWndtoolbox,SW_SHOWNORMAL);CheckMenuItem(hMenu,IDM_VIEW_TOOLHIDE,MF_BYCOMMAND|MF_UNCHECKED);}break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_CREATE:{hWndtoolbox=CreateWindow(szShapeBtnClass,L"工具栏",(WS_POPUP |WS_CAPTION | WS_SYSMENU|WS_VISIBLE),500,100,72,122,hWnd,NULL,hInst,NULL);hWndcolorbox=CreateWindow(szColorBtnClass,L"11",WS_CHILD|WS_BORDER|WS_VISIBLE,0,0,280,40,hWnd,NULL,hInst,(LPVOID)RGB(0,0,0));hMenu=GetMenu(hWnd);pMouseDown=PenMouseDown;        pMouseUp=PenMouseUp;        pMouseMove=PenMouseMove;PopFileInitialize(hWnd);        ds.color=RGB(255,0,0);ds.bFill=false;ds.iPenWidth =2;ds.hBr=CreateSolidBrush(ds.color);        ds.hPen=CreatePen(PS_SOLID,ds.iPenWidth,ds.color);CheckMenuItem(hMenu,IDM_VIEW_COLORBOXDOCK,MF_BYCOMMAND|MF_CHECKED);}break;case WM_HIDECOLORBOX:CheckMenuItem(hMenu,IDM_VIEW_COLORBOXHIDE,MF_BYCOMMAND|MF_UNCHECKED);break;case WM_LBUTTONDOWN:{pMouseDown(&ds,hWnd,wParam,lParam);}break;case WM_MOUSEMOVE:
                {        pMouseMove(&ds,hWnd,wParam,lParam);
                }break;case WM_LBUTTONUP:{pMouseUp(&ds,hWnd,wParam,lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: 在此添加任意绘图代码...DrawGraphics(hdc,ds.g);(列表重绘)//for (int i = 0; i <= iShNum; i++)//{//HPEN pen=CreatePen(PS_SOLID,ds.iPenWidth,SHAPESTR[i].color);//SelectObject(hdc,pen);//SHAPESTR[i].hBr=CreateSolidBrush(SHAPESTR[i].color);//HBRUSH hbrOld=(HBRUSH)SelectObject(hdc,SHAPESTR[i].hBr);//ShapeSelect(i,hdc);//DeleteObject(pen);//DeleteBrush(hbrOld);//}(结构体数组重绘)EndPaint(hWnd, &ps);break;case WM_CHANGECOLOR:{DeleteObject(ds.hPen);DeleteObject(ds.hBr);        ds.color=(COLORREF)lParam;        ds.hPen=CreatePen(PS_SOLID,ds.iPenWidth,ds.color);        ds.hBr=CreateSolidBrush(ds.color);}break;case WM_CHANGEPENWIDTH:        ds.iPenWidth=(INT)(lParam);DeleteObject(ds.hPen);ds.hPen=CreatePen(PS_SOLID,ds.iPenWidth,ds.color);break;case WM_CHANGETOOL:ds.pSh=(SHAPE)(lParam);//ds.pCurShp=(PDRAWSHAPE)ds.pSh;switch (ds.pSh){case SHAPECURVE:{pMouseDown=PenMouseDown;        pMouseUp=PenMouseUp;pMouseMove=PenMouseMove;break;   }case SHAPELINE:{pMouseDown=LineMouseDown;        pMouseUp=LineMouseUp;pMouseMove=LineMouseMove;break;}case SHAPERECT:{ds.bFill=false;pMouseDown=RectMouseDown;        pMouseUp=RectMouseUp;pMouseMove=RectMouseMove;break;}case SHAPERECTF:{ds.bFill=true;pMouseDown=RectMouseDown;        pMouseUp=RectMouseUp;pMouseMove=RectMouseMove;break;}case SHAPECIRCLE:{ds.bFill=false;pMouseDown=ElliMouseDown;        pMouseUp=ElliMouseUp;pMouseMove=ElliMouseMove;break;}case SHAPECIRCLEF:{ds.bFill=true;pMouseDown=ElliMouseDown;        pMouseUp=ElliMouseUp;pMouseMove=ElliMouseMove;break;}}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}
调色板的回调函数:

LRESULT CALLBACK ColorBtnWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;int num;static COLORREF COLBOX[]={RGB(255, 255, 255), RGB(0, 0, 0),RGB(192, 192, 192), RGB(128, 128, 128),RGB(255, 0, 0),     RGB(128, 0, 0),RGB(255, 255, 0),   RGB(128, 128, 0),RGB(0, 255, 0),     RGB(0, 128, 0),RGB(0, 255, 255),   RGB(0, 128, 128),RGB(0, 0, 255),     RGB(0, 0, 128),RGB(255, 0, 255),   RGB(128, 0, 128),RGB(255, 255, 128), RGB(128, 128, 64),RGB(0, 255, 128),   RGB(0, 64, 64),RGB(128, 255, 255), RGB(0, 128, 255),RGB(128, 128, 255), RGB(0, 64, 128),RGB(255, 0, 128),   RGB(64, 0, 128),RGB(255, 128, 64),  RGB(128, 64, 0)};POINT pt,ptp;switch (message){case WM_COMMAND:wmId    = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_CREATE:ptp.x=0;ptp.y=0;if(!(GetWindowLong(hWnd,GWL_STYLE)&WS_CHILD))ClientToScreen(GetParent(hWnd),&ptp);break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: 在此添加任意绘图代码...for(int i=0;i<28;i++){HBRUSH hbr=CreateSolidBrush(COLBOX[i]);SelectObject(hdc,hbr);if(i<14){Rectangle(hdc,i*20,0,(i+1)*20,20);}else{Rectangle(hdc,(i-14)*20,20,(i-13)*20,40);}DeleteObject(hbr);}EndPaint(hWnd, &ps);break;case WM_LBUTTONDOWN:{pt.x=GET_X_LPARAM(lParam);pt.y=GET_Y_LPARAM(lParam);if(pt.y<=20){num=pt.x/20;}else{num=pt.x/20+14;}COLORREF color=COLBOX[num];SendMessage(GetParent(hWnd),WM_CHANGECOLOR,(WPARAM)0,(LPARAM)color);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}

工具栏的回调函数:

LRESULT CALLBACK ShapeBtnWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){PAINTSTRUCT ps;        HDC hdc;POINT pt;static HDC hDcMem;int num;static HBITMAP hBitmap[6][2];bool bFill=false;static SHAPE TOOLBOX[]={SHAPECURVE,SHAPELINE,SHAPERECT,SHAPERECTF,SHAPECIRCLE,SHAPECIRCLEF};switch (message){case WM_CREATE:{hdc=GetDC(hWnd);    hDcMem=CreateCompatibleDC(hdc);            hBitmap[0][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDPENCIL));            hBitmap[0][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TUPENCIL));            hBitmap[1][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDLINE));            hBitmap[1][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TULINE));            hBitmap[2][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDRECT));            hBitmap[2][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TURECT));            hBitmap[3][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDSRECT));            hBitmap[3][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TUSRECT));            hBitmap[4][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDCIRCLE));            hBitmap[4][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TUCIRCLE));            hBitmap[5][0]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TDSCIRCLE));            hBitmap[5][1]=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_TUSCIRCLE));}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);SelectObject(hDcMem,hBitmap[0][0]);BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);SelectObject(hDcMem,hBitmap[1][1]);BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);SelectObject(hDcMem,hBitmap[2][1]);BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);SelectObject(hDcMem,hBitmap[3][1]);BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);SelectObject(hDcMem,hBitmap[4][1]);BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);SelectObject(hDcMem,hBitmap[5][1]);BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);EndPaint(hWnd, &ps);break;case WM_LBUTTONDOWN:{HDC hdc=GetDC(hWnd);pt.x=GET_X_LPARAM(lParam);pt.y=GET_Y_LPARAM(lParam);int cx=pt.x/28;int cy=pt.y/28;if(cy==0){if(cx==0){num=0;SelectObject(hDcMem,hBitmap[0][0]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][1]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][1]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][1]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][1]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][1]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}else{num=1;SelectObject(hDcMem,hBitmap[0][1]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][0]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][1]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][1]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][1]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][1]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}}else if(cy==1){if(cx==0){bFill=false;num=2;SelectObject(hDcMem,hBitmap[0][1]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][1]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][0]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][1]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][1]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][1]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}else{bFill=true;num=3;SelectObject(hDcMem,hBitmap[0][1]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][1]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][1]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][0]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][1]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][1]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}}else if(cy==2){if(cx==0){bFill=false;num=4;SelectObject(hDcMem,hBitmap[0][1]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][1]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][1]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][1]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][0]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][1]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}else{bFill=true;num=5;SelectObject(hDcMem,hBitmap[0][1]);            BitBlt(hdc,0,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[1][1]);            BitBlt(hdc,28,0,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[2][1]);            BitBlt(hdc,0,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[3][1]);            BitBlt(hdc,28,28,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[4][1]);            BitBlt(hdc,0,56,100,100,hDcMem,0,0,SRCCOPY);            SelectObject(hDcMem,hBitmap[5][0]);            BitBlt(hdc,28,56,100,100,hDcMem,0,0,SRCCOPY);}}SHAPE nTool=TOOLBOX[num];SendMessage(GetParent(hWnd),WM_CHANGETOOL,bFill,(LPARAM)nTool);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}
画笔宽度设置的回调函数:

LRESULT CALLBACK PenWidth(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){HWND hWndSpin;INT wmId;static INT *piPenWidth;switch (message){case WM_INITDIALOG:piPenWidth=(INT *)(lParam);hWndSpin=GetDlgItem(hDlg,IDC_SPIN);SetDlgItemInt(hDlg,IDC_EDIT,*piPenWidth,FALSE);//设置指定控件的值SendMessage(hWndSpin,UDM_SETRANGE ,(WPARAM)0,(LPARAM)MAKELONG (10 , 1)); return TRUE;case WM_COMMAND:{BOOL bSuccessed;wmId=LOWORD(wParam);switch (wmId){case IDOK:*piPenWidth=GetDlgItemInt(hDlg,IDC_EDIT,&bSuccessed,FALSE);EndDialog(hDlg, LOWORD(wParam));break;case IDCANCEL:EndDialog(hDlg, LOWORD(wParam));break;}return TRUE;}break;}    return FALSE;}
画笔设置函数:

void PenMouseDown( PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){pDs->ptStart.x=GET_X_LPARAM(lParam);pDs->ptStart.y=GET_Y_LPARAM(lParam);pDs->ptPrev.x=pDs->ptStart.x;pDs->ptPrev.y=pDs->ptStart.y;pDs->bMouseDown=TRUE;iShNum++;SHAPESTR[iShNum].pSh=SHAPECURVE;SHAPESTR[iShNum].color=pDs->color;SHAPESTR[iShNum].iPenWidth=pDs->iPenWidth;SHAPESTR[iShNum].ptStart=pDs->ptStart;SHAPESTR[iShNum].ptEnd=pDs->ptEnd;//-----新建DRAWSHAPE对象以存储曲线的信息PDRAWCURVE pCurve;PDRAWSHAPE pShp;pShp=new DRAWSHAPE;pDs->pCurShp=pShp;pShp->color=pDs->color;pShp->shape=SHAPECURVE;pShp->penWidth=pDs->iPenWidth;pCurve=new DRAWCURVE;pShp->pData=pCurve;SHAPESTR[iShNum].pData=pCurve;pCurve->AddTail(pDs->ptStart);//-----新建DRAWSHAPE对象以存储曲线的信息SetCapture(hWnd);}void PenMouseUp( PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){pDs->bMouseDown=FALSE;ReleaseCapture();hdc=GetDC(hWnd);MoveToEx(hdc,pDs->ptPrev.x,pDs->ptPrev.y,NULL);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码LineTo(hdc,pDs->ptEnd.x,pDs->ptEnd.y);SetPixel(hdc,pDs->ptEnd.x,pDs->ptEnd.y,pDs->color);SelectObject(hdc,hPenOld);//增加的选出画笔的代码ReleaseDC(hWnd,hdc);SHAPESTR[iShNum].pSh=SHAPECURVE;SHAPESTR[iShNum].color=pDs->color;SHAPESTR[iShNum].iPenWidth=pDs->iPenWidth;//-----取得DRAWSHAPE对象以存储曲线的信息PDRAWCURVE pCurve;PDRAWSHAPE pShp;pShp=pDs->pCurShp;pCurve=(PDRAWCURVE)pShp->pData;pCurve=(PDRAWCURVE)SHAPESTR[iShNum].pData;pCurve->AddTail(pDs->ptEnd);pDs->g.AddTail(pShp);//-----新建DRAWSHAPE对象以存储曲线的信息}}void PenMouseMove( PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){hdc=GetDC(hWnd);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码MoveToEx(hdc,pDs->ptPrev.x,pDs->ptPrev.y,NULL);pDs->ptPrev.x=GET_X_LPARAM(lParam);pDs->ptPrev.y=GET_Y_LPARAM(lParam);LineTo(hdc,pDs->ptPrev.x,pDs->ptPrev.y);SelectObject(hdc,hPenOld);//增加的选出画笔的代码ReleaseDC(hWnd,hdc);SHAPESTR[iShNum].pSh=SHAPECURVE;    SHAPESTR[iShNum].color=pDs->color;    SHAPESTR[iShNum].iPenWidth=pDs->iPenWidth;//-----取得DRAWSHAPE对象以存储曲线的信息PDRAWCURVE pCurve;PDRAWSHAPE pShp;pShp=pDs->pCurShp;pCurve=(PDRAWCURVE)pShp->pData;pCurve=(PDRAWCURVE)SHAPESTR[iShNum].pData;pCurve->AddTail(pDs->ptPrev);//-----新建DRAWSHAPE对象以存储曲线的信息}}void LineMouseDown(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){pDs->ptStart.x=GET_X_LPARAM(lParam);pDs->ptStart.y=GET_Y_LPARAM(lParam);pDs->ptEnd.x=pDs->ptStart.x;pDs->ptEnd.y=pDs->ptStart.y;pDs->bMouseDown=TRUE;SetCapture(hWnd);}void LineMouseUp(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if (pDs->bMouseDown){pDs->bMouseDown=FALSE;ReleaseCapture();//该函数从当前线程中的窗口释放鼠标捕获,并恢复通常的鼠标输入处理hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);//用于设定当前前景色的混合模式。R2_NOT就是取反的意思,即前景色为背景色的反色,经常用R2_NOT来画橡皮线,因为两次取反可以还原背景色。MoveToEx(hdc,pDs->ptStart.x,pDs->ptStart.y,NULL);LineTo(hdc,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);SetROP2(hdc,R2_COPYPEN);//使用当前的画笔颜色HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码MoveToEx(hdc,pDs->ptStart.x,pDs->ptStart.y,NULL);LineTo(hdc,pDs->ptEnd.x,pDs->ptEnd.y);SelectObject(hdc,hPenOld);//增加的选出画笔的代码ReleaseDC(hWnd,hdc);iShNum++;SHAPESTR[iShNum].pSh=SHAPELINE;SHAPESTR[iShNum].ptStart=pDs->ptStart;SHAPESTR[iShNum].ptEnd=pDs->ptEnd;SHAPESTR[iShNum].color=pDs->color;
PDRAWSHAPE pShp;pShp=new DRAWSHAPE;pShp->color=pDs->color;pShp->shape=SHAPELINE;pShp->penWidth=pDs->iPenWidth;pShp->ptStart=pDs->ptStart;pShp->ptEnd=pDs->ptEnd;if((pDs->ptStart.x==pDs->ptEnd.x)&&(pDs->ptEnd.y==pDs->ptStart.y)){//如果起点与终点相同则删除线段delete pShp;}else{//存储线段pDs->g.AddTail(pShp);}//-----将新建DRAWSHAPE对象添加到g中}}void LineMouseMove(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){hdc=GetDC(hWnd);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码//SelectObject(hdc,pDs->hPen);SetROP2(hdc,R2_NOTXORPEN);MoveToEx(hdc,pDs->ptStart.x,pDs->ptStart.y,NULL);LineTo(hdc,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);MoveToEx(hdc,pDs->ptStart.x,pDs->ptStart.y,NULL);LineTo(hdc,pDs->ptEnd.x,pDs->ptEnd.y);ReleaseDC(hWnd,hdc);}}void RectMouseDown(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){pDs->ptStart.x=GET_X_LPARAM(lParam);pDs->ptStart.y=GET_Y_LPARAM(lParam);pDs->ptEnd.x=pDs->ptStart.x;pDs->ptEnd.y=pDs->ptStart.y;pDs->bMouseDown=TRUE;//-----新建DRAWSHAPE对象以存储矩形的信息//PDRAWRECT pRect;//PDRAWSHAPE pShp;//pShp=new DRAWSHAPE;////pDs->pCurShp=pShp;//pShp->color=pDs->color;//pShp->shape=SHAPERECT;//pShp->penWidth=pDs->iPenWidth;//pRect=new DRAWRECT;//pShp->pData=pRect;//pRect->rect.left=pDs->ptStart.x;//pRect->rect.top=pDs->ptStart.y;//pRect->rect.right=pDs->ptEnd.x;//pRect->rect.bottom=pDs->ptEnd.y;//pRect->bFill=pDs->bFill;////-----新建DRAWSHAPE对象以存储矩形的信息SetCapture(hWnd);}void RectMouseUp(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){pDs->bMouseDown=FALSE;ReleaseCapture();hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);pDs->hBr=CreateSolidBrush(pDs->color);HBRUSH hbrOld=(HBRUSH)SelectObject(hdc,pDs->hBr);if(pDs->bFill==false){    SelectObject(hdc,GetStockObject(NULL_BRUSH));}Rectangle(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);SetROP2(hdc,R2_COPYPEN);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码Rectangle(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);SelectObject(hdc,hPenOld);//增加的选出画笔的代码ReleaseDC(hWnd,hdc);iShNum++;SHAPESTR[iShNum].pSh=SHAPERECT;SHAPESTR[iShNum].bFill=pDs->bFill;SHAPESTR[iShNum].ptStart=pDs->ptStart;SHAPESTR[iShNum].ptEnd=pDs->ptEnd;SHAPESTR[iShNum].color=pDs->color;
PDRAWSHAPE pShp;pShp=new DRAWSHAPE;pShp->color=pDs->color;pShp->shape=SHAPERECT;pShp->penWidth=pDs->iPenWidth;pShp->ptStart=pDs->ptStart;pShp->ptEnd=pDs->ptEnd;pShp->bFill=pDs->bFill;if((pDs->ptStart.x==pDs->ptEnd.x)&&(pDs->ptEnd.y==pDs->ptStart.y)){//如果起点与终点相同则删除线段delete pShp;}else{//存储线段pDs->g.AddTail(pShp);}//-----将新建DRAWSHAPE对象添加到g中}}void RectMouseMove(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){hdc=GetDC(hWnd);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);SetROP2(hdc,R2_NOTXORPEN);pDs->hBr=CreateSolidBrush(pDs->color);HBRUSH hbrOld=(HBRUSH)SelectObject(hdc,pDs->hBr);if(pDs->bFill==false){    SelectObject(hdc,GetStockObject(NULL_BRUSH));}Rectangle(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);Rectangle(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);ReleaseDC(hWnd,hdc);}}void ElliMouseDown(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){pDs->ptStart.x=GET_X_LPARAM(lParam);pDs->ptStart.y=GET_Y_LPARAM(lParam);pDs->ptEnd.x=pDs->ptStart.x;pDs->ptEnd.y=pDs->ptStart.y;pDs->bMouseDown=TRUE;////-----新建DRAWSHAPE对象以存储圆的信息//PDRAWRECT pRect;//PDRAWSHAPE pShp;//pShp=new DRAWSHAPE;//pDs->pCurShp=pShp;//pShp->color=pDs->color;//pShp->shape=SHAPECIRCLE;//pShp->penWidth=pDs->iPenWidth;//pRect=new DRAWRECT;//pShp->pData=pRect;//pRect->rect.left=pDs->ptStart.x;//pRect->rect.top=pDs->ptStart.y;//pRect->rect.right=pDs->ptEnd.x;//pRect->rect.bottom=pDs->ptEnd.y;//pRect->bFill=pDs->bFill;////-----新建DRAWSHAPE对象以存储圆的信息}void ElliMouseUp(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){pDs->bMouseDown=FALSE;ReleaseCapture();hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);pDs->hBr=CreateSolidBrush(pDs->color);HBRUSH hbrOld=(HBRUSH)SelectObject(hdc,pDs->hBr);if(pDs->bFill==false){    SelectObject(hdc,GetStockObject(NULL_BRUSH));}Ellipse(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);SetROP2(hdc,R2_COPYPEN);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);//增加的画笔选择代码Ellipse(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);SelectObject(hdc,hPenOld);//增加的选出画笔的代码ReleaseDC(hWnd,hdc);iShNum++;SHAPESTR[iShNum].pSh=SHAPECIRCLE;SHAPESTR[iShNum].bFill=pDs->bFill;SHAPESTR[iShNum].ptStart=pDs->ptStart;SHAPESTR[iShNum].ptEnd=pDs->ptEnd;SHAPESTR[iShNum].color=pDs->color;PDRAWSHAPE pShp;pShp=new DRAWSHAPE;pShp->color=pDs->color;pShp->shape=SHAPECIRCLE;pShp->penWidth=pDs->iPenWidth;pShp->ptStart=pDs->ptStart;pShp->ptEnd=pDs->ptEnd;pShp->bFill=pDs->bFill;if((pDs->ptStart.x==pDs->ptEnd.x)&&(pDs->ptEnd.y==pDs->ptStart.y)){//如果起点与终点相同则删除线段delete pShp;}else{//存储线段pDs->g.AddTail(pShp);}}//-----将新建DRAWSHAPE对象添加到g中}void ElliMouseMove(PDRAWSTRU pDs,HWND hWnd,WPARAM wParam,LPARAM lParam){HDC hdc;if(pDs->bMouseDown){hdc=GetDC(hWnd);HPEN hPenOld=(HPEN)SelectObject(hdc,pDs->hPen);SetROP2(hdc,R2_NOTXORPEN);pDs->hBr=CreateSolidBrush(pDs->color);HBRUSH hbrOld=(HBRUSH)SelectObject(hdc,pDs->hBr);if(pDs->bFill==false){    SelectObject(hdc,GetStockObject(NULL_BRUSH));}Ellipse(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);pDs->ptEnd.x=GET_X_LPARAM(lParam);pDs->ptEnd.y=GET_Y_LPARAM(lParam);Ellipse(hdc,pDs->ptStart.x,pDs->ptStart.y,pDs->ptEnd.x,pDs->ptEnd.y);ReleaseDC(hWnd,hdc);}}
结构体数组的重绘操作:

void ShapeSelect(int i,HDC hdc){switch (SHAPESTR[i].pSh){case SHAPECURVE:{PDRAWCURVE pCurve=(PDRAWCURVE)(SHAPESTR[i].pData);POSITION pos;POINT pt;pos=pCurve->GetHeadPosition();//获取链表头部位置pt=pCurve->GetNext(pos);//获取该值,并且pos加一MoveToEx(hdc,pt.x,pt.y,NULL);while(pos){pt=pCurve->GetNext(pos);LineTo(hdc,pt.x,pt.y);}SetPixel(hdc,pt.x,pt.y,SHAPESTR[i].color);//该函数将指定坐标处的像素设为指定的颜色。}break;case SHAPELINE:    MoveToEx(hdc,SHAPESTR[i].ptStart.x,SHAPESTR[i].ptStart.y,NULL);    LineTo(hdc,SHAPESTR[i].ptEnd.x,SHAPESTR[i].ptEnd.y);break;case SHAPERECT:    if(SHAPESTR[i].bFill==false)    {        SelectObject(hdc,GetStockObject(NULL_BRUSH));    }    Rectangle(hdc,SHAPESTR[i].ptStart.x,SHAPESTR[i].ptStart.y,SHAPESTR[i].ptEnd.x,SHAPESTR[i].ptEnd.y);break;case SHAPECIRCLE:    if(SHAPESTR[i].bFill==false)    {        SelectObject(hdc,GetStockObject(NULL_BRUSH));    }    Ellipse(hdc,SHAPESTR[i].ptStart.x,SHAPESTR[i].ptStart.y,SHAPESTR[i].ptEnd.x,SHAPESTR[i].ptEnd.y);break;}}
列表的重绘操作:

 DrawShape(HDC hdc,PDRAWSHAPE &pShp){HPEN hPen,hOldPen;HBRUSH hBr,hOldBr;PDRAWCURVE pCurve;hPen=CreatePen(PS_SOLID,pShp->penWidth,pShp->color);hBr=CreateSolidBrush(pShp->color);hOldPen=(HPEN)SelectObject(hdc,hPen);switch(pShp->shape){case SHAPELINE:MoveToEx(hdc,pShp->ptStart.x,pShp->ptStart.y,NULL);LineTo(hdc,pShp->ptEnd.x,pShp->ptEnd.y);break;case SHAPECIRCLE:if(pShp->bFill){hOldBr=(HBRUSH)SelectObject(hdc,hBr);}else{hOldBr=(HBRUSH)SelectObject(hdc,GetStockObject(NULL_BRUSH));}Ellipse(hdc,pShp->ptStart.x,pShp->ptStart.y,pShp->ptEnd.x,pShp->ptEnd.y);SelectObject(hdc,hOldBr);break;case SHAPERECT:if(pShp->bFill){hOldBr=(HBRUSH)SelectObject(hdc,hBr);}else{hOldBr=(HBRUSH)SelectObject(hdc,GetStockObject(NULL_BRUSH));}Rectangle(hdc,pShp->ptStart.x,pShp->ptStart.y,pShp->ptEnd.x,pShp->ptEnd.y);SelectObject(hdc,hOldBr);break;case SHAPECURVE:{pCurve=(PDRAWCURVE)(pShp->pData);POSITION pos;POINT pt;pos=pCurve->GetHeadPosition();//获取链表头部位置pt=pCurve->GetNext(pos);//获取该值,并且pos加一MoveToEx(hdc,pt.x,pt.y,NULL);while(pos){pt=pCurve->GetNext(pos);LineTo(hdc,pt.x,pt.y);}SetPixel(hdc,pt.x,pt.y,pShp->color);//该函数将指定坐标处的像素设为指定的颜色。}break;}SelectObject(hdc,hOldPen);}VOID DrawGraphics(HDC hdc,GRAPHICS &g){POSITION pos;PDRAWSHAPE pShp;pos=g.GetHeadPosition();while(pos){pShp=g.GetNext(pos);DrawShape(hdc,pShp);}}
保存、打开和清除文件操作:

VOID SaveGraphic(LPCTSTR lpszFilename,GRAPHICS &g){INT iCount;SHORT iShape;SHAPE shape;POSITION pos;PDRAWSHAPE pShp;CFile File(lpszFilename,CFile::modeWrite|CFile::modeCreate);CArchive ar(&File,CArchive::store);PDRAWCURVE pCurve;iCount=g.GetCount();ar<<iCount;pos=g.GetHeadPosition();while(pos){pShp=g.GetNext(pos);shape=pShp->shape;iShape=(SHORT)shape;ar<<iShape;ar<<pShp->penWidth;ar<<pShp->color;switch(shape){case SHAPELINE:ar<<pShp->ptStart;ar<<pShp->ptEnd;break;case SHAPECIRCLE:case SHAPERECT:ar<<pShp->bFill;ar<<pShp->ptStart;ar<<pShp->ptEnd;break;case SHAPECURVE:pCurve=(PDRAWCURVE)pShp->pData;pCurve->Serialize(ar);break;}}}VOID OpenGraphic(LPCTSTR lpszFilename,GRAPHICS &g){INT iCount,i;SHORT iShape;SHAPE shape;PDRAWSHAPE pShp;CFile File(lpszFilename,CFile::modeRead);CArchive ar(&File,CArchive::load);PDRAWRECT pRect;PDRAWCURVE pCurve;ar>>iCount;//pos=g.GetHeadPosition();for(i=0;i<iCount;i++){pShp=new DRAWSHAPE;ar>>iShape;shape=pShp->shape=(SHAPE)iShape;ar>>pShp->penWidth;ar>>pShp->color;switch(shape){case SHAPELINE:ar>> pShp->ptStart;ar>>pShp->ptEnd;break;case SHAPECIRCLE:case SHAPERECT:pShp->pData=pRect=new DRAWRECT;ar>>pShp->bFill;ar>> pShp->ptStart;ar>>pShp->ptEnd;break;case SHAPECURVE:pShp->pData=pCurve=new DRAWCURVE;pCurve->Serialize(ar);break;}g.AddTail(pShp);}}VOID ClearGraphic(GRAPHICS &g){PDRAWSHAPE pShp;while(!(g.IsEmpty())){pShp=g.RemoveHead();delete pShp;}}
文件相关函数:

void PopFileInitialize (HWND hwnd){     static TCHAR szFilter[] = TEXT ("Text Files (*.TXT)\0*.txt\0")  \                               TEXT ("ASCII Files (*.ASC)\0*.asc\0") \                               TEXT ("All Files (*.*)\0*.*\0\0") ;          ofn.lStructSize       = sizeof (OPENFILENAME) ;     ofn.hwndOwner         = hwnd ;     ofn.hInstance         = NULL ;     ofn.lpstrFilter       = szFilter ;     ofn.lpstrCustomFilter = NULL ;     ofn.nMaxCustFilter    = 0 ;     ofn.nFilterIndex      = 0 ;     ofn.lpstrFile         = NULL ;          // Set in Open and Close functions     ofn.nMaxFile          = MAX_PATH ;     ofn.lpstrFileTitle    = NULL ;          // Set in Open and Close functions     ofn.nMaxFileTitle     = MAX_PATH ;     ofn.lpstrInitialDir   = NULL ;     ofn.lpstrTitle        = NULL ;     ofn.Flags             = 0 ;             // Set in Open and Close functions     ofn.nFileOffset       = 0 ;     ofn.nFileExtension    = 0 ;     ofn.lpstrDefExt       = TEXT ("txt") ;     ofn.lCustData         = 0L ;     ofn.lpfnHook          = NULL ;     ofn.lpTemplateName    = NULL ;}BOOL PopFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName){     ofn.hwndOwner         = hwnd ;     ofn.lpstrFile         = pstrFileName ;     ofn.lpstrFileTitle    = pstrTitleName ;     ofn.Flags             = OFN_HIDEREADONLY | OFN_CREATEPROMPT ;          return GetOpenFileName (&ofn) ;}BOOL PopFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName){     ofn.hwndOwner         = hwnd ;     ofn.lpstrFile         = pstrFileName ;     ofn.lpstrFileTitle    = pstrTitleName ;     ofn.Flags             = OFN_OVERWRITEPROMPT ;          return GetSaveFileName (&ofn) ;}