OnSize 함수는 다이얼로그 초기화 함수인 OnInitDialog 이전에도 호출될 수 있다.
만약 OnSize 함수를 오버로드했다면, OnSize 함수 내부에서 SetWindowsPos 같이 윈도우 핸들을 조작하는 함수 호출은 조심해서 다뤄야한다.
프로세스를 생성 과정 중에 처음으로 m_hWnd 를 얻을수 있는 지점은 OnInitDialog 함수이기 때문이다.
DoModal 호출 전에는 m_hWnd가 존재하지 않으며 DoModal이 리턴한 후에도 m_hWnd 는 존재하지 않는다. 즉, DoModal 함수 호출 중에만 m_hWnd가 nullptr이 아닌 것이다.
예를들어 내 다이얼로그에 리스트박스를 하나 넣고 m_ListBox로 변수로 선언했다.
다이얼로그 사이즈가 변경될 때 리스트박스의 크기도 변경해주기 위해 m_ListBox.OnSize 함수에서는 SetWindowPos 함수를 호출한다고 가정하자.
MyDialog의 OnSize 함수가 호출될 때(즉 WM_SIZE 메시지가 발생할 때) 이 리스트박스의 OnSize 함수도 호출해주고자 아래처럼 코드를 작성하면
void MyDialog::OnSize(UINT nType, int cx, int cy)
{
m_ListBox.SendMessage(WM_SIZE, 0, MAKEPARAM(cx,cy));
...
}
이런 오류를 만나게 될 것이다.

이유는 m_ListBox 의 OnSize 함수에서 호출한 SetWindowPos 때문인데,
실제 SetWindowPos 함수에서 314번 라인에서 m_hWnd 가 nullptr 이어서 ASSERT가 발생했다.

이런 문제를 해결하기 위해 OnSize 처럼 OnInitDialog가 호출되기 전에 호출될 수 있는 메시지 처리 핸들러 함수들은
필수적으로 윈도우 핸들이 nullptr 인지 체크하는 로직을 넣어야한다.
댓글