프로그램의 중복실행을 방지하는 방법으로는 CreateMutex가 많이 쓰이는 것 같습니다.
저는 조금 고전적이지만 이해하기 쉬운 Global Atom Table을 이용한 방법을 소개합니다.
실은 10년전쯤에 컴포넌트로 만든 것을 컴포넌트 설치과정 없이 바로 이용할 수 있도록 단순한 유니트로
바꾼 것입니다.
이용법은 프로그램 소스 내용 중 상수로 정의된 Author와 RunProgram 값을 올바르게 고친 후 프로젝트가 위치한
폴더에 복사해 두고, 아래와 같이 프로젝트 소스화일(*.dpr)의 uses절에 제일 먼저 RunOne을 등록만 하면 됩니다.
uses RunOne,
Forms, . . . .
그리고 RunOne은 실행하고자 하는 프로그램이 이미 실행중일 경우 최소화 상태이면 원래 크기로, 최상위
윈도우가 아니면 최상위 윈도우로 변경하여 사용자가 이전에 이미 실행 중이었다는 것을 바로 인식할 수
있도록 해 줍니다.
아래는 RunOne.pas 소스입니다.
unit RunOne;
interface
uses WinTypes, SysUtils, Forms;
const
Author = 'Silhwan Hyun'; // 저자명 : 실행여부를 검사하기 위한 검색어를 구성함.
RunProgram = 'TClock'; // 프로그램명 : "
implementation
var
AtomText: array[0..63] of Char;
AtomSaved : boolean = false;
MyClassName : array[0..255] of Char;
FoundPrevInst : boolean = false;
PrevInstHandle : HWnd = 0;
FoundAtom : TAtom;
NewAtom : TAtom;
MyPopup : HWnd;
function LookAtAllWindows(Handle: HWnd; Temp: Longint): BOOL; stdcall;
var
ClassName : array[0..255] of Char;
begin
LookAtAllWindows := true;
if GetClassName(Handle, ClassName, SizeOf(ClassName)) > 0 then
begin
if StrComp(ClassName, MyClassName) = 0 then // 동일 window class ?
begin
// 중복실행여부를 조사하기 위한 검색어 생성
StrPCopy(AtomText, Author + RunProgram + IntToStr(Handle));
// 검색어가 Global Atom Table에 등록되어 있는지 확인
FoundAtom := GlobalFindAtom(AtomText);
if FoundAtom <> 0 then // Global Atom Table에 등록되어 있으면
begin
FoundPrevInst := true; // 이미 실행 중인 것으로 표시
PrevInstHandle := Handle; // 실행 중인 어플리케이션 윈도우 핸들
LookAtAllWindows := false; // enumeration 함수를 종료시킨다
end;
end;
end;
end;
initialization
// 프로그램의 클래스명을 알아낸다.
GetClassName(Application.Handle, MyClassName, SizeOf(MyClassName));
// 윈도우를 검색하여 중복실행이 아닌지 확인한다
EnumWindows(@LookAtAllWindows, 0);
if FoundPrevInst then // 이미 실행 중이면
begin
MyPopup := GetLastActivePopup(PrevInstHandle);
BringWindowToTop(PrevInstHandle);
if IsIconic(MyPopup) then
begin
ShowWindow(MyPopup, SW_RESTORE); // 최소화 상태이면 원래 크기로
end else
BringWindowToTop(MyPopup); // 최상위 윈도우로
SetForegroundWindow(MyPopup); // 포커스를 준다. *** Added ***
Halt(0); // 새로 실행한 프로그램은 강제로 종료시킨다
end else
begin
// 실행중이 아니면 검색어를 Global Atom Table에 등록한다
StrPCopy(AtomText, Author + RunProgram + IntToStr(Application.Handle));
NewAtom := GlobalAddAtom(AtomText);
if NewAtom <> 0 then // Global Atom Table에 등록성공이면
AtomSaved := true;
end;
finalization
// 프로그램 종료시는 Global Atom Table에 등록해 둔 검색어를 해제한다.
if AtomSaved then
begin
FoundAtom := GlobalFindAtom(AtomText);
if FoundAtom <> 0 then
GlobalDeleteAtom(FoundAtom);
end;
end.
댓글 중~
단지...
BringWindowToTop 다음에
SetForegroundWindow(MyPopup);
이것을 추가하는것이 더 편할것 같습니다.
어차피 실행할려고 한것이니 최상위 및 원복 후 포커스를 주는것이 좋을듯 합니다. ^^
원본 링크 : http://www.delmadang.com/community/bbs_print.asp?bbsNo=3&bbsCat=0&indx=412497
'공부방 > Delphi' 카테고리의 다른 글
[델파이] 퀀텀그리드 짝수열 색상변경하기 (1) | 2016.03.10 |
---|---|
[델파이] Form 생성에 대한 정리 (0) | 2015.12.14 |
[델파이] DateUtils.pas 날짜 연산 정리 (0) | 2015.05.28 |
[델파이] format 관련 (0) | 2015.03.16 |
[델파이] MastEdit 에 대한 간략한 예시 (0) | 2014.11.12 |