BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Previewing Window Messages

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
Mike King
Guest





PostPosted: Sun Apr 25, 2004 7:43 pm    Post subject: Previewing Window Messages Reply with quote



Is it possible to preview a Windows Message before a window can receive it?

I have a TForm that hosts a TCppWebBrowser (IE) control. The problem is I
need to see the messages before the TCppWebBrowser does so I can stop them
if the form handles it.


Back to top
Michel Leunen
Guest





PostPosted: Sun Apr 25, 2004 7:54 pm    Post subject: Re: Previewing Window Messages Reply with quote



Mike King wrote:
Quote:
Is it possible to preview a Windows Message before a window can receive it?

I have a TForm that hosts a TCppWebBrowser (IE) control. The problem is I
need to see the messages before the TCppWebBrowser does so I can stop them
if the form handles it.

I think what you need is TApplication::OnMessage.
From the online help: "If the application doesn't have a specific
handler for an incoming message, the message is dispatched to the window
for which it was intended, and Windows handles the message."

Michel
--
----------------------------------------
Michel Leunen
mailto: see my homepage.
C++Builder, C++BuilderX, BCC5.5.1 Web site:
http://www.leunen.com/
----------------------------------------

Back to top
Vladimir Stefanovic
Guest





PostPosted: Sun Apr 25, 2004 8:02 pm    Post subject: Re: Previewing Window Messages Reply with quote



http://www.bcbdev.com/faqs/faq16.htm


Q: Respond to messages sent to the application.

Answer:
There is more than one way to catch messages that Windows sends to your
program. You can override the virtual WndProc function of the main form, you
can create a message map, or you can create an OnMessage handler for the
application. This FAQ describes each one briefly.

[...]

Overriding WndProc: All descendants of TControl, including TForm, contain a
WndProc function that serves as the window procedure for the component. This
function is virtual, which means that you can override the function to
intercept messages. The argument to WndProc is a TMessage structure passed
by reference that contains the message command ID and the WPARAM and LPARAM
values.

Step 1: Add the WndProc declaration to your form's header.

private:
void __fastcall WndProc(Messages::TMessage &Message);

Step 2: Code the function. The derived WndProc should call the base class
TForm::WndProc for all messages that you don't process. This function
prevents the windows screensaver from starting.

void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
if( (Message.Msg == WM_SYSCOMMAND) &&
(Message.WParam == SC_SCREENSAVE) )
{
Application->MessageBox("Good bye screen saver", "SCR No",
MB_OK);
Message.Result = true;
}
else
TForm::WndProc(Message);
}





Back to top
Mike King
Guest





PostPosted: Sun Apr 25, 2004 9:59 pm    Post subject: Re: Previewing Window Messages Reply with quote

"Vladimir Stefanovic" <antivari (AT) ptt (DOT) yu> wrote

Quote:
http://www.bcbdev.com/faqs/faq16.htm


Q: Respond to messages sent to the application.

Answer:
There is more than one way to catch messages that Windows sends to your
program. You can override the virtual WndProc function of the main form,
you
can create a message map, or you can create an OnMessage handler for the
application. This FAQ describes each one briefly.

[...]

Overriding WndProc: All descendants of TControl, including TForm, contain
a
WndProc function that serves as the window procedure for the component.
This
function is virtual, which means that you can override the function to
intercept messages. The argument to WndProc is a TMessage structure passed
by reference that contains the message command ID and the WPARAM and
LPARAM
values.

Step 1: Add the WndProc declaration to your form's header.

private:
void __fastcall WndProc(Messages::TMessage &Message);

Step 2: Code the function. The derived WndProc should call the base class
TForm::WndProc for all messages that you don't process. This function
prevents the windows screensaver from starting.

void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
if( (Message.Msg == WM_SYSCOMMAND) &&
(Message.WParam == SC_SCREENSAVE) )
{
Application->MessageBox("Good bye screen saver", "SCR No",
MB_OK);
Message.Result = true;
}
else
TForm::WndProc(Message);
}



Thanks for your response, but it does not work. The problem is only one
control on the form can receive focus which is TCppWebBrowser (IE). How can
I capture the message before IE does?



Back to top
JD
Guest





PostPosted: Mon Apr 26, 2004 1:28 am    Post subject: Re: Previewing Window Messages Reply with quote


"Mike King" <emailMK (AT) excite (DOT) com> wrote:
Quote:
Thanks for your response, but it does not work.

It does. The sample WndProc receives *all* messages sent to the form *prior* to (optionally) passing them on to the
intended base handler.

What exactly are you trying to accomplish?

~ JD


Back to top
Mike King
Guest





PostPosted: Mon Apr 26, 2004 3:48 am    Post subject: Re: Previewing Window Messages Reply with quote

"JD" <nospam (AT) nospam (DOT) com> wrote

Quote:

"Mike King" <emailMK (AT) excite (DOT) com> wrote:
Thanks for your response, but it does not work.

It does. The sample WndProc receives *all* messages sent to the form
*prior* to (optionally) passing them on to the
intended base handler.

What exactly are you trying to accomplish?

~ JD


I have a form that hosts a TCppWebBrowser (IE) control. I want the user to
be able to press the T key or spacebar to execute a commonly used function.
I want the same functionality as the KeyPreview does for other controls. Do
I have to subclass the TCppWebBrowser control to do a message map or does
the form need the message map?



Back to top
JD
Guest





PostPosted: Mon Apr 26, 2004 5:46 am    Post subject: Re: Previewing Window Messages Reply with quote

"Mike King" <emailMK (AT) excite (DOT) com> wrote:
Quote:
[...] I want the same functionality as the KeyPreview does
for other controls. Do I have to subclass the TCppWebBrowser
control to do a message map or does the form need the message map?

You have 2 basic choices when it comes to intercepting the
messages: A message map OR the WndProc method. To be clear,
both methods accomplish the exact same thing only in different
ways.

Each of the 2 methods can be implimented in 1 of 2 ways: At
the form level or the control level. IMO, the best choice is
to work at the control level but your needs may make it better
to work at the form level.

With the message map, to impliment it at the control level, you
would have to derive a new class from the WebBrowser, add the
map and then dynamically allocate it at run time. To use the
control at design time, you would need to derive a new component
and install it onto the pallette.

This is not true if you subclass the control's WndProc method.
You simple write the function and replace the default in the
constructor and restore the default in the destructor.

Coding for both methods remain much the same from the control
level to the form level with the exception that now you need
additional testing so that you can be sure that the message is
for the correct control. Also, with the WndProc method (at the
form level) you don't subclass it but rather override it. What
this means to you is that you don't assign it in the c'tor and
restore it in the d'tor.

~ JD

//--- message map for derived class - in the header -----------
class TMyWebBrowser : public TCPPWebBrowser
{
protected:
private:
typedef TCPPWebBrowser inherited;
// pick and choose what messages you want to listen for
MESSAGE void __fastcall WMPaint ( TWMPaint &Message );
MESSAGE void __fastcall WMKillFocus ( TMessage &Message );
MESSAGE void __fastcall WMSetCursor ( TWMSetCursor &Message );
MESSAGE void __fastcall WMCancelMode ( TMessage &Message );
MESSAGE void __fastcall CMCancelMode ( TCMCancelMode &Message );
MESSAGE void __fastcall WMLButtonDblClk( TWMLButtonDblClk &Message );
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER( WM_PAINT, TWMPaint, WMPaint );
VCL_MESSAGE_HANDLER( WM_KILLFOCUS, TMessage, WMKillFocus );
VCL_MESSAGE_HANDLER( WM_SETCURSOR, TWMSetCursor, WMSetCursor );
VCL_MESSAGE_HANDLER( WM_CANCELMODE, TMessage, WMCancelMode );
VCL_MESSAGE_HANDLER( CM_CANCELMODE, TCMCancelMode, CMCancelMode );
VCL_MESSAGE_HANDLER( WM_LBUTTONDBLCLK, TWMLButtonDblClk, WMLButtonDblClk );
END_MESSAGE_MAP( TCPPWebBrowser )
__fastcall TMyBrowser( TComponent* Owner );
};
//--- in the unit ---------------------------------------------
__fastcall TMyBrowser::TMyBrowser( TComponent* Owner ) : TCPPWebBrowser( Owner )
{
}
//-------------------------------------------------------------
MESSAGE void __fastcall TMyBrowser::WMPaint( TWMPaint &Message )
{
// do something
// then unconditionally send the message on for processing
inherited::Dispatch(&Message);
}
//-------------------------------------------------------------
MESSAGE void __fastcall TMyBrowser::WMKillFocus( TMessage &Message )
{
if( some condition )
{
// do something
}
else
{
// conditionally send the message on to be processed
inherited::Dispatch(&Message);
}
}
//-------------------------------------------------------------

//--- subclass the control's wndproc - in the form's header ---
private: // User declarations
TWndMethod OldWndProc;
void __fastcall NewWndProc( TMessage &Message );
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall TForm1::~TForm1();
//--- in the unit ---------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
OldWndProc = CPPBrowser1->WindowProc;
CPPBrowser1->WindowProc = NewWndProc;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
CPPBrowser1->WindowProc = OldWndProc;
}
//-------------------------------------------------------------
void __fastcall TForm1::NewWndProc( TMessage &Message )
{
switch( Message.Msg )
{
case CM_MOUSEENTER : MouseInControl = true;
OldWndProc( Message );
break;
case CM_MOUSELEAVE : MouseInControl = false;
OldWndProc( Message );
break;
case WM_KEYDOWN : // doing nothing here swallows the keystroke
case WM_KEYUP : break;
default : OldWndProc( Message );
}
}
//-------------------------------------------------------------


Back to top
Mike King
Guest





PostPosted: Mon Apr 26, 2004 6:18 pm    Post subject: Re: Previewing Window Messages Reply with quote

Thanks for your help. I've got it to a point where I can use it, but I
think it could be cleaner. Is it possible to implement the KeyPreview
functionality of the form because that would be the perfect solution? The
following code works, but the TMemo handles the message before my code can.
If I run the following program and push the 'T' key a "T" appears on the
TMemo and then the exception is throw. I would like for my code to
intercept the message and not pass it to the TMemo control. Is that
possible?

//--------------------------------------------------------------------------
-
#ifndef InterceptH
#define InterceptH
//--------------------------------------------------------------------------
-
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//--------------------------------------------------------------------------
-
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//--------------------------------------------------------------------------
-
extern PACKAGE TForm1 *Form1;
//--------------------------------------------------------------------------
-
#endif

//--------------------------------------------------------------------------
-
#include <vcl.h>
#pragma hdrstop
#include "InterceptForm2.h"
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

class TMikesMemo : public TMemo
{
public:
__fastcall TMikesMemo (Classes::TComponent* AOwner) : TMemo(AOwner) { }

private:
void __fastcall WndProc( TMessage &Message )
{
switch( Message.Msg ) {
case WM_KEYDOWN : WMOnKeyDown(Message);
break;
default : TMemo::WndProc( Message );
}
}

MESSAGE void __fastcall WMOnKeyDown ( TMessage &Message )
{
if (Message.WParam == 'T') throw new EAbort("");
}
};

//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMikesMemo* memo = new TMikesMemo(this);
memo->Parent = this;
}
//--------------------------------------------------------------------------
-


Back to top
JD
Guest





PostPosted: Mon Apr 26, 2004 7:49 pm    Post subject: Re: Previewing Window Messages Reply with quote


"Mike King" <emailMK (AT) excite (DOT) com> wrote:
Quote:
[...] but I think it could be cleaner.

I thought that I was clear with the samples but I guess not.
I posted 2 samples - 0ne subclassing the control and the other
subclassing the control's WndProc method.

You combined elements from both and ended up subclassing the
control AND the control's WndProc. You can do this if it's
what you really want but not how you did it.

Quote:
Is it possible to implement the KeyPreview functionality of
the form because that would be the perfect solution?

Try it. Set the form's KeyPreview property to true and use the
form's OnKeyDown event:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
if( Key == 'T' ) ShowMessage( "T was pressed" );
// swallow the key
Key = 0;
}

Quote:
The following code works, but the TMemo handles the message
before my code can.

I'm surprised that it even linked. Try this - Add a TMemo to
the form and then make it look like:

//--- the main form's header ----------------------------------
#ifndef InterceptH
#define InterceptH
//-------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//-------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo1 Memo1;
private: // User declarations
// add the next 2 declarations
// this one is to save the old base handler
TWndMethod OldMemoWindowProc;
// this is the subclassed wndproc method
void __fastcall NewMemoWindowProc( TMessage &Message );
public: // User declarations
__fastcall TForm1(TComponent* Owner);
// now you need to declare a destructor for the form
// because you need it to restore the Memo's wndproc before the form closes
__fastcall TForm1::~TForm1();
};
//------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//------------------------------------------------------------
#endif

//--- form1 unit ---------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "InterceptForm2.h"
//-------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// save the memo's wndproc method
OldMemoWindowProc = Memo1->WindowProc;
// assign the subclassed wndproc to the memo
Memo1->WindowProc = NewMemoWindowProc;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
// this is the form's destructor. It is executed as the
// form is being destroyed.
// restore the memo's wndproc
Memo1->WindowProc = OldMemoWindowProc;
}
//-------------------------------------------------------------
void __fastcall TForm1::NewMemoWindowProc( TMessage &Message )
{
if( Message.Msg == WM_KEYDOWN || Message.Msg == WM_KEYUP )
{
if( Message.WParam == 'T' )
{
if( Message.Msg == WM_KEYDOWN ) ShowMessage("T was pressed" );
else ShowMessage("T was released");
}
else
{
// pass all other keys onto the old handler
OldMemoWindowProc( Message );
}
}
else OldMemoWindowProc( Message );
}
//-------------------------------------------------------------

Quote:
if (Message.WParam == 'T') throw new EAbort("");

What's this? If you really want to close down the application,
just call Close() and your application will exit gracefully. If
you like, display an error message first:

MessageDlg("Some error message", mtError, TMsgDlgButtons() << mbOK, 0);
Close();

~ JD


Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.