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
[15752] Re:윈도우즈종료와 프로그램 강제종료.
임문환 [] 2701 읽음    2002-02-24 14:57
유지상 님이 쓰신 글 :
: 저는 간단한 노트형태의 윈도우들을 데스크탑에 돌아다니게 하는 프로그램을 제작하고 있습니다.
: 이 프로그램은 윈도우즈가 돌아가고 있을 때는 항상 켜져 있어야 합니다.
: 즉, 윈도우즈가 부팅되면, 이 노트프로그램도 자동으로 실행됩니다.(시작프로그램 디렉토리에 링크파일을 올려주면 이렇게 되지요.)
: 그리고, 사용자가 직접 노트프로그램을 종료하지 않는한은 윈도우즈가 종료될 때 까지 계속 running 하게 됩니다.
: 저는 이 노트프로그램의 메인폼의 OnClose()루틴 속에 노트정리된 정보들을 모두 저장하는 루틴이 포함되어있씁니다.
: 즉, 이 노트프로그램이 종료되면서 자신의 정보를 설정파일에 저장합니다.
: 그리고 윈도우즈가 다시 부팅되어서 노트프로그램이 다시 실행되게 되면, 설정파일에서 정보를 복구하게 되는 것입니다.
: 그런데 제가 테스트로 메인폼의 OnClose()함수 내에 ShowMessage("OnClose"); 를 삽입해봤습니다.
: 이때, 윈도우즈가 종료되면서 (제가 사용하는 것은 windows XP) 그 윈도우즈는 이 때 켜져 있는 프로그램들이 무엇이 있나를 찾아본 후, 켜져 있는 프로그램들을 강제종료하게 됩니다.
: 제 노트프로그램이 강제종료될 때, ShowMessage("OnClose"); 는 실행되지 않았습니다.
: 즉, 메인폼의 OnClose()함수는 실행되지 않은 것입니다. 따라서 설정파일에 정보저장하는 루틴도 실행되지 않은 체 강제종료되는 것이었씁니다.
: 이 문제를 어떻게 해결하면 좋을까요?
:
: (질문1) 윈도우즈종료될때, 윈도우즈가 강제종료를 시행하기 전에, 제 노트프로그램이 알아서, 그 전에 정상적으로 종료를 하게 하려면 어떻게 해야 하나요?
:
: (질문2) 이 노트프로그램의 링크를 사용자가 원하는 대로 시작프로그램디렉토리에 생성했다가 지웠다가 해야 하는데, 이를 위해서 링크를 생성해주는 함수는 무엇인가요?
:
:



Windows 운영체제 종료 시 작업을 해야 한다면 아래와같이 하시면 됩니다.
참고로, 응용 프로그램에서 Windows를 종료시키려면 ExitWindowsEx() API 함수를 사용합니다.



//헤더 파일
class TForm1 : public TForm
{
//중략
void __fastcall WMQueryEndSession(Messages::TMessage &Msg);
void __fastcall WMEndSession(Messages::TMessage &Msg);
    BEGIN_MESSAGE_MAP
      MESSAGE_HANDLER(WM_QUERYENDSESSION,TMessage,WMQueryEndSession);
      MESSAGE_HANDLER(WM_ENDSESSION,TMessage,WMEndSession);
    END_MESSAGE_MAP(TForm);
};


//유닛 파일

//---------------------------------------------------------------------------
//Windows 운영체제가 종료하려할 때 현재 실행 중인 각 프로그램에게
//종료 가능여부를 물음
void __fastcall TForm1::WMQueryEndSession(TMessage &Msg)
{
Msg.Result=1; //종료 가능 ,
//종료하지 못하게 하려면 Msg.Result=0;

}

//---------------------------------------------------------------------------
//Windows 운영체제가 종료
void __fastcall TForm1::WMEndSession(TMessage &Msg)
{
if(Msg.WParam==true)
{
  //Windows 운영체제 종료 시 처리할 작업 수행
}
Msg.Result=0;
}


//아래 예제는 어디에선가 가져온 것인데 잘 기억이 나질 않는군요.

//단축 아이콘

#include <shlobj.hpp>

//----------------------------------------------------------------------
//바탕화면에 단축 아이콘 만들기
bool  CreateShortCut(const AnsiString &file, const AnsiString &linkName)
{
    IShellLink* pLink;
    IPersistFile* pPersistFile;
    LPMALLOC      ShellMalloc;
    LPITEMIDLIST  DesktopPidl;
    char DesktopDir[MAX_PATH];

    // pidl  을 하나 만들 때, 이것은 쉘의 mallocator에 의해
    // 해제 되어야 한다.  쉘의 mallocator 객체는
    // API SHGetMalloc 함수를 통해서 얻을 수 있다.
    if(FAILED(SHGetMalloc(&ShellMalloc)))
        return false;

    // 데스크탑 디렉토리에 대한  pidl 을 얻기 위해 다음과 같이 작성한다.
    // 함수가 실패하면 아무런 처리도 하지 않게 된다.
    if(FAILED(SHGetSpecialFolderLocation(NULL,
                                         CSIDL_DESKTOPDIRECTORY,
                                         &DesktopPidl)))
        return false;

    // pidl을 문자열로 바꾼다.

    if(!SHGetPathFromIDList(DesktopPidl, DesktopDir))
    {
        ShellMalloc->Free(DesktopPidl);
        ShellMalloc->Release();
        return false;
    }

    // pidl 을 해제한다.
    ShellMalloc->Free(DesktopPidl);
    ShellMalloc->Release();

// 제일 먼저, COM 라이브러리를 초기화한다.
    if(SUCCEEDED(CoInitialize(NULL)))
    {
        // CoInitialize 가 성공하면 CoCreateInstance를 호출해
// 인스턴스를 생성한다.
        if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL,
                                      CLSCTX_INPROC_SERVER,
                                      IID_IShellLink, (void **) &pLink)))
        {
            // 인스턴스가 생성되면, 그 안에 필요한 속성을 채운다.
            pLink->SetPath(file.c_str());
            pLink->SetDescription("단축 아이콘 생성");
            pLink->SetShowCmd(SW_SHOW);

            // 이제 필요한 과정은 하드 드라이브에 대한 단축키 지정이다.
            // IShellLink 객체는 IPersistFile 인터페이스도 생성해준다.
            // QueryInterface 를 사용해 이 객체의 IPersistFile 부분을 얻는다.
            if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile,
                                               (void **)&pPersistFile)))
            {
                // 성공하면, 단축키를 작성하기 위해
                // IPersistFile 를 저장한다.
                WideString strShortCutLocation((String(DesktopDir)+"\\" + linkName).c_str());
                pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
                pPersistFile->Release();
                pLink->Release();
                CoUninitialize();
                return true;
            }
            pLink->Release();
        }

        // 마지막으로 인스턴스에 대한 메모리로부터의 해제를 위해 CoUninitialize
// 를 호출한다.
        CoUninitialize();
    }
    return false;
}
:
:

+ -

관련 글 리스트
15741 윈도우즈종료와 프로그램 강제종료. 유지상 1478 2002/02/23
15752     Re:윈도우즈종료와 프로그램 강제종료. 임문환 2701 2002/02/24
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.