[lazarus] Lazarus help html document

Shane Miller SMiller1 at stvgb.org
Mon Jan 10 16:50:02 EST 2000


Can I get comments on this file please.  I spent a lot of time typing but not much editing it so it's rough.

Please let me know if you guys think it'll be helpful to new developers out there, plus let me know sections that could be added.

Thanks
Shane



Title: Welcome to the Lazarus Project Information Page

 

 





<IMG SRC="SMLogo/lazarus_sm.jpg"
WIDTH="250" HEIGHT="188">
The Official Source of Lazarus Project Information

<IMG SRC="SMDecors/baroque2J.gif" ALT="Welcome"
WIDTH="480" HEIGHT="52">




<IMG SRC="SMDecors/baroque10.gif"
WIDTH="120" HEIGHT="36"> 

Welcome to the Lazarus Project
Information Page
Welcome to the Lazarus Project Information page. 
This document is designed for the "new" developer to Lazaurs. From
this document you will learn how to add code to lazarus and how we have setup
the components, controls, events, etc inside the Lazarus code.
This page will be updated as changes are made to the componets and the
underlying structure of the LCL (Lazarus Component
Library).
A
brief explaination:Lazarus is built to allow it the be run using many
differnet types of "widget" sets. A few examples of widget sets would
be the default Win32 widgets (controls) that are used within the Windows
environment. Also, within linux you can use GTK widgets or QT widgets. This
allows Lazarus to be run under Windows and Linux and have total code
compatability.
All the code that determines which widget set to use is found
within a file called Interfaces.pp or one of the files it uses. Within this
file are the "{$Define}"'s that specify which widget set the controls
should be built off of.
"{$define GTK}" causes the InterfaceObject class to
become a class of "TGtkObject" and therefore inherit all the gtk
specific commands/methods/properties. This is a quick and easy method of
controlling the widget set without making the developer control which files or
directories should be in the search path. This way it's all controlled by one
"Define". Later, this will be a setting within the IDE itself and
will allow the developer to simply choose which widget set to use by selecting
them from a list..
Currently, the GTK widget set is the most complete within
Lazarus and therefore I will start by explaining the files associated with that
widget set.
Interfaces.pp defines a class TInterfaceObject that inherits
from TGTKObject which is found in GTKInt.pp
GTKInt.PP:Contains the class definition for TGTKObject
The most important method in this class definition is
IntSendMessage3That function is called by the TControl class and is used
to send the widget set messages such as LM_CREATE to create a widget,
LM_SETLABEL to change a widget's caption, LM_SHOWHIDE to set a widget's visible
property to true/false, etc. Each widget set (QT, WIN32, GTK) will have it's
own IntSendMessage3 function inside their specific class definition (like
TWIN32Object or TQTObject). All code associated with the GTKInt.pp class
definition can be found in GTKObject.inc.
EVENTS: Events are currently assigned by calling a
procedure within TControl called "SetCallback" which then calls each
widget interface object (in GTK's case, it calls TGTKObject") and assigns
a event/signal for that control. For example, in TWinControl.AttachSignals, a
event is assigned for LM_DETROY. That signal/event is then assigned to that
twincontrol. The SetCallback function in gtkobject tells the GTK widget to call
a proceure in gtkcallback when it being destroyed and pass it the SENDER from
the initial SetCallBack call. When the control is being destroyed, gtk fires a
"destroy" signal. When that signal occurs, a procedure in
gtkcallback.inc gets called and uses the SENDER property that we told it to
send along when we connected the signal, and we call
TControl(SENDER).WindowProc(Message). Message is a TLMessage (compatable with
TMessage) that we fill with the appropriate information for each event.
As an example of a component, I will explain TButton.

TButton:TButton inherits from TButtonControl. All
TButton does is declare a few "message" procedures. These procedures
are called automatically when the associated message is dispatched. LM_PRESSED
is dispatched when the button is pressed, LM_RELEASED is dispatched when the
button is released, etc. All these procedure's do is check to see if the
developer assigned the OnPressed or OnReleased events to a procedure. If so, it
then calls that procedure.
TButton.Create's only job is to call the inherited create,
then set the fCompStyle property. Every control has a fCompStyle property. This
allows the widget set to know what type o control it is and therefore
create/destroy/click/show/hide/... the correct type of widget. In TButton,
fCompStyle is set to csButton.
TButtonControl does nothing but call the inherited Create.
TButtoncontrol inherits from TWinControl.
TWinControl is in charge of doing most of the work. It set's
all the call backs for "windowed" controls, creates a list of
controls and their children, and inherits from TControl.
TControl sends messages back and forth to the interface
object for each widget type. For example, when "caption" is set to
some value, a procedure called SetCaption is called. This procedure calls
Sendmessage(LM_SETLABEL,Self,nil). SendMessage (defined in controls.pp) calls
the InterfaceObject.IntSendMessage3 and passes it the message (LM_SETLABEL) and
self. 
In the case that GTk is defined and we are using GTK widgets,
IntSendMessage3 in gtkObject is called. It determines that a LM_SETLABEL
message was sent and it calls TgtkObject.SetLabel(Sender) where Sender equals
the "Self" that we sent it. In gtk's SetLabel we call a procedure
gtk_label_set_text after determining that SENDER is a TBUTTON. We pass it the
label of the button (which is actually a child widget of the button widget) and
we also pass it the value of TButton(Sender).Caption.
If we were using WIN32 our IntSendMessage3 in win32interface
would call a SetLabel function that would call a Windows API function to set
the label. In QT widgets we call a QT specific function call.
All other properties/settings for the controls are set the
same way. Each type of property has it's own message and this implementation is
hidden within TControl so most developers will never need to understand this. 

How can I participate?: Let's say you are looking
through the code and notice that we don't have a TCalendar component but GTK
does and you would like to implement it. If Delphi doesn't have this control
already, you will need to create a new unit and include file. The skeleton
files for this can be found in lazarus/lcl/templates. make sure you load these
and save tham as Calendar.pp and Calendar.inc in lazarus/lcl.
Create the classes called TCalendar and add a fCompStyle
constant for a calendar into vclglobals.pp. Call it csCalendar and assign it to
the last cs???? +1. In TCalendar call the inherited method, then set fCompStyle
to csCalendar.
In gtkobject.inc, go to IntSendMessage3. If you follow the
message LM_CREATE through this procedure, you will see that it calls
CreateComponent. In the procedure CreateComponent the property fCompStyle is
looked at (the local variable CompStyle is assigned fCompStyle's value) and
this is used to determine how to create the widget. To create a gtk Calendar
widget, the call is gtk_calendar_new() so you create a entry into the CASE
statement
csCalendar : begin
p := gtk_calendar_new();
gtk_widget_show(p);
end;Now in your form's code (where you want the Calendar) all
you need to do is add the code 
Calendar1 : TCalendar;
Calendar1 := TCalendar.create;
Calendar1.Parent := Form1; //Form1 should be the form name
Calendar1.Show;It's basically that simple! Now gtk offers a
few other procedures that you can take advantage of for this control.
gtk_calendar_select_day, gtk_calendar_select_month, etc. These can be used when
you add a Day and Month property to TCalendar. In the SetDay and SetMonth, you
simply call SendMessage(LM_SETDAY,Self,nil) or
SendMessage(LM_SETMONTH,Self,Nil). You will need to add LM_SETDAY and
LM_SETMONTH into the LMessage.pp file under the section for messages sent to
the interface. Once you have this, you need to go into gtkobject and add to the
case statement in IntSendMessage3 for those two messages. For each message,
call the appropriate gtk call using either TCalendar's day property or
TCalendar's Month property (which should be set in SetDay and SetMonth in
TCalendar).
How Can I Help : Chapter 2: Of course there are many
things that can be done without modifying any widget specific code. For
example, we are currently trying to create an IDE based on our code. We are
close to getting the editor portion working but we have many TODO's left. If
you are interested in getting involved, this is a great spot to jump in. If you
are familiar with the tool "grep" you can search for the words
"TODO" in the source. Each one marks a spot that needs to be
finished. Simply find one you are interested in, let the mailing list know you
will be working on it and go to it.
A brief map of files: 

Interfaces.pp - Declares a class called InterfaceObject that (depending
on the "define" inherits from GTKInt.pp. InterfaceObject is
created within the Initialization portion of this file.


GTKINT.pp declares a class called gtkobject. Code is found in
gtkobject.inc
GTKObject (class) inherits from InterfaceBase which defines functions that are
either specific to the widget set, or other functions that simply don't belong
in any other class. 
Interfacebase uses the file winapih.inc to define calls that are compatable
with the windows API calls that are required for compatability. If they are
widget set dependent (for example gtk) then the calls in winapih.inc are
overridded in a widget dependent file. In GTK's case it's called gtkwinapih.inc
and the actual code for those procedures are found in gtkwinapi.inc. This
allows us to create different definitions for windows API calls based on the
interface.

TControl send all messages to InterfaceBase.IntSendmessage3 which is overrided
by the widget specific files. Therefore if GTK is defined in Interfaces.pp then
the IntSendMessage3 is called in gtkobject.inc.This
may seem confusing but once you look into it you will get the hang of it. Feel
free to email the mailing list with questions. Any idea's on how to improve
this BRIEF explanation please email the mailing list.





 
 


This
document maintained by <A
HREF="mailto:smiller1 at stvgb.org">smiller1 at stvgb.org.
Material Copyright © 2000 Lazarus Project










More information about the Lazarus mailing list