呵呵,下面的代码你可以参考一下,思路就是在用自己的消息循环代替Application对象的消息循环 program Project1;uses windows, Messages, Forms, Unit1 in 'Unit1.pas' {Form1};{$R *.RES} const WM_MY_CREATE_WINDOW = WM_USER + 100;var msg: TMsg; begin Application.Initialize; while GetMessage(Msg, 0, 0, 0) do begin if Msg.message = WM_MY_CREATE_WINDOW then begin Application.CreateForm(TForm1, Form1); end; end; Application.Run; end.
begin hMutex := CreateMutex(nil, False, 'MyProject'); Ret := GetLastError; try if Ret = ERROR_ALREADY_EXISTS then begin SendMsg(WM_MY_CREATE_WINDOW); end else begin Application.Initialize; while not Application.Terminated do begin PeekMessage(Msg, 0, 0, 0, PM_REMOVE); if Msg.message = WM_MY_CREATE_WINDOW then begin ShowMessage('Application.CreateForm(TForm1, Form1);'); Break; end; end; end; finally CloseHandle(hMutex); end; end;function GetThreadId(ProcessName: string): THandle; var SnapshotHandle: THandle; ProcessEntry: TProcessEntry32; ProcessID: DWORD; Next: Boolean; S: string; begin ProcessId := 0; if OsIsNt then begin ProcessID := GetProcessID(ProcessName); end else begin SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if SnapshotHandle <> THandle(-1) then begin ProcessEntry.dwSize := SizeOf(TProcessEntry32); Next := Process32First(SnapshotHandle, ProcessEntry); while Next do begin S := ExtractFileName(ProcessEntry.szExeFile); if CompareText(S, ProcessName) = 0 then begin ProcessID := ProcessEntry.th32ProcessID; Break; end; Next := Process32Next(SnapshotHandle, ProcessEntry); end; CloseHandle(SnapshotHandle); end; end; Result := ProcessID; end; procedure SendMsg(M: DWORD); var ThreadId: DWORD; begin ThreadId := GetThreadId(ExtractFileName(Application.ExeName)); if ThreadId <> 0 then begin PostThreadMessage(ThreadId, M, 0, 0); end; end;这样写还是没有反应,是代码有问题吗???GetThreadId得到的ThreadId与Application.Handle并不一样,是不是这个不一样的ThreadId导致了消息没有收到?????
procedure SendMsg(M: DWORD); var ThreadId: DWORD; begin ThreadId := ProcessId(ExtractFileName(Application.ExeName)); ThreadId := GetThreadId(ThreadId); if ThreadId <> 0 then begin PostThreadMessage(ThreadId, M, 0, 0); end; end;function ProcessId(ProcessName: string): THandle; var SnapshotHandle: THandle; ProcessEntry: TProcessEntry32; ProcessID: DWORD; Next: Boolean; S: string; begin ProcessId := 0; if OsIsNt then begin ProcessID := GetProcessID(ProcessName); end else begin SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if SnapshotHandle <> THandle(-1) then begin ProcessEntry.dwSize := SizeOf(TProcessEntry32); Next := Process32First(SnapshotHandle, ProcessEntry); while Next do begin S := ExtractFileName(ProcessEntry.szExeFile); if CompareText(S, ProcessName) = 0 then begin ProcessID := ProcessEntry.th32ProcessID; Break; end; Next := Process32Next(SnapshotHandle, ProcessEntry); end; CloseHandle(SnapshotHandle); end; end; Result := ProcessID; end;function GetThreadId(ProcessID: DWORD): DWORD; var SnapshotHandle: THandle; Thread32Entry: TThreadEntry32; ThreadId: DWORD; Next: Boolean; begin ThreadId := 0; SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if SnapshotHandle <> THandle(-1) then begin Thread32Entry.dwSize := SizeOf(TThreadEntry32); Next := Thread32First(SnapshotHandle, Thread32Entry); while Next do begin if Thread32Entry.th32OwnerProcessID = ProcessId then begin ThreadId := Thread32Entry.th32ThreadID; Break; end; Next := Thread32Next(SnapshotHandle, Thread32Entry); end; CloseHandle(SnapshotHandle); end; Result := ThreadId; end; hMutex := CreateMutex(nil, False, 'MyProject'); Ret := GetLastError; try if Ret = ERROR_ALREADY_EXISTS then begin SendMsg(WM_MY_CREATE_WINDOW); end else begin Application.Initialize; while True {GetMessage(Msg, 0, 0, 0)} do begin PeekMessage(Msg, 0, 0, 0, PM_REMOVE); if Msg.message = WM_MY_CREATE_WINDOW then begin if Form1 = nil then Application.CreateForm(TForm1, Form1); Break; end; end; end; Application.Run; finally CloseHandle(hMutex); end;成功,散分
program Project1;uses
windows,
Messages,
Forms,
Unit1 in 'Unit1.pas' {Form1};{$R *.RES}
const
WM_MY_CREATE_WINDOW = WM_USER + 100;var
msg: TMsg;
begin
Application.Initialize;
while GetMessage(Msg, 0, 0, 0) do
begin
if Msg.message = WM_MY_CREATE_WINDOW then
begin
Application.CreateForm(TForm1, Form1);
end;
end;
Application.Run;
end.
Application.CreateForm(TForm1, Form1);
下面要有还要 break;用来跳出循环!
有问题:当程序执行到GetMessage时便停住不动了,根本执行不到if判断那。
你可以改用PeekMessage就不会这样了
hMutex := CreateMutex(nil, False, 'MyProject');
Ret := GetLastError;
try
if Ret = ERROR_ALREADY_EXISTS then
begin
SendMsg(WM_MY_CREATE_WINDOW);
end
else
begin
Application.Initialize;
while not Application.Terminated do
begin
PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
if Msg.message = WM_MY_CREATE_WINDOW then
begin
ShowMessage('Application.CreateForm(TForm1, Form1);');
Break;
end;
end;
end;
finally
CloseHandle(hMutex);
end;
end;function GetThreadId(ProcessName: string): THandle;
var
SnapshotHandle: THandle;
ProcessEntry: TProcessEntry32;
ProcessID: DWORD;
Next: Boolean;
S: string;
begin
ProcessId := 0;
if OsIsNt then
begin
ProcessID := GetProcessID(ProcessName);
end else begin
SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapshotHandle <> THandle(-1) then
begin
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
Next := Process32First(SnapshotHandle, ProcessEntry);
while Next do
begin
S := ExtractFileName(ProcessEntry.szExeFile);
if CompareText(S, ProcessName) = 0 then
begin
ProcessID := ProcessEntry.th32ProcessID;
Break;
end;
Next := Process32Next(SnapshotHandle, ProcessEntry);
end;
CloseHandle(SnapshotHandle);
end;
end;
Result := ProcessID;
end;
procedure SendMsg(M: DWORD);
var
ThreadId: DWORD;
begin
ThreadId := GetThreadId(ExtractFileName(Application.ExeName));
if ThreadId <> 0 then
begin
PostThreadMessage(ThreadId, M, 0, 0);
end;
end;这样写还是没有反应,是代码有问题吗???GetThreadId得到的ThreadId与Application.Handle并不一样,是不是这个不一样的ThreadId导致了消息没有收到?????
可用Thread32First(), Thread32Next()找到你要的线程(通过线程的进程ID可识别),然后向此线程发消息
var
ThreadId: DWORD;
begin
ThreadId := ProcessId(ExtractFileName(Application.ExeName));
ThreadId := GetThreadId(ThreadId);
if ThreadId <> 0 then
begin
PostThreadMessage(ThreadId, M, 0, 0);
end;
end;function ProcessId(ProcessName: string): THandle;
var
SnapshotHandle: THandle;
ProcessEntry: TProcessEntry32;
ProcessID: DWORD;
Next: Boolean;
S: string;
begin
ProcessId := 0;
if OsIsNt then
begin
ProcessID := GetProcessID(ProcessName);
end else begin
SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapshotHandle <> THandle(-1) then
begin
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
Next := Process32First(SnapshotHandle, ProcessEntry);
while Next do
begin
S := ExtractFileName(ProcessEntry.szExeFile);
if CompareText(S, ProcessName) = 0 then
begin
ProcessID := ProcessEntry.th32ProcessID;
Break;
end;
Next := Process32Next(SnapshotHandle, ProcessEntry);
end;
CloseHandle(SnapshotHandle);
end;
end;
Result := ProcessID;
end;function GetThreadId(ProcessID: DWORD): DWORD;
var
SnapshotHandle: THandle;
Thread32Entry: TThreadEntry32;
ThreadId: DWORD;
Next: Boolean;
begin
ThreadId := 0;
SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if SnapshotHandle <> THandle(-1) then
begin
Thread32Entry.dwSize := SizeOf(TThreadEntry32);
Next := Thread32First(SnapshotHandle, Thread32Entry);
while Next do
begin
if Thread32Entry.th32OwnerProcessID = ProcessId then
begin
ThreadId := Thread32Entry.th32ThreadID;
Break;
end;
Next := Thread32Next(SnapshotHandle, Thread32Entry);
end;
CloseHandle(SnapshotHandle);
end;
Result := ThreadId;
end; hMutex := CreateMutex(nil, False, 'MyProject');
Ret := GetLastError;
try
if Ret = ERROR_ALREADY_EXISTS then
begin
SendMsg(WM_MY_CREATE_WINDOW);
end
else
begin
Application.Initialize;
while True {GetMessage(Msg, 0, 0, 0)} do
begin
PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
if Msg.message = WM_MY_CREATE_WINDOW then
begin
if Form1 = nil then
Application.CreateForm(TForm1, Form1);
Break;
end;
end;
end;
Application.Run;
finally
CloseHandle(hMutex);
end;成功,散分