우선 창을 아예 안보이게 하려면, 작업표시줄에도 표시가 안되게 해야한다.
ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);
위의 코드는 윈도우 스타일을 조정하여, 작업표시줄에 표시를 하지 않는다.
WS_EX_APPWINDOW : Forces a top-level window onto the taskbar when the window is visible.(프로그램이 처음 시작할 때, 활성화되게 하는 것)
WS_EX_TOOLWINDOW : A tool window does not appear in the task bar or in the window that appears when the user presses ALT+TAB.(툴윈도우는 작업표시줄에 보이지않으며, ALT+TAB으로도 찾을 수 없다.)
이 다음에 프로그램이 창이 뜨는 위치에서 ShowWindow를 해도 될 것 같지만, 대화상자 DoModal 메소드의 내부에서 WM_SHOWWINDOW를 사용하여 윈도우를 출력시키기 때문에, OninitialDialog에서 ShowWIndow(SW_HIDE); 를 하더라도 창이 보인다.
하지만 SendMessage를 이용하기에도 문제가 있다. SendMessage는 그 특성상 함수의 호출과 유사하다. 이는 SendMessage의 구조에서 찾아볼 수 있는데, SendMessage를 보낸 쪽은 받는 쪽에서 작업을 완료할 때 까지 다른 작업을 수행하지 않는다. 따라서 자신이 자신에게 SendMessage를 하는 경우, 결과적으로 함수를 호출하는 것처럼 보이게 되고, 위치상으로 가장 마지막에 호출된 SendMessage가 사용자에게 반영된 것으로 보일 수 있다.
문제는 DoModal 메소드가 내부적으로 메시지 루프를 형성하기 이전에 SendMessage를 이용하여 대화상자를 출력하는 코드를 사용한다는 것이다. 즉, 프로그램이 마지막에 불릴 때, SendMessage를 이용하여 대화상자를 출력하는 것이다.
이 해결 방법은 PostMessage를 사용하는 것이다. PostMessage는 SendMessage와 달리 메시지를 받는 쪽의 상황에 관여하지 않는다. 즉, 메시지를 대기열에만 넣어놓고, 자기는 할일을 한다. 따라서 PostMessage로 들어온 메시지는 메시지 루프가 형성되어야 실행되는 것이다. 즉, 제일 마지막에 PostMessage를 사용하여 윈도우를 감출 수 있게 되는 것이다.
PostMessage (WM_SHOWWINDOW,FALSE, SW_OTHERUNZOOM);
WM_SHOWWINDOW 메시지는 윈도우를 감추거나 보여줄 때 윈도우로 전달된다. 이 메시지가 가지는 두개의 매개 변수 중 wParam은 윈도우의 Show/Hide를 결정시키는 값을 전달한다. wParam의 값이 TRUE이면 윈도우는 출력될 것이고 FALSE이면 윈도우는 감추어질 것이다. 그리고 lParam은 현재 적용되는 윈도우의 상태를 명시하게 된다. 하지만 lParam에 명시되는 값은 별 의미가 없다. lParam에 들어가는 값은 '왜 해당 메시지가 발생되었는가' 에 따른 값이다.
그런데 여기까지 구현하면 좀 이상할 것이다. 왜냐면 깜박이는 현상이 나타나기 때문이다.
이 현상을 없애려면, 위의 PostMessage 이전에
ShowWindow(SW_SHOWMINIMIZED);
를 적어주자. 최소화 상태로 만들은 상태에서 감추면 되는 것이다.
즉, 최소화 상태로 만든 후에, 창을 아예 사라지게 하는 것이다.
그리고 이렇게 사라진 창을 보이게 하려면,
ShowWindow(SW_RESTORE);
SetForegroundWindow(); //최상위로
위와 같이,적절한 곳에 코딩하면 된다.
마지막으로 현재 프로그램이 보이고(Visible)인지 확인하는 함수는
IsWindowVisible(); 이다
정유석님글을 참고했습니다.)
댓글 없음:
댓글 쓰기