
MFC 파일에서 RC 파일을 편집하다 보면 사이즈를 정확하게 Pixel 단위로 맞춰야 하는 경우가 있다.
많은 초보 프로그래머 들이

오른쪽 하단에 적힌 단위로 크기 조절을 하면 된다고 생각하지만
이는
pixel이 아닌 DLU 라는 단위로서
폰트 평균 높이 값이 8이고 평균 높이 값이 4일때 1DLU = 1pixel 인 되는 경우가 있고 이도 해상도에 따라 달라질수 있으며
https://devblogs.microsoft.com/oldnewthing/20180510-00/?p=98725
On the difficulty of getting pixel-perfect layout in Win32 dialog templates
That's not what it's for.
devblogs.microsoft.com
위에 있는 25년차 마이크로소프트 개발자 글에 따르면
DLU는 폰트 캐릭터 높이의 평균 1/8 값이고 폰트 너비의 1/4값이고 이또한 라운딩을 통해 구현하였기 때문에 정확한 값이 아니라고 한다. 또한 해상도에 따라 폰트 높이가 바뀔수 있고 폰트 substitution이나 폰트 linking으로 변경 될수 있다고 한다.
"Dialog boxes are not intended for pixel-perfect layout"
다이얼로그 박스는 픽셀 완벽 레이아웃을 염두해두고 만든것이 아니라고 한다.
(의역을 하였기 때문에 정확한 내용은 위에 글을 참조하기 바랍니다)
따라서 해당 RC 파일을 보고 스크린샷을 통해 실행 윈도우의 크기를 재다가 폰트를 변경하고 또 다시 재는 무한 반복작업을 할 것이 아니고
필자가 생각하기에는
RC 파일로는 대략적인 윤곽만 잡고
윈도우가 생성되는 시점에
예를 들어 Init Dlg 를 하는 곳에
런타임에 윈도우
실행될때 윈도우 크기를 조절 할수 있도록
함수를 쓰는게 적당하다는 생각이 든다.
예를 들면 다이얼로그 윈도우 사이즈와 위치를 직접 아래와 같은 사이즈로 정한다.
MoveWindow(int x, int y, int Width, int Height);
클래스 마법사에서 OninitDialog() 추가후
외부 사이즈를 100 x 100 으로 설정한 박스를 만들어 보았다.

테두리에 프레임 때문에 그런지
86 px X 93 px이 나온다.
그렇다면 테두리 프레임을 제거해보자

프레임 제거후 외부 사이즈를 100 X 100 픽셀로 정한 about 박스이다.

정확하게
100 x 100 px 이다

나는 프레임이 필요하다
일단 폰트 사이즈를 변경해 보겠다.
12 픽셀로 변경하였다.


이번에는 15px 8px이 더 필요하다고 한다.
8픽셀일때는 14 px 6px이였는데....
16픽셀일때도 15px 8px이다
생각해보니까 내가 왜 그림판을 사용하고 있지? 라는 생각이 들었다
비쥬얼 스튜디오 도구-> SPY++를 사용해서 창을 분석해 보았다.

클라이언트 영역이 84 x 61을 차지하고 있다고 한다.
이는 생각해보면
BOOL GetClientRect(
HWND hWnd,
LPRECT lpRect
);
GetClientRect를 사용해서
클라이언트 영역 너비와 높이를 구하고
원했던 100에 차이 만큼 더해주면 완벽진다.

정확하게 100px 100px이 되다
코드는 다음과 같다
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
this->SetWindowPos(NULL, 0, 0, 100, 100, SWP_NOMOVE);
CRect rc;
this->GetClientRect(&rc);
//TRACE("rc.left : %d\n", rc.left);
//TRACE("rc.top : %d\n", rc.top);
//TRACE("rc.width(): %d\n", rc.Width());
//TRACE("rc.height() : %d\n", rc.Height());
if (rc.Width() != 100 || rc.Height() != 100)
{
int tempModifiedWidth = 100 + (100 - rc.Width());
int tempModifiedHeight = 100 + (100 - rc.Height());
this->SetWindowPos(NULL, 0, 0, tempModifiedWidth, tempModifiedHeight, SWP_NOMOVE);
}
return TRUE;
}
자 이제 500 x 500 으로 바꿔보고 내부도 꾸며 보았다.
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//CWnd* AboutDlg = GetDlgItem(IDD_ABOUTBOX);
this->SetWindowPos(NULL, 0, 0, 500, 500, SWP_NOMOVE);
CRect rc;
this->GetClientRect(&rc);
//TRACE("rc.left : %d\n", rc.left);
//TRACE("rc.top : %d\n", rc.top);
//TRACE("rc.width(): %d\n", rc.Width());
//TRACE("rc.height() : %d\n", rc.Height());
if (rc.Width() != 500 || rc.Height() != 500)
{
int tempModifiedWidth = 500 + (500 - rc.Width());
int tempModifiedHeight = 500 + (500 - rc.Height());
this->SetWindowPos(NULL, 0, 0, tempModifiedWidth, tempModifiedHeight, SWP_NOMOVE);
}
this->GetDlgItem(IDOK)->SetWindowPos(NULL, 200, 200, 100, 100, NULL);
// 이미지
this->GetDlgItem(IDC_STATIC_03)->SetWindowPos(NULL, 0, 0, 100, 100, NULL);
this->GetDlgItem(IDC_STATIC_01)->SetWindowPos(NULL, 300, 300, 200, 100, NULL);
this->GetDlgItem(IDC_STATIC_02)->SetWindowPos(NULL, 300, 350, 200, 100, NULL);
this->SetWindowText(_T("My Name")); // Initialize control values
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
정확하게 500 x 500 픽셀이며
내부에 있는 이미지들도 정확한 위치에
잘 들어가게 되었다

이로서 쉽고 빠르게 MFC UI를 클라이언트(고객)의 요구에 맞게 픽셀 단위로 수정할수 있게 되었다.
해피 엔딩 ㅋㅋㅋㅋ
국내 자료로는 찾을수 없는 자료들을 주말동안 해외서적, 자료 등을 찾아가면서 찾은게 너무 뿌듯하다.
이게 바로 자료를 찾기 힘든 MFC 프로그래밍의 묘미인가?
참조
https://devblogs.microsoft.com/oldnewthing/20180510-00/?p=98725
On the difficulty of getting pixel-perfect layout in Win32 dialog templates
That's not what it's for.
devblogs.microsoft.com
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-movewindow
MoveWindow function (winuser.h) - Win32 apps
Changes the position and dimensions of the specified window.
docs.microsoft.com
https://forums.codeguru.com/showthread.php?444829-RC-File-Dialog-Size
RC File, Dialog Size
RC File, Dialog Size How can I set a dialog size in pixels with the RC file? Setting the size of a dialog to 100,100 results in an actual pixel size of about 150,163 Is there anyway to set the size based on pixels? Currently I am using a cheap fix, using O
forums.codeguru.com
'C++ > MFC' 카테고리의 다른 글
| (MFC 꿀팁)MFC에서 TRACE로 파일명, 해당위치 출력하기 (0) | 2021.10.22 |
|---|---|
| MFC에서 화면해상도에 반응해서 창 출력하는 방법 (1) | 2021.06.23 |
| MFC에서 다이얼로그 폰트 사이즈 찾아오기 (1) | 2021.06.16 |
| MFC 리소스로 만든 다이얼로그 사이즈 변경 (1) | 2021.06.04 |