#include <windows.h>
#include "resource.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
HINSTANCE g_hInstance;
int g_nToolID = 0;
struct tagLine
{
POINT ptB;
POINT ptE;
bool bIsDelete;
};
tagLine g_AllLines[100];//直線數組
int g_nLineNumber = 0; //實際直線數
struct tagCircle
{
POINT ptCenter;
int nRadius;
bool bIsDelete;
};
tagCircle g_AllCircles[100];//整圓數組
int g_nCircleNumber = 0; // 實際保存的圓個數
POINT pt1 = {200,200};
POINT pt2 = {200,200};
POINT pt3 = {0,0};
int g_nState = 0;
//功能:畫壹線直線段
void DrawLine(HDC hDC,POINT ptB,POINT ptE)
{
::MoveToEx(hDC,ptB.x,ptB.y,NULL);
::LineTo(hDC,ptE.x,ptE.y);
}
//功能:已知兩點求距離
int Distance(POINT pt1,POINT pt2)
{
int nR = 0;
nR=sqrt((pt1.x - pt2.x)*(pt1.x - pt2.x) +(pt1.y - pt2.y)*(pt1.y- pt2.y));
return nR;
}
void DrawCircle(HDC hDC,POINT ptC,int nR)
{
::Ellipse(hDC,ptC.x - nR,ptC.y - nR,ptC.x + nR,ptC.y + nR);
}
void OnMouseMove(POINT ptPos,HWND hWnd)
{
if(g_nToolID == ID_CIRCLE)
{
if(g_nState == 1)
{
HDC hDC = ::GetDC(hWnd);
//取得系統預定義壹個“空心刷子”
HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
::SelectObject(hDC,hBrush);
::SetROP2(hDC,R2_NOTXORPEN);
DrawLine(hDC,pt1,pt2);
int nR = Distance(pt1,pt2);
DrawCircle(hDC,pt1,nR);
pt3 = ptPos;
nR = Distance(pt1,pt3);
DrawCircle(hDC,pt1,nR);
DrawLine(hDC,pt1,pt3);
pt2 = pt3;
::ReleaseDC(hWnd,hDC);
}
}else if(g_nToolID == ID_LINE)
{
if(g_nState == 1)
{
HDC hDC = ::GetDC(hWnd);
pt3=ptPos;
//用背景色,繪制上壹次的位置==>擦除
::SetROP2(hDC,R2_NOTXORPEN);
::DrawLine(hDC,pt1,pt2);
::DrawLine(hDC,pt1,pt3);
pt2 = pt3;
::ReleaseDC(hWnd,hDC);
}
}
}
void OnLButtonUp(POINT ptPos)
{
if(g_nToolID == ID_CIRCLE)
{
if(g_nState == 1)
{
tagCircle aCir;
aCir.ptCenter = pt1;
aCir.nRadius = Distance(pt1,ptPos);
aCir.bIsDelete = false;
g_AllCircles[g_nCircleNumber] = aCir;
g_nCircleNumber = g_nCircleNumber + 1;
g_nState = 0;
}
}else if(g_nToolID == ID_LINE)
{
if(g_nState == 1)
{
g_nState = 0;
tagLine aLine;
aLine.ptB = pt1;
aLine.ptE = pt3;
aLine.bIsDelete = false;
g_AllLines[g_nLineNumber] = aLine;
g_nLineNumber = g_nLineNumber + 1;
}
}
}
//功能:判斷點是否在直線段上
bool PtOnCircle(POINT pt,POINT ptC,int nR)
{
int nL = Distance(pt,ptC);
if( fabs(nL - nR) < 5 )
{
return true;
}else
{
return false;
}
}
//功能:判斷點是否在直線段上
bool PtOnLine(POINT pt,POINT ptB,POINT ptE)
{
int nL1 = Distance(pt,ptB);
int nL2 = Distance(pt,ptE);
int nL3 = Distance(ptB,ptE);
if( fabs(( nL1 + nL2 ) - nL3) < 5 )
{
return true;
}else
{
return false;
}
}
void OnLButtonDown(HWND hWnd,POINT ptPos)
{
if(g_nToolID == ID_CIRCLE)
{
if(g_nState == 0)
{
g_nState = 1;
pt2 = pt1 = ptPos;
}
}else if(g_nToolID == ID_LINE)
{
if(g_nState == 0)
{
g_nState = 1;
pt2 = pt1 = ptPos;
}
}else if(g_nToolID == ID_DELETE)
{
//判斷當前鼠標點是否在某壹個直線段上
for(int nI = 0; nI < g_nLineNumber; nI = nI + 1)
{
tagLine* pLine = &g_AllLines[nI];
if(PtOnLine(ptPos,(*pLine).ptB,(*pLine).ptE))
{
char cTxt[100];
sprintf(cTxt,"nI = %d\n",nI);
::OutputDebugString(cTxt);
(*pLine).bIsDelete = true;
break;
}
}
//判斷當前鼠標點是否在某壹個圓上
for(nI = 0; nI < g_nCircleNumber; nI = nI + 1)
{
tagCircle* pCircle = &g_AllCircles[nI];
if(PtOnCircle(ptPos,(*pCircle).ptCenter,(*pCircle).nRadius))
{
(*pCircle).bIsDelete = true;
break;
}
}
::InvalidateRect(hWnd,NULL,TRUE);
}
}
void OnPaint(HDC hDC)
{
// 1.重繪圓
//取得系統預定義壹個“空心刷子”
HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
::SelectObject(hDC,hBrush);
for(int nI = 0; nI < g_nCircleNumber; nI++)
{
tagCircle aCir;
aCir = g_AllCircles[nI];
if(aCir.bIsDelete == false)
{
DrawCircle(hDC,aCir.ptCenter,aCir.nRadius);
}
}
// 2.重繪直線段
for(nI = 0; nI < g_nLineNumber; nI = nI + 1)
{
tagLine aLine = g_AllLines[nI];
if(aLine.bIsDelete == false)
{
::DrawLine(hDC,aLine.ptB,aLine.ptE);
}
}
}
void OnCommand(HWND hWnd,int nCmdID)
{
switch(nCmdID)
{
case ID_EXIT:
::DestroyWindow(hWnd);
break;
case ID_LINE:
g_nToolID = ID_LINE;
break;
case ID_CIRCLE:
g_nToolID = ID_CIRCLE;
break;
case ID_DELETE:
g_nToolID = ID_DELETE;
break;
}
}
// 窗口回調函數
int WndProc(HWND hWnd,
int message,
int wParam,
int lParam)
{
switch (message)
{
case WM_SETCURSOR:
{
HCURSOR hCur1 = ::LoadCursor(g_hInstance,"pen_cursor");
HCURSOR hCur2 = ::LoadCursor(g_hInstance,"hand_cursor");
HCURSOR hCur3 = ::LoadCursor(g_hInstance,"point_cursor");
HCURSOR hCur4 = ::LoadCursor(g_hInstance,"arrow_cursor");
switch(g_nToolID)
{
case ID_LINE:
::SetCursor(hCur1);
break;
case ID_CIRCLE:
::SetCursor(hCur2);
break;
case ID_DELETE:
::SetCursor(hCur3);
break;
default:
::SetCursor(hCur1);
}
break;
}
case WM_COMMAND:
{
int nID = LOWORD(wParam);
OnCommand(hWnd,nID);
break;
}
case WM_LBUTTONDOWN:
{
POINT ptPos;
ptPos.x = LOWORD(lParam);
ptPos.y = HIWORD(lParam);
OnLButtonDown(hWnd,ptPos);
}
break;
case WM_LBUTTONUP:
{
POINT ptPos;
ptPos.x = LOWORD(lParam);
ptPos.y = HIWORD(lParam);
OnLButtonUp(ptPos);
}
break;
case WM_MOUSEMOVE:
{
POINT ptPos;
ptPos.x = LOWORD(lParam);
ptPos.y = HIWORD(lParam);
OnMouseMove(ptPos,hWnd);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = ::BeginPaint(hWnd,&ps);
OnPaint(hDC);
::EndPaint(hWnd,&ps);
break;
}
case WM_DESTROY: //窗口關閉時發送
::PostQuitMessage(0); //在消息隊列的尾部添加壹個0消息,以示,結束程序
break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
char* lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = "menu1";
wcex.lpszClassName = "ABCDE";
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
HWND hWnd = CreateWindow("ABCDE",
"WanJie",
WS_OVERLAPPEDWINDOW,
50, 50, //(x,y)
500, 500, // (w,h)
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd,SW_SHOW);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
return 1;
}