+ Added message methods

This commit is contained in:
michael 1999-06-05 10:50:44 +00:00
parent a1fede8c2a
commit 333d20bace
2 changed files with 163 additions and 5 deletions

View File

@ -800,10 +800,10 @@ error if S is an ansistring:
\begin{verbatim} \begin{verbatim}
Len:=S[0]; Len:=S[0];
\end{verbatim} \end{verbatim}
Instead, you must use the \seefl{Length} function to get the length of a Instead, you must use the \seef{Length} function to get the length of a
string. string.
To set the length of an ansistring, you can use the \seepl{SetLength} To set the length of an ansistring, you can use the \seep{SetLength}
function. function.
Constant ansistrings have a reference count of -1 and are treated specially. Constant ansistrings have a reference count of -1 and are treated specially.
@ -1723,7 +1723,8 @@ an object. To get the size of the class instance data, use the
\var{TObject.InstanceSize} method. \var{TObject.InstanceSize} method.
\end{itemize} \end{itemize}
\section{Methods} \section{Methods}
Method invocation for classes is no different than for objects. The \seubsection{invocation}
Method invocaticn for classes is no different than for objects. The
following is a valid method invocation: following is a valid method invocation:
\begin{verbatim} \begin{verbatim}
Var AnObject : TAnObject; Var AnObject : TAnObject;
@ -1731,6 +1732,138 @@ begin
AnObject := TAnObject.Create; AnObject := TAnObject.Create;
ANobject.AMethod; ANobject.AMethod;
\end{verbatim} \end{verbatim}
\subsection{Virtual methods}
Classes have virtual methods, just as objects do. There is however a
difference between the two. For objects, it is sufficient to redeclare the
same method in a descendent object with the keyword \var{virtual} to
override it. For classes, the situation is different: you {\em must}
override virtual methods with the \var{override} keyword. Failing to do so,
will start a {\em new} batch of virtual methods, hiding the previous
one. The \var{Inherited} keyword will not jup to the inhherited method, if
virtual was used.
The following code is {\em wrong}:
\begin{listing}
Type ObjParent = Class
Procedure MyProc; virtual;
end;
ObjChild = Class(ObjPArent)
Procedure MyProc; virtual;
end;
\end{listing}
The compiler will produce a warning:
\begin{verbatim}
Warning: An inherited method is hidden by OBJCHILD.MYPROC
\end{verbatim}
The compiler will compile it, but using \var{Inherited} can
produce strange effects.
The correct declaration is as follows:
\begin{listing}
Type ObjParent = Class
Procedure MyProc; virtual;
end;
ObjChild = Class(ObjPArent)
Procedure MyProc; override;
end;
\end{listing}
This will compile and run without warnings or errors.
\subsection{Message methods}
New in classes are \var{message} methods. Pointers to message methods are
stored in a special table, together with the integer or string cnstant that
they were declared with. They are primarily intended to ease programming of
callback functions in several \var{GUI} toolkits, such as \var{Win32} or
\var{GTK}. In difference with Delphi, \fpc also accepts strings as message
identifiers.
Message methods that are declared with an integer constant can take only one
var argument (typed or not):
\begin{listing}
Procedure TMyObject.MyHandler(Var Msg); Message 1;
\end{listing}
The method implementation of a message function is no different from an
ordinary method. It is also possible to call a message method directly,
but you should not do this. Instead use the \var{TObject.Dispatch} method.
The \var{TOBject.Dispatch} method can be used to call a \var{message}
handler. It is declared in the system unit will accept a var parameter
which must have at the first position a cardinal with the message ID that
should be called. For example:
\begin{listing}
Type
TMsg = Record
MSGID : Cardinal
Data : Pointer;
Var
Msg : TMSg;
MyObject.Dispatch (Msg);
\end{listing}
In this example, the \var{Dispatch} method will look at the object and all
it's ancestors (starting at the object, and searching up the class tree),
to see if a message method with message \var{MSGID} has been
declared. If such a method is found, it is called, and passed the
\var{Msg} parameter.
If no such method is found, \var{DefaultHandler} is called.
\var{DefaultHandler} is a virtual method of \var{TObject} that doesn't do
anything, but which can be overridden to provide any processing you might
need. \var{DefaultHandler} is declared as follows:
\begin{listing}
procedure defaulthandler(var message);virtual;
\end{listing}
In addition to the message method with a \var{Integer} identifier,
\fpc also supports a messae method with a string identifier:
\begin{listing}
Procedure TMyObject.MyStrHandler(Var Msg); Message 'OnClick';
\end{listing}
The working of the string message handler is the same as the ordinary
integer message handler:
The \var{TOBject.DispatchStr} method can be used to call a \var{message}
handler. It is declared in the system unit and will accept one parameter
which must have at the first position a cardinal with the message ID that
should be called. For example:
\begin{listing}
Type
TMsg = Record
MsgStr : String[10]; // Arbitrary length up to 255 characters.
Data : Pointer;
Var
Msg : TMSg;
MyObject.DispatchStr (Msg);
\end{listing}
In this example, the \var{DispatchStr} method will look at the object and
all it's ancestors (starting at the object, and searching up the class tree),
to see if a message method with message \var{MsgStr} has been
declared. If such a method is found, it is called, and passed the
\var{Msg} parameter.
If no such method is found, \var{DefaultHandlerStr} is called.
\var{DefaultHandlerStr} is a virtual method of \var{TObject} that doesn't do
anything, but which can be overridden to provide any processing you might
need. \var{DefaultHandlerStr} is declared as follows:
\begin{listing}
procedure DefaultHandlerStr(var message);virtual;
\end{listing}
In addition to this mechanism, a string message method accepts a \var{self}
parameter:
\begin{listing}
TMyObject.StrMsgHandler(Data : Pointer; Self : TMyObject);Message 'OnClick';
\end{listing}
When encountering such a method, the compiler will generate code that loads
the \var{Self} parameter into the object instance pointer. The result of
this is that it is possible to pass \var{Self} as a parameter to such a
method.
{\em remark:} The type of the \var{Self} parameter must be of the same class
as the class you define the method for.
\section{Properties} \section{Properties}
Classes can contain properties as part of their fields list. A property Classes can contain properties as part of their fields list. A property
acts like a normal field, i.e. you can get or set it's value, but acts like a normal field, i.e. you can get or set it's value, but
@ -3502,7 +3635,7 @@ const
errorcode : word = 0; errorcode : word = 0;
{ max level in dumping on error } { max level in dumping on error }
max_frame_dump : word = 20; max_frame_dump : word = 20;
\end{verbatim} \end{listing}
\emph{ Remark: } Processor specific global constants are named Testxxxx \emph{ Remark: } Processor specific global constants are named Testxxxx
where xxxx represents the processor number (such as Test8086, Test68000), where xxxx represents the processor number (such as Test8086, Test68000),
and are used to determine on what generation of processor the program and are used to determine on what generation of processor the program
@ -4872,6 +5005,25 @@ None.
\end{function} \end{function}
\latex{\inputlisting{refex/ex79.pp}} \latex{\inputlisting{refex/ex79.pp}}
\html{\input{refex/ex79.tex}} \html{\input{refex/ex79.tex}}
\begin{procedure}{SetLength}
\Declaration
Procedure SetLength(var S : String; Len : Longint);
\Description
\var{SetLength} sets the lentgth of the string \var{S} to \var{Len}. \var{S}
can be an ansistring or a short string.
For \var{ShortStrings}, \var{Len} can maximally be 255. For \var{AnsiStrings}
it can have any value. For \var{AnsiString} strings, \var{SetLength} {\em
must} be used to set the length of the string.
\Errors
None.
\SeeAlso
\seef{Length}
\end{procedure}
\latex{\inputlisting{refex/ex85.pp}}
\html{\input{refex/ex85.tex}}
\begin{procedure}{SetTextBuf} \begin{procedure}{SetTextBuf}
\Declaration \Declaration
Procedure SetTextBuf (Var f : Text; Var Buf[; Size : Word]); Procedure SetTextBuf (Var f : Text; Var Buf[; Size : Word]);

View File

@ -43,7 +43,13 @@
\) \)
\lit*; \lit*;
\[ \[
\lit*{virtual} \lit*; \( \lit*{virtual} \\
\lit*{override} \\
\lit*{message}
\( \synt{integer\ constant} \\
\synt{string\ constant} \)
\)
\lit*;
\] \]
\[ \synt{call\ modifiers} \lit*; \] \[ \synt{call\ modifiers} \lit*; \]
\[ \[