본문 바로가기

Programming Tips/MFC

PreCreateWindow 함수의 재정의...






PreCreateWindow는 MFC가 제공하는 가상함수들 중 하나로 사용자가 쉽게 재정의하여 사용이 가능합니다. 이름처럼 윈도우가 생성되기 직전에 호출되며, 생성될 윈도우에 대한 정보가 파라미터로 넘어오게 되고, 이 파라미터가 가지는 값을 이용해서 윈도우가 생성됩니다. 따라서 개발자가 윈도우의 스타일이나 속성을 변경하고 싶을때는 PreCreateWindow가 넘겨받는 파라미터를 변경시켜주면 생성되는 윈도우의 속성도 따라서 변하게 되는것입니다. 함수의 원형은 아래와 같습니다.
MDI 형태의 프로젝트 일 경우, CMainFrame과 CChildFrame에서 모두 찾을 수 있습니다.

BOOL PreCreateWindow(CREATESTRUCT& cs);

파라미터로 넘어오는 CREATESTRUCT는 아래와 같은 모습을 하고 있습니다.

typedef struct tagCREATESTRUCT{
    LPVOID          lpCreateParams;
    HINSTANCE   hInstance;
    HMENU          hMenu;
    HWND            hwndParent;
    int                 cy;
    int                 cx;
    int                 y;
    int                 x;
    LONG           style;
    LPCWSTR     lpszName;
    LPCWSTR     lpszClass;
    DWORD        dwExStyle;
} CREATESTRUCT, *LPCREATESTRUCT;

위의 CREATESTRUCT 구조체에서 자주 사용되는 녀석들은 x, y, cx, cy, style, dwExStyle 정도가 되겠네요.

◎ x, y, cx, cy
x, y, cx, cy는 윈도우가 생성될때의 위치와 크기를 가지는 멤버변수가 되겠습니다.

ex) 윈도우가 생성될 때 0, 0의 위치에서부터 가로의 크기가 500, 세로의 크기가 300인 윈도우를 만들고 싶을 경우

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: CREATESTRUCT cs를 수정하여 여기에서
 //  Window 클래스 또는 스타일을 수정합니다.

 cs.x = 0;
 cs.y = 0;
 cs.cx = 500;
 cs.cy = 300;

 return TRUE;
}

◎ style
style은 생성될 윈도우의 스타일을 지정하는 멤버변수 입니다. 자주 사용되는 스타일을 정리해보면 아래와 같습니다.

WS_BORDER                     :  경계선을 가진 윈도우
WS_CHILD                        :  다른 윈도우의 위에 올라가는 자식 윈도우
WS_THICKFRAME             :  프레임 윈도우에서 사용되는 경계선을 가지는 윈도우
WS_CAPTION                   :  타이틀 바를 가지는 윈도우
WS_MAXIMIZE                  :  최대화된 윈도우
WS_MINIMIZE                   :  최소화된 윈도우
WS_MAXIMIZEBOX            :  타이틀 바에 최대화 박스를 가지는 윈도우
WS_MINIMIZEBOX             :  타이틀 바에 최소화 박스를 가지는 윈도우
WS_VISIBLE                      :  화면에 보이는 윈도우
WS_OVERLAPPED             :  타이틀 바와 경계선을 가지는 윈도우
WS_SYSMENU                  :  시스템 메뉴를 가지는 윈도우
WS_OVERLAPPEDWINDOW : 다음의 속성들을 결합한 윈도우
                                         WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
                                         WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX

ex) 타이틀 바와 시스템 메뉴, 최대화 박스를 가지는 윈도우를 만들고 싶을 때

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: CREATESTRUCT cs를 수정하여 여기에서
 //  Window 클래스 또는 스타일을 수정합니다.

 cs.style = WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX;
 
 return TRUE;
}

ex) 현재 설정되어있는 윈도우의 속성을 그대로 유지하되, 최대화 박스를 추가해야 할 경우

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: CREATESTRUCT cs를 수정하여 여기에서
 //  Window 클래스 또는 스타일을 수정합니다.

 cs.style |=  WS_MAXIMIZEBOX;
 
 return TRUE;
}

ex) 현재 설정되어있는 윈도우의 속성을 그대로 유지하되, 최대화 박스를 제거해야 할 경우

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: CREATESTRUCT cs를 수정하여 여기에서
 //  Window 클래스 또는 스타일을 수정합니다.

 cs.style =  cs.style & ~WS_MAXIMIZE;
 
 return TRUE;
}

◎ dwExStyle
윈도우 스타일은 아래 와 같이 | 연산자로 조합해서 사용할 수 있도록 한 비트씩만 이용해서 정의되어 있습니다. 따라서 사용 할 수 있는 윈도우 스타일의 갯수에 한계가 있으며 자주 사용되지 않는 윈도우 스타일은 확장 윈도우 스타일이라고 해서 따로 설정하도록 되어 있습니다.

#define  WS_VISIBLE      0x10000000L
#define  WS_MAXIMIZE  0x01000000L
#define  WS_HSCROLL   0x00100000L

자주 사용되지 않는 스타일들을 정의 해 놓은 것이지만 그 중에서도 자주 사용되는 확장 윈도우 스타일에는 다음과 같은 것이 있습니다.

WS_EX_CLIENTEDGE                :  클라이언트 영역을 두드러져보이게 한다.
WS_EX_WINDOWEDGE               :  윈도우 프레임을 입체적으로 보이게 한다.
WS_EX_OVERLAPPEDWINDOW   :  WS_EX_CLIENTEDGE와 WS_EX_WINDOWEDGE의 합
WS_EX_CONTEXTHELP             :  제목 표시줄에 도움말 출력을 위한 버튼을 생성
WS_EX_DLGMODALFRAME        :  입체적으로 보이는 대화상자용 프레임을 생성
WS_EX_TOOLWINDOW               :  타이틀 바의 높이가 짧은 윈도우가 생성.
WS_EX_TOPMOST                    :  항상 최상위에 위치하는 윈도우 생성.

ex) 짧은 타이틀 바를 가지고 항상 최상위에 위치하는 윈도우를 생성할 경우
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: CREATESTRUCT cs를 수정하여 여기에서
 //  Window 클래스 또는 스타일을 수정합니다.

 cs.dwExStyle |= (WS_EX_TOOLWINDOW | WS_EX_TOPMOST);

 return TRUE;
}