메신져같은 프로그램을 보면 대화창이 하나 생길때 마다
작업표시줄에 해당 폼(윈도우)의 버튼이 나타난다.
MS-Office 같은경우에도 새문서를 열면
(버젼에 따라 다르겠지만) 작업표시줄에 해당문서의 버튼이 나타난다.
exe는 하나인데...
이렇게 sub-form을 작업표시줄에 나타내어 프로그램하는 경우가 가끔씩 있다.
이럴경우 VCL에서는 CreateParams를 Override하셔서 관련기능을 쉽게 구현할수 있다.
관련팁
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=18
void __fastcall TForm2::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
Params.ExStyle := WS_EX_APPWINDOW;
Params.WndParent = GetDesktopWindow();
}
그런데 위와같이 sub-form을 작업표시줄에 나타내게 하면 몇가지 문제가 발생한다.
문제점은?
작업표시줄에 버튼이 나타나게 한 Form이 active되어있을때
ShowMessage 또는 hint가 뜨면 ..
MainForm이 앞으로 튀어나온후에 MessageBox나 Hint가 뜨는 현상이 발생한다.
( 델파이 또는 CBuilder버젼에 따라 현상이 조금씩 다르다)
위 문제가 다음의 경우에 나타납니다.
1) ShowMessage , InputQuery , InputBox
2) Hint가 뜰때
3) OpenDialog등의 CommonDialog를 Execute할때 ..
이는 제가 경험한 경우만을 나열한 것입니다. 또다른 문제와 새로운 문제도 있을수 있겠죠..
문제의 원인은?
문제의 핵심은 Hint 든 MessageBox든 Dialog은 모두 새로운 윈도우가 뜨는것인데
새로운 윈도우의 WndParent가 현재Active된 Form(window)이 아닌
Application.Handle 로 주로 지정되는데서 발생하는 문제입니다.
VCL에서는 모든 윈도우(Form등)의 WndParent를 기본적으로
Application.Handle로 설정되도록 되어있기 때문입니다.
* Hint가 뜰때 MainForm이 앞으로 나오는 문제는
BCB6까지는 나타나지 않더군요
Delphi7이상에서만 나타납니다.
* ShowMessage , InputQuery , InputBox 문제는
Application->ModalPopupMode를 pmAuto나 pmExplicit 로 해주면 문제가 해결됩니다만
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=748
Application->ModalPopupMode = pmExplicit;
ModalPopupMode 라는 Property가 2006이상에서나 추가된걸로 알고있습니다.
Delphi7 / BCB6이하에서는 나타납니다.
* CommonDialog에서는 대부분에서 나타나구요
=========================================================================================
문제해결방법
문제해결 방법은 VCL버젼별로 다르게 적용할수 밖에 없습니다.
1) BDB2006이상에서 ShowMessage등의 MessageBox문제는
Application->ModalPopupMode 를 설정하여 쉽게 해결할수 잇습니다만
그 이하의 버젼에서는 직접 ShowMessage나 기타의 MessageBox를 직접구현해야 합니다.
첨부파일에 포함되 Unit_MyShowMessage.pas에 있는
ShowMessage2 , InputQuery2 , InputBox2 를 사용하면 문제가 해결됩니다.
2) Hint의 경우
BCB6까지는 문제가 없구요
Delphi7이상에서 발생하는것 같은데..
BCB2006이상에서는 MainFormOnTaskBar 기능을 이용하면 문제 해결됩니다.
프로젝트 파일에서 CreateForm하기전에 다음가 같이 하면 됩니다.
Application->MainFormOnTaskBar =true;
SetApplicationMainFormOnTaskBar(Application, true);
하지만 Delphi7에서는 위기능이 없으므로
메세시박스처럼 직접 HintWindow클래스를 만들어서 해결가능합니다.
첨부파일 Unit_MyHintWindow.pas 를 사용하시면 됩니다.
그냥 프로젝트에 포함만 해주면 됩니다.
BCB2006이상에서 Unit_MyShowMessage.pas를 사용할경우
MainFormOnTaskBar기능을 쓰지않아도 문제가 해결되죠
3) 마지막으로 Common-dialog는...
이것도 .. 원인은 똑같습니다...
해결방법은 Comdlg32.dll에 있는 GetOpenFileName 라는 api를 이용하여 구현하면 됩니다.
이건 직접 구현해 보세요..
오늘은 일찍 퇴근하려 했는데 이것 작성하다가 조금 늦어졌네요..
아~! 배고파...
그럼..