📄 appinstdemomain.pas
字号:
unit AppInstDemoMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
JclAppInst, ComCtrls, StdCtrls;
type
TForm1 = class(TForm)
InstancesListView: TListView;
Label1: TLabel;
SwitchBtn: TButton;
MsgBtn: TButton;
ColorDialog1: TColorDialog;
Memo1: TMemo;
SendBtn: TButton;
AutoUpdateCheckBox: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure SwitchBtnClick(Sender: TObject);
procedure MsgBtnClick(Sender: TObject);
procedure SendBtnClick(Sender: TObject);
procedure Memo1Change(Sender: TObject);
private
procedure BuildInstancesList;
procedure ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
public
procedure WndProc(var Message: TMessage); override;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const
MaxAllowedInstances = 3;
MyDataKind = 1;
{ TForm1 }
procedure TForm1.BuildInstancesList;
var
I, CurrIndex: Integer;
begin
with InstancesListView, JclAppInstances do
begin
Items.BeginUpdate;
Items.Clear;
for I := 0 to InstanceCount -1 do
with Items.Add do
begin
Caption := IntToStr(I + 1);
SubItems.Add(Format('%.8x', [ProcessIDs[I]]));
SubItems.Add(Format('%.8x', [AppWnds[I]]));
end;
CurrIndex := InstanceIndex[GetCurrentProcessId];
Selected := Items[CurrIndex];
Items.EndUpdate;
end;
Label1.Caption := IntToStr(CurrIndex + 1);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := ApplicationEvents1Message;
BuildInstancesList;
end;
procedure TForm1.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
begin
// AI_* messages handler. These messages are automatically send to all instances
// of the application.
with Msg do
if (hwnd = 0) and (message = JclAppInstances.MessageID) then
begin
case wParam of
AI_INSTANCECREATED, AI_INSTANCEDESTROYED:
BuildInstancesList;
AI_USERMSG:
Label1.Font.Color := TColor(lParam);
end;
Handled := True;
end;
end;
procedure TForm1.SwitchBtnClick(Sender: TObject);
begin
JclAppInstances.SwitchTo(InstancesListView.Selected.Index);
end;
procedure TForm1.MsgBtnClick(Sender: TObject);
begin
with ColorDialog1 do
begin
Color := Label1.Font.Color;
if Execute then
JclAppInstances.UserNotify(Color);
end;
end;
procedure TForm1.SendBtnClick(Sender: TObject);
begin
// TForm.ClassName matches window class name. It sends the data to all windows
// belonging instances of this application. The last parameter identifies the
// 'TForm1' (ClassName) window of this instance.
JclAppInstances.SendStrings(ClassName, MyDataKind, Memo1.Lines, Handle);
end;
var
MemoChanging: Boolean;
procedure TForm1.WndProc(var Message: TMessage);
begin
// Interprocess communication handler.
// First check whether we can safely read TForm.Handle property ...
if HandleAllocated and not (csDestroying in ComponentState) then
begin
// ... then whether it is our message. The last paramter tells to ignore the
// message sent from window of this instance
case ReadMessageCheck(Message, Handle) of
MyDataKind: // It is our data
begin
MemoChanging := True; // prevent deadlock, TMemo.OnChange is also fired now
Memo1.Lines.BeginUpdate;
try
// Read TStrings from the message
ReadMessageStrings(Message, Memo1.Lines)
finally
Memo1.Lines.EndUpdate;
MemoChanging := False;
end;
end;
else
inherited;
end;
end
else
inherited;
end;
procedure TForm1.Memo1Change(Sender: TObject);
begin
if not MemoChanging and AutoUpdateCheckBox.Checked then
SendBtnClick(nil);
end;
initialization
with JclAppInstances do
// CheckInstance returns False if current instance number is greater than
// MaxAllowedInstances constant
if not CheckInstance(MaxAllowedInstances) then
begin
// Switch to the first instance of the application
SwitchTo(0);
// Close this instance
KillInstance;
end;
// Note: For preventing more than one instance of the application you can put
// simple JclAppInstances.CheckSingleInstance line to initialization section
// instead of code above
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -