![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Mutex [D5, D7, WinXP]
вп © (2005-11-04 09:17:00)Вопрос такого характера: использую мютекс для предотвращения повторной загрузки приложения... Можно ли (и как, если возможно) сделать так, что бы второй экземпляр приложения не просто выдавал сообщение , о том, что уже запущена копия данного приложения, но и активировал(переводил фокус) на запущенную копию..
Leonid Troyanovsky (2005-11-09 17:30:00) [1]
> вп (04.11.05 09:17)
> Вопрос такого характера: использую мютекс для предотвращения
> повторной загрузки приложения... Можно ли (и как, если возможно)
> сделать так, что бы второй экземпляр приложения не просто
> выдавал сообщение , о том, что уже запущена копия данного
> приложения, но и активировал(переводил фокус) на запущенную
> копию..
Для этого нужен уже не мьютекс, а, по-крайней мере, семафор,
чтобы хранить значение хендла окна (приложения).
--
Regards, LVT.
gdaujk (2005-11-09 17:26:00) [2]вп (09.11.05 09:35) [3]
Да.
cp.Silver © (09.11.05 16:51) [4]
Неплохо, если ещё где-нибудь добавить вызов
procedure ForceForegroundWindow();
чтоб "фокус" перевести...
cp.Silver (2005-11-09 16:51:00) [3]Вот рабочий пример:
делаешь отдельный unit:
unit check;
interface
implementation
uses
Windows;
var
Mutex: THandle;
MutexName: array[0..255] of Char;
function StopLoading: Boolean;
var
l, i: integer;
begin
l:= GetModuleFileName(MainInstance, MutexName, SizeOf(MutexName));
for i:= 0 to l - 1 do
if MutexName[i] = '\' then
begin
MutexName[i]:= '/';
end;
Mutex:= CreateMutex(nil, False, MutexName);
Result:= (Mutex = 0) or (GetLastError = ERROR_ALREADY_EXISTS);
end;
initialization
if StopLoading then halt;
finalization
if Mutex <> 0 then CloseHandle(Mutex);
end.
И затем модифицируешь свой файл проекта (dpr):
program InControl;
uses
Windows,
check,
Forms,
main in 'main.pas' {frmMain};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end.
вп (2005-11-09 09:35:00) [4]А что такое MainWnd ? =YourMainWndProc?
gdaujk (2005-11-04 13:05:00) [5]Я делаю так:
program YourProgram;
var
UniqueMes: Integer;
hMutex: THandle;
const
UNIQUE_APP_STR = 'Your_Very_Unique_App_Str';
{WinMain}
function YourMainWndProc(aWND: HWND; aMsg: Integer; aWParam: WPARAM; aLParam: LPARAM): Integer; stdcall;
procedure ForceForegroundWindow();
var
fPID, cPID: DWORD;
begin
fPID := GetWindowThreadProcessId(GetForegroundWindow, nil);
cPID := GetWindowThreadProcessId(MainWnd, nil);
AttachThreadInput(fPID, cPID, True);
ShowWindow(MainWnd, SW_SHOW);
SetForegroundWindow(MainWnd);
AttachThreadInput(fPID, cPID, False);
end;
begin
Result := 0;
if aMsg = UniqueMes then ForceForegroundWindow;
case aMsg of
//
else
Result := DefWindowProc(aWND, aMsg, aWParam, aLParam);
end
end;
begin
UniqueMes := RegisterWindowMessage(UNIQUE_APP_STR);
hMutex := CreateMutex(nil, False, UNIQUE_APP_STR);
if GetLastError = ERROR_ALREADY_EXISTS then
begin
PostMessage(HWND_BROADCAST, UniqueMes, 0, 0);
Exit;
end;
//your code
end;
Процедура ForceForegroundWindow позволяет вывести окно первого экземпляра приложения на передний план, а не просто заставить кнопку на панели задач мигать.
PS: Всё вышеописанное проверялось только на XP...
Чапаев (2005-11-04 09:46:00) [6]В советах Валентина Озерова точно было. Поищи.