VCL에서 Form을 하나 추가하면
대게 TForm을 상속 받습니다.
이 TForm은 TCustomForm을 상속받구요
사실 TForm에는 별로 기능이 없구.. 대부분의 Form관련 기능이 TCustomForm에 구현되어있습니다.
CreateParams 함수나 WndProc함수는 TCustomForm의 virtual로 구현되어있는 함수인데요
우리가 만든 TForm1 등에서 함수를 override하여 구현하지 않는다면
TCustomForm등 부모-class에 함수가 동작합니다.
하지만 만약 상속받은 자식-class에서 virtual함수를 override하여 구현하면
자식 class의 함수가 호출되죠
만약 TForm1의 CreateParams에서 TCreateParams Params의 모든 파라메터를 제대로 설정해주면
TCustomForm의 CreateParams을 호출할 필요 없습니다.
WndProc도 마찬가지구요
TForm1::WndProc에서 모든 윈도우메세지처리를 모두 완벽하게 해주면
상위 class의 함수를 호출할 필요가 없죠
자식 클래스 CreateParams에서는
기본 설정은 부모클래스의 CreateParams을 호출해서 설정하구
그중에 한가지를 살짝 변경한것입니다.
WndProc도 마찬가지로
기본 메세지 처리는 부모클래스 TCustomForm에 맡기구
minimiz관련 메세지만 중간에 짤라서 직접 처리한거죠
이렇게 부모 Class에서 Virtual로 구현된 함수를 자식 class에서 다시 구현하는것을
함수 override하고 합니다.
그럼...
조안 님이 쓰신 글 :
: 아까 써주신 글중에
:
: TCustomForm::CreateParams(Params);
:
: TCustomForm::WndProc(Msg);
:
: 이거 두개가 있는데요
:
: 여기서 TCustomForm 은 어떤거죠??
:
: 메인폼 이름은 아닌거같은데.. TCustomForm 으로 쓰는게 맞는건가요?
: 아니면 제 폼명을 쓰는건가요?
:
: 조안 님이 쓰신 글 :
: : 빌더6 쓰고있습니다.
: :
: : 혹시 스킨컴포넌트때문에 이런 문제가 발생할수도 있나요??
: :
: : 아니면... 메인폼이 아닌 child폼 에 모두
: :
: : //---------------------------------------------------------------------------
: : void __fastcall TfrmM_022::CreateParams(TCreateParams &Params)
: : {
: : TForm::CreateParams(Params);
: : Params.ExStyle = WS_EX_APPWINDOW;
: : Params.WndParent = GetDesktopWindow();
: : }
: :
: : 를 코딩했거든요
: :
: : 이게문제는 아닐거같은데..혹시 이것때문일까요;
: :
: : 아니면 이것때문인가..
: :
: :
: : //---------------------------------------------------------------------------
: : void __fastcall TfrmMain::WMFormActive(TMessage &Messages)
: : {
: : HANDLE hForm_Handle;
: :
: : hForm_Handle = (void *)Messages.WParam;
: :
: : SetForegroundWindow(hForm_Handle);
: : }
: :
: :
: : 좀더 찾아봐야겠네요 ㅜㅡ
: :
: : 답변 감사합니다 !!
: :
: : 장성호 님이 쓰신 글 :
: : : 잘돌아가는데 뭐가 문제죠?
: : :
: : : 혹시 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가 뜨게됩니다
: : : : : : : :
: : : : : : : : 이게 어떻게 된건지 ㅜㅜ
: : : : : : : :
: : : : : : : : 어떻게 하면 이문제를 해결 할 수 있을까요?