|
넘 늦게 답글을 다네요 아직도 풀어가고잇는중인데
답글이 정말 많은 도움이 되었습니다. 길을 못잡고있었는데...일단 말씀해주신걸로 시도중입니다.
^^ 감사합니다~
장성호 님이 쓰신 글 :
: 답변이 아닙니다.
:
: 요건 좀 어려운 문제네요
:
: 네이트온 같은 메신져의 경우 대화창이 메임폼과 따고 작업표시줄에 나타나는데
: 이것도 대화창은 작업관리자(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화일이 보이고
: : : : 어플리케이션에서 동적으로 생성한 폼의 이름이 보여서.
: : : : 어플리케이션부에서 하나씩 클릭해서 종료가능한 프로그램을 작성중입니다.
: : : : 코드에 이상이 있나요? 실행 + 종료등 아무에러가 없는데
: : : : 테스트매니져서에서 프로그램을 종료시키면 에러가 발생하고 프로그램이 전부 종료됩니다.
: : : : 메인폼과 서브폼으로 이루어져서 실행시 메인폼은 보이지않고
: : : : 서브폼이 뜹니다. 그이후에도 서브폼으로부터 서브폼을 추가하는 형태의 프로그램입니다.
: : : :
: : : : 뭔가 제가 잘못생각한 부분이 있는지...
: : : :
: : : : 잘부탁드립니다 ^^
|