?
Solved

Checking for designtime without ComponentState

Posted on 2003-03-12
12
Medium Priority
?
438 Views
Last Modified: 2010-04-04
Hi,

Is it possible to check for designtime without using the ComponentState property?

Thanks,

/pivar
0
Comment
Question by:pivar
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 3
12 Comments
 
LVL 6

Expert Comment

by:DaFox
ID: 8118994
Hi 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() and compare it to GetCurrentProcessID(). If they are the same the code is running in the context of the IDE process.
If you run it hitting F9 your program runs in a separate process and it'll return false. ;-)

Markus
0
 
LVL 9

Expert Comment

by:mocarts
ID: 8119287
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].ComponentState
  else
    if Screen.DataModuleCount > 0 then
      Result := csDesigning in Screen.DataModules[0].ComponentState
    else
      Result := False;
end;

wbr, mo.
0
 
LVL 6

Expert Comment

by:DaFox
ID: 8119342
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
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 22

Author Comment

by:pivar
ID: 8119947
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].ComponentState does not hold csDesigning, but ComponentState in the component from where I call the function holds csDesigning!

/pivar
0
 
LVL 6

Expert Comment

by:DaFox
ID: 8120023
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(NTQueryInformationProcess) then
    begin
      // Call NtQueryInformationProcess
      NtQueryInformationProcess(GetCurrentProcess,
ProcessBasicInformation,
        PBI, SizeOf(PBI), ReturnLength);
      // Return parent process ID
      Result := PBI.InheritedFromUniqueProcessID;
    end;
    // Release NTDLL
    FreeLibrary(hNTDLL);
  end;
end;

// 9x, ME, 2000, XP
function GetParentProcessIDForWindows: 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(CreateToolhelp32Snapshot) and
       Assigned(Process32First) and
       Assigned(Process32Next) then
    begin
      // Retrieve current process ID for comparison
      ID := GetCurrentProcessId;
      // Create processes snapshot
      Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 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
0
 
LVL 6

Expert Comment

by:DaFox
ID: 8120076
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
0
 
LVL 9

Expert Comment

by:mocarts
ID: 8120255
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(Application.ExeName), 'delphi32.exe');
  // or
  //IsDesignTime := not SameText(GetModuleName(HInstance), Application.ExeName);

end.
0
 
LVL 6

Expert Comment

by:DaFox
ID: 8120331
I just read on the net that this is another possibily:


var
  bDesigning:boolean;
initialization
  bDesigning := assigned(Application.MainForm) and Application.MainForm.Name='AppBuilder');


(never did that though ;-)

Markus
0
 
LVL 22

Author Comment

by:pivar
ID: 8130443
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
0
 
LVL 6

Accepted Solution

by:
DaFox earned 1000 total points
ID: 8130803
I wouldn't mind if you split the points. It's up to you and you have to decide who helped most. If we both, mocarts and I, helped you to understand how to solve your problem go ahead and split the points!

mocarts, are you okay with that?

Markus
0
 
LVL 9

Expert Comment

by:mocarts
ID: 8130957
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(Application.ExeName), 'delphi32.exe');

that's all. and this is the same as checking for MainForm.Name

wbr, mo.
0
 
LVL 22

Author Comment

by:pivar
ID: 8150294
Hi again,

Since I think both answers should be rewarded I also submit a question with 250 points for mocarts.

Thanks,

/pivar
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month8 days, left to enroll

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question