음.. 저도 잘 이해는 안갔는데..
원래 메인폼 말고도 숨겨진 폼이 하나가 더 안보이게 깔려있는데
강제로 작업표시줄에 나오게 하면 같은게 두개가 뜨기때문에. Application->Handel 을 Hide 시켜야된다고
그때 답변해주셨거든요
그래서 hide 했는데
이게 minimize 하면 다시 뜬다는 거죠..
게다가 작업표시줄이 아니라 화면에까지 떠서 멀쩡히 잘 작동해요..
(minimize 하면 하나가 숨어들어가는 모양은 나오지만 여전히 화면은 떠있는거죠.. 작업표시줄은 두개로 늘어나버리고)
아래 적어주신 코드대로 코딩했는데..
여전히 작업표시줄엔 두개... 최소화 해도 계속 남아있는 현상이 일어나네요
장성호 님이 쓰신 글 :
: 질문의 설명이 잘 이해가 가지 않네요
:
: " 임의로 handle 과 real 을 a,b 로 표현하겠습니다" 라는 문장에서
: "handle"은 뭐고 "real"은 뭔가요?
:
: ==================================================================
:
: 질문에 대한 이해를 떠나서 Main폼의 WndParent를 GesktopWindow로 설정해서 사용할때
: 지난번에 얘기하지 못한 중요한 사실이 있네요..
:
:
:
[VCL 어플리케이션의 메인윈도우 핸들은?]
:
: BDS2005 이상 버젼에서는 설정에 따라서 다르지만
: 기본적으로 VCL(Delphi , CBuilder)에서 메인윈도우는 MainForm->Handle이 아닙니다.
:
:
Application->Handle이 VCL 어플리케이션의 메인윈도우핸들 입니다.
:
: 확인하는 쉬운 방법은 작업표시줄에서 어플리케이션 버튼에서 마우스 우클릭하여
: System메뉴를 띄워보세요
: 보통 System메뉴는 (이전크기,이동,최대화,최소화,닫기) 이렇게 여섯가지 입니다.
: 그런데 메인폼의 캡션에서 메뉴를 띄우면 6개의 메뉴가 나오지만
: 작업표시줄에서 메뉴를 띄우면 (이전크기,최소화,닫기) 이렇게 3가지만 나옵니다.
:
: 왜냐하면 Application->Handle 윈도우를 CreateWindow한후에
: MAXIMIZE , SIZE , MOVE 세개의 시스템 메뉴를 삭제하기때문이죠
:
:
[Application->MainForm은 어떻게 결정되나?]
:
: Application->MainForm은 프로그램에서 Form을 생성하는 순서에 따라
: Form1이 될수도 있구 Form2도 될수 있습니다.
:
: 일반적으로 먼저 생성되는 폼이 Application->MainForm이 되지만
: 정확하게 표현하면 Owner를 Application으로 해서 제일처음 생성된 (new) Form이
: Application->MainForm 이 됩니다.
:
:
[Application->MainForm과 Application->Hanlde은 무슨 관계?]
: 대부분의 경우 VCL로 어플리케이션 개발할때
: Application->Hanlde이 메인윈도우핸들이라는것을 인식하지 못합니다.
:
: 왜냐하면
: Application->MainForm에서 발생하는 System-Message중 일부를 Application->Hadle 로 보내구요
: 작업표시줄의 Application->Handle의 버튼에서 발생하는 System-Message중 일부를
: Application->MainForm->Handle로 보내기때문입니다.
:
:
:
[Application->MainForm과 Application->Hanlde의 연결고리 끊기]
: 여기가 가장 중요한데요
:
: 다음과 같이 Application->Handle을 hide시키면
: ShowWindow(Application->Handle,SW_HIDE);
:
: Application->Handle에서 발생하는 system-message를 필터링 하는 기능은
: 별로 신경쓰지 않아도 될것입니다.
:
: 하지만 Application->MainForm->Handle에서 발생하는 system-message(WM_SYSCOMMAND)는
: Application->Handle의 WindowProc로 가지 않도록 필터링 해줘야 합니다.
:
:
: 아래는 TCustomForm의 WM_SYSCOMMAND 메세지에 대한 처리 코드 입니다.
:
:
:
: procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);
: begin
: with Message do
: begin
: if (CmdType and $FFF0 = SC_MINIMIZE) and (Application.MainForm = Self) then
: Application.WndProc(TMessage(Message)) //여기가 중요
: else if (CmdType and $FFF0 <> SC_MOVE) or (csDesigning in ComponentState) or
: (Align = alNone) or (WindowState = wsMinimized) then
: inherited;
: if ((CmdType and $FFF0 = SC_MINIMIZE) or (CmdType and $FFF0 = SC_RESTORE)) and
: not (csDesigning in ComponentState) and (Align <> alNone) then
: RequestAlign;
: end;
: end;
:
:
: 위 코드를 보면 WM_SYSCOMMAND 에서
: CommandType즉 WParam이 SC_MINIMIZE 이구 현재 폼이 Application->MainForm이면
: 해당 Application.WndProc 로 보내서 처리하도록 하고 있습니다.
:
:
코드
: 다음과 같이 코딩하면 메인폼의 minimize command가 Application->Handle 의 WindowProc로 가는것을
: 막을수 있습니다.
:
:
: __fastcall TForm1::TForm1(TComponent* Owner)
: : TForm(Owner)
: {
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::CreateParams(Controls::TCreateParams &Params)
: {
: TCustomForm::CreateParams(Params);
: //Form1의 Wndparent를 Gesktopwindow로 설정
: Params.WndParent=0;
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::WndProc(TMessage &Msg)
: {
: if(Msg.Msg==WM_SYSCOMMAND && Msg.WParam==SC_MINIMIZE)
: {
: //Form1의minimize 시스템 메세지를 필터링
: this->WindowState=wsMinimized;
: return;
: }
:
: TCustomForm::WndProc(Msg);
: }
: void __fastcall TForm1::FormShow(TObject *Sender)
: {
: //Form1이 Show될때 Application->Handle을 hide시킴
: ShowWindow(Application->Handle,SW_HIDE);
: }
: //---------------------------------------------------------------------------
:
:
:
:
:
: 그럼...
:
:
: 조안 님이 쓰신 글 :
: : 안녕하세요. 저번에 ShowMessage 최상위에 뜨는 내용 질문드렸는데요
: :
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=57217
: :
: : 그때 말씀해주신대로
: :
: : 메인폼의 WndParent도 Application->Handle이 아니라 GetDesktopWindow로 설정하구
: : 메인폼이 Show될때 Application->Handle을 Hide시켜 버립니다.
: :
: : 를 사용한뒤,
: :
: : String sClsName=Screen->ActiveForm->ClassName();
: : if(sClsName=="TMessageForm")
: : SetWindowPos(Screen->ActiveForm->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
: :
: : 를 사용하여 메시지박스를 항상 최상위로 띄웠습니다.
: :
: : 이게 잘 통한다고 생각했는데..
: :
: : 문제는, 메인폼에 최소화 버튼이 있습니다
: :
: : 임의로 handle 과 real 을 a,b 로 표현하겠습니다
: :
: : 최소화 버튼을 누르기 전까지는. a가 hide 상태로 잘되있어서. 작업표시줄에 b만 뜨고, b만 보여집니다
: :
: : 근데 최소화 버튼을 누르면 b 가 작업표시줄로 숨어들어가면서, a 가 나타나고, 화면에도 a가 뜨게됩니다
: :
: : 이게 어떻게 된건지 ㅜㅜ
: :
: : 어떻게 하면 이문제를 해결 할 수 있을까요?