실험 설명 :
-
DRAW CIRCLR / DRAW RANCTANGLE을 선택하고 키보드의 오른쪽 / 왼쪽 / 위 / 아래 화살표를 누르면 CIRCLE / RANCTANGLE의 크기가 그에 따라 변경됩니다. (원 또는 직사각형 그리기를 선택하고 키보드를 클릭합니다. ↑ ↓ ← → 크기 변경)
-
그리고 MOVE CIRCLE / MOVE RANCTANGLE을 선택한 후 키보드의 오른쪽 / 왼쪽 / 위 / 아래 화살표를 누르면 CIRCLE / RANCTANGLE이 그에 따라 이동합니다. (MOVE CIRCLE / MOVE RANCTANGLE을 선택한 다음 오른쪽 / 왼쪽 / 위 / 아래를 누릅니다. 키보드의 화살표를 누르면 CIRCLE / RANCTANGLE이 그에 따라 이동합니다.)
-
ZOOM OUT / ZOOM IN을 선택하면 CIRCLE / RANCTANGLE의 크기가 그에 따라 변경됩니다.
소스 코드는 다음과 같습니다.
demo.cpp 파일
#include<windows.h>
#include<math.h>
#include"demo.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam);
HWND hWndMain;
HINSTANCE hInst;
RECT rect1 = {
100, 100, 100, 100};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
static TCHAR szAppName[] = TEXT ("DEMO");
MSG msg;
HACCEL hAccel;
WNDCLASS wndclass;
HWND hWnd;
HMENU hMenu;
hInst = hInstance;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;
if(!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT("This program requires Window NT!"), szAppName, MB_ICONERROR);
return 0;
}
hMenu = LoadMenu(hInstance,"MENU");
hWnd = CreateWindow(
szAppName,
TEXT("DEMO"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
hMenu,
hInstance,
NULL
);
hWndMain = hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hAccel = LoadAccelerators(hInstance, "Menu");
while(GetMessage(&msg, 0, 0, 0))
{
if(!TranslateAccelerator(hWndMain, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu1, hMenu2;
HDC hDC;
static BOOL bCircle = FALSE, bRect = FALSE;
static BOOL bMove = FALSE;
PAINTSTRUCT ps;
switch(iMessage)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_CIRCLE:
hMenu1 = GetMenu(hWnd);
CheckMenuItem(hMenu1, IDM_CIRCLE, MF_CHECKED);
CheckMenuItem(hMenu1, IDM_RECTANGLE, MF_UNCHECKED);
DeleteMenu(hMenu1, 1, MF_BYPOSITION);
//get the menu of drawing a circle
hMenu2=LoadMenu(hInst, "MENUCIR");
InsertMenu(hMenu1, 1, MF_POPUP | MF_BYPOSITION, (UINT)hMenu2, "CIRCLE(&c)");
DrawMenuBar(hWndMain);
bCircle = FALSE;
bRect = FALSE;
bMove = FALSE;
rect1.left = 100;
rect1.right = 100;
rect1.bottom = 100;
rect1.top = 100;
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_RECTANGLE:
hMenu1 = GetMenu(hWnd);
CheckMenuItem(hMenu1, IDM_CIRCLE, MF_UNCHECKED);
CheckMenuItem(hMenu1, IDM_RECTANGLE, MF_CHECKED);
DeleteMenu(hMenu1, 1, MF_BYPOSITION);
//Get the menu of drawing a rectangle
hMenu2=LoadMenu(hInst, "MENURECT");
InsertMenu(hMenu1, 1, MF_POPUP | MF_BYPOSITION, (UINT)hMenu2, "RECTANGLE(&r)");
DrawMenuBar(hWndMain);
bCircle = FALSE;
bRect = FALSE;
bMove = FALSE;
rect1.left = 100;
rect1.right = 100;
rect1.bottom = 100;
rect1.top = 100;
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_EXIT:
SendMessage(hWnd, WM_DESTROY, 0, 0);
break;
case IDM_DRAWCIRCLE:
bCircle = TRUE;
bRect = FALSE;
bMove = FALSE;
break;
case IDM_DRAWRECT:
bCircle = FALSE;
bRect = TRUE;
bMove = FALSE;
break;
case IDM_MOVECIRCLE:
bMove = TRUE;
break;
case IDM_MOVERECT:
bMove = TRUE;
break;
case IDM_ZOOMIN:
if(bCircle == TRUE || bRect == TRUE)
{
int nLength, nWidth;
nLength = abs(rect1.right - rect1.left);
nWidth = abs(rect1.top - rect1.bottom);
rect1.right = (int)(rect1.left + nLength * 1.2);
rect1.bottom = (int)(rect1.top + nWidth * 1.2);
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case IDM_ZOOMOUT:
if(bCircle == TRUE || bRect == TRUE)
{
int nLength, nWidth;
nLength = abs(rect1.right - rect1.left);
nWidth = abs(rect1.top - rect1.bottom);
rect1.right = (int)(rect1.left + nLength / 1.2);
rect1.bottom = (int)(rect1.top + nWidth / 1.2);
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case IDM_REDRAW:
bMove = FALSE;
rect1.left = 100;
rect1.right = 100;
rect1.top = 100;
rect1.bottom = 100;
InvalidateRect(hWnd, NULL, TRUE);
break;
}
break;
case WM_KEYDOWN:
//To move the circle or rectangle
if(bMove == TRUE)
{
if(wParam == VK_LEFT)
{
rect1.left -= 10;
rect1.right -= 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_RIGHT)
{
rect1.left += 10;
rect1.right += 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_UP)
{
rect1.top -= 10;
rect1.bottom -= 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_DOWN)
{
rect1.top+=10;
rect1.bottom+=10;
InvalidateRect(hWnd,NULL,TRUE);
}
}
//To zoom-in or zoom-out
else if(bCircle == TRUE || bRect == TRUE)
{
if(wParam == VK_RIGHT)
{
rect1.right += 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_DOWN)
{
rect1.bottom += 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_UP)
{
rect1.bottom -= 10;
InvalidateRect(hWnd, NULL, TRUE);
}
else if(wParam == VK_LEFT)
{
rect1.right -= 10;
InvalidateRect(hWnd, NULL, TRUE);
}
}
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
if(bCircle == TRUE)
Ellipse(hDC, rect1.left, rect1.top, rect1.right, rect1.bottom);
if(bRect == TRUE)
Rectangle(hDC, rect1.left, rect1.top, rect1.right, rect1.bottom);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
demo.h 파일
#define IDM_CIRCLE 10
#define IDM_RECTANGLE 11
#define IDM_EXIT 12
#define IDM_DRAWRECT 13
#define IDM_MOVERECT 14
#define IDM_ZOOMIN 15
#define IDM_ZOOMOUT 16
#define IDM_DRAWCIRCLE 17
#define IDM_MOVECIRCLE 18
#define IDM_REDRAW 19
demo.rc 리소스 스크립트 파일 :
결과는 다음과 같습니다 :
DRAW (F) 아래의 메뉴 컨트롤을 통해 원 또는 사각형을 그리거나 Ctrl + C 및 Ctrl + R을 통해 원 그리기 하위 메뉴에 들어갈 수 있습니다. 사각형을 입력합니다. 그리기 하위 메뉴