허세98 2021. 2. 2. 22:39
반응형

프로그램내용 :  선분 그리기 + 대화상자 기반 UI


-------------------------------------------------------------------------------------------

평가 :

- 사용자가 그린 선분들을 저장하고 다시 그린다(WM_PAINT처리) ---- C

- 대화상자의 콤보박스가 작동한다. ---- B

- 대화상자의 스크롤바가 작동한다.      ---- B+

- 대화상자의 미리보기완성           ---- A

#include <windows.h>
#include <tchar.h> //_ttoi
#include "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Mouse");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
	, LPSTR lpszCmdParam, int nCmdShow)
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst = hInstance;

	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	WndClass.hInstance = hInstance;
	WndClass.lpfnWndProc = WndProc;
	WndClass.lpszClassName = lpszClass;
	WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
	WndClass.style = CS_HREDRAW | CS_VREDRAW;// | CS_DBLCLKS;
	RegisterClass(&WndClass);

	hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, (HMENU)NULL, hInstance, NULL);
	ShowWindow(hWnd, nCmdShow);

	while (GetMessage(&Message, NULL, 0, 0)) {
		TranslateMessage(&Message);
		DispatchMessage(&Message);
	}
	return (int)Message.wParam;
}
//선의 위치, 색, 굵기 저장

void PaintWindow(HWND hwnd, int iColor, int iWidth)//선을 그리는 함수
{

	HPEN		hpen;
	HDC         hdc;


	hdc = GetDC(hwnd);
	hpen = CreatePen(PS_SOLID, iWidth, iColor);
	hpen = (HPEN)SelectObject(hdc, hpen);
	MoveToEx(hdc, 10, 10, NULL);
	LineTo(hdc, 130, 10);
	DeleteObject(SelectObject(hdc, hpen));
	ReleaseDC(hwnd, hdc);
}

void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)//선을 지우고 다시 그리는 함수
{
	InvalidateRect(hCtrl, NULL, TRUE); // Dialog box의 윈도우 프로스져인 AboutDlgProc이 아니라 
	UpdateWindow(hCtrl);               // static control의 숨겨진 WndProc으로 WM_PAINT 전달
	PaintWindow(hCtrl, iColor, iFigure);
}
typedef struct _line {
	POINT p[2];
	COLORREF pColor;
	int pWidth;
} line;

line lines[1000];
int iLines;
int sx, sy, oldx, oldy;
COLORREF iCurrentPenColor = RGB(0, 0, 255);
int iCurrentPenWidth = 8;
TCHAR* Items[] = { TEXT("Red"), TEXT("Green"), TEXT("Blue") };//콤보박스에 넣을 문자열
HWND hCombo, hWidth, hPaint;//윈도우 호출 시 사용 핸들 

//대화상자

BOOL CALLBACK DlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	int j;
	static COLORREF iColor;
	static int iWidth;
	switch (iMessage) {
	case WM_INITDIALOG:
		iColor = iCurrentPenColor;//iColor의 값은 iCorrentColor의 
		iWidth = iCurrentPenWidth;
		//자식 윈도우를 사용할 수 있는 핸들 지정
		hPaint = GetDlgItem(hDlg, IDC_STATIC2);
		SetFocus(GetDlgItem(hDlg, iColor));//현재 iColor의 색을 포커스 함
		hCombo = GetDlgItem(hDlg, IDC_COMBO1);
		hWidth = GetDlgItem(hDlg, IDC_SCROLLBAR1);
		//스크롤 바의 범위, 초기 스크롤바 커서 위치
		SetScrollRange(hWidth, SB_CTL, 0, 20, TRUE);
		SetScrollPos(hWidth, SB_CTL, iCurrentPenWidth, TRUE);
		//콤보 박스에 문자열 넣기
		for (int i = 0; i < 3; i++) {
			SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)Items[i]);
		}
		if (iCurrentPenColor == RGB(0, 0, 255))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Blue"));
		if (iCurrentPenColor == RGB(255, 0, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Red"));
		if (iCurrentPenColor == RGB(0, 255, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Green"));
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, FALSE);

		return TRUE;
	case WM_HSCROLL:
		iWidth = GetScrollPos((HWND)lParam, SB_CTL);

		switch (LOWORD(wParam)) {//자식
		case SB_LINELEFT://임시저장된값에서
			iWidth = max(0, iWidth - 1); //최소제어 0 
			break;
		case SB_LINERIGHT:
			iWidth = min(20, iWidth + 1);//최대제어 255
			break;
		case SB_PAGELEFT://스크롤의 오른쪽빈바
			iWidth = max(0, iWidth - 5);
			break;
		case SB_PAGERIGHT:
			iWidth = min(20, iWidth + 5);
			break;
		case SB_THUMBTRACK://끌었을때
			iWidth = HIWORD(wParam);//임지시저장 값은 커서 현재위치
			break;
		}
		
		SetScrollPos((HWND)lParam, SB_CTL, iWidth, TRUE);
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, NULL);
		iCurrentPenWidth = iWidth;
		PaintTheBlock(hPaint, iColor, iWidth);
		return TRUE;
	case WM_COMMAND://부모(대화상자)
		switch (LOWORD(wParam)) {
		case IDOK://자식(OK버튼)
			iCurrentPenColor = iColor;
			EndDialog(hDlg, IDOK);
			return TRUE;
		case IDCANCEL://자식(취소)
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		case IDC_COMBO1:
			switch (HIWORD(wParam))
			{
			case CBN_SELCHANGE:
				j = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
				if (j == 0)
				{
					iColor = RGB(255, 0, 0);
				}
				if (j == 1)
				{
					iColor = RGB(0, 255, 0);
				}
				if (j == 2)
				{
					iColor = RGB(0, 0, 255);
				}
				PaintTheBlock(hPaint, iColor, iWidth);
				break;
			}
			return TRUE;



		}
	case WM_PAINT:
		InvalidateRect(hDlg, NULL, TRUE);
		PaintTheBlock(hPaint, iColor, iWidth);

		break;
	}
	return FALSE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{

	static BOOL bNowDraw = FALSE;
	HPEN hPen;
	HDC hdc;
	PAINTSTRUCT ps;
	switch (iMessage) {
	case WM_CREATE:
		return 0;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDM_MENU:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
			break;
		}
		return 0;
	case WM_LBUTTONDOWN:
		lines[iLines].pColor = iCurrentPenColor;
		lines[iLines].pWidth = iCurrentPenWidth;
		sx = LOWORD(lParam);
		sy = HIWORD(lParam);
		oldx = sx;
		oldy = sy;
		lines[iLines].p[0].x = sx;
		lines[iLines].p[0].y = sy;
		bNowDraw = TRUE;
		return 0;
	case WM_MOUSEMOVE:
		if (bNowDraw) {
			hdc = GetDC(hWnd);
			SetROP2(hdc, R2_NOTXORPEN);
			hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, sx, sy, NULL);
			LineTo(hdc, oldx, oldy);
			oldx = LOWORD(lParam);
			oldy = HIWORD(lParam);
			MoveToEx(hdc, sx, sy, NULL);
			LineTo(hdc, oldx, oldy);
			ReleaseDC(hWnd, hdc);
		}
		return 0;
	case WM_LBUTTONUP:
		bNowDraw = FALSE;
		hdc = GetDC(hWnd);
		hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
		hPen = (HPEN)SelectObject(hdc, hPen);
		MoveToEx(hdc, sx, sy, NULL);
		LineTo(hdc, oldx, oldy);
		lines[iLines].p[1].x = oldx;
		lines[iLines].p[1].y = oldy;
		iLines++;
		ReleaseDC(hWnd, hdc);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		for (int i = 0; i < iLines; i++)
		{
			hPen = CreatePen(PS_SOLID, lines[i].pWidth, lines[i].pColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, lines[i].p[0].x, lines[i].p[0].y, NULL);
			LineTo(hdc, lines[i].p[1].x, lines[i].p[1].y);
		}
		EndPaint(hWnd, &ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

전역변수

typedef struct _line {
	POINT p[2];
	COLORREF pColor;
	int pWidth;
} line;

line lines[1000];
int iLines;
int sx, sy, oldx, oldy;
COLORREF iCurrentPenColor = RGB(0, 0, 255);
int iCurrentPenWidth = 8;
TCHAR* Items[] = { TEXT("Red"), TEXT("Green"), TEXT("Blue") };//콤보박스에 넣을 문자열
HWND hCombo, hWidth, hPaint;//윈도우 호출 시 사용 핸들 

line 구조체

  • POINT p[2]는 선의 시작점과 끝점을 저장
  • pColor는 선마다의 색을 저장
  • pWidth는 선마다의 넓이를 저장

iLines는 선의 갯수를 저장

  • sx, sy, oldx, oldy는 시작 선, 최종 선 좌표 저장

  • iCPC 선 색 저장

  • iCPW 선 굵기 저장

  • Items 콤보박스에 넣을 문자열

  • 핸들 컨트롤 호출 핸들asd

메인 윈도우

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{

	static BOOL bNowDraw = FALSE;
	HPEN hPen;
	HDC hdc;
	PAINTSTRUCT ps;
	switch (iMessage) {
	case WM_CREATE:
		return 0;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDM_MENU:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
			break;
		}
		return 0;
	case WM_LBUTTONDOWN:
		lines[iLines].pColor = iCurrentPenColor;
		lines[iLines].pWidth = iCurrentPenWidth;
		sx = LOWORD(lParam);
		sy = HIWORD(lParam);
		oldx = sx;
		oldy = sy;
		lines[iLines].p[0].x = sx;
		lines[iLines].p[0].y = sy;
		bNowDraw = TRUE;
		return 0;
	case WM_MOUSEMOVE:
		if (bNowDraw) {
			hdc = GetDC(hWnd);
			SetROP2(hdc, R2_NOTXORPEN);
			hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, sx, sy, NULL);
			LineTo(hdc, oldx, oldy);
			oldx = LOWORD(lParam);
			oldy = HIWORD(lParam);
			MoveToEx(hdc, sx, sy, NULL);
			LineTo(hdc, oldx, oldy);
			//ReleaseDC(hWnd, hdc);
		}
		return 0;
	case WM_LBUTTONUP:
		bNowDraw = FALSE;
		//hdc = GetDC(hWnd);
		hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
		hPen = (HPEN)SelectObject(hdc, hPen);
		MoveToEx(hdc, sx, sy, NULL);
		LineTo(hdc, oldx, oldy);
		lines[iLines].p[1].x = oldx;
		lines[iLines].p[1].y = oldy;
		iLines++;
		ReleaseDC(hWnd, hdc);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		for (int i = 0; i < iLines; i++)
		{
			hPen = CreatePen(PS_SOLID, lines[i].pWidth, lines[i].pColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, lines[i].p[0].x, lines[i].p[0].y, NULL);
			LineTo(hdc, lines[i].p[1].x, lines[i].p[1].y);
		}
		EndPaint(hWnd, &ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

메인 윈도우 지역변수

static BOOL bNowDraw = FALSE;
	HPEN hPen;
	HDC hdc;
	PAINTSTRUCT ps;

bNowDraw 마우스 선택 누르는 상태인지 저장하는 bool변수

  • 그리기 도구(펜)
  • 그리기 도구통
  • 그리는 도화지

WM_COMMAND

case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDM_MENU:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
			break;
		}
		return 0;

WM_COMMAND //부모윈도우(메인윈도우)에게 명령보내기

  • 메인윈도우에 IDM_MENU를 누르면 DialogBox를 여는 메시지를 보낸다.

WM_LBUTTONDOWN

case WM_LBUTTONDOWN:
		lines[iLines].pColor = iCurrentPenColor;
		lines[iLines].pWidth = iCurrentPenWidth;
		sx = LOWORD(lParam);
		sy = HIWORD(lParam);
		oldx = sx;
		oldy = sy;
		lines[iLines].p[0].x = sx;
		lines[iLines].p[0].y = sy;
		bNowDraw = TRUE;
		return 0;

WM_LBUTTONDOWN (iLine=0)

  • lines[0].pColor 전역변수에 현재의 색상값과 굵기값을 저장한다.
  • 클릭한 순간 x, y, oldx, oldy좌표를 저장
  • lines[0].p[0].x 전역변수에 시작하는 지점이 좌표를 저장
  • 왼쪽버튼을 누르고 있다는 신호를 주는 bNW를 변환

WM_MOUSEMOVE

case WM_MOUSEMOVE:
		if (bNowDraw) {
			hdc = GetDC(hWnd);
			SetROP2(hdc, R2_NOTXORPEN);
			hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, sx, sy, NULL);//선지우기
			LineTo(hdc, oldx, oldy);
			oldx = LOWORD(lParam);
			oldy = HIWORD(lParam);
			MoveToEx(hdc, sx, sy, NULL);//선그리기
			LineTo(hdc, oldx, oldy);
			ReleaseDC(hWnd, hdc);
		}
		return 0;

 왼쪽버튼이 누르고있다면(bND=T)

  • SetROP2(hdc, R2_NOTXORPEN) 배경과 그리기도구 일치확인 게이트

WM_LBUTTONUP

case WM_LBUTTONUP:
		bNowDraw = FALSE;
		hdc = GetDC(hWnd);
		hPen = CreatePen(PS_SOLID, iCurrentPenWidth, iCurrentPenColor);
		hPen = (HPEN)SelectObject(hdc, hPen);
		MoveToEx(hdc, sx, sy, NULL);
		LineTo(hdc, oldx, oldy);
		lines[iLines].p[1].x = oldx;
		lines[iLines].p[1].y = oldy;
		iLines++;
		ReleaseDC(hWnd, hdc);
		return 0;

왼쪽 버튼 클릭을 그만하면 

  • 누르고 있다는 신호인 bND를 F로
  • 선분을 그리고 lines[0]배열에 x y좌표를 저장
  • 선의 다음값을 지정해주기 위해 iLines++

WM_PAINT

case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		for (int i = 0; i < iLines; i++)
		{
			hPen = CreatePen(PS_SOLID, lines[i].pWidth, lines[i].pColor);
			hPen = (HPEN)SelectObject(hdc, hPen);
			MoveToEx(hdc, lines[i].p[0].x, lines[i].p[0].y, NULL);
			LineTo(hdc, lines[i].p[1].x, lines[i].p[1].y);
		}
		EndPaint(hWnd, &ps);
		return 0;

무효영역이 발생했을때

  • lines[]배열에 저장되어있는 선을 iLines의 갯수만큼 다시 그려준다.

대화상자 콜백 함수

BOOL CALLBACK DlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	int j;
	static COLORREF iColor;
	static int iWidth;
	switch (iMessage) {
	case WM_INITDIALOG:
		iColor = iCurrentPenColor;//iColor의 값은 iCorrentColor의 
		iWidth = iCurrentPenWidth;
		//자식 윈도우를 사용할 수 있는 핸들 지정
		hPaint = GetDlgItem(hDlg, IDC_STATIC2);
		SetFocus(GetDlgItem(hDlg, iColor));//현재 iColor의 색을 포커스 함
		hCombo = GetDlgItem(hDlg, IDC_COMBO1);
		hWidth = GetDlgItem(hDlg, IDC_SCROLLBAR1);
		//스크롤 바의 범위, 초기 스크롤바 커서 위치
		SetScrollRange(hWidth, SB_CTL, 0, 20, TRUE);
		SetScrollPos(hWidth, SB_CTL, iCurrentPenWidth, TRUE);
		//콤보 박스에 문자열 넣기
		for (int i = 0; i < 3; i++) {
			SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)Items[i]);
		}
		if (iCurrentPenColor == RGB(0, 0, 255))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Blue"));
		if (iCurrentPenColor == RGB(255, 0, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Red"));
		if (iCurrentPenColor == RGB(0, 255, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Green"));
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, FALSE);

		return TRUE;
	case WM_HSCROLL:
		TempPos = GetScrollPos((HWND)lParam, SB_CTL);

		switch (LOWORD(wParam)) {//자식
		case SB_LINELEFT://임시저장된값에서
			TempPos = max(0, iWidth - 1); //최소제어 0 
			break;
		case SB_LINERIGHT:
			TempPos = min(20, iWidth + 1);//최대제어 255
			break;
		case SB_PAGELEFT://스크롤의 오른쪽빈바
			TempPos = max(0, iWidth - 5);
			break;
		case SB_PAGERIGHT:
			TempPos = min(20, iWidth + 5);
			break;
		case SB_THUMBTRACK://끌었을때
			TempPos = HIWORD(wParam);//임지시저장 값은 커서 현재위치
			break;
		}
		if ((HWND)lParam == hWidth) iWidth = TempPos;
		SetScrollPos((HWND)lParam, SB_CTL, iWidth, TRUE);
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, NULL);
		iCurrentPenWidth = iWidth;
		PaintTheBlock(hPaint, iColor, iWidth);
		return TRUE;
	case WM_COMMAND://부모(대화상자)
		switch (LOWORD(wParam)) {
		case IDOK://자식(OK버튼)
			iCurrentPenColor = iColor;
			EndDialog(hDlg, IDOK);
			return TRUE;
		case IDCANCEL://자식(취소)
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		case IDC_COMBO1:
			switch (HIWORD(wParam))
			{
			case CBN_SELCHANGE:
				j = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
				if (j == 0)
				{
					iColor = RGB(255, 0, 0);
				}
				if (j == 1)
				{
					iColor = RGB(0, 255, 0);
				}
				if (j == 2)
				{
					iColor = RGB(0, 0, 255);
				}
				PaintTheBlock(hPaint, iColor, iWidth);
				break;
			}
			return TRUE;



		}
	case WM_PAINT:
		InvalidateRect(hDlg, NULL, TRUE);
		PaintTheBlock(hPaint, iColor, iWidth);

		break;
	}
	return FALSE;
}

대화상자 지역변수

	int j;
	static COLORREF iColor;
	static int iWidth;
  • 콤보박스 인덱스 값 j
  • 색상 값 iColor / 굵기 저장 iWidth

대화상자_INITDIALOG

switch (iMessage) {
	case WM_INITDIALOG:
		iColor = iCurrentPenColor;//iColor의 값은 iCorrentColor의 
		iWidth = iCurrentPenWidth;
		//자식 윈도우를 사용할 수 있는 핸들 지정
		hPaint = GetDlgItem(hDlg, IDC_STATIC2);
		hCombo = GetDlgItem(hDlg, IDC_COMBO1);
		hWidth = GetDlgItem(hDlg, IDC_SCROLLBAR1);
		//스크롤 바의 범위, 초기 스크롤바 커서 위치
		SetScrollRange(hWidth, SB_CTL, 0, 20, TRUE);
		SetScrollPos(hWidth, SB_CTL, iCurrentPenWidth, TRUE);
		//콤보 박스에 문자열 넣기
		for (int i = 0; i < 3; i++) {
			SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)Items[i]);
		}
		if (iCurrentPenColor == RGB(0, 0, 255))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Blue"));
		if (iCurrentPenColor == RGB(255, 0, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Red"));
		if (iCurrentPenColor == RGB(0, 255, 0))
			SetDlgItemText(hDlg, IDC_COMBO1, TEXT("Green"));
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, FALSE);

		return TRUE;

대화상자를 열었을때

  • iColor, iWidth의 초기값 설정
  • 대화상자의 컨트롤 핸들들 지정
  • 스크롤바의 초기 위치 지정
  • 콤보 박스에 문자열 넣기
  • if(iCPC==RGB)는 iCPC의 값에 따라 콤보박스에 표시할 텍스트를 알려줌
  • SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, FALSE) iWidth에 값을 IDC_STATIC1에 표기

대화상자_HSCROLL

case WM_HSCROLL:
		switch (LOWORD(wParam)) {//자식
		case SB_LINELEFT://임시저장된값에서
			iWidth = max(0, iWidth - 1); //최소제어 0 
			break;
		case SB_LINERIGHT:
			iWidth = min(20, iWidth + 1);//최대제어 255
			break;
		case SB_PAGELEFT://스크롤의 오른쪽빈바
			iWidth = max(0, iWidth - 5);
			break;
		case SB_PAGERIGHT:
			iWidth = min(20, iWidth + 5);
			break;
		case SB_THUMBTRACK://끌었을때
			iWidth = HIWORD(wParam);//임지시저장 값은 커서 현재위치
			break;
		}
		
		SetScrollPos((HWND)lParam, SB_CTL, iWidth, TRUE);
		SetDlgItemInt(hDlg, IDC_STATIC1, iWidth, NULL);
		PaintTheBlock(hPaint, iColor, iWidth);
		return TRUE;

스크롤이 움직일때마다 

  • iWidth의 값을 변경해주고
  • STATIC1의 값을 iWidth의 값으로 변경해준다.
  • 전역변수 iCPW의 값을 iWidth의 값으로 변경해준다.
  • PaintTheBlock 함수를 호출한다. (미리보기 그리는 함수)

대화상자_COMMAND

	case WM_COMMAND://부모(대화상자)
		switch (LOWORD(wParam)) {
		case IDOK://자식(OK버튼)
			iCurrentPenColor = iColor;
            iCurrentPenWidth = iWidth;
			EndDialog(hDlg, IDOK);
			return TRUE;
		case IDCANCEL://자식(취소)
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		case IDC_COMBO1:
			switch (HIWORD(wParam))
			{
			case CBN_SELCHANGE:
				j = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
				if (j == 0)
				{
					iColor = RGB(255, 0, 0);
				}
				if (j == 1)
				{
					iColor = RGB(0, 255, 0);
				}
				if (j == 2)
				{
					iColor = RGB(0, 0, 255);
				}
				PaintTheBlock(hPaint, iColor, iWidth);
				break;
			}
			return TRUE;
		}

부모 윈도우(대화상자)에게 자식 윈도우(OK, CANCEL, COMBO BOX)가 명령을 전달

  • ok를 눌러야 지역변수의 값이 전역변수로 넘어감
  • 취소를 누르면 지역변수의 값이 전역변수로 넘어가지 않는다
  • 콤보 박스를 눌렀을때\
  •   - 콤보박스가 또 어떤 이벤트(셀 선택변경)를 발생시키면
  •      -변경 시 j에 선택한 인덱스 값을 전달
  •      -if(j == 0) 선택된 인덱스 값이 0이면 레드
  • 미리보기 함수 호출
case WM_PAINT:
		InvalidateRect(hDlg, NULL, TRUE);
		PaintTheBlock(hPaint, iColor, iWidth);
		break;
  • 무효영역에 들어갔을 때 다시 그리기
  • 대화상자 전체를 지우고 다시 그림
  • 미리보기 함수 호출

미리보기 함수

void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)//선을 지우고 다시 그리는 함수
{
	InvalidateRect(hCtrl, NULL, TRUE); // Dialog box의 윈도우 프로스져인 AboutDlgProc이 아니라 
	UpdateWindow(hCtrl);               // static control의 숨겨진 WndProc으로 WM_PAINT 전달
	PaintWindow(hCtrl, iColor, iFigure);
}

InvalidateRect는 hCtrl=미리보기 컨트롤을 무효화 시킨다.  무효영역이 발생하면 항상 WM_PAINT메시지가 발생하므로 lnvalidateRect안에 WM_PAINT가 있다고 생각 할 수도 있지만 WM_PAINT메시지는 무효영역이 왔기때문에 실행될뿐이다. 

UpdataWindow함수를 사용하면 즉시 WM_PAINT메시지를 발생시킬 수 있다.

PaintWindow 함수 호출

PaintWindow 함수

void PaintWindow(HWND hwnd, int iColor, int iWidth)//선을 그리는 함수
{

	HPEN		hpen;
	HDC         hdc;


	hdc = GetDC(hwnd);
	hpen = CreatePen(PS_SOLID, iWidth, iColor);
	hpen = (HPEN)SelectObject(hdc, hpen);
	MoveToEx(hdc, 10, 10, NULL);
	LineTo(hdc, 130, 10);
	DeleteObject(SelectObject(hdc, hpen));
	ReleaseDC(hwnd, hdc);
}

선을 그리는 함수이다.

 

반응형