잘돌아가는데 뭐가 문제죠?
혹시 Builder버젼이 어떻게 되시나요?
아래 코드 copy+paste해서 Cbuilder6에서 테스트 해봤을때 별이상이 없는데요...
...
조안 님이 쓰신 글 :
: 이렇게 코딩했습니다
:
:
: void __fastcall TfrmMain::FormCreate(TObject *Sender)
: {
: Application->OnException = AppException;
: Screen->OnActiveControlChange=OnScreenActiveFormChange;
: }
: //---------------------------------------------------------------------------
: void __fastcall TfrmMain::WndProc(TMessage &Msg)
: {
: if(Msg.Msg==WM_SYSCOMMAND && Msg.WParam==SC_MINIMIZE)
: {
: //Form1의minimize 시스템 메세지를 필터링
: this->WindowState=wsMinimized;
: return;
: }
:
: TCustomForm::WndProc(Msg);
: }
: //---------------------------------------------------------------------------
: void __fastcall TfrmMain::FormShow(TObject *Sender)
: {
: ShowWindow(Application->Handle,SW_HIDE);
: }
: //---------------------------------------------------------------------------
: void __fastcall TfrmMain::CreateParams(TCreateParams &Params)
: {
: TCustomForm::CreateParams(Params);
: Params.WndParent = 0;
: }
: //---------------------------------------------------------------------------
: void __fastcall TfrmMain::OnScreenActiveFormChange(TObject *Sender)
: {
: if( Screen->ActiveForm!=NULL)
: {
: String sClsName=Screen->ActiveForm->ClassName();
: if(sClsName=="TMessageForm" || sClsName=="TbsMessageForm")
: SetWindowPos(Screen->ActiveForm->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
: }
: }
: //---------------------------------------------------------------------------
:
:
:
: 장성호 님이 쓰신 글 :
: : ...
: :
: : 아래 내용관련해서 기능만 코드 올려보세요
: :
: :
: : 조안 님이 쓰신 글 :
: : : 음.. 저도 잘 이해는 안갔는데..
: : : 원래 메인폼 말고도 숨겨진 폼이 하나가 더 안보이게 깔려있는데
: : : 강제로 작업표시줄에 나오게 하면 같은게 두개가 뜨기때문에. 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가 뜨게됩니다
: : : : :
: : : : : 이게 어떻게 된건지 ㅜㅜ
: : : : :
: : : : : 어떻게 하면 이문제를 해결 할 수 있을까요?