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

C++빌더 Q&A
C++Builder Programming Q&A
[55035] Re:Re:Re:Re:프로그램의 테스크매니져로부터의 종료시 문제 - 답변아님
공윤경 [csstra] 1518 읽음    2008-10-28 00:40
넘 늦게 답글을 다네요 아직도 풀어가고잇는중인데
답글이 정말 많은 도움이 되었습니다. 길을 못잡고있었는데...일단 말씀해주신걸로 시도중입니다.
^^ 감사합니다~

장성호 님이 쓰신 글 :
: 답변이 아닙니다.
:
: 요건 좀 어려운 문제네요
:
: 네이트온 같은 메신져의 경우 대화창이 메임폼과 따고 작업표시줄에 나타나는데
: 이것도 대화창은 작업관리자(Task Manager)에서 작업끝내기를 클릭하면 프로그램이 전체 종료해버리네요
:
: 작업관리자 응용프로그램 탭에서 "작업 끝내기"(End Task)를 클릭하는경우
:
: 1. 먼저 WM_CLOSE 메세지를 해당 윈도우에 SendMessage(or Post) 하는것 같습니다.
:
: 2. 그리고 한 2초정도 있다가 TeminateProcess 를 호출해서 프로세서를 완전히 죽여버리는듯 합니다.
:     WM_QUIT 메세지도 안나라 오더라구요
:
:
: 결론적으로
:    방안1.  TaskManager를 Hook 하는 방법
:
:    방안2.  Terminateprocess 같은 API를 HOOK 하는 방안
:
:        등과 같이 Hook을 이용한 방법으로  할수는 있을것 같은데...
:        hook이 그렇게 쉽지는 않으니까...
:    
:    방안3.  sub폼을 모두 process를 분리합니다.
:         구글에서 얼마전에 발표한 웹브라우져 크롬이 멀티 프로세서로 되어있죠
:          프로세서간 통신은 NamedPipe를 이용한다고 어디서 본것 같습니다.
:      
:          요 구조로 하면 작업관리자 hook하지 않고 ,  작업관리자에서 "End Task" 클릭할때  해당 폼만
:          종료되게 할수 있을것입니다.
:
:           그런데 멀티프로세서로 하면 .. 또 신경써야 할것이 한두가지가 아니니
:           배보다 배꼽이 커질듯....
:   
:    방안4. TaskManager를 다른 놈으로 바꿔버리는 방법도 있을것 같습니다.
:    
:
: 별로 도움은 안될것 같은데 ..
: 아뭍은 좋은 해결책 찾으면 공유해 주십시요
:
: 그럼..
:
:
:     
: 저도 SUB폼을
: 공윤경 님이 쓰신 글 :
: : 답변 감사합니다.
: : 메인 프로그램이 아닌 생성한 폼이 다섯개면 프로세스쪽말고 Application탭에 다섯개의 폼이 나와있는데
: : 그걸 클릭해서 폼을 하나씩 죽일수는 없는건가요?
: :
: :
: : Lyn 님이 쓰신 글 :
: : : 프로세스(태스크) 가 죽으면 당연히 거기에 속해있던 폼들은 다 닫히고 해제되는게 당연합니다.
: : :
: : : 폼 여러개 띄웠다고 그게 따로도는게 아닙니다.
: : :
: : : 메인프로그램이 죽어도 나머지가 안죽게 하시려면 멀티프로세스구조(여러개의 exe) 로 가셔야합니다.
: : : 공윤경 님이 쓰신 글 :
: : : : //---------------------------------------------------------------------------
: : : : //MAIN.CPP
: : : : #include <vcl.h>
: : : : #pragma hdrstop
: : : :
: : : : #include "main.h"
: : : : #include "Sub.h"
: : : : //---------------------------------------------------------------------------
: : : : #pragma package(smart_init)
: : : : #pragma resource "*.dfm"
: : : : TSDIMainForm *SDIMainForm;
: : : : //---------------------------------------------------------------------------
: : : : __fastcall TSDIMainForm::TSDIMainForm(TComponent* Owner)
: : : :     : TForm(Owner)
: : : : {
: : : : }
: : : : void __fastcall TSDIMainForm::WMUserMessage(TMessage &msg)
: : : : {
: : : :     CreateSubForm();
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : void __fastcall TSDIMainForm::CreateSubForm(void)
: : : : {
: : : :     m_FormNumber++;
: : : :     AnsiString str = "SDIアプリサンプル["+IntToStr(m_FormNumber)+"]";
: : : :     TSDISubForm *sForm;
: : : :     sForm = new TSDISubForm(this);
: : : :     sForm->Show();
: : : :     sForm->Caption = str;
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : void __fastcall TSDIMainForm::FormCreate(TObject *Sender)
: : : : {
: : : :     m_FormNumber = 0;
: : : :     CreateSubForm();
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : //---------------------------------------------------------------
: : : : //MAIN.H
: : : :
: : : : #ifndef mainH
: : : : #define mainH
: : : : //---------------------------------------------------------------------------
: : : : #include <Classes.hpp>
: : : : #include <Controls.hpp>
: : : : #include <StdCtrls.hpp>
: : : : #include <Forms.hpp>
: : : : #define    message WM_USER + 50
: : : : //---------------------------------------------------------------------------
: : : : class TSDIMainForm : public TForm
: : : : {
: : : : __published:    // IDE 管理のコンポーネント
: : : :     void __fastcall FormCreate(TObject *Sender);
: : : : private:    // ユーザー宣言
: : : :     void __fastcall WMUserMessage(TMessage &msg);
: : : :     BEGIN_MESSAGE_MAP
: : : :           MESSAGE_HANDLER(message, TMessage, WMUserMessage)
: : : :     END_MESSAGE_MAP(TForm);
: : : : public:        // ユーザー宣言
: : : :     __fastcall TSDIMainForm(TComponent* Owner);
: : : :
: : : :     int m_FormNumber;
: : : :     void __fastcall CreateSubForm(void);
: : : :
: : : : };
: : : : //---------------------------------------------------------------------------
: : : : extern PACKAGE TSDIMainForm *SDIMainForm;
: : : : //---------------------------------------------------------------------------
: : : : #endif
: : : :
: : : :
: : : :
: : : :
: : : : //---------------------------------------------------------------------------
: : : : //SUB.CPP
: : : : #include <vcl.h>
: : : : #pragma hdrstop
: : : :
: : : : #include "Sub.h"
: : : : #include "main.h"
: : : : #include <Windows.hpp>
: : : : //---------------------------------------------------------------------------
: : : : #pragma package(smart_init)
: : : : #pragma resource "*.dfm"
: : : : TSDISubForm *SDISubForm;
: : : : //---------------------------------------------------------------------------
: : : : __fastcall TSDISubForm::TSDISubForm(TComponent* Owner)
: : : :     : TForm(Owner)
: : : : {
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : bool __fastcall TSDISubForm::IsLastForm(TForm* form)
: : : : {
: : : :     bool bRst = true;
: : : :     TForm *sForm;
: : : :     for(int idx = 0; idx < Screen->FormCount  ; idx++)
: : : :     {
: : : :         sForm = Screen->Forms[idx];
: : : :         if((sForm != form)&&(sForm->Visible == true)&&
: : : :             (sForm->ParentWindow == 0 || sForm->HandleAllocated() || (IsChild(sForm->Handle,sForm->ParentWindow)==false))) {
: : : :             bRst = false;
: : : :             break;
: : : :         }
: : : :     }
: : : :     return bRst;
: : : : }
: : : :
: : : : void __fastcall TSDISubForm::subNewClick(TObject *Sender)
: : : : {
: : : :     SDIMainForm->CreateSubForm();
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::subCloseClick(TObject *Sender)
: : : : {
: : : :     Close();
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::subAllCloseClick(TObject *Sender)
: : : : {
: : : :     Application->Terminate();
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : // ウィンドウ復帰
: : : : //---------------------------------------------------------------------------
: : : : void __fastcall TSDISubForm::RestoreWind(void)
: : : : {
: : : :     int nWin = Screen->FormCount;
: : : :     HWND hWnd;
: : : :     for(int idx = 0; idx < Screen->FormCount; idx++)
: : : :     {
: : : :         hWnd = Screen->Forms[idx]->Handle;
: : : :         //WindowがNormalではない場合
: : : :         if(Screen->Forms[idx]->WindowState != wsNormal) {
: : : :             if(GetClassNameStr(hWnd) == this->ClassName()) {
: : : :
: : : :                 DefWindowProc(hWnd,WM_SYSCOMMAND,SC_RESTORE,0);
: : : :             }
: : : :         }
: : : :     }
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : void __fastcall TSDISubForm::subCascadeClick(TObject *Sender)
: : : : {
: : : :     RestoreWind();
: : : :     int nWin = Screen->FormCount;
: : : :     HWND *WndHandleList;
: : : :     WndHandleList = new HWND[nWin];
: : : :     for(int idx = 0; idx < Screen->FormCount; idx++)
: : : :     {
: : : :         WndHandleList[idx] = Screen->Forms[idx]->Handle;
: : : :         SetForegroundWindow(WndHandleList[idx]);
: : : :     }
: : : :
: : : :     CascadeWindows(0,
: : : :                     NULL,//MDITILE_SKIPDISABLED
: : : :                     NULL,
: : : :                     Screen->FormCount,
: : : :                     WndHandleList);
: : : :     SetForegroundWindow(Handle);
: : : :     delete [] WndHandleList;
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::subTileVerticalClick(TObject *Sender)
: : : : {
: : : :     RestoreWind();
: : : :     int nWin = Screen->FormCount;
: : : :     HWND *WndHandleList;
: : : :     WndHandleList = new HWND[nWin];
: : : :     for(int idx = 0; idx < Screen->FormCount; idx++)
: : : :     {
: : : :         WndHandleList[idx] = Screen->Forms[idx]->Handle;
: : : :         SetForegroundWindow(WndHandleList[idx]);
: : : :     }
: : : :
: : : :     TileWindows( 0,
: : : :                     MDITILE_VERTICAL,//MDITILE_SKIPDISABLED
: : : :                     NULL,
: : : :                     Screen->FormCount,
: : : :                     WndHandleList
: : : :                     );
: : : :     delete [] WndHandleList;
: : : :     SetForegroundWindow(Handle);
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::subTileHorizontalClick(TObject *Sender)
: : : : {
: : : :     RestoreWind();
: : : :     int nWin = Screen->FormCount;
: : : :     HWND *WndHandleList;
: : : :     WndHandleList = new HWND[nWin];
: : : :     for(int idx = 0; idx < Screen->FormCount; idx++)
: : : :     {
: : : :         WndHandleList[idx] = Screen->Forms[idx]->Handle;
: : : :         SetForegroundWindow(WndHandleList[idx]);
: : : :
: : : :     }
: : : :     TileWindows(0,
: : : :                     MDITILE_HORIZONTAL,//MDITILE_SKIPDISABLED
: : : :                     NULL,
: : : :                     Screen->FormCount,
: : : :                     WndHandleList
: : : :                     );
: : : :     delete [] WndHandleList;
: : : :     SetForegroundWindow(Handle);
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::subAllMinClick(TObject *Sender)
: : : : {
: : : :     HWND hWindow;
: : : :     for(int idx = 0; idx < Screen->FormCount; idx++)
: : : :     {
: : : :         hWindow = Screen->Forms[idx]->Handle;
: : : :         if(GetClassNameStr(hWindow) == this->ClassName()) {
: : : :             PostMessage(hWindow,WM_SYSCOMMAND,SC_MINIMIZE,0);
: : : :         }
: : : :     }
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : String __fastcall TSDISubForm::GetClassNameStr(HWND hWindow)
: : : : {
: : : :     int Len;
: : : :
: : : :     char *Buffer;
: : : :     String Result;
: : : :     Buffer = StrAlloc(MAX_PATH);
: : : :     try {
: : : :         Len = GetClassName(hWindow,Buffer,StrBufSize(Buffer));
: : : :         Result = Buffer;
: : : :
: : : :     }__finally{
: : : :         StrDispose(Buffer);
: : : :         return Result;
: : : :     }
: : : : }
: : : :
: : : : void __fastcall TSDISubForm::FormClose(TObject *Sender,
: : : :       TCloseAction &Action)
: : : : {
: : : :     if(IsLastForm(this)) {
: : : :         Application->Terminate();
: : : :     }
: : : : }
: : : : //---------------------------------------------------------------------------
: : : :
: : : : void __fastcall TSDISubForm::FormShow(TObject *Sender)
: : : : {
: : : :     ShowWindow(Application->Handle,SW_HIDE);
: : : :     if(!NotFirstForm) {
: : : :         NotFirstForm = true;
: : : :         switch(CmdShow)
: : : :         {
: : : :         case SW_SHOWMINNOACTIVE:
: : : :             WindowState = wsMinimized;
: : : :             break;
: : : :         case SW_SHOWMAXIMIZED:
: : : :             WindowState = wsMaximized;
: : : :             break;
: : : :         }
: : : :     }
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : void __fastcall TSDISubForm::CreateParams(TCreateParams &Params)
: : : : {
: : : :     TForm::CreateParams(Params);
: : : :     if(FormStyle == fsNormal || FormStyle == fsStayOnTop)  {
: : : :         if(BorderStyle == bsSingle || BorderStyle == bsSizeable) {
: : : :              Params.ExStyle      = Params.ExStyle |WS_EX_APPWINDOW;
: : : :             Params.WndParent     = 0;
: : : :         }
: : : :     }
: : : : }
: : : :
: : : : //SUB.h
: : : : //---------------------------------------------------------------------------
: : : :
: : : : #ifndef SubH
: : : : #define SubH
: : : : //---------------------------------------------------------------------------
: : : : #include <Classes.hpp>
: : : : #include <Controls.hpp>
: : : : #include <StdCtrls.hpp>
: : : : #include <Forms.hpp>
: : : : #include <Menus.hpp>
: : : : //---------------------------------------------------------------------------
: : : : class TSDISubForm : public TForm
: : : : {
: : : : __published:    // IDE 管理のコンポーネント
: : : :     TMainMenu *MainMenu1;
: : : :     TMenuItem *MenuFile;
: : : :     TMenuItem *subNew;
: : : :     TMenuItem *subClose;
: : : :     TMenuItem *subAllClose;
: : : :     TMenuItem *N3;
: : : :     TMenuItem *Show1;
: : : :     TMenuItem *subCascade;
: : : :     TMenuItem *subTileVertical;
: : : :     TMenuItem *subTileHorizontal;
: : : :     TMenuItem *subAllMin;
: : : :     void __fastcall subNewClick(TObject *Sender);
: : : :     void __fastcall subCloseClick(TObject *Sender);
: : : :     void __fastcall subAllCloseClick(TObject *Sender);
: : : :     void __fastcall subCascadeClick(TObject *Sender);
: : : :     void __fastcall subTileVerticalClick(TObject *Sender);
: : : :     void __fastcall subTileHorizontalClick(TObject *Sender);
: : : :     void __fastcall subAllMinClick(TObject *Sender);
: : : :     void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
: : : :     void __fastcall FormShow(TObject *Sender);
: : : : private:    // ユーザー宣言
: : : :     bool __fastcall TSDISubForm::IsLastForm(TForm *form);
: : : :     void __fastcall TSDISubForm::RestoreWind(void);
: : : : protected:
: : : :     String __fastcall GetClassNameStr(HWND hWindow);
: : : :     void __fastcall CreateParams(TCreateParams ¶ms);
: : : : public:        // ユーザー宣言
: : : :     __fastcall TSDISubForm(TComponent* Owner);
: : : :     bool NotFirstForm;
: : : : };
: : : : //---------------------------------------------------------------------------
: : : : extern PACKAGE TSDISubForm *SDISubForm;
: : : : //---------------------------------------------------------------------------
: : : : #endif
: : : :
: : : :
: : : : //PROJ
: : : : //---------------------------------------------------------------------------
: : : :
: : : : #include <vcl.h>
: : : : #pragma hdrstop
: : : : USERES("prjSdi.res");
: : : : USEFORM("main.cpp", SDIMainForm);
: : : : USEFORM("Sub.cpp", SDISubForm);
: : : : //---------------------------------------------------------------------------
: : : : BOOL IsPrevAppExist(const char * mutextname)
: : : : {
: : : :     bool bRst = false;
: : : :     CreateMutex(NULL, true, mutextname);
: : : :     if (GetLastError() == ERROR_ALREADY_EXISTS) {
: : : :         bRst = true;
: : : :     }
: : : :     return bRst;
: : : : }
: : : : WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
: : : : {
: : : :     HANDLE mutex;
: : : :     HWND hWindow;
: : : :     try
: : : :     {
: : : :         const char *  mutexname= "SDIFORM";
: : : :         if(IsPrevAppExist(mutexname)) {
: : : :             hWindow =  FindWindow("TSDIMainForm",NULL);
: : : :             SetForegroundWindow(hWindow);
: : : :             SendMessage(hWindow, WM_USER+50,0,0);
: : : :         }
: : : :         else {
: : : :             SetProp(Application->Handle,PChar(mutexname),mutex);
: : : :             Application->Initialize();
: : : :             Application->CreateForm(__classid(TSDIMainForm), &SDIMainForm);
: : : :             Application->ShowMainForm = false;
: : : :             Application->Run();
: : : :             RemoveProp(Application->Handle, PCHAR(mutexname));
: : : :         }
: : : :     }
: : : :     catch (Exception &exception)
: : : :     {
: : : :         Application->ShowException(&exception);
: : : :     }
: : : :     ReleaseMutex(mutex);
: : : :     return 0;
: : : : }
: : : : //---------------------------------------------------------------------------
: : : : 안녕하세요? 공윤경이라고 합니다.
: : : : 프로그램의 테스크메니져로부터의 종료시 문제
: : : :
: : : : 테스크메니져서에 프로세스에서는 하나의 EXE화일이 보이고
: : : : 어플리케이션에서 동적으로 생성한 폼의 이름이 보여서.
: : : : 어플리케이션부에서 하나씩 클릭해서 종료가능한 프로그램을 작성중입니다.
: : : : 코드에 이상이 있나요? 실행 + 종료등 아무에러가 없는데
: : : : 테스트매니져서에서 프로그램을 종료시키면 에러가 발생하고 프로그램이 전부 종료됩니다.
: : : : 메인폼과 서브폼으로 이루어져서 실행시 메인폼은 보이지않고
: : : : 서브폼이 뜹니다. 그이후에도 서브폼으로부터 서브폼을 추가하는 형태의 프로그램입니다.
: : : :
: : : : 뭔가 제가 잘못생각한 부분이 있는지...
: : : :
: : : : 잘부탁드립니다 ^^

+ -

관련 글 리스트
54978 프로그램의 테스크매니져로부터의 종료시 문제 공윤경 1196 2008/10/22
54981         Re:Re:프로그램의 테스크매니져로부터의 종료시 문제 공윤경 1208 2008/10/22
54986             Re:Re:Re:프로그램의 테스크매니져로부터의 종료시 문제 - 답변아님 장성호 1433 2008/10/22
55035                 Re:Re:Re:Re:프로그램의 테스크매니져로부터의 종료시 문제 - 답변아님 공윤경 1518 2008/10/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.