........ Despues de todos estos halagos, viene otra inquietud. ........
vaya amigo Luciano, que diplomático jejejeje
Salud OS
Asi soy yo con mi amigo Escafandra
Caramba, si que son alagos y diplomacia internacional, qué barbaridad.
Por otro lado, en la funcion de escafandra, donde debo ponerle el nombre de la aplicacion que quiero que se restaure, porque si tengo minimizadas varias aplicaciones, como ibexpert u otras, todas se restauran.
Te explico. La función está diseñada para usar el Path completo de la aplicación como semilla para crear el mutex. Un archivo sólo puede tener una única ruta en un PC. La limitación que podemos tener es que tengamos dos copias del programa en rutas diferentes, en ese caso lo considera distintas aplicaciones pues los mutex no coincidirán.
En la función que he escrito, enumero todas las ventanas del sistema para buscar el proceso que tenga el mutex de nuestra aplicación. Para encontar el Path del proceso de cada ventana uso la API
GetWindowModuleFileName. Esta API no funciona muy bien cuando se la llama para encontrar el Path de una ventana de otra aplicación, así que otras aplicaciones escritas en delphi o builder pueden interferir. Para resolver este problema he escrito otra función que devuelve con fiabilidad el nombre completo del ejecutable de un proceso.
Podría escogerse otra forma de calcular el mutex, pero vamos a seguir con el mismo sistema.
Para no complicar mucho la cosa publico de nuevo el código tal como quedaría con la modificación:
program Project1;
uses
Windows, Forms, Tlhelp32,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
Buffer: array [0..MAX_PATH] of char;
c: PCHAR;
Mutex: THandle;
Pid: DWORD;
function GetProcessImageFileName(PId: DWORD; ExePath: PCHAR; Size: integer): boolean;
var
hSnapshot: THandle;
ModEntry: MODULEENTRY32;
begin
Result:= True;
if (PId = 0) and (Size > 0) then
begin
ExePath[0]:= #0;
exit;
end;
ModEntry.dwSize:= sizeof(MODULEENTRY32);
Result:= false;
if Size>0 then ExePath[0]:= #0;
hSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PId);
if hSnapshot <> -1 then
begin
if Module32First(hSnapshot, ModEntry) then
begin
Result:= true;
lstrcpyn(ExePath, ModEntry.szExePath, Size);
end;
CloseHandle(hSnapshot);
end;
end;
function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
var
Mutex: THandle;
begin
Result:= true;
GetWindowThreadProcessId(Handle, Pid);
if GetCurrentProcessId <> Pid then
begin
if GetProcessImageFileName(Pid, @Buffer, sizeof(Buffer)) then
begin
c:= Buffer;
repeat Inc(c); if c^ = '\' then c^:= '*'; until c^ = #0;
Mutex:= CreateMutex(nil, FALSE, Buffer);
GetClassName(Handle, Buffer, Sizeof(Buffer));
if (GetLastError <> 0) and (lstrcmp('TApplication', Buffer) = 0) then
begin
ShowWindow(Handle, SW_RESTORE);
SetForegroundWindow(Handle);
end;
if Mutex <> 0 then CloseHandle(Mutex);
end;
end;
end;
begin
GetModuleFileName(0, Buffer, MAX_PATH);
c:= Buffer;
repeat Inc(c); if c^ = '\' then c^:= '*'; until c^ = #0;
Mutex:= CreateMutex(nil, FALSE, Buffer);
if GetLastError <> 0 then
begin
EnumWindows(@EnumWindowsProc, 0);
exit;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
if Mutex <> 0 then CloseHandle(Mutex);
end.
Saludos.
Edito para reparar etiqueta de código.