[windowsAPI] 7주차, 대화상자 다루기


교내 전공과목인 윈도우즈 API수업을 정리합니다

 

 

 

1. str을 원하는 위치와 내용을 띄울 수 있는 대화상자를 만들자

(0). 리소스 설정

  • EditControl, StaticEditor 배치
  • IDM_X, IDM_Y, IDM_STR로 동작할 예정

 

(1) 소스코드

#include "resource.h"  // 리소스 적용하기 위한 헤더파일 적용


// WinMain >
	WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //배경색 칠하기
    
// 전역변수
HWND hWNdMain;
int x, y;
TCHAR str[128];

// InfoDlgProc 작성
BOOL CALLBACK InfoDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	switch (iMessage) {
	case WM_INITDIALOG: // WM_CREATE
		SetDlgItemText(hDlg, IDC_STR, str);
		SetDlgItemInt(hDlg, IDC_X, x, FALSE);
		SetDlgItemInt(hDlg, IDC_Y, y, FALSE);
		return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDOK:
			GetDlgItemText(hDlg, IDC_STR, str, 128);
			x = GetDlgItemInt(hDlg, IDC_X, NULL, FALSE);
			y = GetDlgItemInt(hDlg, IDC_Y, NULL, FALSE);
			EndDialog(hDlg, IDOK); //OK버튼을 누르면 종료할 수 있게 만듦
			// IODK는 InfoDlgpro() 대화상자 procedure의 return값
			return TRUE;
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		}
		break;
	}
	return FALSE;
}

// 동작 작성
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
	HDC hdc;
	PAINTSTRUCT ps; 

	switch (iMessage) {
	case WM_CREATE:
		hWndMain = hWnd;
		x = 100;
		y = 100;
		lstrcpy(str, TEXT("String"));
		return 0;

	case WM_PAINT: 
		hdc = BeginPaint(hWnd, &ps);
		TextOut(hdc, x, y, str, lstrlen(str));
		EndPaint(hWnd, &ps);
		return 0;

	case WM_LBUTTONDOWN:
		if (DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, InfoDlgProc) == IDOK)
			InvalidateRect(hWnd, NULL, TRUE);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}​
  •  GetStockObject( int fnObject);
    이 함수로 핸들을 구해 언제나 사용가능, 파괴시켜 주지 않아도 됨. 스톡 오브젝트(브러쉬)를 구해 윈도우 클래스의 배경 브러시로 지정함. 여기서는 윈도우의 배경을 지울 필요가 있으면 브러쉬를 통해 배경을 흰색으로 채색 
    - fnObject : 사용하고자 하는 스톡 오브젝트를 지정한다. 다음 중 하나를 지정한다.
  • DialogBox( HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc );
    대화상자를 실행, 대화상자가 완전히 종료되면 리턴함.
    - hInstance : 대화상자 템플리트를 가진 인스턴스 핸들. 이 함수를 호출하는 프로세스에 리소스가 정의되어 있으면 WinMain으로 전달된 hInstance값을 넘겨준다. 다른 DLL이나 실행 파일에 리스스가 있을 경우 해당 모듈의 인스턴스 핸들을 넘겨준다.
    - lpTemplate : 대화상자 템플리트의 ID이다. 널종료 문자열로 정의된 템플리트의 이름이거나 정수형의 ID이다. 만약 대화상자 템플리트가 정수형으로 정의되어 있을 경우 MAKEINTRESOURCE 매크로 함수로 ID를 지정해 준다.
    - hWndParent : 이 대화상자를 소유하는 오너 윈도우의 핸들이다. 이 핸들이 지정하는 윈도우는 모달 대화상자가 실행중인 동안에 사용 금지된다.
    - lpDialogFunc : 대화상자로 전달되는 메시지를 처리하는 메시지 처리 함수의 포인터를 지정한다. 이 함수는 반드시 다음과 같은 원형으로 선언되어야 한다.

  • MAKEINTRESOURCE() : Make int Resource, 캐스팅매크로
    리소스의 ID에 문자열(겹따옴표이용)을 대입하지 않았을 경우(편집기에 의해 매크로 정수를 사용할 경우), 정수 타입의 리소스ID를 문자열 포인터에 대입불가. 그럴 때 사용
    => 말이 복잡한데 리소스ID를 정수타입에서 문자열로 바꿔줄 거라구.

(2)실행화면

지정한 위치에 지정한 문자열을 띄우는 동작을 수행함

 

 

2. 대화상자를 통한 선그리기(선굵기, 선색상) 제어를 하자

(0). 리소스 생성

  • Dialog: 라디오버튼, 리스트박스 설정
  • Menu: PopUp을 False, ID를 ID_DIALOG로 변경

(1). 소스코드

#include <windows.h>
#include "resource.h"  // 리소스 적용하기 위한 헤더파일 적용

// WinMain >
	//WndClass.lpszMenuName = NULL;
	WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); // 대화상자 메뉴바
    
// 구조체, 전역변수
typedef struct _line {
	POINT p[1000];
	int iPointCount;
	COLORREF penColor;
	int iPenWidth;
} line;
line lines[500];
int iLineCount;

COLORREF CurrentPenColor = RGB(255, 0, 0);
int iCurrentPenWidth = 2;
TCHAR* Items[] = { TEXT("2"), TEXT("4"), TEXT("6"), TEXT("8") };
HWND hRadioR, hRadioG, hRadioB, hList;

// DlgProc 작성
BOOL CALLBACK DlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) {
	static COLORREF iColor; // 대화상자 내의 선택된 선 색
	static int iWidth; // 대화상자 내의 선택된 선 굵기
	int i;

	switch (iMessage) {
	case WM_INITDIALOG: // WM_CREATE
		iColor = CurrentPenColor;
		iWidth = iCurrentPenWidth;

		hRadioR = GetDlgItem(hDlg, IDC_RADIO1);
		hRadioG = GetDlgItem(hDlg, IDC_RADIO2);
		hRadioB = GetDlgItem(hDlg, IDC_RADIO3);
		hList = GetDlgItem(hDlg, IDC_LIST1);

		if (CurrentPenColor == RGB(255, 0, 0))
			CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1);
		else if (CurrentPenColor == RGB(0, 255, 0))
			CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO2);
		else if (CurrentPenColor == RGB(0, 0, 255))
			CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO3);

		for (i = 0; i < 4; i++) {
			SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)Items[i]);
		}
		SendMessage(hList, LB_SETCURSEL, iWidth / 2 - 1, 0);
		return TRUE;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {

			/* 라디오 버튼 동작*/
		case IDC_RADIO1:
			iColor = RGB(255, 0, 0);
			break;
		case IDC_RADIO2:
			iColor = RGB(0, 255, 0);
			break;
		case IDC_RADIO3:
			iColor = RGB(0, 0, 255);
			break;

			/* listBox 동작*/
		case IDC_LIST1:
			switch (HIWORD(wParam)) {
			case LBN_SELCHANGE: //리스트 선택시
				i = SendMessage(hList, LB_GETCURSEL, 0, 0); //선택 정보를 i에 저장
				iWidth = (i + 1) * 2;
				break;
			}
			break;

			/* 대화상자 설정 정보 수락*/
		case IDOK:
			CurrentPenColor = iColor;
			iCurrentPenWidth = iWidth;
			EndDialog(hDlg, IDOK);
			return TRUE;
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		}
		break;
	}
	return FALSE;
}

// WndProc >
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) {
	HDC hdc;
	PAINTSTRUCT ps;
	static int x, y;
	HPEN hPen;

	switch (iMessage) {
	case WM_COMMAND:
		switch(LOWORD(wParam)) {
		case IDM_DIALOG:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
		}
		return 0;
    
	// WM_KEYDOWN 생략
	// WM_LBUTTONDOWN 생략
	// WM_MOUSEMOVE 생략
	// WM_LBUTTONUP 생략
	// WM_LBUTTONDBCLK 생략
	// WM_PAINT 생략
	// WM_DESTROY 생략

	return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

 

(2). 실행화면

 

# 대화박스 리소스에서 TAP 포커싱 조절하기

(1) 리소스> 다이얼로그> 상단메뉴 서식 > 탭순서(Ctrl + D)
(2) 리소스 > 그룹 내 첫번재 항목(RED라디오버튼) > 속성 > Group :TRUE 설정  => 그룹 내항목을 순회함

 

 

 

 

마지막 포스팅은 ScrollBar 다루기