Hola,
Aunque los condicionales del compilador son -en mi opinión- más que suficientes para aislar partes del código que queremos ejecutar sólo en determinadas ocasiones, tal como apunta
Neftalí, me gustaría aclarar que esta técnica no discierne realmente si nuestra aplicación está o no ejecutandose desde el IDE, sólo distingue si al momento de compilar está o no definido un símbolo y hay que manipular éste y recompilar cada vez que deseemos cambiar el comportamiento.
Una manera de distinguir si el IDE está ejecutándose podría ser ésta:
Código Delphi
[-]
function IsIDERunning(): Boolean;
begin
Result := FindWindow('TAppBuilder', nil) <> 0;
end;
aunque resulta bastante ingenua
pues sólo detecta si hay una ventana cuya clase se llame 'TAppBuilder' (que es como se llama la ventana principal del IDE de Delphi) pero el IDE podría estar abierto y aún así la aplicación ejecutarse desde fuera.
Una mejor aproximación es encontrando qué proceso lanza nuestra aplicación. Normalmente, si la ejecutamos desde fuera, este proceso será 'explorer.exe', mientras que si lo hacemos desde el IDE será 'delphi32.exe' (al menos para Delphi 7, que es con lo que estoy probando).
Dejo un par de funciones para esto último. La primera busca información de un proceso a partir de su identificador y la segunda deterrmina si la aplicacion la lanzó el IDE (1).
Código Delphi
[-]
function FindProcess(ProcId: Cardinal; out ProcInfo: TProcessEntry32): Boolean;
var
SnapShot: THandle;
TempProcInfo: TProcessEntry32;
begin
SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapShot <> INVALID_HANDLE_VALUE then
try
ZeroMemory(@ProcInfo, SizeOf(ProcInfo));
if Process32First(SnapShot, TempProcInfo) then
repeat
Result := TempProcInfo.th32ProcessID = ProcId;
if Result then
ProcInfo := TempProcInfo;
until Result or not Process32Next(SnapShot, TempProcInfo)
else
Result := false;
finally
CloseHandle(SnapShot);
end
else
raise Exception.Create('Cannot take snapshot of processes');
end;
function RunningFromIDE(): Boolean;
var
ProcInfo: TProcessEntry32;
begin
Result :=
FindProcess(GetCurrentProcessId(), ProcInfo) and
FindProcess(ProcInfo.th32ParentProcessID, ProcInfo) and
(ProcInfo.szExeFile = 'delphi32.exe');
end;
(1) Desde luego, estrictamente hablando, la función RunningFromIDE sólo determina si la aplicación fue lanzada por un proceso llamado 'delphi32.exe' y cualquiera puede hacer un proceso que así se llame y que no sea el IDE
pero bueno, no estamos tratando de establecer un mecanismo de seguridad como los de tiempos antiguos en que los creadores de componentes
shareware intentaban restringir su uso al IDE.
Regresando al punto original, podríamos usar esta función para ejecutar bloques condicionalmente dependiendo de si la aplicación corre
desde el IDE o no:
Código Delphi
[-]
if RunningFromIDE then
begin
end;
Aunque, como digo, la compilación condicional es más que suficiente para estos menesteres, creo que en ocasiones esta técnica puede ser cómoda pues nos evita estar cambiando los símbolos. Por ejemplo, ¿no se aburren de escribir una y otra vez el usuario y contraseña de su sistema cuando están haciendo pruebas? Podríamos poner
Código Delphi
[-]
{$ifdef DEBUG}
txtUsuario.Tet := 'yomero';
txtPassord.Text := 'secreto';
{$endif}
de manera que cada vez que ejecutemos el sistema ya estén escritos nuestros datos. Pero ¿qué pasa si nos olvidamos de quitar el símbolo DEBUG antes de entregar la nueva versión?
Podríamos poner:
Código Delphi
[-]
if RunningFromIDE then
begin
txtUsuario.Tet := 'yomero';
txtPassord.Text := 'secreto';
end;
y despreocuparnos de posibles olvidos.
// Saludos