본문 바로가기
Windows (Platform)/Bug tracking

m_hWnd 오류

by 미티치 2020. 3. 22.

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 인지 체크하는 로직을 넣어야한다.

 

댓글