๋ฐ˜์‘ํ˜•

์†Œ๊ฐœ

Visual Studio 2015 MFC์—๋Š” ๋™์  ๋ ˆ์ด์•„์›ƒ(Dynamic Layout) ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ Dialog์˜ Resizing์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ Control๋“ค์˜ ํฌ๊ธฐ๊ฐ€ ์กฐ์ •๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ณด๋ฉด ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Dynamic Layout

๋ณดํ†ต ์ผ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ๋“ค์€ ์ด ๊ธฐ๋Šฅ์ด ๊ฑฐ์˜ ๋“ค์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ๋™์  ๋ ˆ์ด์•„์›ƒ์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ํ”„๋กœ๊ทธ๋žจ์„ ์ฐพ๊ธฐ๊ฐ€ ์–ด๋ ต์ฃ . ํ•˜์ง€๋งŒ ์žฅ๋น„ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋ณดํ†ต ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋‹ˆํ„ฐ ํฌ๊ธฐ(๋˜๋Š” ์œˆ๋„์šฐ ํ•ด์ƒ๋„)๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ๊ณ , ์ž‘์—…์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ทนํžˆ ๋“œ๋ฌผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์— ์ˆ˜๋งŽ์€ ์ปจํŠธ๋กค์ด ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋™์  ๋ ˆ์ด์•„์›ƒ์„ ์ ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์ด๋ผ ์—ฌ๊ฒจ์ง‘๋‹ˆ๋‹ค.

์ด๋ฒˆ ๋ณธ๋ฌธ์—์„œ๋Š” Visual Studio 2015 MFC ๊ธฐ์ค€, Dialog ํ”„๋กœ์ ํŠธ์—์„œ ๋ช‡ ๊ฐ€์ง€ ์ปจํŠธ๋กค์˜ ๋™์  ๋ ˆ์ด์•„์›ƒ ์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผํ•˜๊ธฐ

UI ์ปจํŠธ๋กค ๊ตฌ์„ฑ

MFC์—์„œ Dialog ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜๊ณ , ๋ฆฌ์†Œ์Šค ํŽธ์ง‘๊ธฐ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ปจํŠธ๋กค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค๋งŒ ์ถ”๊ฐ€ํ•˜๊ณ  ์ด๋ฒคํŠธ๋Š” ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์„ ๊ฒ๋‹ˆ๋‹ค.

UI ๊ตฌ์„ฑ

์ฐธ๊ณ ๋กœ, Dialog ์†์„ฑ ์ค‘ Border์˜ ๊ฐ’์€ Resizing์ž…๋‹ˆ๋‹ค. Resizing์œผ๋กœ ๋˜์–ด์žˆ์–ด์•ผ ํฌ๊ธฐ ์กฐ์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Dialog ์†์„ฑ

๋™์  ๋ ˆ์ด์•„์›ƒ ์„ค์ •

๋ฆฌ์†Œ์Šค ํŽธ์ง‘๊ธฐ์—์„œ ์ปจํŠธ๋กค์˜ ์†์„ฑ ์ค‘ ๋™์  ๋ ˆ์ด์•„์›ƒ ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ, ๋™์  ์ด๋™ ๋ฐ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฒˆ ์˜ˆ์ œ์—์„œ๋Š” ์ฝ”๋“œ์—์„œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์ปจํŠธ๋กค ์†์„ฑ

์•„๋ž˜์™€ ๊ฐ™์ด ๋™์  ๋ ˆ์ด์•„์›ƒ์„ ์„ค์ •ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์—๋Š” ์„ค์ • ๊ฐ€๋Šฅํ•œ ๋ช‡ ๊ฐ€์ง€ ์ด๋™ ๋ฐ ํฌ๊ธฐ ์กฐ์ • ์˜ต์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  manager->AddItem()์„ ํ†ตํ•ด ์ปจํŠธ๋กค์˜ ๋™์  ๋ ˆ์ด์•„์›ƒ ์˜ต์…˜๊ณผ ํ•จ๊ป˜ ๋“ฑ๋ก์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

void CExamDynamicLayoutDlg::SetupForDynamicLayout()
{
	// ๋™์  ๋ ˆ์ด์•„์›ƒ ํ™œ์„ฑํ™”.
	this->EnableDynamicLayout();
	
	/* ์ด๋™ ์˜ต์…˜ */
	// 1. ์ด๋™ํ•˜์ง€ ์•Š์Œ.
	auto move_none = CMFCDynamicLayout::MoveSettings{};
	// 2. X,Y ๋ฐฉํ–ฅ์œผ๋กœ 100% ๋น„์œจ ์ด๋™.
	auto move_both_100 = CMFCDynamicLayout::MoveSettings{};
	move_both_100.m_nXRatio = 100;
	move_both_100.m_nYRatio = 100;
	// 3. X ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ 100% ๋น„์œจ ์ด๋™.
	auto move_x_100 = CMFCDynamicLayout::MoveSettings{};
	move_x_100.m_nXRatio = 100;
	// 4. Y ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ 100% ๋น„์œจ ์ด๋™.
	auto move_y_100 = CMFCDynamicLayout::MoveSettings{};
	move_y_100.m_nYRatio = 100;
	/* ํฌ๊ธฐ ์กฐ์ • ์˜ต์…˜ */
	// 1. ํฌ๊ธฐ ์กฐ์ •ํ•˜์ง€ ์•Š์Œ.
	auto size_none = CMFCDynamicLayout::SizeSettings{};
	// 2. X,Y ๋ฐฉํ–ฅ์œผ๋กœ 100% ๋น„์œจ ํฌ๊ธฐ ์กฐ์ •.
	auto size_both_100 = CMFCDynamicLayout::SizeSettings{};
	size_both_100.m_nXRatio = 100;
	size_both_100.m_nYRatio = 100;
	// 3. X ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ 100% ๋น„์œจ ํฌ๊ธฐ ์กฐ์ •.
	auto size_x_100 = CMFCDynamicLayout::SizeSettings{};
	size_x_100.m_nXRatio = 100;
	// 4. Y ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ 100% ๋น„์œจ ํฌ๊ธฐ ์กฐ์ •.
	auto size_y_100 = CMFCDynamicLayout::SizeSettings{};
	size_y_100.m_nYRatio = 100;

	// Dialog์˜ ๋™์  ๋ ˆ์ด์•„์›ƒ ํฌ์ธํ„ฐ ํš๋“.
	auto manager = this->GetDynamicLayout();
	// ๋™์  ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ.
	manager->Create(this);
	// ๋™์  ๋ ˆ์ด์•„์›ƒ์— ๋“ฑ๋กํ•  ์ปจํŠธ๋กค ์ถ”๊ฐ€.
	manager->AddItem(IDC_GRP_FORM, move_none, size_both_100);
	manager->AddItem(IDC_EDIT_NAME, move_none, size_x_100);
	manager->AddItem(IDC_EDIT_AGE, move_none, size_x_100);
	manager->AddItem(IDC_BTN_SUBMIT, move_none, size_both_100);
}

์œ„ ํ•จ์ˆ˜๋Š” OnOnInitDialog()์— ์ถ”๊ฐ€ํ•˜์—ฌ, ๋‹ค์ด์–ผ๋กœ๊ทธ ์ดˆ๊ธฐํ™” ๋•Œ ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

BOOL CExamDynamicLayoutDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// ...

	// ๋™์  ๋ ˆ์ด์•„์›ƒ ์„ค์ •.
	SetupForDynamicLayout();
	
	return TRUE;  // ํฌ์ปค์Šค๋ฅผ ์ปจํŠธ๋กค์— ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด TRUE๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
}

์ด๋ ‡๊ฒŒ๋งŒ ํ•˜๋ฉด ๋‹ค์ด์–ผ๋กœ๊ทธ์— ๋™์  ๋ ˆ์ด์•„์›ƒ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ œ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์• ๋‹ˆ๋ฉ”์ด์…˜๊ณผ ๊ฐ™์ด, ์บก์…˜๋ฐ”๊นŒ์ง€ ๋ฆฌ์‚ฌ์ด์ง• ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋™์  ๋ ˆ์ด์•„์›ƒ ๋ฌธ์ œ

๊ดœ์ฐฎ๋‹ค๋ฉด ๋„˜์–ด๊ฐ€๋„ ๋˜์ง€๋งŒ, ์œ„์™€ ๊ฐ™์€ ํ˜„์ƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์†Œ ๋ฆฌ์‚ฌ์ด์ง• ํฌ๊ธฐ ์ง€์ •ํ•˜๊ธฐ

๋ฆฌ์‚ฌ์ด์ง• ์‹œ ์ตœ์†Œ ์‚ฌ์ด์ฆˆ๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๋‹ค์ด์–ผ๋กœ๊ทธ์˜ GetMinMaxInfo ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค ๋งˆ๋ฒ•์‚ฌ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๋งˆ๋ฒ•์‚ฌ๋Š” ctrl + shift + x ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋งˆ๋ฒ•์‚ฌ ํ™”๋ฉด

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ—ค๋”์— ์ตœ์†Œ ์˜์—ญ์„ ์œ„ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ , OnInitDialog()์—์„œ ์ตœ์ดˆ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ํ–ˆ์„ ๋•Œ์˜ ํฌ๊ธฐ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ํฌ๊ธฐ๋ฅผ ์ตœ์†Œ ์‚ฌ์ด์ฆˆ๋กœ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

// ํ—ค๋”์— ์ •์˜.
CRect m_rcMinimumDialog;

BOOL CExamDynamicLayoutDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	/...

	// ๋™์  ๋ ˆ์ด์•„์›ƒ ์„ค์ •.
	SetupForDynamicLayout();
	
	// ๋ฆฌ์‚ฌ์ด์ง• ์ตœ์†Œ ํฌ๊ธฐ๋ฅผ ์œ„ํ•œ ์˜์—ญ ํš๋“.
	GetClientRect(&m_rcMinimumDialog);
	CalcWindowRect(m_rcMinimumDialog);

	return TRUE;  // ํฌ์ปค์Šค๋ฅผ ์ปจํŠธ๋กค์— ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด TRUE๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
}

void CExamDynamicLayoutDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
	lpMMI->ptMinTrackSize.x = m_rcMinimumDialog.Width();
	lpMMI->ptMinTrackSize.y = m_rcMinimumDialog.Height();
}

๋งˆ์น˜๋ฉฐ

์ด๊ฒƒ์œผ๋กœ ๋™์  ๋ ˆ์ด์•„์›ƒ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋œ ๋‹ค์ด์–ผ๋กœ๊ทธ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ดค์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋„ ์ฒจ๋ถ€ํ•˜๋‹ˆ, ์ฐธ๊ณ ํ•˜์„ธ์š”.

Exam_DynamicLayout - Dialog.zip
0.13MB

์ฐธ๊ณ 

Dynamic Dialog Layout for MFC in Visual Studio C++ 2015

๋ฐ˜์‘ํ˜•