Thứ Ba, 11 tháng 5, 2010

ObjectDrag6

Bài này dùng hướng đối tượng, vẽ nhiều elip


// 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;
}

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