Board index » delphi » Receiving Windows' Messages

Receiving Windows' Messages

I have a fairly simple non-visual wrapper for an MCI object. The functionality
of the wrapper is such that it could easily descend from a TObject.

However it needs to respond to a windows message (for event triggering and
data) and I would rather not go to the additional compiled size/complexity of
descending it from a TWinControl.

Is there any way in which the code can handle the windows message while
descending from a TObject or similar simple parent.

Or have I missed something blindingly obvious <g>.

Alan Lloyd
alangll...@aol.com

 

Re:Receiving Windows' Messages


You can use the handle of the TApplication.

ps. Applicaton has a OnMessage event that can be used to catch any message
sent to the application.

"AlanGLLoyd" <alangll...@aol.com> schreef in bericht
news:20000515061502.08333.00004313@nso-fp.aol.com...

Quote
> I have a fairly simple non-visual wrapper for an MCI object. The
functionality
> of the wrapper is such that it could easily descend from a TObject.

> However it needs to respond to a windows message (for event triggering and
> data) and I would rather not go to the additional compiled size/complexity
of
> descending it from a TWinControl.

> Is there any way in which the code can handle the windows message while
> descending from a TObject or similar simple parent.

> Or have I missed something blindingly obvious <g>.

> Alan Lloyd
> alangll...@aol.com

Re:Receiving Windows' Messages


"AlanGLLoyd" <alangll...@aol.com> skrev i melding
news:20000515061502.08333.00004313@nso-fp.aol.com...

Quote
> I have a fairly simple non-visual wrapper for an MCI object. The
functionality
> of the wrapper is such that it could easily descend from a TObject.

> However it needs to respond to a windows message (for event triggering and
> data) and I would rather not go to the additional compiled size/complexity
of
> descending it from a TWinControl.

> Is there any way in which the code can handle the windows message while
> descending from a TObject or similar simple parent.

I've done this, and I borrowed the code from TThread, it calls a procedure
AddThread; upon creation that allocates a window made only for message
handling.

What you basically do, is check whether the window class name is allready
registered, and then you create a window with everything but a windowproc,
the windowclass name and the hinstance set to non-zero.

--
Bjoerge Saether
Consultant / Developer
Asker, Norway
bsaether.removet...@online.no (remove the obvious)

Re:Receiving Windows' Messages


Thanks Bjorge and M.H.A.

Unless someone else comes up with anything better, I think I'll go with
Bjorge's technique on the basis that it is more independent from the remainder
of the application (I would have to save any existing Application.OnMessage and
call it at the end of my mesage handler). Using A.OM would also have more time
impact on other messages.

It sounds hairy, but looking at the code it is actually fairly simple. I
presume that while I replace CM_EXECPROC and it's code with my message name and
_it's_ code, I keep CMDESTROYWINDOW and Perform() that message from my object's
destructor Destroy.

Alan Lloyd
alangll...@aol.com

Re:Receiving Windows' Messages


Quote
AlanGLLoyd wrote:

> Is there any way in which the code can handle the windows message while
> descending from a TObject or similar simple parent.

> Or have I missed something blindingly obvious <g>.

Alan,

Yes, there's a great way of doing this. Forms contains a couple of
methods: AllocateHWnd and DeallocateHwnd that let you do exactly this.
They are designed for objects which need to do special message
processing but aren't visual controls. I originally got this hot tip out
of Danny Thorpe's book, "Delphi Component Design".

For an example of its use, see my multithreading tutorial on my website.
The newly added chapter 10 (as of yesterday!) contains a "blocking to
asynchronous buffer" component, which is only descended from TComponent,
yet contains a window handle to process messages between threads. The
section "Construction of the BAB." details this. The code for the
component is a couple of paragraphs above, and you'll be looking for the
constructor, destructor and MessageHandler method of the
"TBlockToAsyncBuf" component.

MCH.

--
Martin Harvey. mar...@pergolesi.demon.co.uk
     http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


Quote
AlanGLLoyd wrote:

> Thanks Bjorge and M.H.A.

> Unless someone else comes up with anything better,

I would argue that my solution, requiring only about 3 lines of code is
a lot easier.

MH.

--
Martin Harvey. mar...@pergolesi.demon.co.uk
     http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


"Martin Harvey" <mar...@pergolesi.demon.co.uk> skrev i melding
news:39207249.CE9F9DB@pergolesi.demon.co.uk...

Quote
> AlanGLLoyd wrote:

> > Is there any way in which the code can handle the windows message while
> > descending from a TObject or similar simple parent.

> > Or have I missed something blindingly obvious <g>.

> Alan,

> Yes, there's a great way of doing this. Forms contains a couple of
> methods: AllocateHWnd and DeallocateHwnd that let you do exactly this.
> They are designed for objects which need to do special message
> processing but aren't visual controls. I originally got this hot tip out
> of Danny Thorpe's book, "Delphi Component Design".

Ahh! There it was ! Wondered if there was an easier way, but couldn't
remember what it was called. It does exactly the same as the Thread Window
stuff...all wrapped in two ready-built procedures.

--
Bjoerge Saether
Consultant / Developer
Asker, Norway
bsaether.removet...@online.no (remove the obvious)

Re:Receiving Windows' Messages


In article <3920726C.3ED1C...@pergolesi.demon.co.uk>, Martin Harvey

Quote
<mar...@pergolesi.demon.co.uk> writes:
>I would argue that my solution, requiring only about 3 lines of code is
>a lot easier.

Yes - you're right, Martin. I thought it was strange that there was not a ready
solution to what IMO would be a common requirement.

I'm just wondering about the differences, one (the thread) calls CreateWindow
with a zero style, the other calls CreateWindowEx with an extended window style
of WS_EX_TOOLWINDOW and a window style of WS_POPUP (and with a comment of {! !
! 0} immediately following). The other also calls SetWindowLong() which the
thread does not do.

Alan Lloyd
alangll...@aol.com

Re:Receiving Windows' Messages


"AlanGLLoyd" <alangll...@aol.com> skrev i melding
news:20000516022946.08654.00004221@nso-bj.aol.com...

Quote
> I'm just wondering about the differences, one (the thread) calls
CreateWindow
> with a zero style, the other calls CreateWindowEx with an extended window
style
> of WS_EX_TOOLWINDOW and a window style of WS_POPUP (and with a comment of
{! !
> ! 0} immediately following). The other also calls SetWindowLong() which the
> thread does not do.

The difference is the the AllocteHWnd takes a method as a parameter, and has
an option of setting this method as the window procedure rather then the
DefWindowProc. The TThreadWindow uses a flat procedure for this purpose.
I would like someone to explain the MakeObjectInstance, though...;-)
--
Bjoerge Saether
Consultant / Developer
Asker, Norway
bsaether.removet...@online.no (remove the obvious)

Re:Receiving Windows' Messages


Quote
"Bj?rge S?ther" wrote:

> Ahh! There it was ! Wondered if there was an easier way, but couldn't
> remember what it was called. It does exactly the same as the Thread Window
> stuff...all wrapped in two ready-built procedures.

Just to check I recall rightly, TThread uses a window handle because it
uses the concurrency control inherent in SendMessage to implement the
synchronize method, right?

MH.

--
Martin Harvey. mar...@pergolesi.demon.co.uk
     http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


Yes !

Here it is !

function ThreadWndProc(Window: HWND; Message, wParam, lParam: Longint):
Longint; stdcall;
begin
  case Message of
    CM_EXECPROC:
      with TThread(lParam) do
      begin
        Result := 0;
        try
          FSynchronizeException := nil;
          FMethod;
        except
          if RaiseList <> nil then
          begin
            FSynchronizeException := PRaiseFrame(RaiseList)^.ExceptObject;
            PRaiseFrame(RaiseList)^.ExceptObject := nil;
          end;
        end;
      end;
    CM_DESTROYWINDOW:
      begin
        FreeThreadWindow;
        Result := 0;
      end;
  else
    Result := DefWindowProc(Window, Message, wParam, lParam);
  end;
end;

--
Bjoerge Saether
Consultant / Developer
Asker, Norway
bsaether.removet...@online.no (remove the obvious)

"Martin Harvey" <mar...@pergolesi.demon.co.uk> skrev i melding
news:3920A2CC.21B3C68C@pergolesi.demon.co.uk...

Quote
> "Bj?rge S?ther" wrote:

> > Ahh! There it was ! Wondered if there was an easier way, but couldn't
> > remember what it was called. It does exactly the same as the Thread
Window
> > stuff...all wrapped in two ready-built procedures.

> Just to check I recall rightly, TThread uses a window handle because it
> uses the concurrency control inherent in SendMessage to implement the
> synchronize method, right?

> MH.

> --
> Martin Harvey. mar...@pergolesi.demon.co.uk
>      http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


Quote
"Bj?rge S?ther" wrote:

> Yes !

> Here it is !

Hmm... very interesting. No doubt the call to synchronize executes in
the context of the TThread object does a "SendMessage" (I ;-) don't have
the code for this, but it sounds like a good guess). This blocks the
thread inside the Win32 kernel, and the message is then processed by the
application handlers (VCL thread), being passed to the thread window
handle and consequently ThreadWndProc. The bit of code mentioned below
executes... and it appears to do some cool stuff to transfer any
exceptions back to the TThread calling synchronize.

My other guess is that the CM_DESTROYWINDOW is the bit that enables a
threads OnTerminate event to execute in the context of the main VCL
thread.

Very neat.

MH.

Quote
> function ThreadWndProc(Window: HWND; Message, wParam, lParam: Longint):
> Longint; stdcall;
> begin
>   case Message of
>     CM_EXECPROC:
>       with TThread(lParam) do
>       begin
>         Result := 0;
>         try
>           FSynchronizeException := nil;
>           FMethod;
>         except
>           if RaiseList <> nil then
>           begin
>             FSynchronizeException := PRaiseFrame(RaiseList)^.ExceptObject;
>             PRaiseFrame(RaiseList)^.ExceptObject := nil;
>           end;
>         end;
>       end;
>     CM_DESTROYWINDOW:
>       begin
>         FreeThreadWindow;
>         Result := 0;
>       end;
>   else
>     Result := DefWindowProc(Window, Message, wParam, lParam);
>   end;
> end;

> --
> Bjoerge Saether
> Consultant / Developer
> Asker, Norway
> bsaether.removet...@online.no (remove the obvious)

--
Martin Harvey. mar...@pergolesi.demon.co.uk
     http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


where can i get the windows' messages list and it's infomation?

--
please e-mail me, thanks
E-MAIL
isig...@yahoo.com

Quote
Martin Harvey <mar...@pergolesi.demon.co.uk> wrote in message

news:3921E6A9.A4496E4E@pergolesi.demon.co.uk...
Quote
> "Bjge Sher" wrote:

> > Yes !

> > Here it is !

> Hmm... very interesting. No doubt the call to synchronize executes in
> the context of the TThread object does a "SendMessage" (I ;-) don't have
> the code for this, but it sounds like a good guess). This blocks the
> thread inside the Win32 kernel, and the message is then processed by the
> application handlers (VCL thread), being passed to the thread window
> handle and consequently ThreadWndProc. The bit of code mentioned below
> executes... and it appears to do some cool stuff to transfer any
> exceptions back to the TThread calling synchronize.

> My other guess is that the CM_DESTROYWINDOW is the bit that enables a
> threads OnTerminate event to execute in the context of the main VCL
> thread.

> Very neat.

> MH.

> > function ThreadWndProc(Window: HWND; Message, wParam, lParam: Longint):
> > Longint; stdcall;
> > begin
> >   case Message of
> >     CM_EXECPROC:
> >       with TThread(lParam) do
> >       begin
> >         Result := 0;
> >         try
> >           FSynchronizeException := nil;
> >           FMethod;
> >         except
> >           if RaiseList <> nil then
> >           begin
> >             FSynchronizeException :=

PRaiseFrame(RaiseList)^.ExceptObject;

- Show quoted text -

Quote
> >             PRaiseFrame(RaiseList)^.ExceptObject := nil;
> >           end;
> >         end;
> >       end;
> >     CM_DESTROYWINDOW:
> >       begin
> >         FreeThreadWindow;
> >         Result := 0;
> >       end;
> >   else
> >     Result := DefWindowProc(Window, Message, wParam, lParam);
> >   end;
> > end;

> > --
> > Bjoerge Saether
> > Consultant / Developer
> > Asker, Norway
> > bsaether.removet...@online.no (remove the obvious)

> --
> Martin Harvey. mar...@pergolesi.demon.co.uk
>      http://www.pergolesi.demon.co.uk

Re:Receiving Windows' Messages


Quote
"percy" <percy...@hotmail.com> wrote in message

news:8fva5o$1ir43@ctmsun0.macau.ctm.net...

Quote
> where can i get the windows' messages list and it's infomation?

Open the win32.hlp file, and type WM_ in the index. A list of windows
messages should be displayed.  Select a message to see a description.

Christo Crause

Re:Receiving Windows' Messages


"percy" <percy...@hotmail.com> skrev i melding
news:8fva5o$1ir43@ctmsun0.macau.ctm.net...

Quote
> where can i get the windows' messages list and it's infomation?

I would recommend a Windows programmer's reference manual. It's all in the
Win32.hlp but inconvenient for getting the whole picture. The message
mentioned by Martin is a Delphi - defined message, though (classes.pas):

{ Thread management routines }

const
  CM_EXECPROC = $8FFF;
  CM_DESTROYWINDOW = $8FFE;

...AFAIK, all CN_XXX and CM_XXX messages are defined by VCL.
--
Bjoerge Saether
Consultant / Developer
Asker, Norway
bsaether.removet...@online.no (remove the obvious)

Go to page: [1] [2]

Other Threads