C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[45] 팁! 다이얼로그를 작업표시줄에서 없애기(?)
박지훈.임프 [cbuilder] 10347 읽음    1999-06-04 00:00
임프랍니다.. 에고.. 요즘은 정신이 없어서..
전처럼 매일같이 팁을 올리진 못해도, 생각나는대로 하나씩 올리도록 하죠..
빌라가 부쩍 썰렁해진 것 같아서요.. 섭섭해... ^^

음.. 제목이 좀 이상하죠? 일반적인 다이얼로그를 만들면, 그러니까 여기서
다이얼로그란 메인폼이 아닌 모든 폼을 가리킵니다.. 혼동 없으시길..
어쨌든, 일반적인 exe 어플리케이션에서 메인 폼이 아닌 폼을 만들어
ShowModal() 메소드로 화면에 보이면, 절대로 작업표시줄에 나타나지 않죠.
(이렇게 디폴트로는 작업표시줄에 나타나지 않는 다이얼로그를 작업표시줄에
나타나게 하는 팁은 전에 올렸었습니다.. 필요하신 분은 subj로 검색해보세요.)

그런데.. 제 경험으로는, ocx로 만든 컨트롤에 포함시킨 vcl 폼은 별다른
처리를 하지 않아도 기본적으로 작업표시줄에 나타납니다.
다시 말해서, 호스트 어플리케이션 자체의 작업표시줄 항목 외에, ocx에 포함시킨
폼이 작업표시줄에 튀어나온단 말이죠. 이런 효과를 원하셨던 분이라면 좋겠지만..
사실 이런 결과는 별로 좋을게 없습니다. 더욱이... ShowModal() 메소드로 화면에
나타낸 폼인데도 불구하고, 작업표시줄 상의 메인 어플리케이션의 항목을 클릭하면
황당하게도 메인 어플리케이션 윈도우가 활성화됩니다! (물론 입력 포커스는 받지
않습니다.)

이것은 프로그래머에게는 별일이 아닐수도 있겠지만.. 사용자에게는 상당한 혼란을
줄 수 있겠죠. 모달로 설계한 유저 인터페이스가 무너져버리는 겁니다.. T.T
제가 DLL 프로젝트를 작업한 경험이 많지 않아서 해본적이 없습니다만, 아마도
DLL에 포함시킨 폼에서도 같은 현상이 생기지 않을까 추측됩니다. 물론 DLL과
OCX는 공유 프로세스 공간과 인프록 서버(in-proc server)라는 중대한 차이점이
있기는 합니다만.

그리고.. 회사에서 제 옆자리에 앉은 분의 말로는, 마이다스 작업중에도 그러한
현상을 본적이 있다고 하더군요. 하여튼.. 심각한 오류는 아니라고 하더라도
반복적으로 나타나면 상당히 짜증날 만한 일이겠죠? ^^

어.. 썰이 너무 길었군요. 이제 해법을 찾아봅시다.
그냥 대충 생각해보면... 어플리케이션의 항목이 작업표시줄에 나타나지 않게 하는
일반적인 방법을 사용하면 되지 않을까.. 하는 생각을 누구나 하게 되는데,
해본 결과 안되더군요. 헤헤.
(메인폼의 OnShow 이벤트 핸들러에서, ShowWindow(Application->Handle, SW_HIDE);
하면 됩니다. 물론 일반적인 exe 어플리케이션의 경우죠.)

그래서.. 잔머리를 좀 굴려봤습니다. 저번에 올렸던 팁에서, 기본적으로는
작업표시줄에 나타날 수 없는 다이얼로그의 항목을 작업표시줄에 나오게 했었죠?
그 아이디어를 반대로 활용해봤습니다.

기억하실른지 모르겠습니다만, 그 팁에서는 CreateParams() 멤버를 오버라이딩해서,
api함수 CreateWindow(혹은 ...Ex)로 넘겨질 윈도우의 스타일에 ExAppWindow를
추가하고, 결정적으로 윈도우의 패어런트를 데스크탑 윈도우로 함으로써
작업표시줄에 강제로 나타나게 했었습니다.

그 방법에서 중요한 것은, 윈도우의 패어런트를 결정하는 것이죠.
반대로 작업표시줄에서 지우려면, 윈도우의 패어런트를 상위폼으로 강제로 넣어주면
해결될 것이 아니겠습니까? ^^

그런데, 여기서 약간의 문제가 있습니다. ocx로 작성한 액티브폼(저는 주로
요넘을 이용해서 작업합니다)은 일반적인 vcl 폼과는 달리, 폼 객체의 포인터가
드러나지 않죠. (당연하죠?) 그러니까 폼이름->Handle 을 구할수가 없다는 거죠.

그러면.. 별로 안전하지는 않지만, 일반적인 해법을 생각해봅시다.
폼 객체 포인터가 없을때 폼의 핸들을 찾아내려면? api 함수 FindWindow()를
쓰면 되죠. 뭐. 히히.

그래서.. 완성한 소스는 다음과 같습니다.
void __fastcall TForm1::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    Params.WndParent = FindWindow("TMainForm", NULL);
}


여기서는 호스트 어플리케이션의 클래스 이름만을 지정하고 캡션은 지정하지
않았죠. 캡션으로 윈도우를 찾는건.. 좀 신뢰도가 떨어져서요.

어쨌든.. 결과는 잘 됩니다. 한참동안 속을 썩였던 다이얼로그의 작업표시줄
항목을 깨끗하게 날려버렸답니다.

자아.. 팁은 끝입니다. 약간 부연하자면, 이런 종류의 코딩을 이해하려면
당연히 윈도우즈 api에 대한 기초적인 이해가 필수적입니다.
(CreateParams()는 CreateWindowEx() api 함수에 넘겨질 각종 윈도우의 특징을
지정할 수 있도록 만들어진 멤버함수입니다.)

그럼.. 이만. ^^




임펠리테리 박지훈이었습니다.

+ -

관련 글 리스트
45 팁! 다이얼로그를 작업표시줄에서 없애기(?) 박지훈.임프 10347 1999/06/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.