Beruflich Dokumente
Kultur Dokumente
MessagesandEventsofWindowsControls
MessagesFundamentals
Introduction
Anapplicationismadeofvariousobjectsorcontrols.Duringthelifetimeoftheapplication,its
controls regularly send messages to the operating system to do something on their behalf.
These messages must be processed appropriately. Also, most of the time (in fact all the
time),morethanoneapplicationis(manyprocessesare)runningonthecomputer.
Thecontrolsofatypicalapplicationsendmessagestotheoperatingsystem.Astheoperatingsystem
isconstantlyaskedtoperformtheseassignments,becausetherecanbesomanyrequestspresented
unpredictably,it(theoperatingsystem)leavesituptothecontrolstospecifywhattheywant,when
theywantit,andwhatbehaviororresulttheyexpect.
Amessage,likealetteryousendtosomebody,mustprovideafewpiecesofinformationinordertobe
processed.ForaWin32application,thesepiecesofinformationarestoredinastructurecalledMSG.It
isdefinedasfollows:
typedefstructtagMSG{
HWNDhwnd
UINTmessage
WPARAMwParam
LPARAMlParam
DWORDtime
POINTpt
}MSG,*PMSG
ForaWin32application,eachmessageisprocessedbyafunctioncalledawindowprocedure.A
window procedure is a pointer to function, therefore declared as CALLBACK, and it returns a
positive32bitnumber.Therefore,aMSGvariablemustbepassedtothewindowprocedurefor
processing.
In a Win32 application, a window procedure that processes a message requires 3 pieces of
informationwiththelastpiecedividedintwo(whichproduces4piecesofinformation):
ThefirstpieceofinformationmuststateWHO,thatis,whatcontrol,sentthemessage
Thesecondpieceofinformationmustspecifythenameofthemessage:eachWindows
messageisrecognizedbyaname,whichissimplyapositivebutconstantnumericvalue
Thethirdandthefourthpiecescarryinformationthatdependsonthemessagebeingsent
Hereisanexample:
//
LRESULTCALLBACKWndProc(HWNDhWnd,
UINTMsg,
WPARAMwParam,
LPARAMlParam)
{
switch(Msg)
caseWM_DESTROY:
PostQuitMessage(WM_QUIT)
break
default:
returnDefWindowProc(hWnd,Msg,wParam,lParam)
return0
}
//
Once again, to make programming fast, the VCL provides its own message structure called
TMessageanddefinedasfollows:
structTMessage
{
CardinalMsg
http://www.functionx.com/cppbuilder/Lesson06.htm
1/13
2/9/2015
union
{
struct
{
WordWParamLo
WordWParamHi
WordLParamLo
WordLParamHi
WordResultLo
WordResultHi
}
struct
{
intWParam
intLParam
intResult
}
A TMessage message must provide two pieces of information, as the TMessage structure
shows: the name of the message and one group of information. Unlike the Win32 MSG
structure,inaVCLapplication,theobjectthatsendsthemessageisalreadyknown(becauseit
is the one that sent the message). The accompanying items of the message are coded into
eitherthetoporthebottomstructuresoftheanonymousunion.Thetwoanonymousstructures
insidetheunionindicatethatyouuseeitherthetoporthebottomstructurebutnotboth.
Onceacontrolhascomposedamessage,itmustsendittotherighttarget,whichcouldbethe
operatingsystem.Inordertosendamessage,acontrolmustcreateanevent.Thecontrolis
alsosaidtofireanevent.Tomakeadistinctionbetweenthetwo,amessage'snamewillusually
bewritteninuppercase.AnexamplewouldbeWM_MOVE,whichstandsfor"WindowMessage
Move".ThenameofaneventusuallystartswithOn,whichindicatesanaction.
Remember, the message is what needs to be sent. The event is the action of sending the
message.
PracticalLearning:IntroducingMessages
1. StartEmbarcaderoRADStudio
2. Tocreateanapplication,onthemainmenu,clickFile>New>VCLFormsApplication
C++Builder
3. OntheToolPalette,expandtheStandardsection
4. OntheToolPalette,doubleclickTButton
5. ClicktheTEditcontrol
6. Clickthecentertopsectionoftheform(noneedforprecision)
AMapofMessages
As mentioned already, the messages of a Win32 application are processed by a window
procedure.ForaVCLapplication,youcanusethesameapproach.Alternatively,youcanusea
techniquereferredtoascreatingamapofmessages.
For the compiler to manage messages, they should be listed in a public section of the class
definition. The messages are included in a list referred to as a message map. The list of
messages,that is, the message map, starts with the BEGIN_MESSAGE_MAP and ends with
the END_MESSAGE_MAP macros. The END_MESSAGE_MAP macro takes an argument,
which is the original class that holds the primary implementation of the messages. Here is an
example:
#ifndefStaticTextH
#defineStaticTextH
#include<Controls.hpp>
//
classTStaticText:TGraphicControl
{
__published:
private:
public:
http://www.functionx.com/cppbuilder/Lesson06.htm
2/13
2/9/2015
BEGIN_MESSAGE_MAP
END_MESSAGE_MAP(TGraphicControl)
}
//
#endif
BetweentheBEGIN_MESSAGE_MAPandtheEND_MESSAGE_MAPmacros,eachmessageis
declared using either the MESSAGE_HANDLER or the VCL_MESSAGE_HANDLER macros.
Theirsyntaxesare:
MESSAGE_HANDLER(VCLMessageName,TMessage,EventName)
VCL_MESSAGE_HANDLER(WindowsMsgName,VCLMessageName,EventName)
Therearevariouscategoriesofmessagestheoperatingsystem receives. Some of them come
from the keyboard, some from the mouse, and some others from various other sources. For
example, some messages are sent by the application itself while some other messages are
controlledbytheoperatingsystem.
MessagesCharacteristics
The most commonly sent messages have already been created in the objects of the VCL
controls so much that you will hardly need to define new messages, at least not in the
beginning of your C++Builder programming adventure. Most of what you will do consists of
implementingthedesiredbehaviorwhenaparticularmessageissent.
To start, you should know what messages are available, when, and how they work. As
mentionedalready,eachcontrolsendsitsownmessageswhennecessary.Basedonthis,some
messages are unique to some controls according to their roles. Some other messages are
common to various controls, as they tend to provide similar actions. To manage such various
configurations, the VCL considers the messages in two broad categories. Those that take an
argument and those that do not. The VCL defines events as function pointers (or pointers to
function).
Asithappens,somemessagesdonotrequiremuchinformationtobeperformed.Forexample,
suppose your heart sends a message to the arm and states, Raise your hand. In this case,
supposeeverythingisalright,thearmdoesnotask,"howdoIraisemyhand?".Itsimplydoes.
This type of message would be sent without any accompanying information. Consider another
message where the arm carries some water and says to the mouth, "Swallow the following
water".Themouthwouldneedthewaterthatneedstobeswallowed.Therefore,themessage
mustbeaccompaniedbyadditionalinformation,whichisconsideredanargument.Considerone
moremessagewheretheheartsaystothetongue,Tastethefollowingfoodbutdonotswallow
it.Inordertoprocessthismessage,thetonguewouldneedthefoodandsomethingtoindicate
thatthefoodmustnotbeswallowed.Inthiscase,themessagemustbeaccompaniedbytwo
piecesofinformation.
To process messages that do not require any additional argument, the VCL creates such an
event with the TNotifyEvent type. Such an event is declared as a pointer to function in the
classes.hpplibraryasfollows:
typedefvoid__fastcall(__closure*TNotifyEvent)(System::TObject*Sender)
TheSenderargumentisthecontrolthatissendingthemessages.
BesidesTNotifyEvent,theothereventscarrydifferentandappropriatenames.
EventImplementation
Although there are different ways you can implement an event, there are two main ways you
caninitiateitscoding.Ifthecontrolhasadefaulteventandifyoudoubleclickit,thecompiler
wouldinitiatethedefaultevent.AnothertechniqueyoucanuseistoclicktheEventstabofthe
ObjectInspector.Thiswoulddisplayalistoftheeventsassociatedwiththeselectedcontrol:
http://www.functionx.com/cppbuilder/Lesson06.htm
3/13
2/9/2015
Thelistisdividedintwocolumns.Thenameofeacheventisdisplayedontheleftside.Youcan
clickthenameofaneventtorevealacombobox.Ifasimilarevent(similareventsarethose
thatshareabehavior)hasalreadybeenwritten,youcanclickthearrowofthecomboboxand
selectitfromthelist:
Otherwise, to initiate an event doubleclick the field on the right column of the name of the
desiredevent.
Whenaneventhasbeeninitiated,youwouldbetransportedtotheCodeEditorandthecaret
wouldbepositionedinthebodyoftheevent,readytoreceiveyourinstructions.Tocustomize
anevent,thecompilerdividesitsstructureinthreesections:
//
void__fastcallTForm1::FormMouseMove(TObject*Sender,TShiftStateShift,
intX,intY)
{
//Writecodeassociatedwiththeeventhere
}
//
The coding of an event starts with its return value. All events in C++Builder return void.All
eventsusethe__fastcallconvention.
The return type is followed by the name of the parent class from where the event would be
fired.Thisismainlytheclassthatcontrolstheform.
Afterthenameoftheclass,thecompilerrightlyusestheclassmemberaccessoperator(::)to
calltheevent,followingaC++rule.
The name of an event is made of a combination of the control that owns or fired the event
andthenameoftheevent.
Each event has at least one argument, the TObject *Sender. Some events use additional
argumentsthatwewillreviewwhencodingsuchevents.
http://www.functionx.com/cppbuilder/Lesson06.htm
4/13
2/9/2015
PracticalLearning:ImplementingEvents
1. Doubleclickanunoccupiedareaoftheform
2. Implementtheeventasfollows:
//
void__fastcallTForm1::FormCreate(TObject*Sender)
{
MessageDlg(L"Theformhasbeencreated",
mtConfirmation,
TMsgDlgButtons()<<mbOK,0)
}
//
3. PressF12toreturntotheform
4. Ontheform,doubleclickthebutton
5. Implementtheeventasfollows:
//
void__fastcallTForm1::Button1Click(TObject*Sender)
{
Application>MessageBox("Thebuttonwasclicked",
"ApplicationDesign",
MB_OK|MB_ICONINFORMATION)
}
//
6. PressF12toreturntotheform
7. Ontheform,clickEdit1
8. IntheObjectInspector,clickEvents
9. DoubleclicktheboxontherightsideofOnEnter
10. Implementtheeventasfollows:
//
void__fastcallTForm1::Edit1Enter(TObject*Sender)
{
ShowMessage(L"Theeditboxhasreceivedfocus.")
}
//
11. PressF12toreturntotheform
12. PressF9totesttheform
13. Afterreadingthemessagebox,clickOK
14. Clicktheeditbox
15. Clickthebutton
16. Closetheformandreturntoyourprogrammingenvironment
KeyboardMessages
Introduction
A keyboard is a hardware object attached to the computer. By
default, it is used to enter recognizable symbols, letters, and
othercharactersonacontrol.Eachkeyonthekeyboarddisplays
a symbol, a letter, or a combination of those, to give an
indicationofwhatthekeycouldbeusedfor.
Theusertypicallypressesakey,whichsendsasignaltoaprogram.Thesignalisanalyzedto
finditsmeaning.Iftheprogramorcontrolthathasfocusisequippedtodealwiththesignal,it
may produce the expected result. If the program or control cannot figure out what to do, it
ignorestheaction.
Eachkeyhasacodethattheoperatingsystemcanrecognize.Thiscodeisknownasthevirtual
keycodeandtheyareasfollows:
VirtualKey
Usedfor
VirtualKey
Usedfor
VK_F1
F1
VK_F2
F2
http://www.functionx.com/cppbuilder/Lesson06.htm
5/13
2/9/2015
VK_F3
F3
VK_F4
F4
VK_F5
F5
VK_F6
F6
VK_F7
F7
VK_F8
F8
VK_F9
F9
VK_F10
F10
VK_F11
F11
VK_F12
F12
VK_SCROLL
ScrollLock
VK_SNAPSHOT
PrtScrn(Dependsonkeyboard)
VK_PAUSE
Pause/Break
VK_TAB
Tab
VK_BACK
Backspace
VK_CAPITAL
CapsLock
VK_SHIFT
Shift
VK_CONTROL
Ctrl
VK_MENU
Alt
VK_ESCAPE
Escape
VK_RETURN
Enter
VK_SPACE
SpaceBar
VK_INSERT
Insert
VK_HOME
Home
VK_PRIOR
PageUp
VK_DELETE
Delete
VK_END
End
VK_NEXT
PageDown
VK_UP
UpArrowKey
VK_RIGHT
RightArrowKey
VK_DOWN
DownArrowKey
VK_LEFT
LeftArrowKey
VK_LWIN
LeftWindowsKey
VK_RWIN
RightWindowsKey
VK_APPS
ApplicationsKey
Thefollowingkeysapplytothenumerickeypad
VK_NUMLOCK
NumLock
VK_NUMPAD0
VK_NUMPAD1
VK_NUMPAD2
VK_NUMPAD3
VK_NUMPAD4
VK_NUMPAD5
VK_NUMPAD6
VK_NUMPAD7
VK_NUMPAD8
VK_NUMPAD9
VK_DIVIDE
VK_MULTIPLY
VK_SUBTRACT
VK_ADD
VK_SEPARATOR
VK_DECIMAL
Thereareactuallymorekeysthanthatbuttheabovearethemostfrequentlyused.
TheVCLimplementskeyboardeventsusingtwofunctionpointers,TKeyEventandTKeyPress
thatdependonthemessage.
TheKeyDownMessage
When a keyboard key is pressed, a message called WMKeyDown is sent. WMKeyDown is a
TKeyEventmessagethatproducestheOnKeyDownevent.Itssyntaxis:
void__fastcallOnKeyDown(System::TObject*Sender,Word&Key,
Classes::TShiftStateShift)
TheKey argument specifies the key that was pressed. The OnKeyDown() event can be sent
by any key. Alphabetic keys are represented by their character. For example, if the user
pressesp, the Key argument would be represented as p. If the user presses a key, the Key
argumentwouldhavethevalueof.
The Shift argument specifies whether the Shift, the Ctrl, or the Alt keys were pressed along
withtheKeykey.ItisaPascalSetwhoseenumeratorhasthefollowingmembers:
Value
Description
ssShift
OneoftheShiftkeyswaspressed
ssAlt
OneoftheAltkeyswaspressed
ssCtrl
OneoftheCtrlkeyswaspressed
If the user presses two keys as an uppercase letter, such R, the Key argument would have a
valueofr.TheShiftargumentwouldbeusedtoindicatethattheShiftkeywasdownwhenthe
letterrwaspressed.
PracticalLearning:SendingKeyDownMessages
http://www.functionx.com/cppbuilder/Lesson06.htm
6/13
2/9/2015
1. Ontheform,clickEdit1
2. ToexperimentwiththeWMKeyDownmessage,ontheObjectInspector,clicktheEventstab
ifnecesary.
DoubleclicktherightfieldofOnKeyDown
3. DeletethelineofcodeintheEdit1Enterevent
4. Implementtheeventasfollows:
//
#include<vcl.h>
#pragmahdrstop
#include"Unit1.h"
//
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
TForm1*Form1
//
__fastcallTForm1::TForm1(TComponent*Owner)
:TForm(Owner)
{
}
//
void__fastcallTForm1::FormCreate(TObject*Sender)
{
MessageDlg(L"Theformhasbeencreated",
mtConfirmation,
TMsgDlgButtons()<<mbOK,0)
}
//
void__fastcallTForm1::Button1Click(TObject*Sender)
{
Application>MessageBox("Thebuttonwasclicked",
"ApplicationDesign",
MB_OK|MB_ICONINFORMATION)
}
//
void__fastcallTForm1::Edit1KeyDown(TObject*Sender,WORD&Key,
TShiftStateShift)
{
switch(Key)
caseVK_RETURN:
ShowMessage("YoupressedEnter")
break
caseVK_F1:
ShowMessage("Helpisnotavailableatthemoment")
break
caseVK_DELETE:
ShowMessage("Can'tDeleteThis")
break
case'K':
//IftheuserpressCtrl+K
if(Shift.Contains(ssCtrl))
ShowMessage("Kwaspressed")
break
}
}
//
5. PressF9totesttheapplication
6. Ontheform,clicktheeditbox,pressHomeandpressDelete
7. PressEnter
8. PressCtrl+K
9. PressF1
10. Closetheformandreturntoyourprogrammingenvironment
TheKeyUpMessage
Asopposedtothekeydownmessagethatissentwhenakeyisdown,theWMKeyUpmessage
is sent when the user releases the key. Like WMKeyDown, WMKeyUp is a TKeyEvent
message.ItproducestheOnKeyUpeventwhosesyntaxis:
http://www.functionx.com/cppbuilder/Lesson06.htm
7/13
2/9/2015
void__fastcallOnKeyUp(System::TObject*Sender,Word&Key,
Classes::TShiftStateShift)
The Key argument specifies the key that was pressed. Like the OnKeyDown event, the
OnKeyUpeventprocessesanykey.Alphabetickeysarerepresentedbytheircharacter.
TheShift argument indicates whether the Shift,theCtrl, or the Alt key participates in a key
combinationsuchasShift+$
TheKeyPressMessage
When the user presses a key, the WMKeyPress message is sent. Unlike the other two
keyboard messages, the key pressed for this event should (must) be a character key.
WMKeyPressproducestheOnKeyPresseventwhosesyntaxis:
void__fastcallOnLKeyPress(System::TObject*Sender,char&Key)
TheKeyargumentmustbealetterorarecognizablesymbol.Lowercasealphabeticcharacters,
digits,andthelowerbasecharacterssuchas,[]=/arerecognizedastheyare.Foran
uppercaseletteroranupperbasesymbols,theusermustpressShift+thekey.Thecharacter
would be identified as one entity. This means that the symbol % typed with Shift + 5 is
consideredasonecharacter.
PracticalLearning:SendingKeyPressMessages
1. ToexperimentwiththeWMKeyPressmessage,ontheEventstaboftheObjectInspector,
doubleclicktherightfieldofOnKeyPress
2. DeletethecodeintheOnKeyDownevent
3. ImplementtheOnKeyPresseventasfollows:
//
void__fastcallTForm1::Edit1KeyPress(TObject*Sender,char&Key)
{
switch(Key)
caseVK_RETURN:
ShowMessage("YoupressedEnter")
break
caseVK_F1:
ShowMessage("Helpisnotavailableatthemoment")
break
caseVK_DELETE:
ShowMessage("Can'tDeleteThis")
break
case'k':
ShowMessage("Lowercasekwaspressed")
break
case'K':
ShowMessage("UppercaseKwaspressed")
break
case'$':
ShowMessage("Showmethemoney")
break
}
}
//
4. TesttheapplicationandpresstheDeleteortheF1keys.Noticethatnothinghappens
5. Pressk
http://www.functionx.com/cppbuilder/Lesson06.htm
8/13
2/9/2015
6. ClickOKandpressShift+K
7. ClosetheapplicationandreturnC++Builder
MouseMessages
Introduction
Themouseisanotherobjectthatisattachedtothecomputerallowingtheusertointeractwiththe
machine. The mouse and the keyboard can each accomplish some tasks that are not normally
availableontheotherandbothcanaccomplishsometasksthesameway.
Themouseisequippedwithtwo,three,ormorebuttons.Whenamousehastwobuttons,oneis
usuallylocatedontheleftandtheotherislocatedontheright.Whenamousehasthreebuttons,
one is in the middle of the other two. The mouse is used to select a point or position on the
screen. Once the user has located an item, which could also be an empty space, a letter or a
word,heorshewouldpositionthemousepointeronit.Toactuallyusethemouse,theuserwould
presstheleft,themiddle(ifany),ortherightbutton.Iftheuserpressestheleftbuttononce,this
actioniscalledClick.Iftheuserpressestherightmousebutton,theactionisreferredtoasRight
Click.Iftheuserpressestheleftbuttontwiceandveryfast,theactioniscalledDoubleClick.
MouseeventsareimplementedasTMouseEventandTMouseMoveEventfunctionpointers.
TheMouseDownMessage
Imaginetheuserhaslocatedapositionoranitemonadocumentandpressesoneofthemouse
buttons.Whilethebuttonispressedandisdown,abuttondownmessageissent.Thesyntaxof
thiseventisasfollows:
void__fastcallOnMouseDown(System::TObject*Sender,TMouseButtonButton,
Classes::TShiftStateShift,intX,intY)
TheButton argument specifies what button was clicked. The buttons of the mouse are identified
bytheTMouseButtonenumeratorwhosemembersare:
Value
Description
mbLeft
Theleftmousebuttonwasclicked
mbRight
Therightmousebuttonwasclicked
mbMiddle Themiddlemousebuttonwasclicked
TheShiftargumentindicateswhethermousebuttonand/orakeyboardkeywas/werepressedand
helddownwhentheButtonwasclicked.Itcanhaveoneofthefollowingvalues:
Value
Description
ssShift
OneoftheShiftkeyswaspressed
ssAlt
OneoftheAltkeyswaspressed
ssCtrl
OneoftheCtrlkeyswaspressed
ssLeft
Theleftmousebuttonwashelddown
ssRight
Therightmousebuttonwashelddown
http://www.functionx.com/cppbuilder/Lesson06.htm
9/13
2/9/2015
ssMiddle
Themiddlemousebuttonwasheld
down
ssDouble
TheButtonwasdoubleclicked
TheXandtheYargumentrepresenttheTPoint(X,Y)pointwherethemousewasclicked.
PracticalLearning:SendingaMouseDownMessage
1. Displaytheform
2. Toexperimentwiththemousedowneffect,ontheEventstaboftheObjectInspector,double
clicktherightsideoftheOnMouseDownfield
3. Implementtheeventasfollows:
//
void__fastcallTForm1::FormMouseDown(TObject*Sender,TMouseButtonButton,
TShiftStateShift,intX,intY)
{
ShowMessage("Mouseat("+IntToStr(X)+","+IntToStr(Y)+")")
}
//
4. Testtheprogramandclickvariouspartsoftheform
5. Closeitandreturntoyourprogrammingenvironment
TheMouseUpMessage
Afterpressingamousebutton,theuserusuallyreleasesit.Whilethebuttonisbeingreleased,a
buttonupmessageissentanditdependsonthebutton,leftorright,thatwasdown.Theevent
producedisOnMouseUp.
TheOnMouseUp event uses the same syntax as the OnMouseDown event and processes the
samearguments.
TheMouseMoveMessage
Whenever the mouse is positioned and being moved on top ofacontrol,amouseeventissent.
ThiseventisimplementedasaTMouseMoveEventfunctionpointeranditssyntaxis:
void__fastcallOnMouseMove(System::TObject*Sender,
Classes::TShiftStateShift,intX,intY)
The Shift argument is the same as the other mouse messages. The X and Y values identify the
locationofthemouseatthetimethiseventfires.
ProgrammerDefinedMessages
Introduction
The list of methods and messages available for the objects used in your applications is very
impressivebecausetheVCLtriestohelpprocessasmanymessagesaspossible.Unfortunately,in
someareas,theVCLtendstoaddressonlythemostcommonlyusedmessages,whichisstillvery
long,aswewillseethroughoutourlessons.
The Win32 library provides more messages than the VCL implements. Normally, you should first
checkifamessageyouwanttoprocessisalreadyavailableforyourcontrol.Ifitisnot,youcan
create your own message and its event. Once again you have various options. If the message
belongs to, or must be processed by, a form, you can create it in the header file of the form.
Otherwise,youcancreateanewcontrolbysimplyderivingaclassfromanexistingcontrol.
WindowsFunctions
AnotherwayyouwillmanipulatecontrolsconsistsofcallingaWin32APIfunction.Therearetwo
main categories of functions you will call: those that must identify the control that is calling the
functionandthosethatdonot.Ifthefunctionrequiresthecontrolthatcalledit,you can specify
thecontrolusingitshandle.Ifthefunctiondoesnotneedthispieceofinformation,thenyoucan
omitit.Wewillseevarioustypesofbothcategoriesoffunctions.
Most of the messages we will use in our applications are implemented in various classes of the
VCL.Someothersarenot.SomeofthemessagesareavailableintheWin32libraryandyoucan
use them in your application. This is made possible by calling the SendMessage()function. Its
syntaxis:
http://www.functionx.com/cppbuilder/Lesson06.htm
10/13
2/9/2015
LRESULTSendMessage(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMlParam)
ThehWndargumentistheobjectorcontrolthatissendingthemessage.
TheMsgargumentisthemessagetobesent.
ThewParamandthelParamvaluesdependonthemessagethatisbeingsent.
The advantage of using the SendMessage() function is that, when sending this message, it
wouldtargettheprocedurethatcanperformthetaskandthisfunctionwouldreturnonlyafterits
messagehasbeenprocessed.Becausethisfunctioncansometimesuniversallybeused,thatisby
almost any control or object, the application cannot predict the type of message that
SendMessage() is carrying. Therefore, (the probable disadvantage is that) you must know the
(nameoridentityofthe)messageyouaresendingandyoumustprovideaccurateaccompanying
items.
HereisanexamplethatchangesthecaptionofaformusingtheWM_SETTEXTmessage:
//
void__fastcallTForm1::FormCreate(TObject*Sender)
{
constchar*Msg="Thismessagewassent"
SendMessage(Handle,WM_SETTEXT,0,(LPARAM)(LPCTSTR)Msg)
}
//
PerformingMessages
Besides the SendMessage() function, the TControl class provides the Perform() method that
allowsyoutosendamessageanytime.Itssyntaxis:
int__fastcallPerform(unsignedMsg,intWParam,intLParam)
TheTControl::Perform()methodfunctionsliketheSendMessage()functionexceptthat,since
it is a VCL function, it omits the handle to the control because the control that calls it would be
specified already. The first argument, Msg, is the identifier of the message that needs to be
processed. It is exactly like the second argument of the SendMessage() function. Like the
SendMessage()function,thevaluesofWParamandLParamdependonthemessage.Hereisan
exampleusedtocloseaform:
//
void__fastcallTForm1::Button1Click(TObject*Sender)
{
Perform(WM_CLOSE,0,0)
}
//
CustomMessageImplementation
Tocustomizeanexistingmessageofacontrolortocreateanewmessagethatisnotavailablefor
yourcontrol,theTControlclassprovidestheWndProc()method.Itssyntaxis:
virtualvoid__fastcallWndProc(Messages::TMessage&Message)
Inordertousethismethod,youmustoverrideitinyourownclass.Hereisanexample:
//
classTForm1:publicTForm
{
__published://IDEmanagedComponents
private://Userdeclarations
public://Userdeclarations
__fastcallTForm1(TComponent*Owner)
virtualvoid__fastcallWndProc(TMessage&Msg)
}
//
TheMessageargumentisanymessageyouwanttoprocess.AsdoneforaWin32application,the
Messagevalueistypicallypassedtoaswitchconditionandeachdesiredmessageistreatedina
case statement. After processing the messages and before closing the member function, you
should (must) call the parent class to process the messages that were not treated. Here is an
example that treats the WM_MOVE message and prevents the user from moving the form (by
preventingthemousefromcapturingthetitlebar):
//
void__fastcallTForm1::WndProc(TMessage&Message)
{
switch(Message.Msg)
http://www.functionx.com/cppbuilder/Lesson06.htm
11/13
2/9/2015
caseWM_MOVE:
ReleaseCapture()
break
TForm::WndProc(Message)
}
//
After creating the message, if it is intended for the form to treat, the message is ready and its
event would fire appropriately. If the event is for a particular control, you must let the compiler
knowthatyouhaveawindowprocedurethatwouldprocessaparticularmessageorthemessages
ofacertaincontrol.Todothis,youcanassignWndProctothecontrolsWindowProc member
variable.ThiscouldbedoneintheconstructorortheOnCreate()eventoftheformasfollows:
//
__fastcallTForm1::TForm1(TComponent*Owner)
:TForm(Owner)
{
this>WindowProc=WndProc
}
//
As we mentioned earlier, instead of using a window procedure, you can create a message map
thatliststheevent(s)thatyouwanttofire.Makesureyoualsodeclarethefunctionthatwillcarry
theevent:
//
#ifndefUnit1H
#defineUnit1H
//
#include<Classes.hpp>
#include<Controls.hpp>
#include<StdCtrls.hpp>
#include<Forms.hpp>
//
classTForm1:publicTForm
{
__published: //IDEmanagedComponents
private:
//Userdeclarations
void__fastcallTForm1::DontMoveMe(TObject*Sender)
public:
//Userdeclarations
__fastcallTForm1(TComponent*Owner)
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_MOVE,TObject*,DontMoveMe)
END_MESSAGE_MAP(TForm)
}
//
externPACKAGETForm1*Form1
//
#endif
Afterdoingthisintheheaderfile,inthesourcefile,implementthemethodasyouseefit.Hereis
anexample:
//
#include<vcl.h>
#pragmahdrstop
#include"Unit1.h"
//
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
TForm1*Form1
//
__fastcallTForm1::TForm1(TComponent*Owner)
:TForm(Owner)
{
}
//
void__fastcallTForm1::DontMoveMe(TObject*Sender)
{
ReleaseCapture()
}
http://www.functionx.com/cppbuilder/Lesson06.htm
12/13
2/9/2015
//
MethodsandMessagesCombinations
The events of Windows controls are designed to be executed at specific periods in response to
someoccurrence.Forexample,onlywhentheuserpressesamousebuttoncanamessagerelated
tothisactionwouldoccur.Yet,oneofthemostinfluentialwaysofcreatinganeffectiveprogramis
toanticipateusersactionsasmuchaspossible.Thisallowsyoutocorrectlyrespond.Tosupport
thisidea,theVCLprovidesasystemofcombiningcontrolsmessagesandtheirassociatedevents.
Whentheuserinitiatesanactiontosendamessage,thecontrolthatownstheactionsendsthe
message and an accompanying method. This method, although belonging to the control, allows
othercontrolsorotherpartsoftheprogramtoaccesstheeventasiftheycontrolledwhensuchan
event would occur. For example, if the user clicks a control, the control composes and sends a
clickmessage.BecausethecontrolisalsoequippedwithaClick()method,anothercontrolofthe
applicationcancallitsClick()eventandperformthesameaction.Hereisanexample:
//
void__fastcallTForm1::Button1Click(TObject*Sender)
{
Perform(WM_CLOSE,0,0)
}
//
void__fastcallTForm1::Panel1MouseDown(TObject*Sender,
TMouseButtonButton,
TShiftStateShift,
intX,
intY)
{
Button1>Click()
}
//
PracticalLearning:EndingtheLesson
1. Toendthelesson,onthemainmenu,clickFile>Exit
2. Whenaskedwhetheryouwanttosave,clickNo
Previous
Copyright20102011FunctionX,Inc.
http://www.functionx.com/cppbuilder/Lesson06.htm
Next
13/13