| From: ZioNemo |
|
| Subject: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 26-Apr-2004 at 19:59:32 PST |
Hi, this is first post, so bear with me, please...
I do need to get some event when a Frame is displayed, independent
from who's currently owning said frame. Forms have an "OnShow"
event; Frames do not. I'm currently generating a fake event from the
frame owner, but this is NOT satisfactory (the frame should become a
component and should be able to do some processing when displayed and
some cleanup when hidden); What is the "Right" way to achieve this?
Pointers to relevant docs are VERY welcome!
To be more precise I do have the following:
------------------------------------------
object FormMissioni: TFormMissioni
...
object SpeedBar1: JvTSpeedBar
...
end
object Panel1: JvTPanel
...
object PageControl1: JvTPageControl
....
object TabSheet1: TTabSheet
...
inline pagePorte1: TpagePorte
...
[this is the frame that needs OnShow/OnHide]
...
end
end
end
object TabSheet2: TTabSheet
..
end
object TabSheet3: TTabSheet
...
end
end
end
end
------------------------------------------
I tried trapping the CM_VISIBLECHANGED message in the TpagePorte frame
defined as:
------------------------------------------
TExFrame = class(TFrame)
private
FOnShow: TNotifyEvent;
FOnHide: TNotifyEvent;
//procedure WMShowWindow(var Msg: TWMShowWindow); message
WM_SHOWWINDOW;
procedure WMShowWindow(var Msg: TMessage); message CM_VISIBLECHANGED;
published
property OnShow: TNotifyEvent read FOnShow write FOnShow;
property OnHide: TNotifyEvent read FOnHide write FOnHide;
end;
TpagePorte = class(TExFrame, ImapClient)
...
------------------------------------------
but neither the CM_VISIBLECHANGED nor the WM_SHOWWINDOW (I already tried
that) messages seem to be sent or received by the frame (a breakpoint in
the WMShowWindow procedure is never triggered).
I do get notification when the page control switches tabs, but if I
completely hide the frame (using the [X] caption button or
FormMissioni.Hide) or display it (using FormMissioni.Show) I get no
notification.
This is particularly bad when the frame is docked, because the
containing Form is actually *NOT* visible!
The only workaround I found is to trap the OnShow event in the Form and
call a custom OnShow method in the included Frames, but this seems
"unclean" to me (the including Form must know about the internals of
included Frames).
I also tried handling CM_SHOWINGCHANGED, but this seems to reflect the
SHOWING status of the *FORM* containing the *frame*.
If the form is docked the form itself it's NOT showing, but it's
contents may (or may be not) be showing within the dock server frame!
The frame (TpagePorte) *MUST* know when it is on screen (after all it
repaints itself)! How can I get the info?? Where to hook??
I'm currently trapping WM_PAINT messages to know the frame is actually
on-screen, but I have no way to know when it goes off screen.
Any suggestions??
HEEELLPPPP!!!!
Thanks for Your Time
ZioNemo
|
| From: ZioNemo |
|
| Subject: Re: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 28-Apr-2004 at 23:20:38 PST |
Kurt Barthelmess (TeamB) wrote:
> ZioNemo wrote:
>
>
>>My application is a control for external apparatus.
>>I have a set of Forms that communicate with different pieces of machinery.
>>"Showing" a frame means I do have to connect with the right thing.
>>"Hiding" a frame means (also) to gracefully close connection.
>>I have a limited channel, so I cannot keep all communications alive even
>>while Hidden.
>>I grouped Frames in Forms, and the enclosing Form notifies the included
>>Frames when they are active. I already do not like this because the
>>Frames are not self-contained, but I surely can live with it. To do this
>>I relay on the OnShow/OnHide sent to the verious Frames.
>>
>>The problem is that if I use docking the Docked Forms do *NOT* receive
>>the OnShow/OnHide notifications! (AFAIK the Form is Hidden and its
>>contents are displayed in dome temporary container belonging to the
>>DockServer Frame).
>>
>>Is it possible a component cannot know if it's currently on screen or
>>not?? I cannot belive this!!
>
>
> There are several conditions that might apply to the term "on screen".
> It isn't clear to me when you need to activate your connections based
> on those. The conditions include:
>
> Being Visible (as in the Visible property)
> Being "on screen" (as opposed to being outside the boundaries of the
> display.)
> Being "overlapped" (some other window covers all or a part of the
> component.)
>
> It seems to me that you would want a clearer definition of the
> activation and deactivation logic than some combination of the above
> conditions. The frames should expose an "Active" property which the
> form sets or resets when it "activates" or "deactivates" a particular
> frame. The frame can then open or close the channel as appropriate.
> You can make this fancier such that activating a frame automatically
> deactivates all other frames - as a checking a radio button unchecks
> all others of the group.
>
> I realize that means ripping up a bunch of logic, but as is, you are
> using unrelated events (related to visibility) which may not be stable
> or reliable.
My definition of "Visible" is quite simple:
A component is visible iff its Visible property is True *and* the same
holds for all its parents.
This, from the user point of view, means a certain Frame is visible if
he did something to show it and did nothing direct to hide it, such as
closing the containing frame or switching to another page in a paging
control. On the other hand temporarily covering the frame with another
form or moving it out of screen by pushing the enclosing form near to
the edge of the monitor doesn't change it's visibility.
Actually borland implemented a "Showing" property, but it is not
reliable! (cfr: Showing (TWinControl)).
Worse yet: I can detect "Visibility" (by walking the Parent list), but I
have no event to trigger the check! I'm currently relying on polling
(Timer), but that's far from being a nice solution :(
Thanks for Your Time!
ZioNemo
|
| From: ZioNemo |
|
| Subject: Re: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 27-Apr-2004 at 17:52:25 PST |
Kurt Barthelmess (TeamB) wrote:
> ZioNemo wrote:
>
>
>>I do need to get some event when a Frame is displayed, independent
>
>>from who's currently owning said frame. Forms have an "OnShow"
>
>>event; Frames do not. I'm currently generating a fake event from the
>>frame owner, but this is NOT satisfactory (the frame should become a
>>component and should be able to do some processing when displayed and
>>some cleanup when hidden); What is the "Right" way to achieve this?
>
> I'm not sure why a frame would need to so this - "hiding" a frame or
> any other control normally means you just don't want it drawn on the
> display at the moment. It would not normally change anything else.
> [...SNIP!...]
> Note that this still will not handle the case where the containing
> window is hidden. This only detects whether the frame has been hidden
> or made visible. I don't know of any way for a child to be notified
> when its parent is hidden; that is normally none of its business.
Thanks for Your answer, but... :)
My application is a control for external apparatus.
I have a set of Forms that communicate with different pieces of machinery.
"Showing" a frame means I do have to connect with the right thing.
"Hiding" a frame means (also) to gracefully close connection.
I have a limited channel, so I cannot keep all communications alive even
while Hidden.
I grouped Frames in Forms, and the enclosing Form notifies the included
Frames when they are active. I already do not like this because the
Frames are not self-contained, but I surely can live with it. To do this
I relay on the OnShow/OnHide sent to the verious Frames.
The problem is that if I use docking the Docked Forms do *NOT* receive
the OnShow/OnHide notifications! (AFAIK the Form is Hidden and its
contents are displayed in dome temporary container belonging to the
DockServer Frame).
Is it possible a component cannot know if it's currently on screen or
not?? I cannot belive this!!
Please Help!!
ZioNemo
|
| From: Bill N |
|
| Subject: Re: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 26-Apr-2004 at 14:26:20 PST |
I think you should try overriding the CreateWnd procedure as:
============================
procedure CreateWnd; override;
procedure TFramBrkList.CreateWnd;
begin
inherited;
if FBrkList=nil then FBrkList:= TBrokerList.Create;
end;
============================
HTH,
Bill N
"ZioNemo" wrote in message
news:408d4dfd@newsgroups.borland.com...
> Hi, this is first post, so bear with me, please...
>
> I do need to get some event when a Frame is displayed, independent
> from who's currently owning said frame. Forms have an "OnShow"
> event; Frames do not. I'm currently generating a fake event from the
> frame owner, but this is NOT satisfactory (the frame should become a
> component and should be able to do some processing when displayed and
> some cleanup when hidden); What is the "Right" way to achieve this?
>
> Pointers to relevant docs are VERY welcome!
>
> To be more precise I do have the following:
> ------------------------------------------
> object FormMissioni: TFormMissioni
> ...
> object SpeedBar1: JvTSpeedBar
> ...
> end
> object Panel1: JvTPanel
> ...
> object PageControl1: JvTPageControl
> ....
> object TabSheet1: TTabSheet
> ...
> inline pagePorte1: TpagePorte
> ...
> [this is the frame that needs OnShow/OnHide]
> ...
> end
> end
> end
> object TabSheet2: TTabSheet
> ..
> end
> object TabSheet3: TTabSheet
> ...
> end
> end
> end
> end
> ------------------------------------------
>
> I tried trapping the CM_VISIBLECHANGED message in the TpagePorte frame
> defined as:
>
> ------------------------------------------
> TExFrame = class(TFrame)
> private
> FOnShow: TNotifyEvent;
> FOnHide: TNotifyEvent;
> //procedure WMShowWindow(var Msg: TWMShowWindow); message
> WM_SHOWWINDOW;
> procedure WMShowWindow(var Msg: TMessage); message CM_VISIBLECHANGED;
> published
> property OnShow: TNotifyEvent read FOnShow write FOnShow;
> property OnHide: TNotifyEvent read FOnHide write FOnHide;
> end;
>
> TpagePorte = class(TExFrame, ImapClient)
> ...
> ------------------------------------------
>
> but neither the CM_VISIBLECHANGED nor the WM_SHOWWINDOW (I already tried
> that) messages seem to be sent or received by the frame (a breakpoint in
> the WMShowWindow procedure is never triggered).
>
>
> I do get notification when the page control switches tabs, but if I
> completely hide the frame (using the [X] caption button or
> FormMissioni.Hide) or display it (using FormMissioni.Show) I get no
> notification.
> This is particularly bad when the frame is docked, because the
> containing Form is actually *NOT* visible!
>
> The only workaround I found is to trap the OnShow event in the Form and
> call a custom OnShow method in the included Frames, but this seems
> "unclean" to me (the including Form must know about the internals of
> included Frames).
>
> I also tried handling CM_SHOWINGCHANGED, but this seems to reflect the
> SHOWING status of the *FORM* containing the *frame*.
> If the form is docked the form itself it's NOT showing, but it's
> contents may (or may be not) be showing within the dock server frame!
>
> The frame (TpagePorte) *MUST* know when it is on screen (after all it
> repaints itself)! How can I get the info?? Where to hook??
>
> I'm currently trapping WM_PAINT messages to know the frame is actually
> on-screen, but I have no way to know when it goes off screen.
>
> Any suggestions??
> HEEELLPPPP!!!!
>
> Thanks for Your Time
> ZioNemo
|
| From: Kurt Barthelmess (TeamB) |
|
| Subject: Re: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 26-Apr-2004 at 18:25:31 PST |
ZioNemo wrote:
>I do need to get some event when a Frame is displayed, independent
>from who's currently owning said frame. Forms have an "OnShow"
>event; Frames do not. I'm currently generating a fake event from the
>frame owner, but this is NOT satisfactory (the frame should become a
>component and should be able to do some processing when displayed and
>some cleanup when hidden); What is the "Right" way to achieve this?
I'm not sure why a frame would need to so this - "hiding" a frame or
any other control normally means you just don't want it drawn on the
display at the moment. It would not normally change anything else.
However, one way to detect this is to watch for a WM_WINDOWPOSCHANGING
message:
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging);
message WM_WINDOWPOSCHANGING;
....
procedure TFrame2.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
if (Msg.WindowPos^.flags and SWP_HIDEWINDOW) <> 0 then
Application.Title := 'Hidden'
else if (Msg.WindowPos^.flags and SWP_SHOWWINDOW) <> 0 then
Application.Title := 'Showing';
inherited;
end;
Note that this still will not handle the case where the containing
window is hidden. This only detects whether the frame has been hidden
or made visible. I don't know of any way for a child to be notified
when its parent is hidden; that is normally none of its business.
Good luck.
Kurt
|
| From: Kurt Barthelmess (TeamB) |
|
| Subject: Re: "OnShow" for frames |
| NewsGroup: borland.public.delphi.vcl.components.using.win32 |
| Date Posted: 28-Apr-2004 at 9:1:30 PST |
ZioNemo wrote:
>My application is a control for external apparatus.
>I have a set of Forms that communicate with different pieces of machinery.
>"Showing" a frame means I do have to connect with the right thing.
>"Hiding" a frame means (also) to gracefully close connection.
>I have a limited channel, so I cannot keep all communications alive even
>while Hidden.
>I grouped Frames in Forms, and the enclosing Form notifies the included
>Frames when they are active. I already do not like this because the
>Frames are not self-contained, but I surely can live with it. To do this
>I relay on the OnShow/OnHide sent to the verious Frames.
>
>The problem is that if I use docking the Docked Forms do *NOT* receive
>the OnShow/OnHide notifications! (AFAIK the Form is Hidden and its
>contents are displayed in dome temporary container belonging to the
>DockServer Frame).
>
>Is it possible a component cannot know if it's currently on screen or
>not?? I cannot belive this!!
There are several conditions that might apply to the term "on screen".
It isn't clear to me when you need to activate your connections based
on those. The conditions include:
Being Visible (as in the Visible property)
Being "on screen" (as opposed to being outside the boundaries of the
display.)
Being "overlapped" (some other window covers all or a part of the
component.)
It seems to me that you would want a clearer definition of the
activation and deactivation logic than some combination of the above
conditions. The frames should expose an "Active" property which the
form sets or resets when it "activates" or "deactivates" a particular
frame. The frame can then open or close the channel as appropriate.
You can make this fancier such that activating a frame automatically
deactivates all other frames - as a checking a radio button unchecks
all others of the group.
I realize that means ripping up a bunch of logic, but as is, you are
using unrelated events (related to visibility) which may not be stable
or reliable.
Good luck.
Kurt
|