pivar
asked on
Checking for designtime without ComponentState
Hi,
Is it possible to check for designtime without using the ComponentState property?
Thanks,
/pivar
Is it possible to check for designtime without using the ComponentState property?
Thanks,
/pivar
is it called TAppWindow? I remember (and to be sure I looked with WinSight) TAppBuilder. anyway that's not good idea to check for designtime.
if your app contains forms or datamodules you can use this function:
// uses Screen variable, but that requires Forms in uses.
function IsDesignTime: boolean;
begin
if Screen.FormCount > 0 then
Result := csDesigning in Screen.Forms[0].ComponentS tate
else
if Screen.DataModuleCount > 0 then
Result := csDesigning in Screen.DataModules[0].Comp onentState
else
Result := False;
end;
wbr, mo.
if your app contains forms or datamodules you can use this function:
// uses Screen variable, but that requires Forms in uses.
function IsDesignTime: boolean;
begin
if Screen.FormCount > 0 then
Result := csDesigning in Screen.Forms[0].ComponentS
else
if Screen.DataModuleCount > 0 then
Result := csDesigning in Screen.DataModules[0].Comp
else
Result := False;
end;
wbr, mo.
Hi mocarts.
> anyway that's not good idea to check for designtime
That's why I asked pivar why he does not want to use the "normal" ComponentState way. But it's reliable and I can't think of bad side effects atm.
> is it called TAppWindow? I remember (and to be sure I looked with WinSight) TAppBuilder
Don't know exactly. I don't have access to my Delphi atm :(
Markus
> anyway that's not good idea to check for designtime
That's why I asked pivar why he does not want to use the "normal" ComponentState way. But it's reliable and I can't think of bad side effects atm.
> is it called TAppWindow? I remember (and to be sure I looked with WinSight) TAppBuilder
Don't know exactly. I don't have access to my Delphi atm :(
Markus
ASKER
Thanks for your replies,
The background is that I have a function that is called by several different components, recent changes make me have to check for designtime in this function. I don't want to check ComponentState in the component before calling the function since this I do this in a lot of places and it will give me a lot of work. Nor do I want to send the component in every function-call for the same reason.
I've tested both solutions and I can't get neither to work.
Markus, there is no window called "TAppWindow" (in D5 anyway), but there is a "TAppBuilder". But I receive different process ids from GetWindowThreadProcessID and GetCurrentProcessID, so this return false.
Mocarts, I do have Forms and DataModules (both Counts are > 0) but Screen.Forms[0].ComponentS tate does not hold csDesigning, but ComponentState in the component from where I call the function holds csDesigning!
/pivar
The background is that I have a function that is called by several different components, recent changes make me have to check for designtime in this function. I don't want to check ComponentState in the component before calling the function since this I do this in a lot of places and it will give me a lot of work. Nor do I want to send the component in every function-call for the same reason.
I've tested both solutions and I can't get neither to work.
Markus, there is no window called "TAppWindow" (in D5 anyway), but there is a "TAppBuilder". But I receive different process ids from GetWindowThreadProcessID and GetCurrentProcessID, so this return false.
Mocarts, I do have Forms and DataModules (both Counts are > 0) but Screen.Forms[0].ComponentS
/pivar
Sorry, you have to get the parent pid.
Use:
// NT
function GetParentProcessIDForNT: Integer;
var
hNTDLL: Integer;
NtQueryInformationProcess: TNtQueryInformationProcess ;
PBI: TProcessBasicInformation;
ReturnLength: Integer;
begin
Result := 0;
// Attempt to load NTDLL
hNTDLL := LoadLibrary('NTDLL.DLL');
if hNTDLL <> 0 then
begin
// Retrieve address of NtQueryInformationProcess
NtQueryInformationProcess := GetProcAddress(hNTDLL,
'NtQueryInformationProcess ');
if Assigned(NTQueryInformatio nProcess) then
begin
// Call NtQueryInformationProcess
NtQueryInformationProcess( GetCurrent Process,
ProcessBasicInformation,
PBI, SizeOf(PBI), ReturnLength);
// Return parent process ID
Result := PBI.InheritedFromUniquePro cessID;
end;
// Release NTDLL
FreeLibrary(hNTDLL);
end;
end;
// 9x, ME, 2000, XP
function GetParentProcessIDForWindo ws: Integer;
var
Kernel32: THandle;
CreateToolhelp32Snapshot: TCreateToolhelp32Snapshot;
Process32First: TProcess32First;
Process32Next: TProcess32Next;
Snapshot: THandle;
Entry: TProcessEntry32;
WalkResult: Boolean;
ID: ULONG;
begin
Result := 0;
// Attempt to load KERNEL32
Kernel32 := LoadLibrary('KERNEL32.DLL' );
if Kernel32 <> 0 then
begin
// Retrieve ToolHelp32 function addresses
CreateToolhelp32Snapshot :=
GetProcAddress(Kernel32, 'CreateToolhelp32Snapshot' );
Process32First := GetProcAddress(Kernel32, 'Process32First');
Process32Next := GetProcAddress(Kernel32, 'Process32Next');
if Assigned(CreateToolhelp32S napshot) and
Assigned(Process32First) and
Assigned(Process32Next) then
begin
// Retrieve current process ID for comparison
ID := GetCurrentProcessId;
// Create processes snapshot
Snapshot := CreateToolhelp32Snapshot(T H32CS_SNAP PROCESS, 0);
if Integer(Snapshot) <> -1 then
begin
// Start walking list of processes
Entry.dwSize := SizeOf(TProcessEntry32);
WalkResult := Process32First(Snapshot, Entry);
// Walk through entire list until result can be determined
while (GetLastError <> ERROR_NO_MORE_FILES) and (Result = 0)
do
begin
if WalkResult then
begin
// If this is the current process, return its parent
if Entry.th32ProcessID = ID then
Result := Entry.th32ParentProcessID;
end;
// Move to next item in the process list
Entry.dwSize := SizeOf(TProcessEntry32);
WalkResult := Process32Next(Snapshot, Entry);
end;
// Release handle to the snapshot
CloseHandle(Snapshot);
end;
end;
// Release KERNEL32
FreeLibrary(Kernel32);
end;
end;
Markus
Use:
// NT
function GetParentProcessIDForNT: Integer;
var
hNTDLL: Integer;
NtQueryInformationProcess:
PBI: TProcessBasicInformation;
ReturnLength: Integer;
begin
Result := 0;
// Attempt to load NTDLL
hNTDLL := LoadLibrary('NTDLL.DLL');
if hNTDLL <> 0 then
begin
// Retrieve address of NtQueryInformationProcess
NtQueryInformationProcess := GetProcAddress(hNTDLL,
'NtQueryInformationProcess
if Assigned(NTQueryInformatio
begin
// Call NtQueryInformationProcess
NtQueryInformationProcess(
ProcessBasicInformation,
PBI, SizeOf(PBI), ReturnLength);
// Return parent process ID
Result := PBI.InheritedFromUniquePro
end;
// Release NTDLL
FreeLibrary(hNTDLL);
end;
end;
// 9x, ME, 2000, XP
function GetParentProcessIDForWindo
var
Kernel32: THandle;
CreateToolhelp32Snapshot: TCreateToolhelp32Snapshot;
Process32First: TProcess32First;
Process32Next: TProcess32Next;
Snapshot: THandle;
Entry: TProcessEntry32;
WalkResult: Boolean;
ID: ULONG;
begin
Result := 0;
// Attempt to load KERNEL32
Kernel32 := LoadLibrary('KERNEL32.DLL'
if Kernel32 <> 0 then
begin
// Retrieve ToolHelp32 function addresses
CreateToolhelp32Snapshot :=
GetProcAddress(Kernel32, 'CreateToolhelp32Snapshot'
Process32First := GetProcAddress(Kernel32, 'Process32First');
Process32Next := GetProcAddress(Kernel32, 'Process32Next');
if Assigned(CreateToolhelp32S
Assigned(Process32First) and
Assigned(Process32Next) then
begin
// Retrieve current process ID for comparison
ID := GetCurrentProcessId;
// Create processes snapshot
Snapshot := CreateToolhelp32Snapshot(T
if Integer(Snapshot) <> -1 then
begin
// Start walking list of processes
Entry.dwSize := SizeOf(TProcessEntry32);
WalkResult := Process32First(Snapshot, Entry);
// Walk through entire list until result can be determined
while (GetLastError <> ERROR_NO_MORE_FILES) and (Result = 0)
do
begin
if WalkResult then
begin
// If this is the current process, return its parent
if Entry.th32ProcessID = ID then
Result := Entry.th32ParentProcessID;
end;
// Move to next item in the process list
Entry.dwSize := SizeOf(TProcessEntry32);
WalkResult := Process32Next(Snapshot, Entry);
end;
// Release handle to the snapshot
CloseHandle(Snapshot);
end;
end;
// Release KERNEL32
FreeLibrary(Kernel32);
end;
end;
Markus
BTW:
1. > Nor do I want to send the component in every function-call for the same reason.
What about a global var?
2. You're right, it's called "TAppBuilder"
Markus
1. > Nor do I want to send the component in every function-call for the same reason.
What about a global var?
2. You're right, it's called "TAppBuilder"
Markus
how about to check Application.ExeName?
in designtime it is delphi32.exe..
you can additionaly compare Application.ExeName against Module name where component resides.
interface
...
var
IsDesignTime: boolean = False;
implementation
// copied from sysutils (not exported)
function GetModuleName(Module: HMODULE): string;
var
ModName: array[0..MAX_PATH] of Char;
begin
SetString(Result, ModName, Windows.GetModuleFileName( Module, ModName, SizeOf(ModName)));
end;
initialization
IsDesignTime := SameText(ExtractFileName(A pplication .ExeName), 'delphi32.exe');
// or
//IsDesignTime := not SameText(GetModuleName(HIn stance), Application.ExeName);
end.
in designtime it is delphi32.exe..
you can additionaly compare Application.ExeName against Module name where component resides.
interface
...
var
IsDesignTime: boolean = False;
implementation
// copied from sysutils (not exported)
function GetModuleName(Module: HMODULE): string;
var
ModName: array[0..MAX_PATH] of Char;
begin
SetString(Result, ModName, Windows.GetModuleFileName(
end;
initialization
IsDesignTime := SameText(ExtractFileName(A
// or
//IsDesignTime := not SameText(GetModuleName(HIn
end.
I just read on the net that this is another possibily:
var
bDesigning:boolean;
initialization
bDesigning := assigned(Application.MainF orm) and Application.MainForm.Name= 'AppBuilde r');
(never did that though ;-)
Markus
var
bDesigning:boolean;
initialization
bDesigning := assigned(Application.MainF
(never did that though ;-)
Markus
ASKER
Thanks for all replies,
I will use Markus last suggestion. But I don't know if we should split the points, or? I think Mocarts suggestion was on the same level as Markus, but uses a little more overhead.
What do you think?
/pivar
I will use Markus last suggestion. But I don't know if we should split the points, or? I think Mocarts suggestion was on the same level as Markus, but uses a little more overhead.
What do you think?
/pivar
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I don't mind. but DaFox presented here more advanced tehniques :) so you can give him more points :)
there is no overhead in my example - you don't need this GetModuleName if you use uncommented code:
initialization
IsDesignTime := SameText(ExtractFileName(A pplication .ExeName), 'delphi32.exe');
that's all. and this is the same as checking for MainForm.Name
wbr, mo.
there is no overhead in my example - you don't need this GetModuleName if you use uncommented code:
initialization
IsDesignTime := SameText(ExtractFileName(A
that's all. and this is the same as checking for MainForm.Name
wbr, mo.
ASKER
Hi again,
Since I think both answers should be rewarded I also submit a question with 250 points for mocarts.
Thanks,
/pivar
Since I think both answers should be rewarded I also submit a question with 250 points for mocarts.
Thanks,
/pivar
Why don't you want to use the ComponentState property??
Solution:
Use FindWindow() to look for a window classname "TAppWindow". If you succeed use GetWindowThreadProcessID()
If you run it hitting F9 your program runs in a separate process and it'll return false. ;-)
Markus