Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Modal Form doesn't close.

15 views
Skip to first unread message

Eshwar

unread,
Mar 3, 2010, 12:58:34 PM3/3/10
to
I call a modal form from the main form, just like the way it works. I
read a primer on how to use modal forms, understood it well to write
my code. I can open the form, but when i click the title bar exit
button it doesn't close. I want the modal form, which is Form2 to exit
and Form1 the mainform to remain.

Then i used a button to exit, wrote like Application.Terminate; or
Form2.Close or Form2.hide, Form2.Destroy, it throws an exception :(

I attach the Form1 procedure, from which i call the modal form, Form2,
below:
procedure TForm1.sLabel3Click(Sender: TObject);
var
f:Tform2;
begin
f := Tform2.Create(nil);
try
f.ShowModal;

finally
f.Release;
end;
end;

Its a label, clicking that opens the Form2

Here is the full code of Form2, its a code to get cpu usage per core
in a progress bar. Its in Delphi 7
===============================================================================
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, JwaWindows, ExtCtrls, ComCtrls, Gauges;

type
TForm2 = class(TForm)
Timer33: TTimer;
StopBtn: TButton;
procedure FormCreate(Sender: TObject);
procedure Timer33Timer(Sender: TObject);
procedure StopBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TCounter = record
Path : string;
Handle : cardinal;
mLabel : TLabel;
mGauge : TGauge;
end;

var
Form2: TForm2;
Counters : array of TCounter;
Query : Cardinal = 0;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
var
dwSize, h : cardinal;
cnt, i : Integer;
pPaths:PAnsiChar;
pIterator:PAnsiChar;
InstanceId, CounterPath : string;
status : PDH_STATUS;
begin
//Create a performance query
if PdhOpenQuery(nil, 0, Query) = ERROR_SUCCESS then begin

//Get all valid processor/core usage counter paths by expanding
//a wildcard path. To do this, we must first call
PdhExpandWildCardPath
//with buffer size set to zero to get the actual required buffer
size.
dwSize := 0;
pPaths := nil;

status := PdhExpandWildCardPath(
nil, //search the local
computer
'\Processor(*/*#*)\% Processor Time', //we want CPU usage
counters for all CPUs/cores
pPaths, //user-allocated buffer;
currently null
dwSize, //buffer size
0) ; //no flags

if status = PDH_MORE_DATA then begin
dwSize := dwSize + 1; //+1 byte required in XP and below.
pPaths := GetMemory(dwSize); //Allocate an output buffer.

//Really get the counter paths.
status := PdhExpandWildCardPath(
nil,
'\Processor(*/*#*)\% Processor Time',
pPaths,
dwSize,
0) ;

if status = ERROR_SUCCESS then begin

cnt := 0;
SetLength(Counters, 32);

//PdhExpandWildCardPath returns the counter list (pPaths) as
an array
//of null-terminated strings where the last item is a zero-
length
//string (i.e. just #0). We'll now iterate over this list with
some
//simple pointer math.
pIterator := pPaths;
while (strlen(pIterator)>0) do begin

CounterPath := pIterator;
pIterator := pIterator + Length(pIterator) + 1;

//Find the counter instance ID (the part in parentheses)
i := Pos('(', CounterPath);
InstanceId := Copy(CounterPath, i+1, Pos(')', CounterPath)-
i-1);
//Skip the counter if it indicates the overall CPU usage,
//we only want the per-core values.
if InstanceId = '_Total' then continue;

//Add the counter to the query
status := PdhAddCounter(Query, PAnsiChar(CounterPath), 0,
h);

if status = ERROR_SUCCESS then begin

//Expand the internal counter array if necessary
if cnt > Length(Counters)-1 then
SetLength(Counters, Length(Counters)+16);

//Save the counter data to the array
with Counters[cnt] do begin
Path := CounterPath;
Handle := h;

//Create a label for this core/CPU
mLabel := TLabel.Create(Self);
mLabel.Parent := Self;
mLabel.Caption := 'Core '+InstanceId;
mLabel.Top := (mLabel.Height + 8) * cnt + 10;
mLabel.Left := 10;
mLabel.AutoSize := false;
mLabel.Width := 80;

//Create a "progress bar" to show the core/CPU usage
mGauge := TGauge.Create(Self);
mGauge.Parent := Self;

mGauge.Top := mLabel.Top;
mGauge.Left := mLabel.Width + 20;
mGauge.Height := mLabel.Height+2;
mGauge.Width := Self.ClientWidth - mGauge.Left - 10;

mGauge.ForeColor := $0031D329;
mGauge.Anchors := [akRight, akLeft, akTop];

end;

inc(cnt);
end;
end;//while

//Truncate the array to the actual number of discovered cores
SetLength(Counters, cnt);

//Collect the first data sample
PdhCollectQueryData(Query);

end;
end;

end;

//Did we get any valid counters?
if Length(Counters) = 0 then begin

//Nope. Show an unhelpful error message...
MessageBox(Handle, 'Initialization was unsuccessful. The
application will now exit.',
'Error', MB_OK or MB_ICONEXCLAMATION);

//...and quit.
Application.Terminate;

end else begin
//Everything went well.
//Resize the form to make sure all progress bars are visible.
Self.ClientHeight :=
Counters[Length(Counters)-1].mLabel.Top +
Counters[Length(Counters)-1].mLabel.Height +
Counters[0].mLabel.Top + 20;
StopBtn.Top := Self.ClientHeight - 25;
end;

end;

procedure TForm2.Timer33Timer(Sender: TObject);
var
i:integer;
counterType: PDword;
pValue:_PDH_FMT_COUNTERVALUE;
status : cardinal;
begin
if Query = 0 then exit;

//Collect a data sample.
PdhCollectQueryData(Query);

//Iterate over all counters and update progress bars.
for i := 0 to Length(Counters) - 1 do begin
counterType := nil;

//Get the current core/CPU usage
status := PdhGetFormattedCounterValue(
Counters[i].Handle, //Counter handle as returned by
PdhAddCounter.
PDH_FMT_DOUBLE, //Get the counter value as a double-
precision float.
CounterType, //Counter type; unused.
pValue); //Output buffer for the counter value.

//Update the progress bar.
if status = ERROR_SUCCESS then
Counters[i].mGauge.Progress := Round(pValue.doubleValue);
end;
end;

procedure TForm2.StopBtnClick(Sender: TObject);
begin
//Close the query when quitting.
if Query <> 0 then PdhCloseQuery(Query);
ModalResult:=mrAbort;
Form2.Close;
end;

end.
==================================================================
it uses JwaWindows, a Jedi windows API component which is free
available at : http://jedi-apilib.sourceforge.net/

Any ideas how to close the Form2?


Thanks
Esh


0 new messages