win32实现画图小程序
本周我们的三级项目是用win32完成一个画图软件。今天我们也进行一个总结。如果大家觉得下面表述不清,想直接看代码,可以到我的资源页下载源代码:http://download.csdn.net/download/mr_zhaoz/9849315。
该画图软件要求实现功能:颜色选择、工具选择、画笔宽度设置、画图进行保存和打开文件、调色板的停靠、工具栏和调色板的显示和隐藏
功能演示截图如下:
颜色选择
工具选择
画笔宽度设置
画图进行保存和打开文件
调色板的隐藏和显示
工具栏和调色板的停靠
创建了三个窗口,一个是主窗口,完成画板的主要操作;一个是调色板子窗口,用来进行画图颜色的选择和将选择颜色传给主窗口,完成颜色选择操作;另一个是工具栏窗口,用来进行画图工具的选择和将选择工具传给主窗口,完成工具选择操作。
方法一:在画图的同时,将参数存入列表中,重绘、保存、打开文件和清除窗口,都通过对这个列表进行调用来实现。
方法二:在画图时,将参数存入数组中,具体操作与方法一类似。
以下代码中,我两种方法都进行了编辑,但未区分,且方法二只完成了重绘、文件的相关操作未进行编写,还请读者注意。
主窗口的回调函数:
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) *.txt ") TEXT ("ASCII Files (*.ASC) *.asc ") TEXT ("All Files (*.*) *.* ") ; 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) ; }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。