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