本周我们的三级项目是用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<shape;
iShape=(SHORT)shape;
ar<penWidth;
ar<color;
switch(shape)
{
case SHAPELINE:
ar<ptStart;
ar<ptEnd;
break;
case SHAPECIRCLE:
case SHAPERECT:
ar<bFill;
ar<ptStart;
ar<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>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) ;
}