For various reasons I need not detail here, I wanted to position a
descendant of a tEdit over the cell of a tStringGrid, and I wanted to
watch for the tEdit's OnChange event. It was not working properly, and
eventually I came to the following conclusions:
1. If the parent of the tEdit is the tStringGrid, then the OnChange
event is never triggered.
2. However, if the parent of the tEdit is either the main form itself
or
a tPanel, then the OnChange event is triggered.
3. (This one was a very pleasant surprise!) Number 2 remains true even
if the parent of the tPanel is the tStringGrid. In other words, a
tPanel can insulate a tEdit from the underlying tString Grid.
If you want to see this for yourself, create a small form (Form1) with
four controls on it:
1. a tEdit called EditBox at the extreme upper left
2. a tStringGrid called BaseGrid a little below the edit box
3. a small tPanel called InsulatingPanel somewhere over the string grid
(this does not make the string grid it's parent; we'll take care of
that later)
4. a tButton called TestButton
Attach the following code to the tEdit's OnChange event:
procedure TForm1.EditBoxChange(Sender: TObject);
begin
MessageBeep(0)
end;
Attach the following code to the button click:
procedure TForm1.TestButtonClick(Sender: TObject);
var N: longint;
begin
{Reposition the panel}
with InsulatingPanel do begin
Parent:=BaseGrid;
Left:=0;
Top:=(BaseGrid.ClientHeight) div 2;
Width:=BaseGrid.Width;
Height:=Top
end;
with EditBox do
if (Parent=InsulatingPanel) then
Parent:=BaseGrid
else if (Parent=BaseGrid) then
Parent:=Form1
else
Parent:=InsulatingPanel;
TestButton.Enabled:=false;
EditBox.Text:='Hello, world!';
Application.ProcessMessages;
{The following statement simply wastes a bit of time so that the two
message beeps can both be heard; it gives an appropriate delay on my
Pentium 133}
for N:=1 to 9000000 do;
EditBox.Text:='Goodbye';
Application.ProcessMessages;
TestButton.Enabled:=true
end;
As you press the button several times, you will notice that the changes
to the edit box's text trigger the beeps only when the box's immediate
parent is not the string grid; it does not seem to be important that,
when its immediate parent is the panel, there is a string grid somewhere
in its parentage chain.
Although I seem to have found the required workaround, can anyone
explain why this is happening? I tried looking through some of the
Delphi 2 source (it was on my CD ROM, but the D1 source wasn't), and I
did notice that there's an event called EN_CHANGE involved in the
following code:
procedure TCustomEdit.CNCommand(var Message: TWMCommand);
begin
if (Message.NotifyCode = EN_CHANGE) and not FCreating then Change;
end;
I might guess that perhaps the EN_CHANGE message is being intercepted by
the tStringGrid before it gets to the tEdit, but if that is the case,
then why doesn't it also get intercepted before it gets to the tPanel?
--
Howard L. Kaplan
Psychopharmacology and Dependence Research Unit
Women's College Hospital
76 Grenville Street, 9'th floor
Toronto, Ontario
Canada M5S 1B2
(416)323-6400, ext 4915
howard...@utoronto.ca