BTW, my component has to be self-contained and not rely on the form
processing the WM message...
Thanks
> What's the best way to capture WM_?
This is tough... you'll need to subclass the form's Window procedure
(see SetWindowLong and GWL_WNDPROC in the API), but this approach is
very fragile. More than one component on a form which subclass the
WndProc can easily step on each other. See if you can't choose another
approach.
--
Rick Rogers (TeamB) | Fenestra Technologies
http://www.fenestra.com/
Unless your component descends from TWinControl, it will not have a
window handle and therefore can not receive messages. If you think
that's not the problem, exactly what does your component descend from,
and what message are you not getting?
Good luck.
Kurt
Example:
TYourComponent = class(TWinControl)
procedure YourMethod(var Message: TMessage);
end;
procedure TYourComponent.CreateWnd;
begin
inherited;
FForm:= GetParentForm(Self);
if Assigned(FForm) then
begin
FSaveFormWindowProc:= FForm.WindowProc;
FForm.WindowProc:= YourMethod;
end;
end;
procedure TYourComponent.YourMethod(var: Message: TMessage);
begin
if (Message.Msg = WM_XXX) then DoYourStuff;
FSavedFormWindowProc(Message);
end;
--
Felix Venniker
Bruce Thomas <bru...@simplifi.com> wrote in article
<6pj02m$a6...@forums.borland.com>...
Felix,
This is what I have and it works. I just want to make sure it the most
efficient way of doing it,
TMyThing = class(TComponent)
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
private
FOnChange: TNotifyEvent;
FWindowHandle : HWND;
procedure WndProc(var Msg: TMessage);
.....
constructor TMyThing.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowHandle := AllocateHWnd(WndProc);
......
destructor TMyThing.Destroy;
begin
DeallocateHWnd(FWindowHandle);
inherited Destroy ()
........
procedure TMyThing.WndProc(var Msg: TMessage);
begin
try
if (Msg.Msg = WM_?????) then
..........
else
Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam,
Msg.lParam);
except
Application.HandleException(Self);
end;
end;
Thanks,
Bruce
>TMyThing = class(TComponent)
> constructor Create(AOwner: TComponent); override;
> destructor Destroy; override;
>
> private
> FOnChange: TNotifyEvent;
> FWindowHandle : HWND;
>
> procedure WndProc(var Msg: TMessage);
Instead of using WndProc, declare message handlers, e.g.,
procedure WmMsg...(var Msg: TWmMsg....); message WM_Msg...;
Let Delphi do the dispatching for you.
--
Ray Lischner (http://www.tempest-sw.com/)
Author of "Hidden Paths of Delphi 3: Experts, Wizards, and the Open Tools API"
>Let Delphi do the dispatching for you.
Ray,
That's exact the way I had it initially, but when I placed the component on
a form it never received the message, even though the parent form was
getting the message. I had the message handler declared in the component
but the component never received it, but I placed the same declaration on
the form and the form got the message. That's why I posted the message to
see I am doing something wrong... If you have some ideas about how I can do
this without WndProc let me know (a sample would be cool...)...
>That's exact the way I had it initially, but when I placed the component on
>a form it never received the message, even though the parent form was
>getting the message. I had the message handler declared in the component
>but the component never received it, but I placed the same declaration on
>the form and the form got the message. That's why I posted the message to
>see I am doing something wrong... If you have some ideas about how I can do
>this without WndProc let me know (a sample would be cool...)...
Sorry, my mistake. AllocateHWnd needs a window procedure. That's how
it works. You could have the window procedure dispatch to your
control, but that's not worth the effort.
There is a whole section in the Delphi 3 docs on message
handling, however the "message WM_Msg..."
expects WM_Msg to be a constant...
I want to do IPC (Interprocess communication) through
messages and I need unique messages...
There is a RegisterMessage (or something like that) proc
in Win32 that takes a unique string and registers a message
for you... Next calls to it with the same string return the same
message ID, so that all your running apps can sync on the
same message ID that isn't hardcoded in them but generated
by Win32 at runtime (the first free message ID they can find)
Can't use the standard Delphi dispatcher cause it takes constants,
so one has to dispatch by himself...
What's more controls that are not derived from TWinControl
don't have a real window (maybe that was your problem), so
they can't directly receive events from what I understand (but
expect the form to dispatch events to them [only the ones using
the standard dispatcher mechanism?])
The best way I've found so far was some TBroadcast component
that used WM_COPY to exchange data packets of some length
between apps... It created a window handle for the component...
I changed it to work with any data size and am creating an
hierarchy of provider and consumer components for certain
common properties (TColor,String,TDateTime)...
Hope I can make it with exchanging streamized components...
Does anyone know which other apps use WM_COPY?
I wouldn't want to interfere with the system or other apps when exchanging
data in this way...
BTW it's very fast!!! Put 20 consumers and a provider on different
forms... Changed a property in the provider and all the consumers
changed their corresponding property too immediately...