妖哥 2008-4-8 20:21
防止程序重复执行的单元
[color=#008000]//工程引用此单元就能防止同时出现多个实例
[/color][b][color=#000080]unit[/color][/b] MultInst;
[b][color=#000080]interface[/color][/b]
[b][color=#000080]uses[/color][/b]
Windows ,Messages, SysUtils, Classes, Forms;
[b][color=#000080]implementation[/color][/b]
[b][color=#000080]const[/color][/b]
STR_UNIQUE = '[color=#008000]{2BE6D96E-827F-4BF9-B33E-8740412CDE96}[/color]';
MI_ACTIVEAPP = [color=#0000ff]1[/color]; [color=#008000]{激活应用程序}[/color]
MI_GETHANDLE = [color=#0000ff]2[/color]; [color=#008000]{取得句柄}[/color]
[b][color=#000080]var[/color][/b]
iMessageID : Integer;
OldWProc : TFNWndProc;
MutHandle : THandle;
BSMRecipients : DWORD;
[b][color=#000080]function[/color][/b] NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
Longint; [b][color=#000080]stdcall[/color][/b];
[b][color=#000080]begin[/color][/b]
Result := [color=#0000ff]0[/color];
[b][color=#000080]if[/color][/b] Msg = iMessageID [b][color=#000080]then[/color][/b]
[b][color=#000080]begin[/color][/b]
[b][color=#000080]case[/color][/b] wParam [b][color=#000080]of[/color][/b]
MI_ACTIVEAPP: [color=#008000]{激活应用程序}[/color]
[b][color=#000080]if[/color][/b] lParam<>[color=#0000ff]0[/color] [b][color=#000080]then[/color][/b]
[b][color=#000080]begin[/color][/b]
[color=#008000]{收到消息的激活前一个实例}[/color]
[color=#008000]{为什么要在另一个程序中激活?}[/color]
[color=#008000]{因为在同一个进程中SetForegroundWindow并不能把窗体提到最前}[/color]
[b][color=#000080]if[/color][/b] IsIconic(lParam) [b][color=#000080]then[/color][/b]
OpenIcon(lParam)
[b][color=#000080]else[/color][/b]
SetForegroundWindow(lParam);
Application[color=#0000ff].[/color]Terminate; [color=#008000]{终止本实例}[/color]
[b][color=#000080]end[/color][/b];
MI_GETHANDLE: [color=#008000]{取得程序句柄}[/color]
[b][color=#000080]begin[/color][/b]
PostMessage(HWND(lParam), iMessageID, MI_ACTIVEAPP,
Application[color=#0000ff].[/color]Handle);
[b][color=#000080]end[/color][/b];
[b][color=#000080]end[/color][/b];
[b][color=#000080]end[/color][/b]
[b][color=#000080]else[/color][/b]
Result := CallWindowProc(OldWProc, Handle, Msg, wParam, lParam);
[b][color=#000080]end[/color][/b];
[b][color=#000080]procedure[/color][/b] InitInstance;
[b][color=#000080]begin[/color][/b]
[color=#008000]{取代应用程序的消息处理}[/color]
OldWProc := TFNWndProc(SetWindowLong(Application[color=#0000ff].[/color]Handle, GWL_WNDPROC,
Longint(@NewWndProc)));
[color=#008000]{打开互斥对象}[/color]
MutHandle := OpenMutex(MUTEX_ALL_ACCESS, [b][color=#000080]False[/color][/b], STR_UNIQUE);
[b][color=#000080]if[/color][/b] MutHandle = [color=#0000ff]0[/color] [b][color=#000080]then[/color][/b]
[b][color=#000080]begin[/color][/b]
[color=#008000]{建立互斥对象}[/color]
MutHandle := CreateMutex([b][color=#000080]nil[/color][/b], [b][color=#000080]False[/color][/b], STR_UNIQUE);
[b][color=#000080]end[/color][/b]
[b][color=#000080]else[/color][/b] [b][color=#000080]begin[/color][/b]
Application[color=#0000ff].[/color]ShowMainForm := [b][color=#000080]False[/color][/b];
[color=#008000]{已经有程序实例,广播消息取得实例句柄}[/color]
BSMRecipients := BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK [b][color=#000080]or[/color][/b] BSF_POSTMESSAGE,
@BSMRecipients, iMessageID, MI_GETHANDLE,Application[color=#0000ff].[/color]Handle);
[b][color=#000080]end[/color][/b];
[b][color=#000080]end[/color][/b];
[b][color=#000080]initialization[/color][/b]
[color=#008000]{注册消息}[/color]
iMessageID := RegisterWindowMessage(STR_UNIQUE);
InitInstance;
[b][color=#000080]finalization[/color][/b]
[color=#008000]{还原消息处理过程}[/color]
[b][color=#000080]if[/color][/b] OldWProc <> [b][color=#000080]Nil[/color][/b] [b][color=#000080]then[/color][/b]
SetWindowLong(Application[color=#0000ff].[/color]Handle, GWL_WNDPROC, LongInt(OldWProc));
[color=#008000]{关闭互斥对象}[/color]
[b][color=#000080]if[/color][/b] MutHandle <> [color=#0000ff]0[/color] [b][color=#000080]then[/color][/b] CloseHandle(MutHandle);
[b][color=#000080]end[/color][/b].