// ObjectDrag6.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// <==
enum {DRAW, MOVE};
#define dim(a) (sizeof(a)/sizeof(a[0]))
class CEllipse
{
int x1,y1,x2,y2;
COLORREF crColor;
int hatch;
public:
CEllipse(){Set(0,0,0,0); SetColor(RGB(0,0,255)); SetHatch(HS_DIAGCROSS);}
CEllipse(int _x1, int _y1, int _x2, int _y2)
{
Set(_x1,_y1,_x2,_y2);
SetColor(RGB(0,0,255));
SetHatch(HS_DIAGCROSS);
}
void Set(int _x1, int _y1, int _x2, int _y2, COLORREF cr, int h)
{
x1=_x1;y1=_y1;x2=_x2;y2=_y2;crColor = cr; hatch = h;
}
void Set(int _x1, int _y1, int _x2, int _y2)
{x1=_x1;y1=_y1;x2=_x2;y2=_y2;}
void Set1(int _x1, int _y1){x1=_x1;y1=_y1;}
void Set2(int _x2, int _y2){x2=_x2;y2=_y2;}
void SetColor(COLORREF cr){crColor = cr;}
void SetHatch(int h){hatch = h;}
bool IsInside(int x, int y);
void Draw(HDC hdc);
void Translate(int dx, int dy);
};
// ==>
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_OBJECTDRAG6, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_OBJECTDRAG6);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(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 = LoadIcon(hInstance, (LPCTSTR)IDI_OBJECTDRAG6);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_OBJECTDRAG6;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
// <==
void CEllipse::Draw(HDC hdc)
{
HBRUSH hbr;
hbr = CreateHatchBrush(hatch, crColor);
SelectObject(hdc, hbr);
Ellipse(hdc,x1,y1,x2,y2);
DeleteObject(hbr);
}
bool CEllipse::IsInside(int x, int y)
{
double a = (double(x2)-x1)/2, b = (double(y2)-y1)/2;
if (!a || !b) return false;
double xx = x - (double(x1)+x2)/2, yy = y - (double(y1)+y2)/2;
double xr = xx/a, yr = yy/b;
return xr*xr+yr*yr <= 1;
}
void CEllipse::Translate(int dx, int dy)
{
x1 += dx; y1 += dy;
x2 += dx; y2 += dy;
}
int FindEllipse(CEllipse ae[], int n, int x, int y)
{
for (int i = n-1; i >= 0; i--)
if (ae[i].IsInside(x,y))
return i;
return -1;
}
// ==>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
// <==
static int xc,yc,px,py;
//static CEllipse ae[MAX_ELLIPSE];
static HBRUSH hbr;
static HCURSOR hCursorMove, hCursorCross;
static HPEN hPenDot;
static COLORREF aCrTab[] =
{
RGB(0,255,0),
RGB(0, 255,255),
RGB(0,0,0),
RGB(255,0,0),
RGB(0,0,255),
RGB(255,255,0),
};
static int aHatch[] =
{
HS_HORIZONTAL,
HS_VERTICAL,
HS_FDIAGONAL,
HS_BDIAGONAL,
HS_CROSS,
HS_DIAGCROSS
};
int dx, dy, i;
static int curColor, curHatch = 5;
static INT flag = DRAW, nEllipse,nCur = -1;
RECT rt;
// ==>
switch (message)
{
// <==
case WM_CREATE:
GetClientRect(hWnd, &rt);
hCursorMove = LoadCursor(NULL, IDC_SIZEALL);
hCursorCross = LoadCursor(NULL, IDC_CROSS);
hPenDot = CreatePen(PS_DOT, 1, RGB(0,0,255));
break;
// ==>
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
// <==
case WM_CHAR:
switch(TCHAR(wParam))
{
case 'c':
case 'C':
++curColor %= dim(aCrTab);
break;
case 'h':
case 'H':
++curHatch %= dim(aHatch);
break;
}
break;
case WM_LBUTTONDOWN:
xc = LOWORD(lParam); yc = HIWORD(lParam);
if ((nCur = FindEllipse(ae, nEllipse, xc, yc)) >= 0)
{
flag = MOVE;
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
SetROP2(hdc, R2_NOTXORPEN);
ae[nCur].Draw(hdc);
SetCursor(hCursorMove);
SetCapture(hWnd);
}
else if (nEllipse < MAX_ELLIPSE)// DRAW
{
flag = DRAW;
ae[nEllipse].Set(xc,yc,xc,yc,aCrTab[curColor],aHatch[curHatch]);
hdc = GetDC(hWnd);
SetROP2(hdc, R2_NOTXORPEN);
ae[nEllipse].Draw(hdc);
SetCursor(hCursorCross);
SetCapture(hWnd);
nEllipse++;
}
else
flag = -1;
break;
case WM_MOUSEMOVE:
if (GetCapture() == hWnd)
{
if (flag == MOVE)
{
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
SetROP2(hdc, R2_NOTXORPEN);
ae[nCur].Draw(hdc);
px = xc; py = yc;
xc = LOWORD(lParam); yc = HIWORD(lParam);
dx = xc-px, dy = yc - py;
ae[nCur].Translate(dx,dy);
ae[nCur].Draw(hdc);
}
else if (flag == DRAW)
{
hdc = GetDC(hWnd);
SetROP2(hdc, R2_NOTXORPEN);
ae[nEllipse-1].Draw(hdc);
ae[nEllipse-1].Set2(LOWORD(lParam),HIWORD(lParam));
ae[nEllipse-1].Draw(hdc);
}
}
break;
case WM_LBUTTONUP:
if (GetCapture() == hWnd)
{
ReleaseCapture();
InvalidateRect(hWnd, NULL, TRUE);
}
break;
// ==>
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
// <==
for (i = 0; i < nEllipse; i++)
ae[i].Draw(hdc);
// ==>
EndPaint(hWnd, &ps);
// <==
wsprintf(buf, "Number of Ellipses: %d", nEllipse);
DrawText(hdc, buf, lstrlen(buf), &rt, DT_CENTER);
// ==>
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
Thứ Ba, 11 tháng 5, 2010
ObjectDrag6
Bài này dùng hướng đối tượng, vẽ nhiều elip
Đăng ký:
Đăng Nhận xét (Atom)
Không có nhận xét nào:
Đăng nhận xét
Hãy để lại tin nhắn của bạn nhé. Mình luôn muốn nghe ý kiến của bạn. Cám ơn bạn đã ghé thăm blog nha. See you