Professional Documents
Culture Documents
CoverdesignbyFabienBodard
ForewordbyFabienBodardandBenotMinisini
1
A Beginner's Guide to Gambas
2
A Beginner's Guide to Gambas
Copyright Notice for the electronic (online) version of this work, based on the OpenContent License
(OPL), Version 1.0, July 14, 1998.
This document outlines the principles underlying the OpenContent (OC) movement and may be redistributed provided it remains
unaltered. For legal purposes, this document is the license under which OpenContent is made available for use. The original
version of this document may be found at http://opencontent.org/opl.shtml .
LICENSE
Items other than copying, distributing, and modifying the Content with which this license was distributed (such as using, etc.)
are outside the scope of this license.
1. You may copy and distribute exact replicas of the OpenContent (OC) as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the OC a copy of
this License along with the OC. You may at your option charge a fee for the media and/or handling involved in creating a unique
copy of the OC for use offline, you may at your option offer instructional support for the OC in exchange for a fee, or you may at
your option offer warranty in exchange for a fee. You may not charge a fee for the OC itself. You may not charge a fee for the
sole service of providing access to and/or use of the OC via a network (e.g. the Internet), whether it be via the world wide web,
FTP, or any other method.
2. You may modify your copy or copies of the OpenContent or any portion of it, thus forming works based on the Content, and
distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) You must cause the modified content to carry prominent notices stating that you changed it, the exact nature and content of
the changes, and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the OC or any
part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License, unless otherwise
permitted under applicable Fair Use law.
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the OC, and
can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to
those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is
a work based on the OC, the distribution of the whole must be on the terms of this License, whose permissions for other licensees
extend to the entire whole, and thus to each and every part regardless of who wrote it. Exceptions are made to this requirement
to release modified works free of charge under this license only in compliance with Fair Use law where applicable.
3. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to
copy, distribute or modify the OC. These actions are prohibited by law if you do not accept this License. Therefore, by
distributing or translating the OC, or by deriving works herefrom, you indicate your acceptance of this License to do so, and all
its terms and conditions for copying, distributing or translating the OC.
NO WARRANTY
4. BECAUSE THE OPENCONTENT (OC) IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE OC, TO
THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE OC "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE OF THE OC IS WITH
YOU. SHOULD THE OC PROVE FAULTY, INACCURATE, OR OTHERWISE UNACCEPTABLE YOU ASSUME THE COST OF
ALL NECESSARY REPAIR OR CORRECTION.
5. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
HOLDER, OR ANY OTHER PARTY WHO MAY MIRROR AND/OR REDISTRIBUTE THE OC AS PERMITTED ABOVE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE OC, EVEN IF SUCH HOLDER OR OTHER PARTY
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
3
A Beginner's Guide to Gambas
Table of Contents
Acknowledgments........................................................................16
Foreword.......................................................................................17
Chapter1IntroducingGambas.................................................19
GambasArchitecture......................................................19
TheGambasProgrammingEnvironment......................22
GambasIDEComponents.................................................25
Chapter2GambasLanguageConcepts.................................30
GambasVariables,DatatypesandConstants.............30
VariableAssignment..........................................................35
AssignmentUsingTheWITHStatement...........................35
OperatorsandExpressions............................................36
Comparisonoperators......................................................36
ArithmeticOperators..........................................................36
Let'sStartCodingGambas................................................37
END,RETURNandQUITStatements.......................................37
StringOperators................................................................44
Chapter3KeywordsandProgramFlowControl....................46
ThePRINTStatement.......................................................46
TheIFStatement...............................................................47
TheSELECT/CASEStatement.......................................48
GOTOandLABELS..........................................................49
TheFOR/NEXTStatement..............................................49
DO[WHILE]LOOP............................................................51
WHILE[Expression]WENDLoops...................................52
TheREPEATUNTILloop.................................................53
DefiningandUsingArraysinGambas..........................53
Collections.......................................................................55
TheFOREACHStatement...............................................55
Chapter4IntroducingtheGambasToolBox..........................57
TheButtonControl..........................................................61
CommonControlProperties..............................................62
ButtonMethods.................................................................70
4
A Beginner's Guide to Gambas
ButtonEvents....................................................................78
ThePictureClass............................................................78
Chapter5ControlsforGatheringInput...................................80
TextLabel..........................................................................82
TextBox............................................................................83
ComboBox........................................................................85
ListBox.............................................................................89
Frame................................................................................92
ToggleButton...................................................................93
Checkbox.........................................................................93
Panel.................................................................................95
RadioButton.....................................................................95
Chapter6Menus,Modules,DialogsandMessageBoxes.....97
TheGambasMenuEditor...............................................98
BuildingMenus..............................................................101
Dialogs............................................................................103
Modules..........................................................................105
MessageBoxes...............................................................112
InformationMessages.....................................................112
Query/ConfirmMessages................................................114
ErrorMessages...............................................................115
WarningorAlertMessages.............................................115
DeleteMessages.............................................................116
DialogClassFilerelatedFunctions.............................117
DialogOpenFileFunction................................................117
DialogSaveFileFunction.................................................118
DialogSelectDirectoryFunction......................................119
CompleteExampleListing............................................120
Module1.modulelisting.................................................123
Chapter7HandlingStringsandConvertingDatatypes.....125
StringFunctions............................................................125
Len...................................................................................126
5
A Beginner's Guide to Gambas
Upper$/Ucase$/UcaseandLower$/Lcase$/Lcase........126
Trim$,LTrim$,andRTrim$..............................................127
Left$,Mid$,andRight$..................................................128
Space$............................................................................130
Replace$........................................................................130
String$............................................................................131
Subst$............................................................................131
InStr.................................................................................132
RInStr..............................................................................134
Split..................................................................................134
ConvertingDatatypes..................................................135
AscandChr$..................................................................135
Bin$.................................................................................136
CBool..............................................................................137
CByte...............................................................................138
CDate..............................................................................138
CFloat..............................................................................139
CInt/CintegerandCShort.............................................140
CStr/CString.................................................................140
Hex$................................................................................141
Conv$.............................................................................141
ValandStr$....................................................................142
Str$.................................................................................142
Format$...........................................................................145
Datatypemanagement.................................................147
TypeOf.............................................................................148
Chapter8UsingAdvancedControls.....................................149
IconViewControl...........................................................149
ListViewControl............................................................158
UsingtheGambasIconEditTool................................162
TheTreeViewControl....................................................163
TheGridViewControl....................................................171
TheColumnViewControl..............................................175
LayoutControlsHBox,VBox,HPanelandVpanel. .177
HBoxandVBox...............................................................177
HPanelandVpanel..........................................................177
6
A Beginner's Guide to Gambas
TheTabStripControl.....................................................182
Chapter9WorkingwithFiles.................................................188
Access............................................................................188
Dir....................................................................................189
Eof...................................................................................190
Exist................................................................................190
IsDir/Dir?.....................................................................191
Stat.................................................................................191
Temp/Temp$...............................................................192
OPENandCLOSE..........................................................192
LINEINPUT.....................................................................193
READ,SEEK,WRITEandFLUSH.................................194
COPY,KILLandRENAME.............................................195
MKDIR,RMDIR...............................................................196
Chapter10MathOperations..................................................215
PrecedenceofOperations............................................215
Abs..................................................................................216
Acs/ACos......................................................................216
Acsh/ACosh.................................................................217
Asn/ASin.......................................................................217
Asnh/ASinh..................................................................218
Atn/ATan.......................................................................218
Atnh/ATanh..................................................................219
Cos..................................................................................219
Cosh................................................................................220
DegandRad...................................................................221
Exp..................................................................................221
FixandFrac...................................................................222
Int....................................................................................223
Log..................................................................................223
Log10..............................................................................224
7
A Beginner's Guide to Gambas
MaxandMin...................................................................224
Pi.....................................................................................225
RandomizeandRnd......................................................225
Round.............................................................................227
Sgn..................................................................................227
Sin...................................................................................228
Sinh.................................................................................229
Sqr...................................................................................229
Tan..................................................................................230
Tanh................................................................................231
DerivedMathFunctions................................................231
Chapter11ObjectOrientedConcepts..................................237
FundamentalsofObjectOrientedProgramming........238
Objects............................................................................239
DataAbstraction..............................................................239
Encapsulation..................................................................240
Polymorphism..................................................................240
Inheritance.......................................................................240
TheGambasApproachtoOOP....................................241
GambasClasses.............................................................241
Sampleprogram:Contacts...........................................242
TheContactclass............................................................242
Contact.GetDataMethod.................................................243
Contact.PutDataMethod.................................................246
Form1.classfile...............................................................247
Form1Constructor...........................................................248
Form_OpenSubroutine...................................................250
AddingControlstoForm1.Form......................................250
TheToolButtons.......................................................................251
TheQuitButton.........................................................................251
AddingtheLabelsandTextBoxes............................................252
UpdateForm()Subroutine................................................253
CodingToolbuttons:First,Prev,Next,andLast.......................254
CodingToolButtons:Addingarecord.......................................256
CodingToolButtons:Clearingdata...........................................258
ValidatingUserInput.......................................................258
8
A Beginner's Guide to Gambas
AddingaSearchFeature.................................................260
TheDoFindSubroutine.............................................................262
ToolButtonsagain:UpdatingaRecord............................263
Toolbuttonsagain:DeletingaRecord.............................264
ToolButtonsagain:SavingData......................................265
CreatingaStandaloneExecutable..............................266
Chapter12LearningtoDraw.................................................267
DrawProperties.............................................................267
BackColor/BackgroundandForeColor/Foreground........267
Clip..................................................................................268
FillColor,FillStyle,FillX,FillY..............................................268
Font.................................................................................269
Invert................................................................................269
LineStyle/LineWidth.........................................................270
Transparent.....................................................................270
DrawMethods................................................................270
Text/TextHeight/TextWidth..............................................272
DrawPrimitives:Point/Rect/Ellipse/Line..........................274
DrawPrimitives:PolygonandPolyline............................280
Image/Picture/Tile............................................................284
DrawingwithaDrawingobject........................................292
Chapter13ErrorManagement...............................................298
GeneralConceptsofErrorManagement.....................298
ErrorHandling.................................................................298
BoundaryRelatedErrors.................................................299
CalculationErrors............................................................299
InitialandLaterStates.....................................................300
ControlFlowErrors..........................................................300
ErrorsinHandlingorInterpretingData............................301
RaceandLoadConditions..............................................301
PlatformandHardwareIssues........................................302
Source,Version,andIDControlErrors...........................303
TestingErrors..................................................................303
TestPlanReviews...........................................................303
GambasErrormanagement.........................................304
TRYstatement...IFERROR...........................................304
9
A Beginner's Guide to Gambas
CatchandFinallyStatements..........................................306
GambasEventmanagement........................................309
Chapter14Mouse,KeyboardandBitOperations................312
MouseOperations.........................................................312
KeyboardOperations....................................................316
BitOperations................................................................318
Chapter15GambasandDatabases......................................326
ConnectionClass..........................................................327
ConnectionProperties.....................................................328
Charset.....................................................................................328
Databases.................................................................................328
Host...........................................................................................329
Login.........................................................................................329
Name........................................................................................329
Password..................................................................................330
Port...........................................................................................330
Tables.......................................................................................330
Type..........................................................................................330
Users.........................................................................................330
Version......................................................................................330
TheConceptofaTransaction.........................................331
ConnectionClassMethods..............................................332
Open/Close...............................................................................332
Begin/Commit/Rollback............................................................333
Find...........................................................................................333
Create.......................................................................................334
Edit............................................................................................334
Exec..........................................................................................334
Quote........................................................................................335
ResultObjects.................................................................335
DBClass.........................................................................336
Database.........................................................................337
Field................................................................................337
Index...............................................................................337
Table...............................................................................337
User.................................................................................338
10
A Beginner's Guide to Gambas
TheDatabaseExampleProgram..................................338
Chapter16GlobalGambas....................................................351
Internationalization........................................................351
Localization....................................................................351
UniversalCharacterSet(UCS).....................................352
Unicode..........................................................................352
UTF8..............................................................................353
HowtotranslateinGambas.........................................355
11
A Beginner's Guide to Gambas
Table of Figures
Figure1GeneraloverviewofGambasarchitecture...........................................20
Figure2theGambasOpeningScreen..............................................................21
Figure3TheGambasProjectCreationWizard.................................................22
Figure4AdialogtoselectthetypeofGambasprojectyouwishtocreate.......23
Figure5ProjectNameSelectionDialog............................................................24
Figure6ProjectDirectorySelectionDialog........................................................24
Figure7NewProjectconfirmationdialog...........................................................25
Figure8TheGambasIDE.................................................................................26
Figure9ProjectExplorerFileMenu...................................................................27
Figure10ProjectMenu......................................................................................27
Figure11ProjectExplorerViewMenu...............................................................27
Figure12ProjectExplorerToolsMenu..............................................................27
Figure13ProjectExplorerMenuandToolbar...................................................28
Figure14ADivisionbyZeroErrorDialog..........................................................40
Figure15TheGambasToolBox........................................................................58
Figure16AdditionalcontrolsforQT...................................................................60
Figure17FirstButtoncoderesults....................................................................65
Figure18Demonstratingfontcapabilities..........................................................67
Figure19Thedottedlineindicatesfocusforacontrol......................................72
Figure20ThelayoutforSecondProjectForm1.form.........................................72
Figure21Apartiallyconstructedformwithourfirstfourcontrols.......................73
Figure22Eventmenu........................................................................................74
Figure23AddingtheFunBtntoourform...........................................................76
Figure24Whatourformlookslikewhenamouseisdetectedovertheform.
Notethetextisblankedout...............................................................................77
Figure25TheprogressbarwhentheFunBtnisclickedthreetimes.................77
Figure26ThirdProject(almost)finalresult........................................................80
Figure27UsingHTMLtoformatTextLabeloutput............................................82
Figure28ModifiedTextLabeloutputusingHTMLformatting............................83
Figure29AddingaToolTiptoinformtheuserhowtoshow/hideacontrol.......85
Figure30OurComboBox..................................................................................86
Figure31TheEditlistpropertyeditor................................................................87
Figure32FormattingaTextLabelwithHTML....................................................88
Figure33PlusandminusbuttonstoaltertheComboBoxlist............................88
Figure34WhatourListBoxwilllooklike............................................................90
Figure35ListBoxEditlistpropertyeditor...........................................................90
Figure36Whattheexampleframewebuildwilllooklike..................................92
12
A Beginner's Guide to Gambas
Figure37APanelwithRadioButtons................................................................95
Figure38MenuProjectFinalresults..................................................................97
Figure39TheGambasMenuEditorwhenitfirststarts.....................................98
Figure40EditfieldsfortheMenuEditor............................................................99
Figure41Buildingourprojectmenu................................................................101
Figure42Aformattedtextlabeldisplayingthecolorvalue..............................104
Figure43Selectingcolorsandfonts................................................................111
Figure44MakinganewdefaultfontfortheTextLabel1control......................112
Figure45AnInformationMessageBox............................................................113
Figure46Acheckedmenuitem.......................................................................113
Figure47AQuestionMessageBox.................................................................115
Figure48AnErrorMessage............................................................................115
Figure49AWarningmessage.........................................................................116
Figure50Deletemessagewiththreebuttons..................................................117
Figure51TheOpenFileDialog.......................................................................118
Figure52SaveFileDialog...............................................................................119
Figure53TheSelectDirectoryDialog.............................................................119
Figure54ChoosingtheExplorerexample.......................................................149
Figure55LayoutforourListViewexample......................................................159
Figure56CreatinganewIconimageinGambas............................................163
Figure57Oursquareiconimage.....................................................................163
Figure58IconEditorToolBox.........................................................................163
Figure59Ourcircleiconimage.......................................................................163
Figure60TheTreeViewProjectwindow..........................................................164
Figure61WhatourGridViewwilllooklike.......................................................172
Figure62OurColumnViewexample...............................................................175
Figure63Layoutprojecticons.........................................................................178
Figure64Form1designmodeshowinglayoutofourcontrols.........................179
Figure65Layoutprogramwhenitstartsup.....................................................182
Figure66ATabStripcontrol............................................................................183
Figure67TabProjectForm1.formDesign.......................................................183
Figure68Tab0layout......................................................................................184
Figure69Tab1layout......................................................................................184
Figure70Tab2ToolButtonlayoutwithicons...................................................185
Figure71Tab3layoutwithaComboBox.........................................................186
Figure72TheFileOpsprogramatruntime......................................................196
Figure73Form2.formdesignmode................................................................210
Figure74FinishedContactsprogram..............................................................248
Figure75Form1seenindesignmode.............................................................253
13
A Beginner's Guide to Gambas
Figure76ContactsManagerrunningstandaloneonmydesktop....................266
Figure77gfxDemoForm1layout.....................................................................271
Figure78ResultsofclickingtheTextButton...................................................274
Figure79ResultsofInvRectbuttonclick.Notethetinyblackcrosshaircenter
screen................................................................................................................275
Figure80Ellipsesdemonstratesdrawinglinesandellipses............................278
Figure81OutputafterclickingtheFillRectbutton...........................................280
Figure82UsingDraw.Polygontodrawatriangle............................................282
Figure83UsingDraw.Polylinetodrawlines....................................................284
Figure84UsingtiledimageswiththeTileImgbuttonofourdemoprogram....292
Figure85LoadinganSVGfileinGambas.......................................................295
Figure86ErrorresultscaughtwithTRY..........................................................305
Figure87CATCHtestprogramopeningscreen..............................................307
Figure88DivbyZeroerrorcaughtbyCATCH................................................307
Figure89TheTextLabelupdatedwitherrorinfo.............................................308
Figure90Infomessagethattheerroriscleared..............................................308
Figure91Mainscreenaftererrorhasbeencleared........................................308
Figure92DefaultGambaserrordialog............................................................309
Figure93Oureventwasraised.......................................................................311
Figure94MouseOpsprogramrunning............................................................315
Figure95KbdOpsprogramrunning.................................................................318
Figure96TheBitOpsprogramindesignmode...............................................320
Figure97OurbitOpsprogramrunning............................................................325
Figure98TheFMainformindesignmode......................................................339
Figure99FRequestFormindesignmode.......................................................339
Figure100ChoosingtheTranslateoptioninGambas.....................................356
Figure101TheTranslateDialoginGambas...................................................356
14
A Beginner's Guide to Gambas
Thispageisintentionallyblank.
15
A Beginner's Guide to Gambas
Acknowledgments
Firstofall,averyspecialthankstoBenotMinisini forthecreationofGambas
andforhissupportofthisefforttofurtherdocumentthiswonderfullanguage.Without
Benot'sinitiative,wewouldallbestrugglingtofindabettertoolthanwhatexiststoday
onLinuxplatforms.MuchoftheinitialdocumentationoftheGambaslanguagewasput
ontheGambasWikibyBenotandhedeservesspecialcreditformakingthisinformation
available. Asitwasthe onlyknownpublishedsourceofdefinitivedocumentationin
existencepriortothiswriting,muchofthereferencematerialhereinwasgleanedfrom
thatinitialsetofdocumentation. Aswithanywrittenmaterial,thereisnoguarantee
thatthisdocumentationisasaccurateaswhatyoumayfindinthelatestreleaseofthe
Gambasproduct.
TheauthorwouldliketoextendaspecialthankstoFabienBodardforhishelpin
makingthisworkbecomeareality. Fabientirelesslyeditedcode,reviewedthesample
projectspresentedherein,andprovidedgreatinsightintotheinnerworkingsofGambas
allatthetimeofharvestforhisvineyard.LaurentCarlierandSteveStarrbothalso
deservemygratitudefortheirmeticulousworkeditingthecodeandensuringeverything
worked as advertised. Their feedback, suggestions and corrections were greatly
appreciated.IwouldalsoliketothankDanielCamposwhowasagreatassetinhelping
metounderstandsomeofthefinerpointsofGambas.NigelGerrardalsocontributedto
thesuccessofthisprojectbyprovidingafinalreviewandeditofthedatabasematerial.
FromamongtheseGambasHallofFamecoders,whoelsecouldhavedoneitbetter?
CountlessemailswerereceivedfrommanymembersoftheGambascommunity,
all of which provided ongoing encouragement and support which motivated me to
completethiseffortandmakeitavailabletoeveryone.Giventhedifficultiesofwritinga
bookinthefirstplace,itwasagreatfeelingofsatisfactiontoreceivesuchsupportfrom
completestrangerswhoallsharethesinglevisionofmakingGambasasuccess. Ican
onlyhopethatthisbookwilldojusticetothateffortandwelcomeanysuggestionsfor
change,aswellasanycomplimentsorconstructivecriticism.Ithasbeenalotoffunto
learnthiswonderfulnewlanguageandtoexplorethepossibilitiesitoffers.Idedicate
thisbooktoallofthoseGambasusersanddeveloperswhohavereliedoneachotherin
the Gambasuser/developercommunitytomake this productbecomereality. Shared
vision,commongoals,andopensoftwarearepowerfulforcesthatshouldnoteverbe
underestimated.Suchforceshavebeenknowntochangetheworldandwillcontinueto
dosolongafterthisbookhasbeenreadandforgotten.
JohnW.Rittinghouse,Ph.D.,CISM
October,2005
16
A Beginner's Guide to Gambas
Foreword
For the last three years, I have plunged headfirst into the Linux
programmingenvironment.ConsideringmyfirstinstallationofLinuxwasbackin
1996, it shouldnotbeconsidered agoodfirststart. Asan enthusiastic Basic
developer,theLinuxenvironmentlackedatoolthatwould allowmetoeasily
programintheLinuxenvironment.Bychance,Istumbleduponasmallproject,
thefruitofmorethantwoyearsofworkfromamannamedBenoitMinisini.After
figuringouthowtogetpasttheidiosyncrasiesofcompilation,Idiscoveredwhat
wastobetheembryonicstagesofoneofthemostfabulousprojectsicouldhave
imagined,Gambas!Atthattime,Gambaswasalreadyimplementedwithit'sown
IntegratedDevelopmentEnvironment(IDE)andasyntaxhighlighter.Theability
ofGambastodynamicallyloadcomponentsandremainfairlytruetotheBasic
languageasusedunderWindowswasanaddedbenefit.
Today,Gambashasarrivedasamatureproductthat,init'sfirstversion,
allowsausertoconstructgraphicalapplicationsorconsolebasedapplications,
supportsdatabasemanagement,connectiontotheInternetortosocketservers,
utilizesdatacompression,supportsDCOPwithKDEapplications,andmuchmore.
AGambasapplicationcanbetranslateddirectlyfromtheIDEandpackagedin
binaryformfordifferentLinux distributions.Whatwasinitiallyalluringtome
still is Gambas has gone beyond being just another programming language
becauseitsupportsallofthefeaturesofa"professional"productwhileretaining
itssimplicity. Gambasprovidesarealtoolforthebeginningprogrammerand
makesitpossibleforanoviceprogrammertodevelophighqualityapplications.
Here,inthisbook,youwillfindthefirstcomprehensivetreatmentofGambas.It
makes approaching the Gambas language simple and the reader can easily
progressfromthebeginner'sleveltopicstothemoreadvancedtopicsprofessional
programmersusedaily.
Gambashasandwillcontinuetoevolve.GambasVersion1.0(discussedin
thisbook)isthefoundationofalanguagewhichwillevolvetobeevenmore
powerful.Forexample,GambasVersion2willmakeitpossibletomakeAPIcalls
toa native library. Itwillallowprogrammers to manageevenmore typesof
database servers and will work equally well with either Qt or GTK graphics
libraries. Gambas2willallowprogrammerstodeveloptheirowncomponents
fromwithintheGambasenvironment. Developerswillbeabletocreategames
usingSDLandOpenGL.ThescopeoftheGambaslanguageisgrowinglargerand
andthesyntaxisbecomingmorecompact. Alloftheseideasforimprovement
17
A Beginner's Guide to Gambas
and change do not rest solely in the heads of a stable of chosen developers
workingontheGambas2project.TheycomefromallGambasuserswhoprovide
theideasthatmakeGambas2evenbetterthanbefore.Alreadyitcandosomuch
morethanversion1.0.Istronglyrecommendthatwhileyouarewaitingforthe
stablereleaseofGambas2,youbeginyourGambastrainingwithyourmachine
and what you will find in this book. It will prepare you for a wonderful
programmingexperienceintheLinuxenvironment.
FabienBodardandBenoitMinisini
18
A Beginner's Guide to Gambas
GambasislicensedundertheGNUPublicLicense2andhastakenonalife
ofit'sownduetoitsimmensepopularity. Gambasrunsonmostofthemajor
Linux platforms and the current (at the timeof this writing) stable version is
Release1.0.9. MinisinimakesitveryclearthatGambasisnotcompatiblewith
Visual Basic and itwill never bemade compatible. The syntax and internal
workingsofGambasarefarbetterandmoreuserfriendly. Minisinistated[sic]
that he took from Visual Basic what he found useful: the Basic language, the
developmentenvironment,andtheabilitytoquickly[andeasily]makeprograms
with[graphical]userinterfaces.3
GambasArchitecture
EveryprogramwrittenwithGambasBasiciscomprisedofasetofproject
files. Each file within a project describes a class. The class files areinitially
compiled and subsequently executed by the Gambas Interpreter. This is very
similartohowJavaworks.Gambasismadeupofthefollowingprograms:
1 Thereaderisencouragedtovisithttp://gambas.sourceforge.net/index.htmltolearnmoreabouttheGambasproject.
2 Forinformationaboutthelicense,visithttp://www.gnu.org/licenses/licenses.html#GPL.
3 SeetheGambasWikiWebSiteIntroductionathttp://gambas.sourceforge.net/index.htmlformoredetails.
19
A Beginner's Guide to Gambas
Acompiler
Aninterpreter
Anarchiver
Agraphicaluserinterfacecomponent
Adevelopmentenvironment
Figure1below4isanillustrationoftheoverallarchitectureofGambas.In
Gambas,aprojectcontainsclassfiles,forms,modules,anddatafiles.AGambas
projectisstoredinasingledirectory.Compilingaprojectuses inincremental
compilemethodthatonlyrequiresrecompilationofthemodifiedclasses.Every
external reference of a class is solved dynamically at runtime. The Gambas
archiver transforms the entire project directory structure into a standalone
executable.TheGambasdevelopmentenvironmentwaswrittenwithGambasto
demonstratethefantasticcapabilitiesofthelanguage.
Figure1GeneraloverviewofGambasarchitecture.
SomeotherfeaturesthatsetGambasapartfromotherlanguagesinclude
the fact that Gambas has an extensible component architecture that allows
programmerstoextendthelanguage.Anyonecanwritecomponentsasshared
libraries that dynamically add new native classes to the interpreter. The
componentarchitectureisdocumentedonlineintheGambasWikiencyclopedia5.
4 See URL http://gambas.sourceforge.net/architecture.html, for the original graphic.
5 Copyright (c) 1999-2005 by contributing authors. All material on the Gambas Wiki is the property of the contributing
20
A Beginner's Guide to Gambas
WewillcoverGambascomponentsingreaterdetaillaterinthisbook.Bydefault,
the GambasInterpreter isatextonly(consolebased)program. Thecomponent
architectureisusedforthegraphicaluserinterface(GUI)partofthelanguage.
BecausetheGUIisimplementedasaGambascomponent,ithastheabilitytobe
independentofanyspecificGUItoolkit.WithGambas,youcanwriteaprogram
and choosewhichtoolkit,suchas GTK+6, Qt7,etc., touselater. Thecurrent
releaseofGambasimplementsthegraphicaluserinterfacewiththe Qt toolkit.
TheGUIcomponentsarederiveddirectlyfromtheQTlibrary.Itisrecommended
thatthereaderalsoconsultwiththeQTdocumentation8tobetterunderstandthe
GUIcontrols.AccordingtoMinisini,a GTK+ componentwithanearlyidentical
interfaceastheQtcomponentisplanned.
Figure2theGambasOpeningScreen.
authors.
6 FormoreinfoaboutGTK+,visithttp://www.gtk.org/.
7 FormoreinfoaboutQt,visithttp://www.trolltech.com/products/qt/.
8 http://doc.trolltech.com/3.3/index.html
21
A Beginner's Guide to Gambas
TheGambasProgrammingEnvironment
For now, let's take a quick tour of Gambas and introduce you to the
Gambasprogrammingenvironment.Alloftheexamplesandcodewrittenforthis
book were developed using Gambas version 1.0.9 running on Linspire 5.09.
TheyshouldworkonanyplatformthatyoucaninstallGambasonsuccessfully.
ForLinspireusers,itisassimpleastheclickofabuttonusingtheClickNRun
warehousefeatureofthatproduct.Whenyoufirstclickthedesktopicontostart
theGambasprogram,youwillbepresentedwithanopeningscreensimilartothat
foundinFigure2above.Thewelcomescreenallowsyoutocreateanewproject,
openanexistingproject,viewandselectfromrecentprojects,lookatexamples,
orquit. ForourquicktourofGambas,wearegoingtoselecttheNewProject
optionandcreateourfirstGambasproject.YouwillseeadialogsimilartoFigure
3belowappear.
Figure3TheGambasProjectCreationWizard.
9 FormoreinfoaboutLinspire,visithttp://www.linspire.com.
22
A Beginner's Guide to Gambas
Figure4AdialogtoselectthetypeofGambasprojectyouwish
tocreate.
Forourexample,choosethefirstselection,Createagraphicalprojectand
clicktheNext>>buttonatthebottomofthedialog. The next dialog that you
willseerequiresyoutonameyourprojectandchoosewhereitwillbelocatedon
yourlocalfilesystem.ItisshowninFigure5below.
Thissectionofthewizardhasyoutospecifythenameoftheprojectasit
willbestoredondisk.Remember,inGambasaprojectisentirelyselfcontained
inadirectoryorfolder.Thefoldernameyouchooseasthenamefortheproject
iswhatwillbecreatedonyoursystem.
Thetitleoftheprojectwillbewhatyouspecifyinthesecondtextinput
field of the dialog. Additionally, the Options section allows you to choose
whetherornotyourprojectwillbetranslatableandifthecontrolsusedonyour
formsaregoingtobemadepubliclyaccessible.Wewilldiscusstheseoptionin
moredetaillaterinthisbook.Fornow,justfilloutthedialogasshowninFigure
5andclickNext>>.
23
A Beginner's Guide to Gambas
Figure5ProjectNameSelectionDialog.
Chooseadirectoryappropriateforyourfilesystemandclickthe Next>>
button to proceed to the final dialog screen of the wizard, as shown on the
followingpageinFigure7. Thisdialogissimplyaconfirmationscreenofthe
choicesyouhavemade.Themostimportantthingtorememberaboutthisscreen
isthatitisthelastchanceyouhavetobackupandmakechangesbeforeyour
newprojectiscreated.
Figure6ProjectDirectorySelectionDialog.
24
A Beginner's Guide to Gambas
Figure7NewProjectconfirmationdialog.
OnceyouhaveclickedontheOKbuttontofinishthiswizard,Gambas
will present you with the Gambas integrated development environment (IDE).
TheIDEconsistsofseveralcomponentsthatareshowninFigure8onthenext
page.
GambasIDEComponents
TheProjectExploreristhemainGambaswindow.ItshowyouaTreeView
ofthetypesoffilesfoundwithinyourproject(i.e.,classfiles,forms,modules,and
othertypesoffilessuchasdataandpictureoriconfiles)andtheProjectExplorer
allows you to perform most Gambas project management operations, such as
opening and saving projects, building executables, running your program or
debuggingit,showingorhidingvariousGambasdialogs,etc.FromtheTreeView
intheProjectExplorer,youwillseetheitemslistedasfollows:
Classes
Forms
Modules
Data
Classes lists the class files you've created for your project. Classes are
basicallytemplatesthatcanbeusedtomakeobjectsoutofatruntime,withcode
todefineproperties,methodsandeventhandlersforeachobjectyoucreate.
25
A Beginner's Guide to Gambas
Figure8TheGambasIDE.
Modulesdisplaythemodulesyou'vewrittenforyourproject.Modulesare
simplysetsofsubroutinesandfunctionstobeusedanywhereinyourprogram.
Unlikeclasses,youcan'tmakeobjectsoutofthematruntimeandtheyhaveno
eventhandlers.
Dataliststheotherfilesinyourproject.Thesecanincludeanyotherkind
offileused tobuildyourproject,suchasgraphicfiles,icons,bitmaps,textor
HTMLfiles,andevenmediafiles.AtthebottomoftheProjectExploreryouwill
findtheStatusBarwhichisusedtoindicatewhatGambasiscurrentlydoing.
WhenyoustarttodevelopaprojectinGambas,youwillusuallywantto
begin with a main form. The main form is where the program startup and
initializationwilloccuranditisusuallythefirstthingyouruserwillseewhen
theyexecute(orrun)theapplicationyouhavebuilt.Thisistheformyouwilladd
controlstoandspecifywhatactionsaretobetakenwhentheuserinteractswith
26
A Beginner's Guide to Gambas
thosecontrols. SuchinteractionbetweentheuserandtheGUIisreferredtoas
events. The controls are found in the ToolBox window. You can change the
appearanceandbehaviorofthecontrolsbysettingthepropertiesforeachcontrol.
Propertiescanbeseeninthepropertieswindow.
Now,letstakealookatthemenusandbuttonsfoundatthetopofthe
ProjectExplorer.Themenus(seeFigures9through12below)controlallthemain
Gambasmanagementtasks.TheFilemenuwillallowyoutoopenaproject,save
aproject,createanewproject, opensomeGambasexampleprojects,orquit
usingGambas.TheProjectMenuiswhereprogramcompilationoccurs.Youcan
also create the program executable, make a source archive, or create an
installation package. This menu offers you the option of translating your
programintoanotherlanguage.Finally,youcansetGambasIDEpropertiesfrom
thismenu.
Figure9ProjectExplorerFileMenu.
Figure10ProjectMenu.
Figure12ProjectExplorerToolsMenu.
Figure11ProjectExplorerViewMenu.
27
A Beginner's Guide to Gambas
TheViewmenuwillallowyoutobringupthepropertieswindoworthe
ToolBox window. You can open a console or use the Icon Editor to create
programicons. TheHierarchyoptionwillopenawindowandshowyouyour
project'sclasshierarchy.Finally,fromthismenu,youcancloseallofthewindows
thatarecurrentlyopenintheIDE. The ToolBar buttons (seeFigure13below)
providesingleclickaccesstothemostcommonmenuitems.Hoveringyourmouse
cursoroveroneofthebuttonswilldisplayaToolTipthatwilltellyouwhatmenu
actionthatparticularbuttonwillperform.
Figure13belowshowsyoutheFilemenuandToolBar.FromtheProject
ExplorerTreeView youcandoubleclickonaformanditwillpopupforyouto
edit.Editingformsissimplyamatterofselectingwhattypeofcontrolyou'dlike
toplaceontheformandthenusingthemousetoresize(draw)itonyourform.
Figure13ProjectExplorerMenuandToolbar.
Rightclickingontheformoranyofitschildren(controls)willshowyoua
popupmenuthatwillallowyoutoperformoperationsonthecontrol,editits
propertiesordeleteit.Thecurrentlyselectedcontrolisindicatedbyfourblack
squarescalledhandles. Clickingonahandleandusingthemousetodragthe
controlwhereyouwantitwillallowyoutomoveorresizethecontrol.Double
clicking on a control will bring up the code editor window and display any
existingeventhandlerforthecontrolordisplayadefaulteventhandlerifthere
havebeennonespecified.
TheGambasCodeEditorenablesyoutowritecodetohandleeventsforthe
controlsyou'veplacedonyourform.IntheToolBoxwindow,theSelectionTool
istheonlyitemintheToolBoxthatisn'tactuallyacontrol. TheSelectionTool
simplygivesyoucontrolofthedefaultmousepointer. Youusethispointerto
selectcontrolsandperformpositioningandresizingoperationsonformsandtheir
associatedcontrols.
FromtheProjectExplorerFileMenu,choosetheQuitoptionandsaveyour
project.Whenwereopenit,allyourworkwillbesaved.Inthenextsection,we
willbegintocovertheessentialsyouneedtounderstandinordertoprogramwith
28
A Beginner's Guide to Gambas
Gambas. Wewillcomebacktothisprojecttodevelopaprogramthatusesthe
GUIafterwelearnabitmoreabouttheGambascodingenvironment,theprimary
languageconceptsthatarerequiredtouseGambas,andsomebasicsaboutdata
typesandvariables. Thatisallcoveredinthenextsectionandconstitutesthe
remainderofthisintroductiontoGambasprogramming.Fornow,takeashort
breakandwewillcontinuewhenyoucomeback.
29
A Beginner's Guide to Gambas
GambasVariables,DatatypesandConstants
Variablesmustbedefinedatthebeginningofaclass,methodorfunction.
Variabledeclarationscaneitherbelocaltoaprocedureorfunctionortheycanbe
declaredglobaltoaclass.Aglobalvariableisaccessibleeverywhereintheclass
itisdeclared.TheformatofaglobalvariabledeclarationinGambastakesthe
followinggeneralform:
[STATIC](PUBLIC|PRIVATE)Identifier[Arraydeclaration]AS[NEW]Datatype
IfthePUBLICkeywordisspecified,itisalsoaccessibletotheotherclasses
thathaveanyreferencetoanobjectofthatclass.Ifthe PRIVATE keyword is
specified,itisnotaccessibleoutsidetheclass inwhichitwasdefined. Ifthe
STATICkeywordisspecified,thesamevariablewillbesharedwitheveryobject
oftheclasswhereitisdeclared.IftheNEWkeywordisspecified,thevariableis
initializedwith(i.e.,instantiatedwith)anewinstanceoftheclassusingthedata
typespecified.Forlocalvariabledeclarations,theformatislikethis:
[DIM]IdentifierASDatatype
Thiswilldeclarealocalvariableinaprocedureorfunction.Thisvariableis
onlyaccessibletotheprocedureorfunctionwhereitisdeclared.Anexampleof
severallocaldeclarationsisshownbelow:
DIMiValueASINTEGER
DIMstMyNameASSTRING
DIMfMyMatrix[3,3]ASFLOAT
DIMoMyObjectASOBJECT
30
A Beginner's Guide to Gambas
Therearecurrentlyninebasicdatatypesaprogrammercanusetowrite
programcodeinGambas10.Thesedatatypesincludethefollowing:
STATICPRIVATEbGridASBoolean
STATICPRIVATEbySomethingASByte
Theletters'ar' 's', 'i', 'f', 'd', 'st', 'v' and 'o' arecommonlyusednotations
whendeclaringvariableswhileprogramminginGambas.Itisgoodprogramming
practicetoforceyourselftoadheretothistechniquesothatotherscanpickup
yourcodeanduseitwithouthavingtosearcharoundtofindthedatatypefor
eachvariableencountered.Someprogrammersevenusemorethanthefirstletter
(s) to name their variables. For example, they would code IntMyNumber or
ByteSomething.
10 In the second release of Gambas (Gambas2) "Long" and "Single" data types are planned. These data-types are like the C
LONG LONG and FLOAT data types. This is a significant improvement because Gambas2 will provide direct programming
access to the C API and will also support 64 bit platforms.
11 Hungarian Notation (HN) is a naming convention originated by Charles Simonyi of Microsoft. It was first presented in his
thesis and is widely used throughout the source code of the Windows operating system, among other places.
31
A Beginner's Guide to Gambas
STATICPUBLICsSomeShortASShort
STATICPUBLICiSomeIntegerASInteger
Whenintegerswillnotworkforyourpurposes,Gambasprovidesyouwith
theFloatdatatype.Thisdatatypeallowsyoutousefloatingpointnumbersfor
yourprogram.FloatdatatypesarelikeDoubledatatypesusedinCandVB.The
rangeofvaluesfor floatdatatype variablesisfrom1.79769313486232E308to
4.94065645841247E324fornegativevaluesandfrom4.94065645841247E324
to1.79769313486232E308forpositivevalues.Floatvariablesoccupyeightbytes
ofmemoryanddefaulttoazerovaluewhendeclared.Asampledeclarationfora
floatwouldbeasfollows:
DIMfRadiusASFloat
ThelastnumericdatatypewehaveinGambasistheDatedatatype.Date
variablesalsotakeupeightbytesofmemory. Thedateportionofthedateis
storedinafourbyteintegerandthetimeportionisstoredinafourbyteinteger.
Itisstoredas [Year,Month,Day][,Hours,Minutes,Seconds] andisusually
usedwiththeGambasbuiltinDateandTimefunctions,whichwewillexplain
about later in this book. The date datatype defaults to a NULL value when
initialized.HereishowtodeclareaDatedatatype:
DIMddateASDate
DIMdtimeASDate
Strings,VariantsandObjectsarethenonnumericdatatypessupportedin
Gambas. A String datatype is a series of zero or more characters that are
treatedasasingleentity.Stringscancontainalphanumericdata.Alphanumeric
32
A Beginner's Guide to Gambas
meansthatthedatacancontainanycombinationoflettersandintegersorspecial
characterssuchas$%^&*.Strings,whendeclaredtakefourbytesofmemory.
Thismeansthemaximumsizeforastringis4bytes*8bitsperbyte,or32bits
squared(1,024bytes).StringvariablesdefaulttoaNULLvaluewhendeclared.
Declareastringvariablejustlikeyouwouldanyothervariable:
STATICPUBLICstSomeStringASString
TheVariantdatatypeisusedwhenyoudonotknowwhatkindofdata
typethevariablewillbereceiving.Forexample,ifreadingdatafromafile,you
couldreadaninteger,astring,asinglecharacter,floatingpointnumbers,etc.To
ensure the data is placed in a variable without causing a program crash, the
variantdatatypeisused.Youcanthentestthevariantdatausingsomebuiltin
functionsofGambastodeterminethedatatypeoryoucanjustconvertthedata
tothedatatypeyouneedusingaconversionfunction.Wewilldemonstratethis
laterinthebook.Fornow,itisonlyimportantthatyouunderstandthatvariant
datatypesexistandthattheyareusedwhenyouarenotsureofthetypeofdata
thevariablewillhold.
Gambas data-types
Name Description Memorysize Default
Boolean TrueorFalse 1byte FALSE
Byte 0...255 1byte 0
Short 32768...+32767 2bytes 0
Integer 2147483648...+2147483647 4bytes 0
Float SimilartothedoubledatatypeinC 8bytes 0
Date Date/time,eachstoredina4byteinteger. 8bytes NULL
String Areferencetoavariablelengthstring. 4bytes NULL
Variant Canconsistofanydatatype. 12bytes NULL
Object Anindirectreferencetoanobject. 4bytes Null
Now that you know about all the different types of data that Gambas
supports,wewillstarttolookatwhatyoucandowiththosedatatypes.When
usingyourvariablesinGambasprograms,theycanberepresentedbydatathat
changes (e.g.,itisavariable) ortheycanberepresentedbydatathatremains
33
A Beginner's Guide to Gambas
(PUBLIC|PRIVATE)CONSTIdentifierASDatatype=value
PUBLICCONSTMAX_FILEASInteger=30
PRIVATECONSTMAGIC_HEADERASString="#Gambasformfile"
ThebuiltinconstantsyouwoulduseinGambasarelistedinthetablebelow:
Gambas Constants
Constant Example
TheTRUEvalue. TRUE
TheFALSEvalue. FALSE
Integernumbers. 0,562,17,32769
Hexadecimalshortsignedintegers. &H100F3,&HF0FF,&FFFF
Hexadecimalsignedintegers. &H1ABF332E,&1CBF302E
Hexadecimalunsignedintegers. &H80A0&,&HFCFF&
Binaryintegers. &X1010111101,%101000011
Floatingpointnumbers. 1.1110,5.3419E+4
Stringconstants. "Hello,GambasWorld!"
Stringconstantstobetranslated. ("Thisisvery,verycool")
NULLconstant/voidstring. NULL
34
A Beginner's Guide to Gambas
Stringconstantscanalsocontainthefollowingescapecharacters:
Escapecharacter ASCIIequivalent
\n CHR$(13)
\r CHR$(10)
\t CHR$(9)
\ Doublequote
\\ Backslash
\xx CHR$(&Hxx)
Youcanwriteastringconstantinseveralsuccessiveparts.Forexample,
"Myson""is""sixteen"isseenbyGambasas"Mysonissixteen".
VariableAssignment
AprogrammercanassignanyvaluetoavariableinGambasbyusingthe
followinggeneralformat:
Variable=Expression
Alocalvariable
Afunctionparameter
Aglobal(class)variable
Anarrayelement
Apublicobjectvariableorproperty
Herearesomeexampleofvariableassignments:
iMyVal=1984
stMyName="Orwell"
fMyNum=123.45
AssignmentUsingTheWITHStatement
Thisstatementismostcommonlyusedtosetpropertiesforcontrols.The
expressionthatexistsbetweentheWITHkeywordandtheENDWITHinstruction
35
A Beginner's Guide to Gambas
WITHExpression
.object=something;.
ENDWITH
Asanexample,thecodebelowiscodeequivalenttohButton.Text="Exit"
WITHhButton
.Text="Exit"
ENDWITH
OperatorsandExpressions
Comparisonoperators
ArithmeticOperators
36
A Beginner's Guide to Gambas
Let'sStartCodingGambas
Nowthatweknowaboutdatatypesandvariableassignments,letsgetour
feetwetwithGambas. StartGambasandfromthe ProjectExplorer FileMenu
selectNewProject.AsyougothroughtheNewProjectWizard,selectaTerminal
ProjectandclickNext.NamethisprojectTerminalTestandplaceitinadirectory
called TerminalTest. Don't worry about any of the other options. Just click
Next>>untilthewizardcompletes.OncetheIDEappearswithyournewproject
wewillneedtocreateastartupclassinordertorunourcode.FromtheProject
ExplorerfindtheTreeViewitemcalledClassesandrightclickthemouse.Choose
the New... option and take the default name Class1. The code window will
appearandinsidethewindowitshouldlooksomethinglikethis:
'Gambasclassfile
STATICPUBLICSUBMain()
END
Let'stakealookatsomeGambaskeywordsyoushouldknowabitmoreabout
beforeweproceed.
END,RETURNandQUITStatements
37
A Beginner's Guide to Gambas
RETURN[Expression]
WhenGambasexecutestheRETURNcommand,itquitsaprocedureora
functionandcompletesitsworkbyreturningthevalueofExpression.Now,enter
thefollowing code after the ' Gambas class file line (note thatcomments in
Gambasstartwiththe'[akathetickmark]) andbetweenthe STATICPUBLIC
SUBMain()andENDstatements.Onceyouhaveenteredthecodebelowinthe
Gambas code window, click the green button from the Project Explorer
ToolBartoexecuteyourprogram.Hereisthecodeyouwanttotryfirst:
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=3
R=6
PRINT===>;N;"|";R;"and";N;"|";R;
END
Ifallgoeswell(anditshould),youwillseetheblueshrimp(a.k.a.,theGambas
mascot)danceandtheconsolewindowwillrespondwiththefollowing:
===>3|6and6|3
NotethatthevalueofvariableNchangedfromapositive3to3andthe
valueof6changedtoapositivevalueof6.Don'tworryaboutthesyntaxofthe
PRINTstatementortheuseofthekeywordDIMusedtodeclareourvariablesfor
now.Wewillcoverthesekeywordslaterinthebook.
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=8
R=5
PRINT"===>";NR;
END
Theconsolewillrespondwiththefollowing:
==>3
38
A Beginner's Guide to Gambas
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=8
R=5
PRINT"===>";N*R;
END
Theconsolewillrespondwiththefollowing:
==>40
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=9
R=3
PRINT"===>";N/R;
END
Theconsolewillrespondwiththefollowing:
==>3
Nowtryusingthe\todivideinsteadofthe/character:
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=9
R=5
PRINT"===>";N\R;
END
Theconsolewillrespondwiththequotient:
==>1
39
A Beginner's Guide to Gambas
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=9
R=5
PRINT"===>";N\R;"andtheremainderis:";9MOD5;
END
Theconsolerespondswith:
===>1andtheremainderis:4
UsingNumberMODNumbercomputestheremainderofthequotientof
thetwonumbers.Adivisionbyzeroerrorwilloccurifthevalueofthenumberto
therightoftheMODoperatoriszero.Finally,wecantesttheDivisionbyZero
errorbytypingthisexample:
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=9
R=0
PRINT"===>";N/R;
END
Gambaswillrespondwiththefollowing:
Figure14ADivisionbyZeroErrorDialog.
NOTE:ClicktheStopbuttonwhenyouseethisdialogappear.
40
A Beginner's Guide to Gambas
Inordertoraiseanumbertoagivenpower(exponent),usetheformatof
Number^PowerandGambasraisesNumbertothepowerthePoweroperator
specified.Trythis:
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=2
R=3
PRINT"===>";N^R;
END
Theconsolewillrespondwiththefollowing:
==>8
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=0
R=0
PRINT"=>";NANDR;"istheANDresultof";N;"and";R
R=1
PRINT"=>";NANDR;"istheANDresultof";N;"and";R
N=1
PRINT"=>";NANDR;"istheANDresultof";N;"and";R
END
Theconsolewindowrespondswith:
=>0istheANDresultof0and0
=>0istheANDresultof0and1
=>1istheANDresultof1and1
12 In Gambas2, it will allow the use of concatenated operators. For example, a += 2 or B /= 4 will work just as if you were
programming in C or C++.
41
A Beginner's Guide to Gambas
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=0
R=0
PRINT"=>";NORR;"istheORresultof";N;"OR";R
R=1
PRINT"=>";NORR;"istheORresultof";N;"OR";R
N=1
PRINT"=>";NORR;"istheORresultof";N;"OR";R
END
Theconsolewindowrespondswith:
=>0istheORresultof0OR0
=>1istheORresultof0OR1
=>1istheORresultof1OR1
Number XOR Number uses the XOR operator and computes the
mathematicalexclusiveORofthebinaryvalueofthetwonumbers.
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=0
R=0
PRINT"=>";NXORR;"istheXORresultof";N;"XOR";R
R=1
PRINT"=>";NXORR;"istheXORresultof";N;"XOR";R
N=1
PRINT"=>";NXORR;"istheXORresultof";N;"XOR";R
END
Theconsolewindowrespondswith:
=>0istheXORresultof0XOR0
=>1istheXORresultof0XOR1
=>0istheXORresultof1XOR1
Additionally,thefollowingoperatorsmanipulateoneormorenumericvaluesand
returnanumericvalue:
DEC|INC|LIKE|NOT
42
A Beginner's Guide to Gambas
TheDECoperatorisusedtodecrementavaluebyone.TheINCoperator
willincrementthevaluebyone.Thevariablecanbeanytargetofanassignment
butmustbeanumericvalue.
STATICPUBLICSUBMain()
DIMNASInteger
DIMRASInteger
N=5
R=5
DECN
INCR
PRINT"===>";N;"|";R;
END
Theconsolewillrespondwiththefollowing:
==>4|6
* MatchNnumberofanytypeofcharacter.
? Matchanysinglecharacter.
[abc] Matchanycharacterspecifiedbetweenthebracketsymbols.
[xy] Matchanycharacterthatexistsintheintervalxy.
[^xy] Matchanycharacterthatdoesnotexistintheintervalxy.
STATICPUBLICSUBMain()
PRINT"Rittinghouse"LIKE"R*"
END
Theconsolerespondswith:
TRUE
Thespecialcharacter\preventsthenextcharacterfollowingitinastring
frombeinginterpretedasagenericpartofthestring.Thinkofthe\characteras
acontrolcode.Trythis:
STATICPUBLICSUBMain()
PRINT"Samson"LIKE"S*"
43
A Beginner's Guide to Gambas
PRINT"Gambas"LIKE"?[Aa]*"
PRINT"Leonard"LIKE"G[Aa]\\*"
PRINT"Alfred"LIKE"G[^Aa]*"
END
Theconsolerespondswith:
TRUE
TRUE
FALSE
FALSE
Note:youmustuseadoublebackslashcharacter,\\toprintabackslashorspecial
stringsequencecontainingbackslashes. Otherwisethe\willbeinterpretedbythe
compilerasaspecialcharacterlike'\n','\t','\*',etc.Alternatively,youcanusethis
patternstring:LIKE"G[Aa][*]"
TheNOToperatorisusedtoreturnaresultofanexpression.Theformatis
asfollows:
Result=NOTExpression
WhenGambasevaluatesthisexpression,itcomputesthelogicalNOTofthe
expression.Iftheexpressionisastringoranobject,GambasreturnsTRUEifthe
expressionisNULL.Herearesomeexamplestotryonyourconsole:
STATICPUBLICSUBMain()
PRINTNOTTRUE
PRINTNOTFALSE
PRINTNOT11
PRINTNOT"Gambas"
PRINTNOT""
END
Theconsolerespondswith:
False
True
12
False
True
StringOperators
InGambas,whenyouwanttocompareorconcatenatestrings,youcanuse
44
A Beginner's Guide to Gambas
thestringoperators. Theseoperatorsallowyoutoconcatenatestringsandfile
paths,performLIKEoperationsasexplainedabove,determineifstringsareequal
ornotequal,lessthan,greaterthan,lessthanorequalto,orgreaterthanorequal
to each other. The following table of string operations is shown for your
convenience:
Note:allstringoperatorcomparisonsarecasesensitive.
HerearesomethingstotryusingGambasconsole:
STATICPUBLICSUBMain()
DIMaASString
DIMbASString
a="ham"
b="burger"
PRINT"===>";A&B;
a="Gambas"
b=1
PRINT"===>";A&"isnumber"&B;
END
Theconsolerespondswith:
===>hamburger
===>Gambasisnumber1
45
A Beginner's Guide to Gambas
Thebestwaytounderstandwhatthesekeywordsandconditionalsmeanis
tograduallyintroducethemwithexamples. Ratherthangothroughthelistof
keywordsinalphabeticalorder,let'staketheapproachofintroducingthembased
on the type of functionality they support. We will start with the most basic
statementsandcommandsandprogressthroughthemorecomplexonesaswe
continue.Let'sstartwiththeGambasPRINTstatement.
ThePRINTStatement
Bracketsusedinthesyntaxdefinitionaboveindicateoptionalparameters.
Ifthereisnosemicolonorcommaafterthelastexpression,anewlinecharacteris
automaticallyprintedafterthelastexpression. Ifacommaisusedinsteadofa
semicolontoseparateexpressions,thenatabcharacter(ASCIIcode9)isprinted
betweenoutputvaluestoseparatetheexpressions.PRINTcanalsousedtodirect
outputtoafile. Wewilldiscussprintingtofileswhenwegettothesectionon
46
A Beginner's Guide to Gambas
InputandOutput. WhenusingPRINTtowriteoutputtoafile,expressionsare
senttothestreamFileandthisformatisused:
PRINT#File,Expression[(;|,)Expression...][(;|,)]
HereissomethingtotryusingPRINT:
STATICPUBLICSUBMain()
DIMbASInteger
b=1
PRINT"===>"&"bis:"&B
PRINT"===>","bis:",B
PRINT"===>";"bis:"&B
END
Theconsoledisplaysthefollowingoutput:
===>bis:1
===>bis:1
===>bis:1
TheIFStatement
TheIFstatementisusedtomakeadecision.IFisoneofthemostcommon
structuresusedbyprogrammerstomakecomparisonsanddecisionsbasedonthe
resultofthatcomparison.UsingIFlogic,yourprogramcanperformcomparisons
usingoperatorsyouhavelearnedaboutandsubsequentlymakedecisionsbased
ontheresultofsuchcomparisons.IFtakesthegeneralformof:
IFExpressionTHEN
dosomething...
[ELSEIFExpressionTHEN
dosomethingelse...]
[ELSE
dosomethingcompletelydifferent...]
ENDIF
HereisanexampleusingIFthatyoucantryontheconsole:
STATICPUBLICSUBMain()
DIMbASInteger
b=1
47
A Beginner's Guide to Gambas
IFb=1THEN
PRINT"===>"&"Gambasisnumber"&B;
ELSEIFb<>1THEN
PRINT"Shouldnotprintme!";
ELSE
PRINT"Somethingbadishappening"
ENDIF
END
Theconsolerespondswith:
===>Gambasisnumber1
TheSELECT/CASEStatement
TheSELECTstatementevaluatesanexpression,comparingittoeachCASE
specified,andwillexecutethecodeenclosedinthematchingCASEstatementif
theexpressionevaluatedisTRUE.IfnoCASEstatementmatchestheexpression
under evaluation, the DEFAULT or CASE ELSE statement is executed. The
SELECT/CASEstatement allowsaprogrammertobuildacodeblockcapableof
evaluatingmanyexpressionresultswithouthavingtocodeanexcessiveamount
ofIF/ELSEIF/ELSEstatements.TheformatoftheSELECTstatementis:
SELECTExpression
[CASEExpression[,Expression...]
[CASEExpression[,Expression...]
[CASEELSE|DEFAULT...]
ENDSELECT
HereissomecodetoshowyouhowtousetheSELECTstatement:
STATICPUBLICSUBMain()
DIMwASInteger
w=1
'START:isaLABEL,usedwithGOTOexplainedbelow.
START:
PRINT"Thevalueofwis:"&w
SELECTCASEw
CASE1
INCw
GOTOSTART
CASE2
48
A Beginner's Guide to Gambas
INCw
GOTOSTART
CASE3
INCw
GOTOSTART
CASEELSE
PRINT"Thevariablewhasnohandlerfor:"&w
ENDSELECT
PRINT"FinalvalueofwIS:"&w
END
Theconsoleshouldrespondwiththefollowingoutput:
Thevalueofwis:1
Thevalueofwis:2
Thevalueofwis:3
Thevalueofwis:4
Thevariablewhasnohandlerfor:4
FinalvalueofwIS:4
Becausethevariablewwasincrementedtothevalueof4andtherewasto
CASE tohandlethatvalue,the CASEELSE block isexecuted. CASEELSEcan
alsobewrittenasCASEDEFAULT.Eitherway,itiswherecodedefaultstowhen
nocasesatisfiesthevalueofthevariablebeingchecked.
GOTOandLABELS
TheFOR/NEXTStatement
Many times when writing code, programmers find the need to iterate
throughasetofvalues(calledlooping)toprocessdata.TheFORstatementisa
loopingstatementcommonlyusedinprograms.Ittakesthegeneralformof:
FORVariable=ExpressionTOExpression[STEPExpression]...NEXT
49
A Beginner's Guide to Gambas
The FOR statement repeats a loop while at each iteration of the loop
incrementingavariable.Notethatthevariablemustbeanumericdatatype(i.e.,
abyte,ashort,anintegerorafloatingpointnumber)anditmustbedeclaredas
alocalvariable.Iftheinitialexpressionthe FORstatement evaluatesishigher
thantheTOexpression(forpositiveSTEPvalues)oriftheinitialexpressionisless
thantheTOExpression(fornegativeSTEPvalues)theloopwillnotbeexecuted
atall.TheSTEPkeywordallowstheprogrammertodefinethesizeoftheinterval
incrementedbetweenloopiterations.Hereisanexample:
STATICPUBLICSUBMain()
DIMIASInteger
DIMJASInteger
J=1
FORI=1TO21STEP3
PRINT"LOOPiteration:"&J&",Iisequalto:"&I
INCJ
NEXT
PRINT"JIS:"&J&"andIis:"&I
END
Thiscoderesultsinthefollowingoutput:
LOOPiteration:1,Iisequalto:1
LOOPiteration:2,Iisequalto:4
LOOPiteration:3,Iisequalto:7
LOOPiteration:4,Iisequalto:10
LOOPiteration:5,Iisequalto:13
LOOPiteration:6,Iisequalto:16
LOOPiteration:7,Iisequalto:19
JIS:8andIis:22
NotethatoncethevalueofJexceedsthetestof21intheloop,theloop
stopsandcode flowmovespastthe NEXTstatement. ThevalueofJremains
unchangedwhenexitingtheloop.Experimentwiththecodeabove,changingthe
STEPvaluefrom3to1,forexample.TrytomodifytheFORstatementlikethis:
FORI=21to1STEP1
50
A Beginner's Guide to Gambas
examplesandchangevariablevalues,practiceusingthe PRINTstatement,etc.
Get to know the console and you will quickly learn it is a great tool to test
expressions,codesegments,etc. DonotbeafraidtoexperimentwithGambas!
Theveryworstthingthatcanhappenisyourprogramblowsupandyouhaveto
restart your computer unlikely, but indeed possible. Play around and get
comfortablewithGambas.Itisthebestwaytolearn.
DO[WHILE]LOOP
The DO[WHILE]LOOPstructurebeginsexecutionofaloopthatwillnot
enduntilaconditionismetorcodewithintheloopstructureforcesanexit.The
codeexecutedintheloopisdelimitedbythekeywords DO and LOOP. Ifthe
optionalkeyword WHILE isnotspecified, theloopwould executeforever (an
infiniteloop)oruntilsomeconditionwithintheloopstructureforcedanexit.If
theoptionalkeywordWHILEisspecified,theloopisstoppedoncetheevaluated
resultoftheexpressionbecomesFALSE.Inotherwords,whiletheresultsofthis
expressionareTRUE,continuetoiterate(do)theloop.IftheexpressionisFALSE
whentheloopisstarted,theloopwillnotbeexecutedatall.Hereistheformat
oftheDOLOOP:
DO[WHILEExpression]
...
LOOP
Thefollowingcodeexampleshouldhelpyoubetterunderstandhowtousethe
DO...WHILELOOP:
STATICPUBLICSUBMain()
DIMaASInteger
a=1
DOWHILEa<=5
IFa=1THEN
PRINT"HelloWorld,looping"&a&"time."
ELSE
PRINT"HelloWorld,looping"&a&"times."
ENDIF
INCa
LOOP
DECa
PRINT
PRINT"GoodbyeWorld,Iloopedatotalof:"&a&"times."
END
51
A Beginner's Guide to Gambas
Theconsoleprintsthefollowing:
HelloWorld,looping1time.
HelloWorld,looping2times.
HelloWorld,looping3times.
HelloWorld,looping4times.
HelloWorld,looping5times.
GoodbyeWorld,Iloopedatotalof:5times.
WHILE[Expression]WENDLoops
This loop structure begins a loop delimited by the WHILE ... WEND
instructions.TheloopisrepeatedwhileExpressionisTRUE.If,oninitialentry,the
expression is FALSE, the loop is never executed. The DO WHILE LOOP and
WHILE...WENDstructuresareequivalent.Trythiscode:
STATICPUBLICSUBMain()
DIMaASInteger
a=1
WHILEa<=5
IFa=1THEN
PRINT"HelloWorld,WHILE...WENDlooping"&a&"time."
ELSE
PRINT"HelloWorld,WHILE...WENDlooping"&a&"times."
ENDIF
INCa
WEND
DECa
PRINT
PRINT"Goodbye,WHILE...WENDloopedatotalof:"&a&"times."
END
Theconsoleshouldprintthefollowing:
HelloWorld,WHILE...WENDlooping1time.
HelloWorld,WHILE...WENDlooping2times.
HelloWorld,WHILE...WENDlooping3times.
HelloWorld,WHILE...WENDlooping4times.
HelloWorld,WHILE...WENDlooping5times.
Goodbye,WHILE...WENDloopedatotalof:5times.
52
A Beginner's Guide to Gambas
TheREPEATUNTILloop
STATICPUBLICSUBMain()
DIMaASInteger
a=1
REPEAT
IFa=1THEN
PRINT"HelloWorld,REPEATUNTILlooping"&a&"time."
ELSE
PRINT"HelloWorld,REPEATUNTILlooping"&a&"times."
ENDIF
INCa
UNTILa>5
DECa
PRINT
PRINT"Goodbye,REPEATUNTILloopedatotalof:"&a&"times."
END
Theconsoleshouldprintthefollowing:
HelloWorld,REPEATUNTILlooping1time.
HelloWorld,REPEATUNTILlooping2times.
HelloWorld,REPEATUNTILlooping3times.
HelloWorld,REPEATUNTILlooping4times.
HelloWorld,REPEATUNTILlooping5times.
Goodbye,REPEATUNTILloopedatotalof:5times.
DefiningandUsingArraysinGambas
TherearetwokindsofarraysthatcanbeusedinGambas.Thefirsttypeof
Gambasarrayworkslikearraysusedinthe Java programminglanguage. The
othertypeofarraythatisusedinGambasisknownasa Nativearray. When
using Javalike arrays, you must remember that the arrays are objects of the
followingclasses:Integer[],String[],Object[],Date[],andVariant[].Allofthese
typesof Javalike arrayscanhaveonlyonedimension. Youdeclarethemlike
this:
DIMMyArrayASNEWInteger[]
53
A Beginner's Guide to Gambas
Arraysarealwaysinitializedasvoidatstartup. Theyaredynamic,and
havealotofusefulmethodsapplyingtothem. Whenusingsingledimension
arrays,thesearetherightchoice. Nativearrays ontheotherhandcansupport
multidimensionalimplementationsorarrayswitharraysobjectsofthefollowing
classes:Integer,String,Object,Date,andVariant.Theyaredeclaredlikethis:
DIMMyArray[Dim1,Dim2,...]ASInteger
DIMMyArray[Dim1,Dim2,...]ASString
DIMMyArray[Dim1,Dim2,...]ASVariant
Nativearrayscanhaveuptoeightdimensions. TheyareNOTobjects.
Theyareallocatedonthestackifyoudeclarethemlocaltoafunction.Theyare
allocatedinsidetheobjectdataifyoudeclarethemasglobalinscope. Native
arraysareNOTdynamic.Theycan'tgroworshrinkoncetheyaredeclared.You
canonlyonlysetorgetdatafromanelementinthesetypesofarrays.Hereisan
exampleofusingathreedimensionalnativearrayinGambas. Inthisexample,
thearrayisfilledwithintegervaluesrangingfrom0to26. Enterthiscodein
yourconsolecodewindow:
STATICPUBLICSUBMain()
DIMiASInteger
DIMiiASInteger
DIMiiiASInteger
DIMnarMatrix[3,3,3]ASInteger
FORi=0TO2
FORii=0TO2
FORiii=0TO2
PRINTi,ii,iii&"==>";
narMatrix[i,ii,iii]=i*9+ii*3+iii
PRINTnarMatrix[i,ii,iii]
NEXT
NEXT
NEXT
END
Whenyouexecutethiscode,youroutputintheconsolewindowshouldbesimilar
towhatisshownhere:
000==>0
001==>1
...
221==>25
222==>26
54
A Beginner's Guide to Gambas
Collections
DIMhCollectionASCollection
hCollection=NEWCollection([ModeASInteger])
NotethewordEACHaftertheFORstatement.TheFOREACHconstructis
discussednext.Also,wewillgointomuchgreaterdetailaboutcollectionslaterin
thisbookwhenwetalkaboutobjectorientedprogramming.Wewilldevelopan
application that makes extensive use of collections. For now, just note that
collectionelementsareenumeratedintheorderinwhichtheywereinsertedinto
thecollection.However,ifyoureplacethevalueofanalreadyinsertedkey,the
originalinsertionorderiskept.
TheFOREACHStatement
FOREACHExpression...NEXT
FOREACHVariableINExpression...NEXT
ThissyntaxmustbeusedwhenExpressionisanenumerableobjectthatis
not a container. For example, an object returned as the result of a database
query.Thestatementsabovecreateanewcollectionobject.Enterthefollowing
codeintoyourconsolecodewindowandrunit.
STATICPUBLICSUBMain()
DIMMyDictASNEWCollection
DIMstrElementASString
MyDict["absolute"]=3
55
A Beginner's Guide to Gambas
MyDict["basic"]=1
MyDict["carpet"]=2
FOREACHstrElementINMyDict
PRINTstrElement&"";
NEXT
END
Yourconsoleshoulddisplaythisoutput:
312
Atthispoint,youshouldbegettingaprettygoodfeelforthesyntaxand
structureofGambas.Wearegoingtomoveawayfromconsolebased(terminal)
applicationsandreturntoourfirstprojecttobeginexploringtheGambasToolBox
andlearnhowtodevelopaGUIbasedprogram. Itistimetotakeabreakand
whenyoucomebacktothenextchapter,youwillberefreshedandreadytocode.
Ah,heck.Ifyoujustcannotwaittojumpin,goaheadandturnthepage!
56
A Beginner's Guide to Gambas
Button
Label
TextLabel
TextBox
TextArea
CheckBox
ComboBox
ListBox
RadioButton
ToggleButton
Frame
Panel
TabStrip
ProgressBar
Image
Timer
Dial
SpinBox
ScrollBar
Slider
LCDNumber
ListView
TreeView
IconView
GridView
ColumnView
ScrollView
DrawingArea
GambasEditor
TableView
Workspace
Asyoucansee,thereisawideselectionoftoolsforyoutoplaywithin
57
A Beginner's Guide to Gambas
Gambas.Ourintroductiontothetools(whicharealsocalledcontrols)willteach
youaboutwhateachcontroldoes,whatproperties,methods,andeventsyoucan
usetodirectthebehavioroftheinterfaceyouarebuilding,andhowtocodethe
controltomakeitworkexactlyasyoudesire.Alongtheway,wewillbebuilding
severalsimpleprojectstogetyoumoreexperiencedinusingtheGambasIDE.All
of the controls in the ToolBox are builtin using the gb.qt component. This
componentimplementstheGraphicalUserInterfaceclasses.ItisbasedontheQT
library.Hereisalistofthevariousfunctionalitythegb.qtcomponentprovides:
Clipboard
Containers
DragandDrop
Drawing
Fonts
IconView
KeyboardandMouse
Menus
ListView,TreeViewandColumnView
Printing
Wewillcoverothercomponentslaterinthisbook.AtthetopofFigure15,
you see the word Form displayed. This is the default toolkit for the gb.qt
component.Fornow,let'stakeaquicklookattheToolBoxagainandreviewthe
iconstherein.
Figure15TheGambasToolBox.
58
A Beginner's Guide to Gambas
FromthetopleftofFigure1,thecontrolsintheToolBox(Row1)are:
Select
Label
TextLabel
PictureBox
ProgressBar
Button
CheckBox
Onthesecondrowyouwillfind:
RadioButton
ToggleButton
ToolButton
TextBox
ComboBox
TextArea
ListBox
Onthethirdrowwehave:
ListView
TreeView
IconView
GridView
ColumnView
HBox
VBox
Thefourthrowofcontrolsdisplay:
HPanel
VPanel
Frame
Panel
TabStrip
ScrollView
DrawingArea
Timer
59
A Beginner's Guide to Gambas
AtthebottomoftheToolBoxwindow,thewordQTisseen.Ifyouclickon
that,youwillseethecontrolsspecifictotheQTuserinterfaceappear,similarto
Figure2below:
Figure16AdditionalcontrolsforQT.
TheQTSpecificControlsfoundonthetoprowofFigure2are:
Selector
LCDNumber
Dial
SpinBox
ScrollBar
Slider
MovieBox
Thesecondrowofcontrolsincludethesetools:
TableView
HSplit
VSplit
Workspace
TextView
ThegeneralapproachtoprogrammingGambasistodesignthelayoutof
yourforms,placethecontrolsthatmakeupyourinterfacetotheuseronthe
form,determineandhandlethevariouseventsthatcanoccurwitheachcontrol
usingacombinationofbuiltinGambasmethodsandyourowncode,anddirect
theoperationsoftheprogramusinginput/outputdata.Ifitsoundssimple,itis
60
A Beginner's Guide to Gambas
becauseonceyouunderstandthemechanicsofitall,itissimple.Onceyouget
usedtoprogrammingeventdrivenapplicationsinGambas,itwillbecomesecond
naturetoyou.
Thefirstgroupofcontrolswearegoingtolearnaboutaretextorientedin
natureandservetoeitherdisplayorgathertextdataortogenerateaneventthat
youcanwritecodefor,suchaspushingabutton.Thesecontrolsare:
Button
Label
TextLabel
TextBox
InputBox
TextArea
TheButtonControl
ThisclassobjectinheritsitsattributesfromtheControlclass,asdoallthe
controlsintheGambasToolBox.Usingthiscontrolimplementsapushbuttonon
aform.Apushbuttoncandisplaytext,apicture,orboth.Youhavetheabilityto
setonebuttoninsideawindowtobethe Defaultbutton.Then,whentheuser
pressestheRETURNkey,itwillactivatethatbuttonautomatically.Also,youcan
setonebuttoninsideawindowtobetheCancelbutton.PressingtheESCkey
willactivatetheCancelbuttonautomatically. Thisclass iscreatable,meaning
thatyoucanwritecodetodynamicallygenerateabuttononaformatruntime.
Todeclareabuttonobject,theformatbelowisused:
DIMhButtonASButton
hButton=NEWButton(ParentASContainer)
TheContainer,inmostcases,willbetheformwhereyouplacethebutton.
Itcould beany container object, however. This code will create a new push
buttoncontrol. Notethevariablenameisprecededbythelowercaseletter h.
Thisisastandardconventionprogrammersusetorefertothehandle(handlesare
really references to something) of an object. Since Gambas supports object
orientedprogramming,wewillgraduallyintroduceOO(ObjectOriented)concepts
to you as we encounter them. OO will be covered in much greater detail in
Chapter11ofthisbook.Generally,objectsarecreatedfromaclassbyassigninga
copyoftheobjecttoavariable,inthiscase hButton. Thisprocess,knownas
instantiating anobjectoccurswhenhButtonisassignedavalueusingtheNEW
61
A Beginner's Guide to Gambas
keyword. WhatthelinebelowmeansishButtonwillbeinstantiatedasaNEW
Button object and Parent is the property (read only) that will read a method
(thinkofmethodsasfunctionsthatsetorgetavalue)thatisimplementedinside
theContainerclass.TheContainerclassisusedbecauseitistheparentclassof
everycontrolthatcancontainothercontrols.Now,thislineofcodeshouldmake
perfectsensetoyou:
hButton=NEWButton(ParentASContainer)
CommonControlProperties
Buttonpropertiesareattributesthatyoucansetorreadusingtheproperty
windoworbyusingcodeinyourprogram.Forexample,thelineofcodebelow
willsettheTextpropertyofabutton:
hButton.Text=OK
Notetheformatofthestatementabove.Control.Property=Expressionis
thestandardconventionusedforsettingorgettingattributeinformationfroma
control.Manyofthepropertiesforcontrolsarecommonamongallcontrols,so
wewilltakethetimenowtoexplainallofthebuttonpropertieshere.Laterinthe
book,wewillonlyexplainthepropertiesthatareuniquetoagivencontrolwhen
weencounterthem.
BackColorisdefinedasPROPERTYBackColorASInteger
Thisintegervaluerepresentsthecolorusedforthecontrolbackground.It
is synonymous with the Background property. Note that PROPERTY is a
predefined datatype used internally in Gambas. You can use the Gambas
predefinedconstantsforcolortosetcommoncolorvalues:
TosettheBackColorpropertyforhButtontored,youwouldusethiscode:
hButton.BackColor=Color.Red
62
A Beginner's Guide to Gambas
Alternatively, if you know the RGB (red, green, blue) or HSV (hue,
saturation,value)valuesforaspecificcolor,Gambasprovidesameanstoconvert
thosevaluestoanintegervaluethatcanbepassedontotheBackColor(orother
colorrelated)property.TheclassColorprovidestwomethods,RGBandHSVthat
youcanuse.Hereishowthosefunctionsaredefined:
STATICFUNCTIONRGB(RASInteger,GASInteger,BASInteger[,AlphaAS
Integer])ASInteger
The RGB function returns a color value from its red, green and blue
components.FortheHSVfunction,usethis:
STATICFUNCTIONHSV(HueASInteger,SatASInteger,ValASInteger)ASInteger
HSVreturnsacolorvaluefromitshue,saturationandvaluecomponents.Touse
one of these functions to set the button's background color, here is what you
couldcode:
hButton.BackColor=Color.RGB(255,255,255)
Thiswouldsetthebutton'sbackgroundcolortowhite.Thisismostusefulwhen
youaretryingtosetcolorswhosevaluesfalloutsidethedefaultcolorconstant
valuesprovidedwithGambas.
hButton.Border=Border.Plain
hButton.Cancel=TRUE
IftheCancelpropertyisusedinyourprogram,itwouldallowyoutohandlethe
eventandgracefullyexittheformjustasiftheuserhadclickedaQuit,Exitor
Cancelbutton.
63
A Beginner's Guide to Gambas
hButton.Caption=OK
isthesameas
hButton.Text=OK
andcanbeusedinterchangeably.Let'strysomecode.StartGambasandopenup
theprojectwecreatednamedFirstProject.FromtheTreeView,doubleclickyour
mousecursorontheMainFormformandtheblankformwillopenup.Double
clickanywhereontheblankformandyouwillseethecodewindow. Itshould
looklikethis:
'Gambasclassfile
PUBLICSUBForm_Open()
END
Now, enter this code between the PUBLIC SUB Form_Open() and END
statementssoitlookslikethis:
PUBLICSUBForm_Open()
DIMhButtonASButton
hButton=NEWButton(ME)AS"hButton"
hButton.X=215
hButton.Y=60
hButton.Width=200
hButton.Height=40
hButton.Enabled=TRUE
hButton.Text="ClickorpressESCtoQuit"
hButton.Border=TRUE
hButton.Default=TRUE
hButton.Cancel=TRUE
hButton.Show
END
AfterthePUBLICSUBForm_Open()'sENDstatement,addthisroutine:
PUBLICSUBhButton_Click()
MainForm.Close
END
64
A Beginner's Guide to Gambas
Onceyouhaveenteredthecodeabove,clickthegreenprogramrunbutton
andyoushouldseesomethingsimilartothefollowing:
Figure17FirstButtoncoderesults.
Simply click the button or press the ESC key to exit this program.
Congratulations!YouhavejustcreatedyourfirstGUIbasedprograminGambas!
Yes, it is a little bit ugly but remember, you did it the hard way, using code
instead of taking advantage of the Gambas ToolBox. Remember, a good
programmerwillalwaystryusepredefinedconstantsiftheyareavailableinstead
ofhardcodingnumericvalues. Forexample,keycodesandmousestyleshave
thesamenamesastheyaredefinedasconstants,buttheirnumericvaluesare
totallydifferent.Theanticpatedgb.gtkcomponentwillnotworkwithgb.qtcode
ifyouarenotusingpredefinedconstantssowhenwritingcode,itisimperativeto
use these constants instead of numeric values. If not, the code will not be
portable.Goodcodeshouldneverusenumericvaluesforthesetasks.Now,save
yourprojectandexitGambasfornowandwewillproceedwithlearningmore
abouttheToolBox.
CursorisdefinedasPROPERTYCursorASCursor andyoucanusethe
Cursorpropertyforassigningacustomcursortoacontrol.Thisclassimplements
acustommousecursor.Thisclassiscreatable. Hereishowtodeclareacursor
objectvariableandinstantiateacursorobject:
DIMhCursorASCursor
hCursor=NEWCursor(MyPicASPicture[,XASInteger,YASInteger])
ThecodeformatabovecanbeusedtocreateanewcursorfromaPicture
objectandsetanoptionalhotspot.Ifitisnotspecified,thedefaulthotspotisthe
topleftofthepicture.Cursorhastwoproperties,XandY,thatcanbeusedtoset
orgetthecurrentmouseposition.Hereisanexamplethatshowsyouhowtouse
aCursorobjectinyourprogram:
65
A Beginner's Guide to Gambas
DIMhPictASPicture
DIMhCursorASCursor
hPict=Picture["torric.png"]
hCursor=NEWCursor(hPict)
ME.Cursor=hCursor
hButton.Default=FALSE
DesignisdefinedasPROPERTYDesignASBooleananditindicatesthat
thecontrolisindesignmode.ThismeansthatwhentheDesignpropertyissetto
TRUE,controlsindesignmodejustdrawthemselvesandwillnotreacttoany
inputevent. ThispropertyisusedbytheGambasDevelopmentEnvironment to
displaycontrolsintheformeditor.Whatthisreallymeansisyoudonotneedto
worryaboutthisproperty.
IFhButton.Drop=FALSETHEN
hButton.ToolTip="NoDropsallowed"
ELSE
hButton.ToolTip="Dropsomethinghere"
ENDIF
IFExpression=FALSETHEN
hButton.Enabled=TRUE
ELSE
hButton.Enabled=FALSE
ENDIF
66
A Beginner's Guide to Gambas
FontisdefinedasPROPERTYFontASFontanditreturnsorsetsthefont
usedtodrawtextinthecontrol. Toset Fontproperty attributes,codelikethis
canbeused:
hButton.Font.Name="Lucida"
hButton.Font.Bold=TRUE
hButton.Font.Italic=FALSE
hButton.Font.Size="10"
hButton.Font.StrikeOut=FALSE
hButton.Font.Underline=FALSE
Theoutputoftheabovecodewouldbeasfollows:
Figure18Demonstratingfontcapabilities.
ForeColorisdefinedasPROPERTYForeColorASIntegerandthisinteger
valuerepresentsthecolorusedforthecontrolforeground.Itissynonymouswith
theForegroundproperty.YoucanusetheGambaspredefinedconstantsforcolor
tosetcolorvalue:
TosettheForeColorpropertyforhButtontored,youwouldusethiscode:
hButton.ForeColor=Color.Red
AswiththeBackColorproperty,ifyouknowtheRGBorHSVvaluesfora
specificcolor,youcanpassthemtotheForeColorpropertywiththiscode:
hButton.ForeColor=Color.RGB(255,255,255)
67
A Beginner's Guide to Gambas
Thiswouldsetthebutton'sforegroundcolortowhite.
TheXpropertyisdefinedasPROPERTYXASIntegeranditisusedtoset
orreturnthexpositionofthecontrol. X isthesameas Leftproperty. The Y
propertyisdefinedasPROPERTYYASIntegeranditisusedtosetorreturnthey
positionofthecontrol(topleftcorner).
TheHeightpropertyisdefinedasPROPERTYHeightASIntegeranditis
used to set or returnthe height of the control. Itissynonymous withthe H
property and can be used interchangeably. This value describes how tall the
controlisfromthexpositionmovingdownHeightpixels.TheWidthpropertyis
definedasPROPERTYWidthASIntegeranditisusedtosetorreturnthewidth
of the control. It is synonymous with the W property and can be used
interchangeably.Thisvaluedescribeshowwidethecontrolisfromthexposition
totherightWidthpixels.
CursorShape Value
Default 1
Arrow 0
Cross 2
Wait 3
Text 4
SizeS 5
SizeE 6
SizeNESW 7
SizeNWSE 8
SizeAll 9
Blank 10
SplitV 11
SplitH 12
Pointing 13
68
A Beginner's Guide to Gambas
TheNextpropertyisdefinedasPROPERTYREADNextASControlandit
isusedtoreturnthenextcontrolhavingthesameparentwithinaContainer.Itis
usefulwheniteratingthroughaseriesofcontrolstosetfocus.Wewilldiscussthis
property in more detail when we discuss the SetFocus() method. To get the
previouscontrol,onewouldusethe Previous property,defined as PROPERTY
READPreviousASControl. Thispropertyreturnsthepreviouscontrolhaving
thesameparent.
TheScreenXpropertyisdefinedasPROPERTYREADScreenXASInteger
anditreturnsthepositionoftheleftborderofthecontrolinscreencoordinates.
Usually,itisusedinconjunctionwithScreenY.
TheScreenYpropertyisdefinedasPROPERTYREADScreenXASInteger
andreturnsthepositionofthetopborderofthecontrolinscreencoordinates.
TheTagpropertyisdefinedasPROPERTYTagASVariantandisusedto
return or sets the control tag. This property is intended for use by the
programmer and is never used by the component. It can contain any Variant
value.
TheTextpropertyisdefinedasPROPERTYTextASStringandreturnsor
setsthetextdisplayedinthebutton.Itisalmostalwaysusedandit'svaluecan
be changed dynamically. We have already used this property in the example
above:
hButton.Text="ClickorpressESCtoQuit"
hButton.ToolTip="Clickme!"
69
A Beginner's Guide to Gambas
TheToppropertyisdefinedasPROPERTYTopASIntegerandreturnsor
setsthepositionofthetopborderofthecontrolrelativetoitsparent.
Atthispoint,wehavecoveredallofthepropertiesfortheButtonControl
andyoushouldhaveaprettygoodunderstandingofwhattheyareusedforand
howtousethem.Rememberthatmostofthesepropertiesarecommontomany
controls. Next,wewillcoverthemethods(thingsyoucandowiththebutton)
andprovideyousomeexamplesofhowtousethem.
ButtonMethods
Methodsarethebuiltinroutinesprovidedforacontrolthatallowyouto
dothingslikeshowit,hideit,moveit,etc.Herearethemethodssupportedby
theButtoncontrol:Delete,Drag,Grab,Hide,Lower,Move,Raise,Refresh,Resize,
SetFocus,andShow.Usually,amethodiscalledinresponsetosomeevent.We
willdiscusseventsinthenextsection.Let'stakealookatthemethodsusedwith
Button:
70
A Beginner's Guide to Gambas
IFExpression=TRUETHEN
hButton.Hide
ELSE
hButton.Show
ENDIF
PUBLICSUBhButton_Click()
Button1.Hide
Label1.Text="Ouch!"
WAIT2.0
Button1.Show
Label1.Text="Betternow!"
END
Onceyouhaveenteredthecode,runtheprogramandseewhathappens.
WhenyouclickthebuttonitwilldisappearandLabel1.Textwillchange. After
twoseconds, it will reappearand change the label again. Also, note thatwe
slippedinanewcommandforyoutotry WAIT. WAITtakesafloatingpoint
valueasaparameterthatrepresentssecondsorfractionsofsecondsexpressedas
decimalvalues. Numberslessthan1areprocessedasmilliseconds. WAIT1.5
wouldpauseexecutionfor1,500 milliseconds. IfyouspecifyWAITwithouta
parameter,itwillrefreshtheinterfaceanditdoesnotallowtheusertointeract
withtheapplication.
TheMovemethodisdefinedasSUBMove(XASInteger,YASInteger[,
WidthASInteger,HeightASInteger])andisusedtomoveand/orresizethe
control.
hButton.Move(hButton.X50,hButton.Y20)
71
A Beginner's Guide to Gambas
TheResizemethodisdefinedasSUBResize(WidthASInteger,Height
ASInteger)andisusedtoresizethecontrol.
Figure19Thedottedlineindicates
focusforacontrol.
WehavecoveredallofthemethodsavailablefortheButtonclass(control)
andwillnowbegindiscussingtheeventsforthatclass.Asachangeofpace,let's
trytolearnabouteventswithamorehandsonapproach. Wecandothisby
buildinganewprogramandlearningwhattheeventsdoandhowtousethem.
CloseGambas(asmallquirkofGambasisthelackofacloseprojectmenuselection)
andrestartittoinitiatetheNewProjectWizard.Selectagraphicaluserinterface
projectandgothroughthewizardjustlikewedidwiththeprojectFirstProject.
NamethisprojectSecondProject. OncetheIDEappears,createanewstartup
classformandnameitForm1.Forthisproject,wearegoingtoplacethreeLabel
controlsontheform,asshowninFigure20below.
Figure20ThelayoutforSecondProjectForm1.form.
72
A Beginner's Guide to Gambas
The first label's text caption is set with the Label.Text property. The setting
shouldbeHereistheandthesecondisGambasMascotandthethirdis
> which points to a PictureBox control (where the shrimp lives). Name the
labelsLabel1,Label2andLabel3respectively.Next,namethePictureBoxcontrol
PictureBox1.
ToobtainthegraphicoftheGambasmascot,youcangototheofficial
Gambaswebsite13andrightclickonthemascot.Choosetosavetheimageand
samveitasgambasmascot.pngonyourcomputer. Movethefiletothedata
directory in the SecondProject folder. (Another Gambas quirk is that the file
explorerdialogsdon'tseemtobedynamic.Oncetheyhaveinitialized,changesmade
outside theGambasenvironment arenotupdateddynamically.) Once you have
done this, you can set the Picture property for PictureBox1 to the file named
gambasmascot.png.Atthispoint,thetopofyourformshouldlooklikethis:
Figure21Apartiallyconstructedformwithourfirstfourcontrols.
Now,selecttheProgressBarcontrolfromtheToolBoxandplaceitonthe
form so it looks like that shown in Figure 20 above. Finally, we have three
buttonstoaddtotheform.NamethesebuttonsFunBtn,NoFunBtn,andQuitBtn.
Allofthenecessarycontrolsforourexamplehavebeenaddedtotheformatthis
point. TrytogetthelayouttolookasclosetothepictureshowninFigure3
aboveaspossible. Atthispoint,youmaybeaskingwhatallofthisisgoingto
accomplish? Remember, we are going to learn how to use events with these
controls. Wehaveplacedthecontrolswherewewantthemandnowthenext
stepistodecidewhateventswearegoingtohandle.
Forthisexercise,wearegoingtohandlemouseeventswhenthemouse
movesoverlabels.Ifthemousemovesoffofthemainwindow(Form1.form)or
backontoitwewillhandlethoseevents.Wewillalsohandlebuttonclicksand
theESCkeyifitispressed.
13 TheofficialGambassiteishttp://gambas.sourceforge.net/index.html.
73
A Beginner's Guide to Gambas
'Gambasclassfile
PUBLICSUBForm_Open()
ProgressBar1.Value=0.50
ProgressBar1.BackColor=Black
ProgressBar1.ForeColor=Yellow
END
Whenthemousemovesoverthestartupform(ourGambasprogramonthe
desktop),wewanttosetthethreetoplabel'stextpropertiestoblankvaluessoit
appearsthatthetextdisappears. Thisrequireschoosingan eventhandler. To
chooseaneventfromtheGambasIDE,movethemouseovertheform(butnot
directlyoveracontrol)andclickitonce. Next,rightclickthemouseandyou
shouldseeamenupopup,similartotheoneshowninFigure22below.Choose
theEventselectionitemfromthepopupandpicktheEnterevent.Addthiscode,
asshownbelow:
PUBLICSUBForm_Enter()
Label1.Text=""
Label2.Text=""
Label3.Text=""
END
Figure22Eventmenu.
Repeatthisprocesstochooseanotherevent,theLeaveevent,sothatwhen
themousemovesofftheprogramwindowwecandetectthatanddosomething
aboutit.Addthiscode:
74
A Beginner's Guide to Gambas
PUBLICSUBForm_Leave()
ProgressBar1.Value=0.50
Label1.Text="Wasn'tthat"
Label2.Text="somereal"
Label3.Text="funstuff?"
END
Thenextthingwewanttodoishandlethesituation(event)thatoccurs
whenthemousemovesoveranyofourlabels. Inthisevent,wearegoingto
changetheLabel.Textpropertyoftheaffectedlabeltoindicatethatamousehas
beendetectedoverthecontrol.Singleclickyourmousecursoronthefirstlabel
and whenthehandlesappear,rightclick and choose the Enter eventwhen it
appearsontheEventsubmenu. Inthecodewindow,findthe Label1_Enter()
subroutineandenterthiscode:
PUBLICSUBLabel1_Enter()
Label1.Text="Here'sthe"
END
RepeatthesameprocessfortheLabel2.TextandLabel3.Textproperties. Your
codeshouldlooklikethis:
PUBLICSUBLabel2_Enter()
Label2.Text="GambasMascot"
END
PUBLICSUBLabel3_Enter()
Label3.Text=">"
END
Wealsowanttodetectandrespondtoeventswhenthemousemovesover
ourmascotpictureaswell.ClickonceonthePictureBox1controlandchoosethe
EnterEvent.Gotothecodewindowandmakethecodelooklikethis:
PUBLICSUBPictureBox1_Enter()
Label1.Text=""
Label2.Text=""
Label3.Text=""
PictureBox1.Border=Border.Plain
END
Repeattheprocess,choosingtheLeaveeventandensureyourcodeistypedinthe
codeeditorasfollows:
PUBLICSUBPictureBox1_Leave()
75
A Beginner's Guide to Gambas
Label1.Text="Wasn'tthat"
Label2.Text="somereal"
Label3.Text="funstuff?"
PictureBox1.Border=Border.Sunken
END
ThenextcontrolthatwewanttotakecareofistheQuitbutton.Double
clickonitandthecodewindowdisplaystheQuitBtn_Click()subroutine,which
respondstoaClickevent.AddtheForm1.Closeline,asshownbelow.
PUBLICSUBQuitBtn_Click()
Form1.Close
END
Figure23AddingtheFunBtntoourform.
Now,wehavetowritecodefortheProgressBar.Forourexample,wewill
incrementitwhentheFunBtnisclickedanddecrementitwhentheNoFunBtnis
clicked.DoubleclickontheFunBtncontrolandaddthiscode:
PUBLICSUBFunBtn_Click()
ProgressBar1.Value=ProgressBar1.Value+0.01
IFProgressBar1.Value>0.99THEN
ProgressBar1.Value=0.0
ENDIF
END
Now,doubleclickontheNoFunBtnandaddthis:
PUBLICSUBNoFunBtn_Click()
ProgressBar1.Value=ProgressBar1.Value0.01
IFProgressBar1.Value<0.01THEN
ProgressBar1.Value=0.0
ENDIF
END
76
A Beginner's Guide to Gambas
Thatisnearlyallthereislefttodo!Now,savetheprojectandclicktherun
button.Youshouldseethisonprogramstart:
Figure24Whatourformlookslikewhenamouseisdetected
overtheform.Notethetextisblankedout.
Now, click the Click me for more fun button and the progress bar
changes.Clickitthreetimesandyoushouldseethis:
Figure25TheprogressbarwhentheFunBtnisclickedthreetimes.
Ifyoumoveyourmouseoverthemascotpicture,youshouldseethelabel
textappearanddisappearasyoumovethemouseonandoffthepicture.Finally,
youcanhitESCorclicktheQuitbuttontoexittheprogram.Thelasteventwe
are going to write code for in this example is the doubleclick event. This
requiresyoutoonceagainchooseaneventhandler.
FromtheGambasIDE,movethemouseovertheFunBtnandclickitonce.
Next,rightclickthemouseandyouwillseethemenupopupallowingyouto
77
A Beginner's Guide to Gambas
PUBLICSUBFunBtn_DblClick()
ProgressBar1.Value=ProgressBar1.Value+0.1
IFProgressBar1.Value>0.90THEN
ProgressBar1.Value=0.0
ENDIF
END
RepeatthisprocessfortheNoFunBtnandaddthiscode:
PUBLICSUBNoFunBtn_DblClick()
ProgressBar1.Value=ProgressBar1.Value0.1
IFProgressBar1.Value<0.1THEN
ProgressBar1.Value=0.0
ENDIF
END
Now,savetheprojectandclicktherunbutton.Thistime,whenyouclick
the progress bar it works just as it did before, but if you doubleclick, it will
incrementthevalueby10unitsratherthanbyone.Onceyouexityourprogram,
saveyourprojectandexitGambas.Next,wearegoingtolookatthetheother
eventsthatcanusedwiththeButtoncontrol.
ButtonEvents
The Button events we have used in our previous example include the
Click,DblClick,Enter,andLeaveevents. Wewillreserveourdiscussionofthe
remaining events, namely Drag, DragMove, Drop, LostFocus and GotFocus for
when we deal with drag and drop operations. The Menu, KeyPress and
KeyRelease events will be covered when we talk about menu and keyboard
operations. Finally, when we cover mouse operations, we will discuss the
MouseDown,MouseMove,MouseUp,andMouseWheelevents.
ThePictureClass
Earlier in the chapter, when we used the Picture control to place our
mascotontheforminoursecondexample,wementionedthePictureClassand
saidwewouldcoveritlater.Well,nowitistimetotalkaboutthePictureClass.
Thisclassrepresentsapictureanditscontentsarestoredinthedisplayserver,not
inprocessmemorylikeanImagewouldbenormallystored.EvenifXWindows
78
A Beginner's Guide to Gambas
does not manage transparency (yet), each picture object can have a mask
assignedwithit.Thiscanbesetexplicitlyatthetimethepictureisinstantiated,
or it can be set implicitly when loading an image file that has transparency
attributes,likeaPNGfile.Whendrawingonapicturehavingamask,boththe
pictureandthemaskaremodified.Thisclassiscreatable.Itisdefinedas:
DIMhPictureASPicture
andtheprocessofinstantiatingitusesthisformat:
hPicture=NEWPicture([WidthASInteger,HeightASInteger,
TransparentASBoolean])
Thecodeabovewillcreateanewpictureobject.IftheWidthandHeightarenot
specified,thenewpictureisempty(void). Youcanspecifyifthepicturehasa
maskwiththeTransparentparameter. Thepictureclassactslikeanarray.For
example:
DIMhPictureASPicture
hPicture=Picture[PathASString]
willreturnaPictureobjectfromtheinternalpicturecache.Ifthepictureisnot
presentinthecache,itisautomaticallyloadedfromthespecifiedfile.Toinserta
pictureinthecache,usethiscall:
Picture[PathASString]=hPicture
PropertiesforthiscontrolincludeDepth,Height,Image,Transparent,and
Width.ThemethodsprovidedincludeClear,Copy,Fill,Flush,Load,Resize,and
Save.Wewillcovertheuseofthesemethodsandpropertiesinlaterexamplesin
thisbook.Atthispoint,youshouldhaveasolidunderstandingofhowtousethe
Gambas programming environment and it's various tools. In the next few
chapters,wewillpresentmorecontrolswithmorecomplexexamplesasthebest
waytolearnisbydoing.
79
A Beginner's Guide to Gambas
TextLabel
TextBox
ComboBox
ListBox
ToggleButton
Panel
Frame
Checkbox
RadioButton
Hereiswhatourprogramwilllooklikewhenwearefinishedwithit:
Figure26ThirdProject(almost)finalresult.
80
A Beginner's Guide to Gambas
Inthisexercise,wewilllearntoputtitlesonourprogramwindow,usean
inputboxtogatherHTMLformattedinputfromtheuseranddisplaythatresultin
anewtypeoflabel,theTextLabel.Wewillalsolearnhowtogroupandorganize
our controls on the form, using panels and frames, and place controls like
RadioButtonsandCheckBoxeswithinthoseorganizationalcontrols.Finally,we
willlearnhowtouseListBoxesandComboBoxestoallowtheusertoselectfrom
oneofmanychoices.Alongtheway,wewilllearnabitmoreabouteventcoding
andtrytomakeitinteresting. Let'sgetstartedbycreatinganewProjectwith
Gambas.StartGambasandchoosetocreateanewprojectusingaGraphicalUser
Interface. Gothroughthewizardmakingtheprojecttranslatableandtheform
controlspublic. Selectthename ThirdProject andputitinadirectoryofyour
choosing.WhentheIDEstarts,createanew,startupclassform.Doubleclickon
the blank form and the code editor window will appear. You should see
somethinglikethis:
'Gambasclassfile
PUBLICSUBForm_Open()
END
Now,wewillstartbyputtingthetitleofourprogramatthetopofthe
window when the program runs. To accomplish this, we will set the form's
Captionproperty tothetextwewanttouseasthetitle. Enterthislineinthe
Form_Open()subroutine:
ME.Caption="***ThirdProject***"
Thattakescareofthetextforthewindowtitle. Now,ifwelookatour
finalresultpicture,westillhavetoaddourcontrols. Wewillstartatthetop,
addingthecontrolswealreadyknowabout:Label,TextBox,andButton.Place
eachcontrolontheformasshowninFigure26above.NamethecontrolsLabel1,
TextBox1,and UpdateBtn. Thesecontrolswereusedinthelastchapter,soyou
shouldbecomfortableusingtheminyourprograms.Next,wewilladdtheQuit
Buttonatthebottomrightcorneroftheform.NamethiscontrolQuitBtn.Now,
let'saddthecodeforthesecontrols.DoubleclickthemouseontheQuitBtnand
addthiscodetotheQuitBtn_Click()subroutine:
PUBLICSUBQuitBtn_Click()
Form1.Close
END
81
A Beginner's Guide to Gambas
Fortheupdatebutton,wearegoingtotransferthetexttheusertypedinto
the TextBoxcontrol totheTextLabel,reflectingany HTML formattingthatthey
entered.Hereisthecodeneededforthat:
PUBLICSUBUpdateBtn_Click()
TextLabel1.Text=TextBox1.Text
END
Fromthispointon,wewillbelearningtousenewcontrolsandfeaturesof
Gambas.WehavealreadywrittencodetoassigninputdatatotheTextLabel,so
let'stakethetimenowtolearnallwecanaboutit.Beforewestart,itisprobably
agoodideatogoaheadandclickthesavebuttonontheIDEtosaveyourwork.
TextLabel
ThisclassiscreatableanditinheritsitsattributesfromtheControlclass.It
implementsacontrolcapableofdisplayingsimpleHTMLtext.YoucanuseHTML
entitiessuchas<and>todisplaycharacterslike<and>.ForHTMLthat
requirestheuseof quotemarks, avoid the because itwill notwork. For
example,entering:
<divalign="center"><b>Thiswon'twork.</b>
Thefigurebelowshowsyouanexampleofhowthisworks:
Figure27UsingHTMLtoformatTextLabeloutput.
hTextLabel=NEWTextLabel(ParentASContainer)
Whatwewanttodonowiscodetheupdatebuttontotakeadvantageof
thesecool HTML features. Toaccomplishthis,weneedtomodifythecodewe
previously entered for the update button's click event. Doubleclick on the
82
A Beginner's Guide to Gambas
UpdateBtncontrolandchangethecodetolooklikethis:
PUBLICSUBUpdateBtn_Click()
TextLabel1.Text="<divalign=center><b>"&TextBox1.Text&"</b>"
END
Instead of simply assigning the input text from the TextBox to the
TextLabel1.Textproperty,wearegoingtomakeitlookfancy.Now,anythingthe
user types will automatically be centered in boldface and placed on the
TextLabel1.Ifyousaveyourprojectandrunitatthistime,yourresultsshouldbe
likethatofFigure28below:
Figure28ModifiedTextLabeloutputusingHTMLformatting.
TextBox
OurnexttaskistolearnmoreabouttheTextboxcontrolwejustused.You
alreadyknowthatitisusedtolettheuserenteralineoftextinputandreturn
thatinputtotheprogramasastring. TextBoxinheritsitsattributesfromthe
Controlclassandthisclassimplementsasinglelinetexteditcontrol.Thisclassis
creatableandisdeclaredas:
DIMhTextBoxASTextBox
hTextBox=NEWTextBox(ParentASContainer)
Let's try something else now. Suppose that we want to streamline our
applicationsothattheuserdoesnothavetoclicktheupdatebuttonwhenthey
entertext. Also,itwouldbenicetohavethetextfieldclearitselfifthemouse
entered the control area and to put back the default prompt when when the
mouseismovedawayfromthecontrol. Wewouldwanttopreservewhatever
wastypedintothefieldbytheuserwhenthemouseleavesthecontrolsowehave
83
A Beginner's Guide to Gambas
toremembertoassignthevaluethatiscurrentlyintheTextBox1.Textfieldtothe
TextLabel1.Text field. We want to continue to use the HTMLcapable format
capabilitiesoftheTextLabel.
Wewillneedtomodifyourcode.First,wemustcreatetheeventhandlers
forthemouseenteringthecontrolandleavingthecontrol. Clickonceonthe
TextBox1controlontheformandrightclickthemousetoselecttheEventitem.
FromtheEventsubmenuchooseEnter.RepeatthisprocessandchoosetheLeave
event.Now,gotothecodeeditor,findthefirstsubroutine(TextBox1_Enter())
andinsertthefollowingcodebetweenthefirstandlastline:
TextBox1.Clear
That'sitforthisroutine.WejustcallthebuiltinmethodtocleartheTextBoxand
wearedone.Now,westillneedtogototheTextBox1_Leave()subroutineand
enterthiscode:
TextLabel1.Text="<divalign=center><b>"&TextBox1.Text&"</b>"
TextBox1.Text="<Entertexthere>"
The first line of code will use HTML to format and center the
TextBox1.Textstringandsetittoaboldfacefont.Thenextlineofcodeassigns
thedefaultpromptstringweinitiallycreatedtotheTextBox1.Textsowhenthe
mouse leaves we have saved whatever the user typed and reset it to what it
lookedlikebeforethemouseenteredthecontrol. Saveyourworkandrunthe
programtoseehowitworks.
TherearenotreallyanyTextBoxuniqueMethodstodiscuss,butwhilewe
arelearningaboutevents,let'splayaroundwiththecodealittleandlearnabout
theShowandHidemethodsandhowtheymaybeusedinaprogram.Clickonce
ontheform(becarefulnottoclickonanycontrolontheform)andrightclickthe
mousetoselecttheEventitem.FromtheEventsubmenuchooseMouseDown.
RepeatthisprocessandchoosetheDblClickevent.Now,gotothecodeeditor,
findthesubroutineForm_MouseDown()andinsertthefollowingcodebetween
thefirstandlastline:
UpdateBtn.Hide
ThatisallweneedtodotohidetheUpdateBtncontrol.Ifyouuseropts
nottousethebuttonnow,alltheneedtodoisclicktheformanditwillhidethe
button.Howdowebringitback?Doubleclickwilldothetricknicely.Fromthe
84
A Beginner's Guide to Gambas
codeeditor,findtheForm_DblClick()subroutineandenterthiscode:
UpdateBtn.Show
Right now, you may be asking yourself How the user would ever know
this? Goodpoint. Let'sletthemknowwithaToolTipproperty.Clickonthe
UpdateBtncontrol. NowgotothepropertywindowandfindToolTip. Onthe
rightsideofthatentryisaninputfieldandwithagrayboxwiththreedots(...).
Thatmeansanotherdialogwilltakeplacewhenyouclick. Inthiscase,itwill
openaneditwindowsoyoucanformatyourToolTipusingHTML.Clickitand
whentheeditdialogappears,enterthistext(orcode,asyouwish):
Click<b>(ordoubleclick)</b>ontheformtohide<b>(orshow)</b>me.
Now,saveyourworkandruntheprogramtoseehowitworks.Hoverthe
mouseovertheUpdateButtonandthenicelyformattedToolTipwillappear. It
shouldlooklikethefigurebelow.Cool,huh?
Figure29AddingaToolTiptoinform
theuserhowtoshow/hideacontrol.
ThereareacoupleofTextBoxuniqueeventswecoulddiscussatthispoint,
namely KeyPress and KeyRelease,butwearegoingtoholdoffonthoseuntil
laterinthebookwhenwestartworkingwiththekeyboarddirectly. Readyto
moveon?Wearegoingtoaddsomeselectorcontrolstoourprogramnext.The
ComboBoxandListBoxallowuserstoselectfromamongseveralchoices.Wewill
startwiththeComboBoxfirst.
ComboBox
The ComboBox control inherits its attributes from the Control class. It
implementsatextboxcombinedwithapopuplistbox. Thisclassiscreatable
andisdeclaredusingtheformatbelow:
85
A Beginner's Guide to Gambas
DIMhComboBoxASComboBox
Toinstantiatethevariablewejustdeclared,usethisformat:
hComboBox=NEWComboBox(ParentASContainer)
ThiswillcreateanewComboBoxcontrol.Thisclassactslikeareadonly
array. Inotherwords,declaringthevariable,instantiatingit,andretrievinga
valuefromcodedirectlywouldworklikethis:
DIMhComboBoxASComboBox
DIMhComboBoxItemAS.ComboBoxItem
DIMIndexasInteger
hComboBoxItem=hComboBox[Index]
Thelineofcodeabovewillreturnacomboboxitemfromitsintegerindex.
Notethatthe.ComboBoxItem representsaniteminthecomboboxpopuplist
box.Thisclassisvirtual.Youcannotuseitasadatatypeanditisnotcreatable.
It has a single property, Text which returns a string value representing the
ComboBoxitemrepresentedbyIndex. WearegoingtocreateaComboBoxon
ourformnow.Hereiswhatourcontrolwilllooklike:
Figure30OurComboBox.
OK,iagreethatitisnothingveryfancyanditprobablyrankskindoflow
onthecreativitylist,butitwillgetthejobdoneandteachyouwhatyouneedto
knowtouseComboBoxes.Tobuildournewcontrol,wewillgototheGambas
ToolBoxand selectthe ComboBoxcontrol. Placeitontheform(refertoour
initialFigureattheverybeginningofthischaptertoseewhereitshouldgo)andtry
togetitasclosetowhatyouseeinthatpictureasyoucan.Onceyouaredone
withthat,clickonitonceifyoudonotseethehandlesandgototheProperties
Window.FindtheListproperty.Theinputboxtotherightofthiswillenablea
86
A Beginner's Guide to Gambas
selectordialogifyouclickinsideit.Clicktheselectordialogbutton(remember,
withthethreedots?)anditwillbringuptheEditlistpropertyDialog:
Figure31TheEditlistpropertyeditor.
Toinsertaniteminthelist,typetheitemintheTextBoxatthebottomof
theeditor.Thefirstiteminthelististhedefault.Itismostoftenusedtoseta
defaultselection(likeNoneorPicksomething,etc.)Inourcase,typePickanitem
andclickinsert.AddItem1,Item2,Item3,andItem4tothelist.Makesurethey
appearintheordershowninFigure31abovesoitwilllookrightwhenitruns.
Onceyouhaveitsetthewayyouwant,justclicktheOKbuttonandtheeditor
willcloseandsaveyourwork. Saveyourprojectandruntheprogramtosee
whatitlookslikeonyourform.Whenyouhavefinishedlookingattheworkwe
havedonesofar,exittheprogramandwewillcontinuebyaddingsomecodeto
processComboBoxselections.
IftheuserselectssomethingfromtheComboBox,theitemwillchangeand
thischangegeneratesaneventthatyoucanhandle. Fromtheform,selectthe
ComboBox control and rightclick. Choose Event and select Change from the
submenu. Now, go to the code editor and find the subroutine PUBLIC SUB
ComboBox1_Change().Addthecodesothesubroutinelookslikethis:
PUBLICSUBComboBox1_Change()
DIMresultASString
result=Trim(ComboBox1.Text)
TextLabel1.Text=result&"wasselectedfromtheComboBox"
END
Saveyourprojectandruntheprogramtoseewhathappens.Noticethat
whenanitemisselectedtheTextLabel1.Textvalueisupdatedbutdoesnothave
87
A Beginner's Guide to Gambas
anyfancyformattingthatitiscapableof.Well,thatiseasytofix.Let'schange
thecodelikethis:
PUBLICSUBComboBox1_Change()
DIMresultASString
result="<divalign=center><b>"&Trim(ComboBox1.Text)&"</b>"
TextLabel1.Text=result&"wasselected."
END
Changethecodeandruntheprogramagain.Youshouldseesomethingsimilarto
thisintheTextLabel1control:
Figure32FormattingaTextLabelwithHTML.
Sotherealprogrammersouttherearealreadyaskinghowtodothiswith
code,eh?Ithoughtyouwouldneverask!Seriously,itisnothard.Let'smodify
our program slightly to allow dynamically add or remove items from the
ComboBox.Todothis,wearegoingtoneedabuttonthatwillindicateaddingan
itemandanotherbuttontoremoveanitem.Addtwobuttons,onecalledPlusBtn
andtheothercalledMinusBtntotheform,asshownbelow:
Figure33Plusandminusbuttons
toaltertheComboBoxlist.
DoubleclickonthePlusBtnandinsertthiscode:
PUBLICSUBPlusBtn_Click()
DIMItemASString
DIMNumItemsASInteger
ComboBox1.Refresh
NumItems=ComboBox1.Count
IFNumItems=0THEN
Item="PickanItem"
ELSE
Item="Item"&Str(NumItems)
ENDIF
ComboBox1.Refresh
ComboBox1.Add(Item,NumItems)
END
88
A Beginner's Guide to Gambas
Inthecodeabove,wedeclaretwovariables,ItemandNumItems.Itemisa
stringandNumItemsanInteger.WewilluseNumItemstodeterminehowmany
itemsarealreadyinthelist.Thisisdoneusingthe.Countproperty.Ifthereare
noitemsinthelist,wewillsetourdefaultpromptofPickanItemasItemzero.
ComboBoxarraysarezerobased,meaningthecountingstartsatzero,not
one.IttheNumItemsvalueiszerowewillcreateadefaultstring.Otherwise,we
aregoingtoconcatenatetheitemnumbertothewordItemsoitwilladdtothe
nextopenslotinthelist.WecalltheRefreshmethodtoforcetheComboBoxto
refreshitscountpropertysoiftheusertriestoselectagainitwillbecurrent.The
lastlineofcodeusesthe.AddmethodtoaddtheitemtotheComboBoxitemlist.
Now,doubleclickontheMinusBtnandaddthiscode:
PUBLICSUBMinusBtn_Click()
DIMNumItemsASInteger
'Thecomboboxarraystartsatzero
ComboBox1.Refresh
NumItems=ComboBox1.Count
IFNumItems>0THEN
DECNumItems
IFNumItems<>0THEN
ComboBox1.Remove(NumItems)
ENDIF
ComboBox1.Refresh
ENDIF
END
Removingelementsfromthelistismuchsimpler.Weonlyneedaninteger
variabletodeterminethenumberofelementsinthelist.Onceagain,thisisdone
usingthe.Countproperty.Inourexample,Countwillreturnavalueof5thefirst
timeitisread.Iftherearenoitemsinthelist,wewillnotdoanything.Because
the ComboBoxitems arestoredinazerobasedarray,wemustdecrementthe
count by one if it is not already zero. Now, save your project and run the
program.Tryremovingalltheitemsinthelistandreinsertingthem.Cool,eh?
MorecoolstufftocomewiththeListBox,whichwediscussnext.
ListBox
TheListBoxcontrolalsoinheritsitsattributesfromtheControlclass.The
ListBoximplementsalistofselectabletextitems. Thisclassiscreatable. The
followingcodewilldeclareaListBoxandcreateit:
89
A Beginner's Guide to Gambas
DIMhListBoxASListBox
hListBox=NEWListBox(ParentASContainer)
LiketheComboBox,thisclassactslikeareadonlyarray.
DIMIndexasInteger
DIMhListBoxASListBox
DIMhListBoxItemAS.ListBoxItem
hListBoxItem=hListBox[Index]
ThelineofcodeabovewillreturnaListBoxitemfromitsintegerindex.
Notethatthe.ListBoxItemrepresentsanitemintheListBoxpopuplistbox.This
classisvirtual.Youcannotuseitasadatatypeanditisnotcreatable.Ithasa
singleproperty,TextwhichreturnsastringvaluerepresentingtheListBoxitem
representedbyIndex.WearegoingtocreateaListBoxonourformnow.Here
iswhatournewcontrolwilllooklike:
Figure34WhatourListBoxwill
looklike.
Inordertobuildournewcontrol,wewillgototheGambasToolBoxand
selecttheListBoxcontrol.Placeitontheform(refertoourinitialpictureatthe
verybeginningofthischaptertoseewhereitshouldgo)andtrytogetitascloseto
whatyouseeinthatpictureasyoucan.Onceyouaredonewiththat,clickonit
onceifyoudonotseethehandlesandgotothePropertiesWindow.FindtheList
property. Theinputboxtotherightofthiswillenableaselectordialogifyou
clickinsideit.Clicktheselectordialogbutton(remember,withthethreedots?)
anditwillbringuptheEditlistpropertyDialog:
Figure35ListBoxEditlistpropertyeditor.
90
A Beginner's Guide to Gambas
ThisisexactlythesameeditorweusedtobuildtheComboBox1control.
Thistime,wearegoingtoadditemstothelistandalsolearnabouttheSystem
class.The Systemclass ispartofthe Gambas componentlibrary andprovides
supportforalltheclassesincludedintheinterpreterbydefault.TheSystemclass
is static and provides readonly information about the operating system
environment. The properties of this class that you can read include Charset,
Domain,Home,Host,Language,Path,andUser.Usetheeditorandenterthe
followingitemsinthelist:
Charset
Domain
Home
Host
Language
Path
User
Next,doubleclickontheListBox1controlontheform.Thiswilltakeyou
to the code editor and you should be in the PUBLIC SUB ListBox1_Click()
subroutine.Thefollowingcodewillshowyouhowtoaccessthesevalues.Enter
itasfollows:
PUBLICSUBListBox1_Click()
IFTrim(ListBox1.Text)="System.Charset"THEN
TextLabel1.Text=System.Charset
ELSEIFTrim(ListBox1.Text)="Domain"THEN
TextLabel1.Text=System.Domain
ELSEIFTrim(ListBox1.Text)="Home"THEN
TextLabel1.Text=System.Home
ELSEIFTrim(ListBox1.Text)="Host"THEN
TextLabel1.Text=System.Host
ELSEIFTrim(ListBox1.Text)="Language"THEN
TextLabel1.Text=System.Language
ELSEIFTrim(ListBox1.Text)="Path"THEN
TextLabel1.Text=System.Path
ELSEIFTrim(ListBox1.Text)="User"THEN
TextLabel1.Text=System.User
ENDIF
END
Now,saveyourprojectandruntheprogram.Tryselectingalltheitemsin
thelistandseewhatinformationisreturned. ListsandComboBoxesarevery
91
A Beginner's Guide to Gambas
easytoimplementanduse. Agreatadvantageofusingthesetypesofselector
components is that it virtually eliminates the possibility of a user typing data
incorrectly. In the next section, we are going to learn how to organize the
controlsonourformtobettermanagethepresentationtocontrolstotheuser.
Also,wewilllearnwhyframesandpanelsareagoodthingtoconsiderearlyin
thedevelopmentprocess.
Frame
The Frame class inherits its attributes from the Container class. This
controlisacontainerwithanetchedborderandalabel.Thisclassiscreatable.
DodeclareandinstantiateaFrame,usethisformat:
DIMhFrameASFrame
hFrame=NEWFrame(ParentASContainer)
Thegreatthingaboutaframeisthatitworkssortoflikeawindowwithin
awindow.Anycontrolyouplaceintheframebecomesapartoftheframe,ina
mannerofspeaking. Whatthismeansisthatifyouput CheckBoxcontrolsor
buttonsorwhateverintheframeanddecidetomovetheframe,theyallmove
withit.Theycanberearrangedwithintheframe,butiftheframemoves,hides,
etc.,sodothey.Hereiswhatourframeandthecontrolswewilladdtoitlook
like:
Figure36Whattheexampleframewebuildwilllooklike.
Tocontinuedevelopmentofourproject,wewillfirstaddaFramecontrol
totheform(nameitFrame1)andplaceitsimilartothatfoundinFigure24atthe
beginningofthischapter.Next,wewilladdtwoToggleButtoncontrols(named
ToggleButton1 and ToggleButton2) and three CheckBox controls (named
CheckBox1,CheckBox2,andCheckBox3). ArrangethemtolooklikeFigure 33
above.Onceyouhaveeverythingplacedcorrectlyontheform,let'sgotothenext
stepandwritecodefortheeventswewillrespondtoinourprogram.
92
A Beginner's Guide to Gambas
ToggleButton
TheToggleButtoncontrolinheritsitsattributesfromtheControlclassand
implementsatogglebutton.Thismeansiteithertogglesupordown.Thisclass
iscreatable.Todeclareandinstantiatethiscontrol,usetheformat:
DIMhToggleButtonASToggleButton
hToggleButton=NEWToggleButton(ParentASContainer)
PUBLICSUBToggleButton1_Click()
IFToggleButton1.Value=TRUETHEN
Frame1.Text="Toggled1down"
ELSE
Frame1.Text="Toggled1up"
ENDIF
END
RepeatthepreviousstepfortheToggleButton2controlandenterthiscode:
PUBLICSUBToggleButton2_Click()
DIMresultASString
IFToggleButton2.Value=TRUETHEN
Frame1.Text="Toggled2down"
ELSE
Frame1.Text="Toggled2up"
ENDIF
END
WhatwehavedonewiththecodeaboveischecktheToggleButton.Value
propertytoseeifitisTRUE,indicating thatthebuttonwasclickeddown. If
FALSE,anotherclicktoggledittotheupposition.Regardlessofthepositionitis
at,wewanttheFrame1.Texttodisplaythestatusofthebuttonlastclicked.Now,
let'smoveontolearnabouttheCheckBoxcontrols.
Checkbox
TheCheckBoxclassinheritsitsattributesfromtheControlclass.Thisclass
implementsacheckboxcontrolanditiscreatable. Declareandinstantiatethe
variablelikethis:
DIMhCheckBoxASCheckBox
93
A Beginner's Guide to Gambas
hCheckBox=NEWCheckBox(ParentASContainer)
WhenaCheckBoxcontrolisclickedinourprogram,wewanttodetectthe
click event and immediately respond. In this case, we will change the
Checkbox.TextpropertywhenevertheCheckBox.Valueischeckedandturnsout
tobeTRUE.Thiswillshowthatwecaughttheclickeventandrespondedtothe
valueofTRUEorFALSE(checkedorunchecked). Iftheboxisunchecked,we
willwanttoreturnittotheNormalstate.ForCheckBox1,doubleclickonthe
control and enter this code in the code editor for the PUBLIC SUB
CheckBox1_Click()subroutine:
PUBLICSUBCheckBox1_Click()
DIMoutline1ASString
DIMoutline2ASString
DIMoutline3ASString
IFCheckBox1.Value=TRUETHEN
Checkbox1.Text="Iwaspicked"
ELSE
Checkbox1.Text="Checkbox1"
ENDIF
END
RepeatthisprocessforCheckBox2andCheckBox3:
PUBLICSUBCheckBox2_Click()
IFCheckBox2.Value=TRUETHEN
Checkbox2.Text="Iwaspicked"
ELSE
Checkbox2.Text="Checkbox2"
ENDIF
END
PUBLICSUBCheckBox3_Click()
IFCheckBox3.Value=TRUETHEN
Checkbox3.Text="Iwaspicked"
ELSE
Checkbox3.Text="Checkbox3"
ENDIF
END
Now, save your project and run the program. Once you have satisfied
yourselfthattheyworkasweplanned,endtheprogramandwewillcontinueour
projectbyaddingthelasttwocontrolsthatwearegoingtocoverinthischapter,
thePanelandRadioButton.
94
A Beginner's Guide to Gambas
Panel
The PanelclassinheritsitsattributesfromtheContainerclass.Thisclass
implementsa Panelcontrol withachangeableborder. Thisclassiscreatable.
Declareandinstantiateapanellikethis:
DIMhPanelASPanel
hPanel=NEWPanel(ParentASContainer)
Inourprogram,wearegoingtousethePaneltogroupourRadioButtons
insideit.Hereiswhatthispanelwilllooklikewhenwearefinished:
Figure37APanelwithRadioButtons.
WewillfirstneedtoaddaPanelcontroltotheform(nameitPanel1)and
placeittolooklikethePanelfoundatthebeginningofthischapter. Next,we
will add two RadioButton controls (named RadioButton1 and RadioButton2).
ArrangethemtolooklikeFigure37above.
RadioButton
DIMhRadioButtonASRadioButton
hRadioButton=NEWRadioButton(ParentASContainer)
SelecttheRadioButtoncontrolfromtheToolBoxandplaceitontheform.
Namethe firstRadioButton RadioButton1 and repeat thisprocessfor another,
namedRadioButton2. Onceyouhaveeverythingplacedcorrectlyontheform,
let'sgotothenextstepandwritecode.DoubleclickonthefirstRadioButtonand
enterthiscode:
95
A Beginner's Guide to Gambas
PUBLICSUBRadioButton1_Click()
RadioButton1.Text="HaHaRB2"
RadioButton2.Text="RadioButton2"
END
Repeatthisprocessforthesecondone:
PUBLICSUBRadioButton2_Click()
RadioButton2.Text="HaHaRB1"
RadioButton1.Text="RadioButton1"
END
Now, save your project and run the program. Once you have satisfied
yourselfthateverythingwehavedoneinthischapterwillworkasweplanned,
takeawelldeservedbreakandwewillstartfreshonthenextchapter.
96
A Beginner's Guide to Gambas
Figure38MenuProjectFinalresults.
97
A Beginner's Guide to Gambas
PUBLICSUBQuitBtn_Click()
Form1.Close
END
Doubleclickontheformanywhereoutsideacontrolboundaryandyou
willgetthePUBLICSUBForm_Open()subroutinetoappearinthecodeeditor.
Insertthiscodeinthatemptysubroutine:
ME.Caption="WorkingwithMenus"
TheGambasMenuEditor
Gambas has a builtin Menu Editor. You can access it from the form
windowbypressing CTRLE orbyrightclickingontheformandselectingthe
MenuEditor optionfromthepopupthatappears. Eitherway,the MenuEditor
willappearandyouwillseesomethinglikethis:
Figure39TheGambasMenuEditorwhenitfirststarts.
98
A Beginner's Guide to Gambas
WhenyoufirststarttheMenuEditor,theeditorwindowwill,ofcourse,be
blank. It is not anintuitively obvious tool to use, so let's spend a minute to
explaintheMenuEditor.First,somecommonterminology.Thetextthatyousee
runninghorizontallyacrossthetopofaformisreferredtoasamenu.Amenu
cancontainMenuItems(whicharelistedverticallybelowthemenu).MenuItems
cancontain subMenus,whicharebasicallynewnestedmenusthatbelongtoa
MenuItemand willpopupanddisplay anotherlistof MenuItems. Menus can
containseverallayersofnestedsubMenus.
ToinsertamenuyouwillhavetousetheInsertbutton.TheNextbutton
willmovethecurrentmenucursorpositiontothenextiteminthewindow. It
onlymovesdownandthereisnopreviousbutton.Ifyoureachtheendofthelist,
itwillstopandtheonlythingyoucandoisclickthemouseonamenuentryor
insertanewone.TheDeletebuttonwillremovethemenuentryunderthemenu
cursor.
Figure40EditfieldsfortheMenuEditor.
99
A Beginner's Guide to Gambas
TheNamefieldshouldprobablyhavebeencalledVariable Namebecause
thatiswhatthisfieldisusedfor.Thisisthevariablenamethatyourcodeinthe
classfilewillusetoreferencethisparticularobject.
TheGroupfieldreferstoaControlGroup.ControlGroupsareusedinthe
GambasIDEtocreateandhandlegroupsofcontrolsasasingleentity.Whenyou
selectanycontrolonaform,inthePropertiesdialog,youshouldnoticeaGroup
propertythatdoesn'tcorrespondtoanydocumentedpropertyofthatcontrol.This
specialpseudopropertyallowsyoutoassigncontrolgroups.Essentially,whenthat
controliscreatedatruntime,itwillbetreatedasthoughyouhadcreateditin
codelikeso:
myControl=NEWColumnView(ME)AS"myGroup"
anditseventhandlersmustbenamedlikeso:
PUBLICSUBmyGroup_Click()
You can refer to the control that generated the event with the LAST
keyword,oryoucanassignaTagtoeachcontroltodifferentiatethembyusing
thetagvalue.
Captionisthetextthattheenduserwillseewhentheprogramruns.Tag
isreservedforprogrammerstostoredataandisacommonpropertyfornearlyall
controls. WewillcoverhowtousetheTagpropertylater. Fornow,youonly
needtoknowthatitcancontainANYVarianttypedata.
The CheckBoxes to the right of the input fields, Visible, Enabled, and
Checked refertothe state ofthemenuentry. Bydefault,allmenuentriesare
createdtobeenabledandvisible.Youcanspecifyiftheitemischeckedornot.
Incode,youcanseeiftheentryischeckedornotbylookingatthemenuentry's
Checkedproperty.ItwillreturnaTRUEorFALSEvalueindicatingthestatusof
theitem. Hereisanexampleofhowtotoggleacheckmarkonoroffwhena
menuitemispicked:
100
A Beginner's Guide to Gambas
IFMenu2Item1.CheckedTHEN
Menu2Item1.Checked=FALSE
ELSE
Menu2Item1.Checked=TRUE
ENDIF
TheIFstatementwilltesttheCheckedpropertyoftheMenu2Item1object
andiftheBooleanvalueisTRUEwillsetittoFALSE(togglingit).IftheBoolean
valueisNOTTRUEtheELSEclauseisexecuted,togglingthe.Checkedvalueto
TRUE.ThislogiccanbeusedtotoggleanymenuorsubMenuItem.
NOTE:AwordofcautionusethisfeaturesparinglyforgoodGUIdesign. Many
users feel overwhelmed when they are presented with too much gadgetry in an
interface.
BuildingMenus
Now,let'screateourmenu.Whenyouarefinished,itwilllooksomething
likethisfromthemenueditor:
Figure41Buildingourprojectmenu.
Tobegin,clicktheInsertbutton.First,wewillinsertthetoplevelmenus,
ColorDialog,MessageBoxes,FileDialogs,andHelp. Tomakethiseasy,usethe
101
A Beginner's Guide to Gambas
tablebelowtofillintheinputfielddata:
Now,let'sputthemenuitemsintothefirstmenu.Thesemenuitemswillbelong
totheColorDialogmenu:
After you have inserted these items with the editor, ensure they are
positionedbelowtheColorDialogentryandindentedonelevel.Now,movethe
menucursoroverthesecondmainmenuentry,MessageBoxesandwewillinsert
themenuitemsforthismenu.
102
A Beginner's Guide to Gambas
That'sallthereistoit!ClicktheOKbuttontoleavethemenueditorand
whenyourreturntotheform,amenuwillbethere.Ifitdoesnotlooklikeour
example,gobacktothemenueditorandadjusttheentriesuntilitdoes. After
youarecompletelysatisfiedwiththemenu'sformatandappearance,thenextstep
istocodeactionsforeachmenuclickevent. However,beforewedothat,we
needtolearnaboutthestandarddialogsandMessageBoxesthatareprovidedin
Gambas.
Dialogs
TheDialogclassisusedtoimplementalloftheGambasstandarddialogs.
Thisclasscontainsstaticmethodsusedtocallthestandard dialogboxes.This
classisstatic. TheDialogmethodssupported (i.e.,thestandard dialogs) are:
OpenFile,SaveFile,SelectColor,SelectDirectory,andSelectFont.Theproperties
supportedbythisclassare:Color,Filter,Font,Path,andTitle.
WhenworkingwiththefilerelatedDialogs,theFilterandPathproperties
arereturned. Filterisdefinedas STATICPROPERTYFilterASString[] andit
returnsorsetsthefilters(i.e.,categorizebyfileextension,suchasall.docor.png
files)usedinthestandardfiledialogs.Thispropertyreturnsorreceivesastring
array.Eachelementinthearrayrepresentsonefiltertousewhenthefiledialog
callismade.Eachfilterstringmustfollowthefollowingsyntax:
Thefiltername.
Aspace.
Anopeningbracket.
Oneormorefilepatterns,separatedbysemicolons.
Aclosingbracket.
HereisanexamplethatalsodemonstratestheuseoftheDialogTitleproperty:
103
A Beginner's Guide to Gambas
Dialog.Title="Chooseafile"
Dialog.Filter=["Pictures(*.png;*.jpg;*.jpeg)","Allfiles(*.*)"]
Dialog.OpenFile
ThefilerelatedDialogcalls(SelectDirectory,OpenFileDialogandSaveFile
Dialog)allreturnthePathproperty,whichisastringthatcontainsthefilepath
selected.InthecaseoftheSelectDirectoryDialogcall,thestringistruncatedat
thedirectorylevel.Now,let'sstartcodingourfirstmenuitem,ForegroundColor.
Fromtheformwindow,choosetheForegroundColoritemfromthemenuwejust
builtandyouwillbetakentothecodewindowinasubroutinecalled PUBLIC
SUBMenu1Item1_Click()whereyouwillwanttoinsertthiscode:
PUBLICSUBMenu1Item1_Click()
Dialog.Title="Chooseaforegroundcolor"
Dialog.SelectColor
TextLabel1.ForeColor=Dialog.Color
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
First,wesettheTitleoftheDialogtoChooseaforegroundcolorsothe
userhassomeideaofwhattheDialogisusedfor. Wecallthestandarddialog
withDialog.SelectColor.Oncetheuserhaspickedacolororcanceledfromthe
dialog, we will place the name of the color returned in the TextLabel1.Text
control wecreated atthe beginning of ourproject. We choose the TextLabel
becauseitallowsustoformatouroutputlikethis:
TextLabel1.Text="<b>Colorselectedwas</b>"&Str$(Dialog.Color)&"."
ThelineofcodeabovewillsettoboldfacetheColorselectedwaspartof
thestring,concatenatetheColorvaluetothestringafterconvertingtheintegerto
astringusingtheStr$conversionfunction,andthenconcatenatetheterminating
punctuationtothestring(wedowantittolookprofessional,don'twe?).Nowrun
thecodeandyoushouldseesomethinglikethis:
Figure42Aformattedtextlabeldisplayingthecolorvalue.
104
A Beginner's Guide to Gambas
Well,21760isnotveryusefulinformation. Thisnumberistheinternal
representationofthatgreenishcolorIselected.Weneedtodevelopsomemethod
ofknowingifthecolorisred,blue,green,i.e.,anamedcolorconstant.Thisis
whatwewerealludingtointheprevioussectionabouttheproblemwithcolors.
Hereisweremodulescomeintoplay.
Modules
Wearegoingtocreateamoduletoreturnthenameofacolorifitisa
predefinedconstant.Ifnot,wewantastringthattellsusitis not apredefined
colorconstant.Oncewedefineourmodule,wewillcomebackandmodifyour
codetousethemodule.FromtheProjectwindow,findModulesintheTreeview
andselectanewmodule,namedModule1.Whenthedialogappears,leavethe
CheckBoxes blank and just take the default name and click OK. You will be
presentedwithanewcodewindowtitledModule1.module. Itshouldstartout
withacommentlikethis:
'Gambasmodulefile
Now, we write all the code for our function, which we will call
SetColorName.First,wemustdeclarethefunctionandidentifywhatinputand
outputparametersitwillprocess.Hereishowwedothat:
PUBLICFUNCTIONSetColorName(iValASInteger)ASString
WedeclareapublicFunctionthattakesanintegerparameterandreturnsa
string. Thismodulewillthattheintegervaluethatthe SelectColorDialog has
returned,andcheckitagainstthe32predefinedcolorconstantsusedinGambas.
Ifitmatchesacolorconstant,wewillsetatemporarystringtothenameofthat
color.Ifnot,wewillcreateastringthatidentifiestheconstantvalueandreturn
thattothecallingcode.Wewillneedtocreateatemporarystringvariabletodo
this,soaddthisvariabledeclarationasthefirstlineofcodeinsidethefunction:
rvalASString
Now,wehavetoaddourCASESELECTstatement.Itwillusetheinteger
parameteriValthatispassedintothefunctionfromthecallingsubroutine.Here
isthefulllistingforyoutoenter:
'Gambasmodulefile
PUBLICFUNCTIONSetColorName(iValASInteger)ASString
105
A Beginner's Guide to Gambas
rvalASString
SELECTiVal
CASEColor.Black
rval="Black"
CASEColor.Blue
rval="Blue"
CASEColor.Cyan
rval="Cyan"
CASEColor.DarkBlue
rval="DarkBlue"
CASEColor.DarkCyan
rval="DarkCyan"
CASEColor.DarkGray
rval="DarkGray"
CASEColor.DarkGreen
rval="DarkGreen"
CASEColor.DarkMagenta
rval="DarkMagenta"
CASEColor.DarkRed
rval="DarkRed"
CASEColor.DarkYellow
rval="DarkYellow"
CASEColor.Gray
rval="Gray"
CASEColor.Green
rval="Green"
CASEColor.LightGray
rval="LightGray"
CASEColor.Magenta
rval="Magenta"
CASEColor.Orange
rval="Orange"
CASEColor.Pink
rval="Pink"
CASEColor.Red
rval="Red"
CASEColor.Transparent
rval="Transparent"
CASEColor.Violet
rval="Violet"
CASEColor.White
rval="White"
CASEColor.Yellow
rval="Yellow"
DEFAULT
rval=Str$(ival)&"anditisnotapredefinedcolorconstant"
ENDSELECT
RETURNrval
END
106
A Beginner's Guide to Gambas
Onceyouhavecompletedthiscode,savethismodulefileandreturnback
to the code window for Form1. We have to modify our code in the
Menu1Item1_Clicksubroutine.Hereisthenewsubroutine:
PUBLICSUBMenu1Item1_Click()
Dialog.Title="Chooseaforegroundcolor"
Dialog.SelectColor
ColorName=Module1.SetColorName(Dialog.Color)
TextLabel1.ForeColor=Dialog.Color
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
WehaveaddedthelineColorName=...buthavenotdeclaredColorName
yet.Thisvariablemustbeglobalbecausewearecallingamoduletoreturnthe
valueColorName. AttheverybeginningoftheForm1.classcodefile,addthis
codejustbeforethePUBLICSUBForm_Open():
'Gambasclassfile
'declareaglobalvariabletobeusedwithourSetColorNamemodule
ColorNameASString
Now,whentheprogramexecutes,thevariablewillbeknown.Inthecodebelow,
thecallto:
ColorName=Module1.SetColorName(Dialog.Color)
anditwillreturnthestringtoourColorNamevariable.Wewanttosetthecolor
oftheforegroundtexttothecolorjustpicked:
TextLabel1.Forecolor=Dialog.Color
Now,wewilltakethestringanddisplayit(formatted,ofcourse)byassigningit
totheTextLabel1.Textproperty.
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
ThefinalversionofourMenu1Item1_Clickroutineshouldlooklikethis:
PUBLICSUBMenu1Item1_Click()
Dialog.Title="Chooseaforegroundcolor"
Dialog.SelectColor
ColorName=Module1.SetColorName(Dialog.Color)
TextLabel1.ForeColor=Dialog.Color
107
A Beginner's Guide to Gambas
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
Wewillwanttodothesamethingforthebackgroundcolor.Thesecond
menuitemintheColorDialogmenuisBackgroundColorsolet'sclickonthat
fromtheIDEandcodethefollowing:
PUBLICSUBMenu1Item2_Click()
Dialog.Title="Chooseabackgroundcolor"
Dialog.SelectColor
ColorName=Module1.SetColorName(Dialog.Color)
TextLabel1.BackColor=Dialog.Color
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
DIMhFontASFont
hFont=NEWFont([FontASString])
Thecodeabovecreatesanewfontobjectfromafontdescription.Thisclass
acts like a readonly array. This code creates a new font object from a font
descriptionandreturnsit:
DIMhFontASFont
hFont=Font[FontASString]
ThepropertiesthatyoucanusewithFontinclude:
Ascent
Bold
Descent
Fixed
Italic
Name
Resolution
Size
StrikeOut
108
A Beginner's Guide to Gambas
Styles
Underline
HereisanexampleofhowtousecodetosettheFontproperties:
Form1.Font.Name="Utopia"
Form1.Font.Bold=TRUE
Form1.Font.Italic=TRUE
Form1.Font.Size="14"
Form1.Font.StrikeOut=FALSE
Form1.Font.Underline=TRUE
The Font class has three Methods you can call: Height, ToString, and
Width.Heightisafunctionthatreturnstheheightofthetextdisplayedwiththe
font.Itisdeclaredas:
FUNCTIONHeight(TextASString)ASInteger
ToStringreturnsthefullnameofafontasadescriptionstring.Thisstringisa
concatenationofallthefontpropertiesseparatedbycommas.Itisdeclaredas:
FUNCTIONToString()ASString
AnexamplecalltoToStringwouldbe:
PRINTApplication.Font.ToString()
WidthisafunctionjustlikeHeightbutitreturnsthewidthofthetextdisplayed
withthefont:
FUNCTIONWidth(TextASString)ASInteger
Now,let'scontinuetoenterourcodeforourMenuProjectprograminthe
PUBLIC SUB Menu1Item3_Click() routine. First, we will declare two local
variables,fontdataandoldfontdata.Wewanttogetthenewfontfromthecallto
the SelectFontDialog,butwealsowanttoretaintheoldfontdataincasewe
need it. Next, we declare two string variables, attr and sel (attribute and
selection)tobeusedtosetthefontattributestring;selectionisaworkstringwe
willbuilddynamically,basedonthevariousselectionstheusercouldmakeinthe
dialog.
PUBLICSUBMenu1Item3_Click()
DIMfontdataASfont
109
A Beginner's Guide to Gambas
DIMoldfontdataASFont
DIMattrASString
DIMselASString
Atthispoint,youmaybeaskingyourselfifyoucouldnotsimplyusethe
ToStringpropertytodothis.Yes,butyouwouldnotlearnasmuch.Bearwith
meandcodealong.Thefollowinglineofcodesimplyblanksoutourattrstring:
attr=""
Now,weassignthecurrentTextLabel1.fontpropertytotheoldfontdatavariable:
oldfontdata=TextLabel1.Font
Next,let'ssetthetitleforthedialogandcalltheSelectFontDialogwiththesetwo
lines:
Dialog.Title="Pickafont..."
Dialog.SelectFont
Whentheuserselectsafontfromthe SelectFontDialog,wewanttoassignthe
fontselectedtothefontdatavariable:
fontdata=Dialog.Font
Atthispoint,wewillchecktoseewhatattributestheuserhaschosenand
dynamically build an output string. We could have built this IF THEN ELSE
statementtocheckeverypropertysupportedbythe Fontclass,butwearenot
interestedinallofthemforthisexercise.
IFfontdata.ItalicTHEN
sel="Italic"
attr=attr&sel
ENDIF
IFfontdata.BoldTHEN
sel="Bold"
attr=attr&sel
ENDIF
IFfontdata.StrikeoutTHEN
sel="Strikeout"
attr=attr&sel
ENDIF
IFfontdata.UnderlineTHEN
sel="Underline"
attr=attr&sel
ENDIF
110
A Beginner's Guide to Gambas
Next,wewillsetthefontintheTextLabel1controltobewhattheuser
selectedanddisplaythedynamicallycreatedstringoffontdatatotheuser:
TextLabel1.Font=fontdata
TextLabel1.Text="Font:"&fontdata.Name&","&Str(Round(fontdata.Size))&attr
Wewillwaitfivesecondstoletthetakealookattheresult,thengivethem
achoiceastowhetherornottheywanttokeepthesesettingsorrevertbackto
theprevioussettings.
WAIT5.0
SELECTMessage.Question("Keepthenewfont?","Yes","No","Don'tknow")
CASE1
TextLabel1.Text="Thisisnowthedefaultfont."
CASE2
TextLabel1.Font=oldfontdata
TextLabel1.Text="Revertedtopreviousfontsetting."
CASE3
TextLabel1.Font=oldfontdata
TextLabel1.Text="Nochangewasmadetodefaultfont."
ENDSELECT
END
Note that we have jumped the gun a bit and introduced the use of
MessageBoxeswithoutexplainingthem. Thatisournexttask,butIwantedto
giveyouapreview. Saveyourprojectandexecuteitatthistime. Yourresults
shouldbesimilartothis,dependingonthecolorsandfontyouselected:
Figure43Selectingcolorsandfonts.
Andifyoudecidetokeepitasthedefault,youwillseesomethinglikethis:
111
A Beginner's Guide to Gambas
Figure44MakinganewdefaultfontfortheTextLabel1control.
Atthispointinyourlearningjourney,youknowhowtodoquiteabitin
Gambas. Wemustcontinuethisjourneybyexpandingourabilitytodealwith
inputandoutputfromtheuser.TheMessageBoxesareanothervaluabletoolin
ourGambasarsenal.Let'sfindoutmoreaboutusingthem.
MessageBoxes
STATICFUNCTIONMessage(MessageASString[,ButtonASString])ASInteger
InformationMessages
TheInfomethodisdeclaredas:
STATICFUNCTIONInfo(MessageASString[,ButtonASString])ASInteger
anditisusedtodisplayaninformationMessageBox,withonlyonebutton.Since
theuserdoesnothavetomakeadecision,theyonlyneedtoacknowledgethe
message.Hence,onlyonebuttonisneeded.Hereiswhatourcodewillproduce:
112
A Beginner's Guide to Gambas
Figure45AnInformationMessageBox.
PUBLICSUBMenu2Item1_Click()
Message.Info("Hereissomeinformationtoconsider.")
END
Prettysimple,eh?Whatifwewantedtotogglethecheckedpropertyvalue
fromTRUEtoFALSEorviceversaeachtimethismenuitemwasselected.Modify
thecodeaboveasfollows:
PUBLICSUBMenu2Item1_Click()
IFMenu2Item1.CheckedTHEN
Menu2Item1.Checked=FALSE
ELSE
Menu2Item1.Checked=TRUE
ENDIF
Message.Info("Hereissomeinformationtoconsider.")
END
Figure46Achecked
menuitem.
113
A Beginner's Guide to Gambas
Query/ConfirmMessages
QuestionandDeletefallintothiscategory.Questionisdefinedas:
STATICFUNCTIONQuestion(MessageASString[,Button1ASString,
Button2ASString,Button3ASString])ASInteger
InvokingitdisplaysaquestionMessageBoxwithuptothreebuttons.Theindex
ofthebuttonclickedbytheuserisreturned.Let'sgobacktoourpreviouscode
andexamineitindetail:
SELECTMessage.Question("Keepthenewfont?","Yes","No","Don'tknow")
CASE1
TextLabel1.Text="Thisisnowthedefaultfont."
CASE2
TextLabel1.Font=oldfontdata
TextLabel1.Text="Revertedtopreviousfontsetting."
CASE3
TextLabel1.Font=oldfontdata
TextLabel1.Text="Nochangewasmadetodefaultfont."
ENDSELECT
Becausetheindexofthebuttonclickedbytheuserisreturned,itiseasiest
toembedthecalltoMessage.QuestioninaSELECT/CASEstatement. SELECT
takestheintegerreturnvalueand,becauseweknowitcanonlybereturnedas
CASE1,2,or3,wewillnotneedtomakeaDEFAULTsection. Wecould,of
course,butitisnotnecessary.Dependingonthevaluereturned,wewilleither
takea Yes action,a No action,ora Don'tknow actionbecausethatiswhatwe
specifiedinourcalltotheDialog(intheSELECTstatementabove).Let'swrite
newcodeforourMessageBoxesMenumenuitemQuestionnow.Chooseitfrom
theformwindowandenterthiscode:
PUBLICSUBMenu2Item3_Click()
SELECTMessage.Question("Didyoulikethis?","Yes","No","Don'tknow")
CASE1
TextLabel1.Text="Likedit."
CASE2
TextLabel1.Text="Didnotlikeit."
CASE3
TextLabel1.Text="Didnotknow."
ENDSELECT
END
114
A Beginner's Guide to Gambas
Whenyouexecutetheprogram,hereiswhatyoushouldsee:
Figure47AQuestionMessageBox.
ErrorMessages
TheErrorfunctiondisplaysanerrorMessageBox,withuptothreebuttons.
Theindexofthebuttonclickedbytheuserisreturned.Errorisdefinedas:
STATICFUNCTIONError(MessageASString[,Btn1ASString,Btn2ASString,Btn3
ASString])ASInteger
GototheformandclicktheErrorMessagesubMenuItemtosetupaclickevent
andenterthiscode:
PUBLICSUBsubMenuItem1_Click()
Message.Error("Wow!Thiswasamistake.")
END
Hereiswhatyoushouldseewhenyouruntheprogram:
Figure48AnErrorMessage.
WarningorAlertMessages
115
A Beginner's Guide to Gambas
declaredas:
STATICFUNCTIONWarning(MessageASString[,Btn1ASString,Btn2AS
String,Btn3ASString])ASInteger
Inourexampleprogram,error,warninganddeletemessagesarepartof
the submenu we created to appear when the menu item Alert Messages is
activated.Tocodethewarningmessage,weneedtosettheclickeventbygoing
tothemenuandclickingontheWarningMessagesubMenuItem.Thiswillputus
inthecodewindowwherewewillenterthiscode:
PUBLICSUBsubMenuItem2_Click()
Message.Warning("Youhavebeenwarnedaboutthis!")
END
Whenyouexecutetheprogram,hereiswhatyoushouldsee:
Figure49AWarningmessage.
DeleteMessages
STATICFUNCTIONDelete(MessageASString[,Btn1ASString,Btn2AS
String,Btn3ASString])ASInteger
SettheclickeventforthesubMenuItemDeleteMessageandenterthiscode:
PUBLICSUBsubMenuItem3_Click()
SELECTMessage.Delete("Delete?","Yes","No","Cancel")
CASE1
TextLabel1.Text="Deletedit"
CASE2
TextLabel1.Text="NotDeleted"
CASE3
TextLabel1.Text="Canceled!"
116
A Beginner's Guide to Gambas
ENDSELECT
END
Whenyouexecutetheprogram,hereiswhatyoushouldsee:
Figure50Deletemessagewiththreebuttons.
DialogClassFilerelatedFunctions
The standard dialogs provided with Gambas also support file operation
suchasopeningafile,savingafile,andchoosingadirectorypath. Theyare
prettystandardbutthegreatadvantageisthatyoudon'thavetobuildthemevery
time you want to write a program. Consistency in user interface is now
demandedfromusersandanythinglessmakesyourprogramlessapproachable
and,resulting,lessacceptedbyusersthanitcouldbe.Thissectionwillshowyou
howeasyitistouseGambasstandarddialogsforfileoperations.
DialogOpenFileFunction
TheOpenFileDialogfunctioncallsthefilestandarddialogtogetthename
ofafiletoopen. ThisfunctionreturnsTRUEiftheuserclickedontheCancel
button,andFALSEiftheuserclickedontheOKbutton.Itisdeclaredasfollows:
STATICFUNCTIONOpenFile()ASBoolean
Fromtheexampleprogramformwindow,clickonthemenuFileDialogs
andselecttheFileopen...menuitem. Thissetsuptheclickeventandwewill
enterthiscode:
PUBLICSUBMenu3Item1_Click()
Dialog.Title="Openfile..."
Dialog.OpenFile
TextLabel1.Text="OPEN:"&Dialog.Path
END
117
A Beginner's Guide to Gambas
Thecodeabovesimplysetsthetitleandcallsthestandarddialog.When
theuserfinishesthestringreturnedfromtheOpenFileDialogfunctionisassigned
totheTextLabel1.Textvariable. Hereiswhatitshouldbringupwhenyourun
thecode:
Figure51TheOpenFileDialog.
Prettyeasystuff.Savingfilesisjustaseasy.
DialogSaveFileFunction
STATICFUNCTIONSaveFile()ASBoolean
CreateaclickeventforourFileSave...menuitemandinthecodewindowenter
thiscode:
PUBLICSUBMenu3Item2_Click()
Dialog.Title="Savefileto..."
Dialog.SaveFile
TextLabel1.Text="SAVE:"&Dialog.Path
END
Hereistheresult:
118
A Beginner's Guide to Gambas
Figure52SaveFileDialog.
DialogSelectDirectoryFunction
TheSelectDirectoryDialogfunctioncallsthefilestandarddialogtogetan
existingdirectoryname.ItreturnsTRUEiftheuserclickedontheCancelbutton,
andFALSEiftheuserclickedontheOKbutton.SelectDirectoryisdeclaredas:
STATICFUNCTIONSelectDirectory()ASBoolean
Thisisthefinalclickeventweneedtocodeforourprogram.Choosethe
SelectDirmenuitemandenterthiscode:
PUBLICSUBMenu3Item3_Click()
Dialog.Title="Pickadir..."
Dialog.SelectDirectory
TextLabel1.Text="SAVEtoDIR:"&Dialog.Path
END
Saveyourprojectandrunthecode.HereiswhatyoushouldseeforSelectDir:
Figure53TheSelectDirectoryDialog.
119
A Beginner's Guide to Gambas
Now we have written all the code needed to finish our MenuProject
program. Save it and execute the program. The next section presents the
completeclassfileforyoutoreview.Itistimeforustomoveontobiggerand
betterthings.Inthenextchapter,wewillstartlearninghowtohandleinputand
outputfromtheuserbyusingstringsandfiles.
CompleteExampleListing
'Gambasclassfile
'declareaglobalvariabletobeusedwithourSetColorNamemodule
ColorNameASString
PUBLICSUBForm_Open()
ME.Caption="WorkingwithMenus"
END
PUBLICSUBQuitBtn_Click()
Form1.Close
END
PUBLICSUBMenu1Item1_Click()
Dialog.Title="Chooseaforegroundcolor"
Dialog.SelectColor
ColorName=Module1.SetColorName(Dialog.Color)
TextLabel1.ForeColor=Dialog.Color
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
PUBLICSUBMenu1Item2_Click()
Dialog.Title="Chooseabackgroundcolor"
Dialog.SelectColor
ColorName=Module1.SetColorName(Dialog.Color)
TextLabel1.BackColor=Dialog.Color
TextLabel1.Text="<b>Colorselectedwas</b>"&ColorName&"."
END
PUBLICSUBMenu1Item3_Click()
DIMfontdataASfont
DIMoldfontdataASFont
DIMattrASString
DIMselASString
attr=""
oldfontdata=TextLabel1.Font
Dialog.Title="Pickafont..."
Dialog.SelectFont
120
A Beginner's Guide to Gambas
fontdata=Dialog.Font
IFfontdata.ItalicTHEN
sel="Italic"
attr=attr&sel
ENDIF
IFfontdata.BoldTHEN
sel="Bold"
attr=attr&sel
ENDIF
IFfontdata.StrikeoutTHEN
sel="Strikeout"
attr=attr&sel
ENDIF
IFfontdata.UnderlineTHEN
sel="Underline"
attr=attr&sel
ENDIF
TextLabel1.Font=fontdata
TextLabel1.Text="Font:"&fontdata.Name&","&Str(Round
(fontdata.Size))&attr
WAIT5.0
SELECTMessage.Question("Keepnewfont?","Yes","No","Don'tknow")
CASE1
TextLabel1.Text="Thisisnowthedefaultfont."
CASE2
TextLabel1.Font=oldfontdata
TextLabel1.Text="Revertedtopreviousfontsetting."
CASE3
TextLabel1.Font=oldfontdata
TextLabel1.Text="Nochangewasmadetodefaultfont."
ENDSELECT
END
PUBLICSUBMenu2Item1_Click()
IFMenu2Item1.CheckedTHEN
Menu2Item1.Checked=FALSE
ELSE
Menu2Item1.Checked=TRUE
ENDIF
Message.Info("Hereissomeinformationtoconsider.")
END
PUBLICSUBsubMenuItem1_Click()
Message.Error("Wow!Thiswasamistake.")
END
PUBLICSUBsubMenuItem2_Click()
121
A Beginner's Guide to Gambas
Message.Warning("Youhavebeenwarnedaboutthis!")
END
PUBLICSUBsubMenuItem3_Click()
SELECTMessage.Delete("Delete?","Yes","No","Cancel")
CASE1
TextLabel1.Text="Deletedit"
CASE2
TextLabel1.Text="NotDeleted"
CASE3
TextLabel1.Text="Cancelled!"
ENDSELECT
END
PUBLICSUBMenu2Item3_Click()
SELECTMessage.Question("Didyoulikethis?","Yes","No","Don'tknow")
CASE1
TextLabel1.Text="Likedit."
CASE2
TextLabel1.Text="Didnotlikeit."
CASE3
TextLabel1.Text="Didnotknow."
ENDSELECT
END
PUBLICSUBMenu3Item1_Click()
Dialog.Title="Openfile..."
Dialog.OpenFile
TextLabel1.Text="OPEN:"&Dialog.Path
END
PUBLICSUBMenu3Item2_Click()
Dialog.Title="Savefileto..."
Dialog.SaveFile
TextLabel1.Text="SAVE:"&Dialog.Path
END
PUBLICSUBMenu3Item3_Click()
Dialog.Title="Pickadir..."
Dialog.SelectDirectory
TextLabel1.Text="SAVEtoDIR:"&Dialog.Path
END
PUBLICSUBMenu4Item1_Click()
Message.Info("Thisisallabout<br><b>GambasProgramming</b>!")
END
122
A Beginner's Guide to Gambas
Module1.modulelisting
'Gambasmodulefile
PUBLICFUNCTIONSetColorName(iValASInteger)ASString
rvalASString
SELECTiVal
CASEColor.Black
rval="Black"
CASEColor.Blue
rval="Blue"
CASEColor.Cyan
rval="Cyan"
CASEColor.DarkBlue
rval="DarkBlue"
CASEColor.DarkCyan
rval="DarkCyan"
CASEColor.DarkGray
rval="DarkGray"
CASEColor.DarkGreen
rval="DarkGreen"
CASEColor.DarkMagenta
rval="DarkMagenta"
CASEColor.DarkRed
rval="DarkRed"
CASEColor.DarkYellow
rval="DarkYellow"
CASEColor.Gray
rval="Gray"
CASEColor.Green
rval="Green"
CASEColor.LightGray
rval="LightGray"
CASEColor.Magenta
rval="Magenta"
CASEColor.Orange
rval="Orange"
CASEColor.Pink
rval="Pink"
CASEColor.Red
rval="Red"
CASEColor.Transparent
rval="Transparent"
CASEColor.Violet
rval="Violet"
CASEColor.White
rval="White"
CASEColor.Yellow
123
A Beginner's Guide to Gambas
rval="Yellow"
DEFAULT
rval=Str$(ival)&"anditisnotapredefinedcolorconstant"
ENDSELECT
RETURNrval
END
124
A Beginner's Guide to Gambas
StringFunctions
InGambas,thereisarichsetofstringfunctions.Wewillusetheconsole
forthischapterandlearnaboutthefollowingfunctions:
Len
Upper$/Ucase$andLower$/LCase$
Trim$/RTrim$andLTrim$
Left$/Mid$/Right$
Space$
Replace$
String$
Subst$
InStr
RInStr
Split
Wewillneedtocreateanewconsoleapplicationtodoourworkinthis
chapter.StartGambasandcreateanewterminalapplicationnamedStringTests.
When the IDE appears, create a new startup class named Class1. The code
windowshouldappearandyoushouldseesomethinglikethis:
'Gambasclassfile
STATICPUBLICSUBMain()
END
Wenowhaveallthepreliminariesoutofthewayandarereadytobegin
125
A Beginner's Guide to Gambas
learningaboutthestringsinGambas.Youmayrememberfromanearlierchapter
thatinGambasastringdatatypeisareferencetoavariablelengthstring.Itis
fourbytesininitialsizeandwhenitiscreateditisinitializedwithaNullvalue.
Len
Lenreturnsthelengthofastring.ThereturnvalueisanInteger.Hereis
howLenwouldbeusedincode:
Length=Len(String)
Fromthecodewindow,let'stypethefollowing:
STATICPUBLICSUBMain()
DIMsStringLengthASInteger
DIMsTestStringASString
sTestString="12345678901234567890"
sStringLength=Len(sTestString)
PRINT"==>"&sStringLength&"isthelengthofourteststring."
sTestString="12345"
sStringLength=Len(sTestString)
PRINT"==>"&sStringLength&"isthelengthofourteststring."
sTestString="12345678901"
sStringLength=Len(sTestString)
PRINT"==>"&sStringLength&"isthelengthofourteststring."
END
Theconsolewillrespondwiththis:
==>20isthelengthofourteststring.
==>5isthelengthofourteststring.
==>11isthelengthofourteststring.
Itisimportanttoknowthatstringlengthbeginscountingatposition1,not
zerolikeinCandsomeotherlanguages. Nowthatwecanfindouthowmany
charactersareinastring,let'slearnhowtoconvertthestringfromonecaseto
another.
Upper$/Ucase$/UcaseandLower$/Lcase$/Lcase
126
A Beginner's Guide to Gambas
synonynmsforUpper$andcanbeusedinterchangeably.Lower$returnsastring
convertedtolowercase.Lcase$andLcasearesynonymsforLower$andcanalso
be used interchangeably. Note that these functions do not work with UTF8
strings.HereisthestandardGambaslanguagesyntaxforusingthesefunctions:
Result=Upper$(String)
Result=UCase$(String)
Typethisinthecodewindowandexecutetheprogram:
STATICPUBLICSUBMain()
DIMsStringLengthASInteger
DIMsTestStringASString
sTestString="abcdefg"
PRINT"==>"&sTestString&"isourstartingstring."
PRINT"==>"&UCase$(sTestString)&"isnowuppercase."
PRINT"==>"&LCase$(sTestString)&"isnowbacktolowercase."
PRINT"==>"&Upper$(sTestString)&"isnowbacktouppercase."
sTestString="123abc456def789ghiZZZ"
PRINT"==>"&sTestString&"isourstartingstring."
PRINT"==>"&UCase(sTestString)&"isnowuppercase."
PRINT"==>"&LCase(sTestString)&"isnowbacktolowercase."
PRINT"==>"&Upper(sTestString)&"isnowbacktouppercase."
PRINT"==>"&Lower$(sTestString)&"isnowbacktolowercase."
END
Theconsolerespondswith:
==>abcdefgisourstartingstring.
==>ABCDEFGisnowuppercase.
==>abcdefgisnowbacktolowercase.
==>ABCDEFGisnowbacktouppercase.
==>123abc456def789ghiZZZisourstartingstring.
==>123ABC456DEF789GHIZZZisnowuppercase.
==>123abc456def789ghizzzisnowbacktolowercase.
==>123ABC456DEF789GHIZZZisnowbacktouppercase.
==>123abc456def789ghizzzisnowbacktolowercase.
Trim$,LTrim$,andRTrim$
Trim$stripsawayallwhitespacesfromeitherendofastring.Itwillnot
127
A Beginner's Guide to Gambas
strip white spaces away after the first nonwhitespace is encountered and
basically ignores all whitespace until the last nonwhitespace character is
encountered,whereuponitwillbegintotrimtrailingwhitespace.Awhitespace
isanycharacterwhoseASCIIcodeisstriclylowerthan32.Trim$isbasicallya
calltoLtrim$andRtrim$simultaneously.Itisusedlikethis:
Result=Trim$(String)
TrythisonyourconsoleseehowtheTrim$functionworks:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
DIMiLengthASInteger
PRINT"12"
PRINT"12345678901234567890"
sTestString="<abcdef"
iLength=Len(sTestString)
PRINTsTestString&">isourstartingstring."
PRINT"Itis"&Str$(iLength)&"characterslong"
sResult=Trim$(sTestString)
PRINTsResult&">istheresultofTrim$call."
END
Theconsolerespondswiththis:
12
12345678901234567890
<abcdef>>isourstartingstring.
Itis14characterslong
<abcdef>istheresultofTrim$call.
Left$,Mid$,andRight$
Result=Left$(String[,Length])
128
A Beginner's Guide to Gambas
position.IfLengthisnotspecified,everythingfromthestartpositionisreturned.
If Length isnegative,everythingfromthestartpositionexceptthe Length last
charactersisreturned.StandardGambaslanguagesyntaxis:
Result=Mid$(String,Start[,Length])
Result=Right$(String[,Length])
Trythisonyourconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
DIMiLengthASInteger
PRINT"12"
PRINT"12345678901234567890"
sTestString="abcdefghi"
iLength=Len(sTestString)
PRINTsTestString&"isourstartingstring."
PRINT"Itis"&Str$(iLength)&"characterslong"
sResult=Left$(sTestString,3)
PRINTsResult&"istheresultofLeft$call."
sResult=Mid$(sTestString,4,3)
PRINTsResult&"istheresultofMid$call."
sResult=Right(sTestString,3)
PRINTsResult&"istheresultofRight$call."
END
Theconsolerespondswiththis;
12
12345678901234567890
abcdefghiisourstartingstring.
Itis9characterslong
abcistheresultofLeft$call.
defistheresultofMid$call.
ghiistheresultofRight$call.
129
A Beginner's Guide to Gambas
Space$
String=Space$(Length)
Trythisontheconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
PRINT"12"
PRINT"12345678901234567890123456"
sTestString="a"
PRINTsTestString&Space$(24)&"z"
END
Replace$
Result=Replace$(String,Pattern,ReplaceString)
Trythisprogramonyourconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
sTestString="abc123ghi"
PRINTsTestString&"isourstartingstring."
sResult=Replace$(sTestString,"123","def")
PRINTsResult&"istheresultofReplacecall."
sTestString="abcdefghi"
PRINTsTestString&"isourstartingstring."
sResult=Replace$(sTestString,"","")
PRINTsResult&"istheresultofReplacecall."
sTestString="\ta\tb\tc\tdef"
130
A Beginner's Guide to Gambas
PRINTsTestString&"isourstartingstring."
sResult=Replace$(sTestString,"\t","")
PRINTsResult&"istheresultofReplacecall."
END
Theconsolerespondswith:
abc123ghiisourstartingstring.
abcdefghiistheresultofReplacecall.
abcdefghiisourstartingstring.
abcdefghiistheresultofReplacecall.
A b c defisourstartingstring.
abcdefistheresultofReplacecall.
String$
String$ simply returns a string containing Length times the Pattern. Use this
format:
String=String$(Length,Pattern)
Trythisontheconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
PRINT"12"
PRINT"12345678901234567890123456"
sTestString="a"
PRINTsTestString&String(24,".")&"z"
END
Theconsolerespondswith:
12
12345678901234567890123456
a........................z
Subst$
Subst$replacesarguments&1,&2,etc.inapatternwiththefirst,second,
andsubsequentReplaceStringsrespectively,andreturntheresult. IfPatternis
null, then a null string is returned. For C developers, this is not unlike a
131
A Beginner's Guide to Gambas
simplifiedsprintf.Thisfunctionisveryusefulwhenyoumustconcatenatestrings
thatmustbetranslated.Donotusethe&operator,astheorderofconcatenation
mightchangewiththelanguage.StandardGambaslanguagesyntaxis:
Result=Subst(Pattern,ReplaceString[,ReplaceString])
Trythislittleapplicationonyourconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
sTestString="abcdef"
sResult="ghijkl"
PRINT"Ourstartstringis:"&sTestString
PRINTSubst$("OurSubststringis:&1",sResult)
END
Theconsolerespondswith:
Ourstartstringis:abcdef
OurSubststringis:ghijkl
InStr
InStrreturnsthepositionofthefirstoccurrenceofSubstringinString.If
Startisspecified,thesearchbeginsatthepositionStart. Ifthesubstringisnot
found,InStr()returnszero.
Position=InStr(String,Substring[,Start])
Thefollowingcodeisabitmoreinvolvedandwilldemonstratethepower
ofthisfunction.Wewanttofindeveryspace(setinthestringatevennumbered
positions)andprintoutthepositionwhereeachspaceoccurs.Enterthiscodein
theconsolecodewindow:
'Gambasclassfile
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMsResultASString
DIMiLengthASInteger
DIMiPositionASInteger
DIMiNextCharPosASInteger
132
A Beginner's Guide to Gambas
DIMiCounterASInteger
sTestString="abcdefghi"
iPosition=Instr(sTestString,"")
PRINTsTestString&"isourstartstring."
PRINT"Firstspaceisatposition:"&iPosition
iNextCharPos=iPosition+1
iPosition=Instr(sTestString,"",iNextCharPos)
PRINT"Nextspaceisatposition:"&iPosition
PRINT
sTestString="abcdefghijklmnopqrstuvwxyz"
PRINT"123456"
PRINT"123456789012345678901234567890123456789012345678901234567890"
PRINTsTestString&"isournewteststring."
PRINT
iLength=Len(sTestString)
PRINT"LengthofsTestStringis:"&iLength
iPosition=Instr(sTestString,"")
PRINT"Firstspaceisatposition:"&iPosition
FORiCounter=iPositionTOiLength/2
iNextCharPos=iPosition+1
iPosition=Instr(sTestString,"",iNextCharPos)
PRINT"Nextspaceisatposition:"&iPosition
NEXT
END
Theresultingoutputis:
abcdefghiisourstartstring.
Firstspaceisatposition:4
Nextspaceisatposition:8
123456
123456789012345678901234567890123456789012345678901234567890
abcdefghijklmnopqrstuvwxyzisournewtest
string.
LengthofsTestStringis:51
Firstspaceisatposition:2
Nextspaceisatposition:4
Nextspaceisatposition:6
.
.
Nextspaceisatposition:46
Nextspaceisatposition:48
Nextspaceisatposition:50
133
A Beginner's Guide to Gambas
RInStr
RInStrreturnsthepositionofthelastoccurrenceofSubstringinString.If
Startisspecified,thesearchstopsatthepositionStart. Ifthesubstringisnot
found,RInStr()returnszero.StandardGambaslanguagesyntaxis:
Position=RInStr(String,Substring[,Start])
Enterthiscodeintheconsole:
STATICPUBLICSUBMain()
DIMsTestStringASString
DIMiPositionASInteger
sTestString="abcdefabcdefabc"
PRINT"12"
PRINT"12345678901234567890"
PRINTsTestString
iPosition=RInstr(sTestString,"abc")
PRINT
PRINT"lastoccurrenceofabcstartsatposition:"&iPosition
END
Theconsolerespondswith:
12
12345678901234567890
abcdefabcdefabc
lastoccurrenceofabcstartsatposition:17
Split
Splitsplitsastringintosubstringsdelimitedbytheseparator(s)designated
asparameters.Escapecharacterscanbespecifiedalso.Anyseparatorcharacters
enclosedbetweentwoescapecharactersareignoredinthesplittingprocess.Note
thatSplittakes onlythreeargumentssoifyouwanttouseseveralseparators,
youshouldpassthemasthesecondparameter,concatenatedinasinglestring.
By default, the comma character is the separator, and there are no escape
characters. This function returns a string array filled with each detected
substring.TheGambaslanguagesyntaxis:
134
A Beginner's Guide to Gambas
Array=Split(String[,Separators,Escape])
Hereisaprogramtotryonyourconsole:
STATICPUBLICSUBMain()
DIMaWordArrayASString[]
DIMsWordASString
'noteweuseaspacedelimiter
aWordArray=Split("ThisisindeedaverycoolfeatureofGambas!","")
FOREACHsWordINaWordArray
PRINTsWord
NEXT
END
Theconsolerespondswith:
This
is
indeed
a
very
cool
feature
of
Gambas!
ConvertingDatatypes
AscandChr$
AscreturnstheASCIIcodeofthecharacteratpositionPositionintheString
.IfPositionisnotspecified,theASCIIcodeofthefirstcharacterisreturned.Chr$
returnsthecharacterwhoseASCIIcodeisCode.Awordofcaution:Gambasuses
the UTF8 charset internally, soany charactercode greaterthan 128 maynot
havethesamemeaningastheywouldhavewithanothercharset(forexample,
ISO88591).HereistheGambaslanguagesyntax:
Code=Asc(String[,Position])
Character=Chr$(Code)
HereisasampleprogramthatillustratestheuseofbothASCandCHR$:
'Gambasclassfile
135
A Beginner's Guide to Gambas
STATICPUBLICSUBMain()
DIMiAsciiCodeASInteger
DIMsTestStringASString
DIMiLengthASInteger
DIMcounterASInteger
sTestString="Gambasisgreat."
iLength=Len(sTestString)
PRINT"LengthofsTestStringis:"&Str$(iLength)
FORcounter=1TOiLength
iAsciiCode=Asc(sTestString,counter)
IFiAsciiCode<>32THEN
PRINTiAsciiCode&"ischar:"&Chr(9)&Chr$(iAsciiCode)
ELSE
PRINTiAsciiCode&"ischar:"&Chr(9)&"<space>"
ENDIF
NEXT
END
Inthecodeabove,Chr(9)isusedtorepresenttheTABcharacter.Theresulting
outputfromtheconsoleis:
LengthofsTestStringis:16
71ischar: G
97ischar: a
109ischar: m
98ischar: b
97ischar: a
115ischar: s
32ischar: <space>
105ischar: i
115ischar: s
32ischar: <space>
103ischar: g
114ischar: r
101ischar: e
97ischar: a
116ischar: t
46ischar: .
Bin$
String=Bin$(Number[,Digits])
136
A Beginner's Guide to Gambas
Examplecodeyoucantryontheconsole:
STATICPUBLICSUBMain()
DIMsBinaryCodeASString
DIMcounterASInteger
FORcounter=0TO15
sBinaryCode=Bin$(counter,4)
PRINTsBinaryCode
NEXT
END
Theoutputshouldlooklikethis:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
CBool
CBoolconvertsanexpressionintoaBooleanvalue.Anexpressionisfalseif
anyofthefollowingconditionsaremet:
AfalseBooleanvalue
Azeronumber
Azerolengthstring
Anullobject
Otherwise,theexpressionistrueinallothercases.HereistheGambaslanguage
syntax:
137
A Beginner's Guide to Gambas
Boolean=CBool(Expression)
Hereisanexample:
STATICPUBLICSUBMain()
PRINTCBool(0);"";CBool(1)
END
Theconsolerespondswith:
FALSETRUE
CByte
CByteconvertsanexpressionintoabyte.Expressionisfirstconvertedinto
aninteger.Then,ifthisintegeroverflowsthebyterange,(32767to32768)itis
truncated.
Byte=CByte(Expression)
Example:
STATICPUBLICSUBMain()
PRINTCByte("17")
PRINTCByte(32769)
PRINTCByte(TRUE)
END
Theconsolerespondswith:
17
1
255
CDate
Date=CDate(Expression)
Example:
STATICPUBLICSUBMain()
138
A Beginner's Guide to Gambas
DIMsDateStringASString
sDateString=CDate(Now)
PRINTsDateString;"isourstarttime."
WAIT1.0
PRINTCDate(Now);"isonesecondlater."
PRINTCDate(sDateString);"isstillwherewestarted."
WAIT1.0
PRINTNow;"isonesecondlater."
END
Theconsolerespondswith:
08/21/200520:52:40isourstarttime.
08/21/200520:52:41isonesecondlater.
08/21/200520:52:40isstillwherewestarted.
08/21/200520:52:42isonesecondlater.
CFloat
CFloatconvertsanexpressionintoafloatingpointnumber. Becareful!
Thecurrent localization isNOTusedbythisfunction. Gambaslanguagesyntax
is:
Float=CFloat(Expression)
Example:
STATICPUBLICSUBMain()
DIMsFloatStringASString
DIMfFloatNumASFloat
sFloatString="0.99"
fFloatNum=0.01
PRINTfFloatNum+CFloat(sFloatString)
PRINTCFloat("3.0E+3")
END
Theconsolerespondswith:
1
3000
139
A Beginner's Guide to Gambas
CInt/CintegerandCShort
CIntissynonymouswithCInteger.Eithercallconvertsanexpressioninto
aninteger.ThestandardGambaslanguagesyntaxis:
Integer=CInt(Expression)
Integer=CInteger(Expression)
Short=CShort(Expression)
Hereisanexamplethatslightlymodifiesthepreviousconsoleexampleto
showbothofthesefunctions:
STATICPUBLICSUBMain()
DIMsFloatStringASString
DIMfFloatNumASFloat
sFloatString="0.99"
fFloatNum=120.901
PRINTfFloatNum+CFloat(sFloatString)
PRINTCInt(fFloatNum);"wasafloat,nowanint."
PRINTCShort(fFloatNum);"wasafloat,nowashort."
END
Theresultis:
121.891
120wasafloat,nowanint.
120wasafloat,nowashort.
CStr/CString
CStr/CStringconvertsanexpressionintoastring.Becareful!Thecurrent
localization is NOTused by this function. Here is howthe Gambas language
syntaxforCStrworks:
String=CStr(Expression)
String=CString(Expression)
140
A Beginner's Guide to Gambas
Example:
STATICPUBLICSUBMain()
DIMsFloatStringASString
DIMfFloatNumASFloat
fFloatNum=120.901
sFloatString=CStr(fFloatNum)
PRINTsFloatString;"isnowastring."
END
Consoleoutputis:
120.901isnowastring.
Hex$
Hex$returnsthehexadecimalrepresentationofanumber.IfDigitsisspecified,
the representation is padded with unnecessary zeros so that Digits digits are
returned.HereistheGambaslanguagesyntax:
String=Hex$(Number[,Digits])
Hereisanexampleprogram:
STATICPUBLICSUBMain()
DIMcounterASInteger
FORcounter=1TO15
PRINTHex$(counter,2);"";
NEXT
END
Thisistheresult:
0102030405060708090A0B0C0D0E0F
Conv$
141
A Beginner's Guide to Gambas
system,butitisUTF8onaRedHatLinuxoperatingsystem.Inthefuture,nearly
allLinuxsystemswillprobablybeUTF8based.Thecharsetusedbythegraphical
userinterfaceisreturnedbyacallto Desktop.Charset.ItisUTF8withthe Qt
component.TheGambaslanguagesyntaxis:
ConvertedString=Conv$(StringASString,SourceCharsetASString,
DestinationCharsetASString)
Theconversionreliesontheiconv()GNUlibraryfunction.Hereisacode
exampletotry:
STATICPUBLICSUBMain()
DIMsStrASString
DIMiIndASInteger
sStr=Conv$("Gambas","ASCII","EBCDICUS")
FORiInd=1TOLen(sStr)
PRINTHex$(Asc(Mid$(sStr,iInd,1)),2);"";
NEXT
END
Hereistheoutput:
C781948281A2
ValandStr$
ValconvertsastringintoaBoolean,anumberoradate,accordingtothe
contentofthestring. Thecurrent localization isusedtoconvertnumbersand
dates.Theconversionalgorithmusesthefollowingorderofprecedence:
Ifstringcanbeinterpretedasadate&time(withdateortime
separators),thenthedate&timeisreturned.
Elseifstringcanbeinterpretedasafloatingpointnumber,then
afloatingpointnumberisreturned.
Elseifstringcanbeinterpretedasaintegernumber,thenan
integernumberisreturned.
ElseifstringisTRUEorFALSE,thematchingBooleanvalueis
returned.
ElseNULLisreturned.
StandardGambaslanguagesyntaxis:
Expression=Val(String)
142
A Beginner's Guide to Gambas
Str$convertsanexpressionintoitsprintablestringrepresentation.Itisthe
exactcontraryofVal().Thecurrentlocalizationisusedtoconvertnumbersand
dates.Gambaslanguagesyntaxis:
String=Str$(Expression)
Trythis:
STATICPUBLICSUBMain()
DIMsDateTimeASString
DIMdDateASDate
PRINTNow;"iscurrentsystemtime."
sDateTime=Val(Str$(Now))
PRINTsDateTime;"isastringrepresentationofcurrentsystemtime."
PRINTVal(sDateTime);"isVALconvofthestringrepresentation."
dDate=Val(sDateTime)
PRINTdDate;"istheDATEvariableconvertedwithVAL."
PRINTStr(dDate);"isastringrepresentationofthedatevariable."
END
Hereistheoutput:
08/21/200521:42:45iscurrentsystemtime.
08/21/200521:42:45isastringrepresentationofcurrentsystemtime.
08/21/200521:42:45isVALconvofthestringrepresentation.
08/21/200521:42:45istheDATEvariableconvertedwithVAL.
08/21/200521:42:45isastringrepresentationofthedatevariable.
Hereisanothersampleprogramtotry:
'Gambasclassfile
STATICPUBLICSUBMain()
DIMsInputLineASString
DIMvalueASVariant
DOWHILEsInputLine<>"quit"
PRINT"==>";
LINEINPUTsInputLine
IFsInputLine=""THEN
sInputLine="<CRLF>"
ENDIF
143
A Beginner's Guide to Gambas
PRINT"Youtyped:";sInputLine
value=Val(sInputLine)
PRINT
IFIsBoolean(value)THEN
PRINTsInputLine;"isBoolean."
ELSEIFIsDate(value)THEN
PRINTsInputLine;"isadate."
ELSEIFIsInteger(value)THEN
PRINTsInputLine;"isanInteger."
IFvalue=0ORvalue=1THEN
PRINT"ItcouldalsobeBoolean."
ENDIF
IFvalue>0ANDvalue<255THEN
PRINT"ItcouldalsobeaByte."
ENDIF
IFvalue>32767ANDvalue<32768THEN
PRINT"Itcouldalsobeashort."
ENDIF
PRINT""
ELSEIFIsFloat(value)THEN
PRINTsInputLine;"isafloat."
ELSEIFIsString(value)THEN
PRINTsInputLine;"isastring."
ELSEIFIsNull(value)THEN
PRINTsInputLine;"isNULL."
ELSE
PRINTsInputLine;"issomethingelse."
ENDIF
LOOP
PRINT
PRINT"Wearedone!"
END
Theoutputshouldbesimilartothis:
==>true
Youtyped:true
trueisBoolean.
==>214
Youtyped:214
214isanInteger.
ItcouldalsobeaByte.
Itcouldalsobeashort.
==>08/23/0512:23:55
Youtyped:08/23/0512:23:55
144
A Beginner's Guide to Gambas
08/23/0512:23:55isadate.
==>John
Youtyped:John
Johnisastring.
==>32756
Youtyped:32756
32756isanInteger.
Itcouldalsobeashort.
==>quit
Youtyped:quit
quitisastring.
Wearedone!
Format$
Format$convertsanexpressiontoastringbyusingaformatthatdepends
onthetypeof theexpression.Formatcan bea predefined format(an integer
constant)orauserdefinedformat(astringthatdepictstheformat).IfFormatis
not specified, gb.Standard component formats are used. This function uses
localization information to format dates, times and numbers. The Gambas
languagesyntaxis:
String=Format$(Expression[,Format])
Auserdefinednumberformatisdescribedbythefollowingcharacters:
FormatSymbol Meaning
"+" printsthesignofthenumber.
"" printsthesignofthenumberonlyifitisnegative.
"#" printsadigitonlyifnecessary.
"0" alwaysprintsadigit,paddingwithazeroifnecessary.
"." printsthedecimalseparator.
"%" multipliesthenumberby100andprintsapercentsign.
"E" introduces theexponential part of afloat number. The sign of the exponentis always
printed.
145
A Beginner's Guide to Gambas
Auserdefineddateformatisdescribedbythefollowingcharacters:
FormatSymbol Meaning
"yy" printsyearusingtwodigits.
"yyyy" printsyearusingfourdigits.
"m" printsmonth.
"mm" printsmonthusingtwodigits.
"mmm" printsmonthinanabbreviatedstringform.
"mmmm" printsmonthinit'sfullstringform.
"d" printsday.
"dd" printsdayusingtwodigits.
"ddd" printsweekdayinanabbreviatedform.
"dddd" printsweekdayinitsfullform.
"/" printsdateseparator.
"h" printshour.
"hh" printshourusingtwodigits.
"n" printsminutes.
"nn" printsminutesusingtwodigits.
"s" printsseconds.
"ss" printssecondsusingtwodigits.
":" Printsatimeseparator.
Hereisaprogramthatdemonstratesseveralexamples:
STATICPUBLICSUBMain()
PRINT""
PRINT"UserdefinednumericFormatexamples:"
PRINTFormat$(Pi,"#.###")
PRINTFormat$(Pi,"+0#.###0")
PRINTFormat$(Pi/10,"###.#%")
PRINTFormat$(11^11,"#.##E##")
PRINT""
PRINT"Userdefineddateandtimeformatexamples:"
PRINT
PRINTFormat$(Now,"mm/dd/yyyyhh:nn:ss")
PRINTFormat$(Now,"m/d/yyh:n:s")
PRINTFormat$(Now,"dddddmmmyyyy")
PRINTFormat$(Now,"ddddddmmmmyyyy")
END
146
A Beginner's Guide to Gambas
Hereistheoutput:
UserdefinednumericFormatexamples:
3.142
+03.1416
31.4%
2.85E+11
Userdefineddateandtimeformatexamples:
08/21/200521:55:14
8/21/0521:55:14
Sun21Aug2005
Sunday21August2005
Datatypemanagement
Manytimeswhencheckingvariables,itisimportanttoknowwhatdata
typeyouaredealingwith.Gambasprovidesahostoffunctionsforthatpurpose.
Youcancheckforthefollowingdatatypes:
IsBoolean/Boolean? IsByte/Byte?
IsDate/Date? IsFloat/Float?
IsInteger/Integer? IsNull/Null?
IsNumber/Number? IsObject/Object?
IsShort/Short? IsString/String?
Each of the functions above are called using the standard Gambas language
syntaxof
BooleanResult=IsBoolean?(Expression)
BooleanResult=IsByte?(Expression)
BooleanResult=IsDate?(Expression)
BooleanResult=IsFloat?(Expression)
BooleanResult=IsInteger?(Expression)
BooleanResult=IsNull?(Expression)
BooleanResult=IsNumber?(Expression)
BooleanResult=IsObject?(Expression)
BooleanResult=IsShort?(Expression)
BooleanResult=IsString?(Expression)
and the given function will return TRUE if an expression is of the datatype
queriedorFALSEifitisnot.
147
A Beginner's Guide to Gambas
TypeOf
TypeOfreturnsthetypeofanexpressionasanintegervalue.Gambashas
definedseveralpredefinedconstantsforthedatatypesreturnedbythisfunction.
The predefinedconstants Gambassupportsareshowninthetablebelow. The
standardGambaslanguagesyntaxforthisfunctionis:
Type=TypeOf(Expression)
That'saboutallwewillcoverinthischapter.Inthenextchapter,wewill
return to the Gambas ToolBox and start learning to use some of the more
advancedcontrols,suchasiconview,listview,etc.Youshouldnowbeadequately
preparedtodealwithmoreadvanceddatahandlingtechniquesrequiredforthose
controls.
148
A Beginner's Guide to Gambas
IconViewControl
Firstofall,startGambasandselecttheExplorerprojectfromtheMiscellaneous
sectionoftheExampleprograms:
Figure54ChoosingtheExplorerexample.
Once youselecttheExplorerproject,theIDEwillopenupandwewill
needtogettothecode.Youcandothisbydoubleclickingontheclassfileorif
theformisalreadyup,doubleclickonacontrolandthenmovetothetopofthe
149
A Beginner's Guide to Gambas
codewindow. Eitherwaywillworkaslongasyoustartatthetopofthecode
windowwhereyouseethefirstline:
'Gambasclassfile
Thefirstthingweseedoneinthiscodeisthedeclarationoftheprogram's
globalvariables.Notethattheyareprefixedwitha'$'characterforclarity.The
$sPathvariableisdeclaredasPRIVATEandusedtoholdthenameofthecurrent
filepath.
PRIVATE$sPathASString
$bHiddenisaPRIVATEBooleanvariablethatwillactasaflagtobeusedto
determineIFafileishiddenornot. Wewillusethe Stat function tocheckits
status.
PRIVATE$bHiddenASBoolean
$bCtrlisaPRIVATEBooleanusedasaflagwhenaCTRLkeyispressed.If
theuserholdsdowntheCTRLkeywhendoubleclickingonafolderitwillopen
upinanewwindow.
PRIVATE$bCtrlASBoolean
ThisisthefirstsubroutineGambaswillexecutewhentheprogramisrun:
STATICPUBLICSUBMain()
Thenexttwolineswilldeclarealocalvariablefortheformwewantto
displaytotheuserandcreateaninstanceoftheformnamed FExplorer,passing
theparameterSystem.Hometoaconstructorroutine,whichisidentifiedas_new
()),andwhichtakesastringparametersPath(System.Home)thevalueofwhich
weobtainedfromtheSystemclass.
DIMhFormASForm
hForm=NEWFExplorer(System.Home)
Now,showtheform:
hForm.Show
END
150
A Beginner's Guide to Gambas
ThisnextsubroutineistheconstructorthatiscalledwhentheMain()subroutine
isactivatedandtheFExplorerformisinstantiated:
PUBLICSUB_new(sPathASString)
Wewillassignthepathpassedin(System.Home)asaparametertoourglobal
variable$sPath:
$sPath=sPath
RefreshExplorer
END
HereistheRefreshExplorer()subroutine.Itisessentiallythemeatofthe
program:
PRIVATESUBRefreshExplorer()
First, we declare the local variables. Let's start with a string var to hold file
names:
DIMsFileASString
Next,declarepicturevariablesforouriconimages:parentdirectory,folderand
file:
DIMhPictDirASPicture
DIMhPictParDirASPicture'addedbytheauthor
DIMhPictFileASPicture
cDirisanarrayofstrings(representingthenamesoffilesordirectories):
DIMcDirASNEWString[]
sNameisaworkstringusedtorepresentfilenamesfoundinadirectory:
DIMsNameASString
151
A Beginner's Guide to Gambas
seemstobeusedasasemaphoresootherprocessescantesttheflagbeforetrying
to get computer time (remember, most applications use some sort of OS
implementedroundrobinCPUschedulingroutinetoshareprocessorresources).
Here,itisbasicallyaflagthattellsalltheothercallingprocessesthattheyhaveto
waituntiluntilthisprocessisnotbusyanymore(indicatedbydecrementingthe
valueoftheBusyproperty).ThisseemstobehowGambassetsflagstoprevent
criticalprocessesfrombeinginterrupted.
INCApplication.Busy
Oncethedon'tinterruptmeflagisthrown,wesetthewindowtitletothe
systempathandcallthebuiltinConv$14 functiontoconvertthesystemcharset
(thesetofcharacterstheoperatingsystemhasprovidedasdefault)towhattheuser
hasdefinedasthedesktopcharset(thesetofcharacterstheuserhaschosentosee
fromtheirdesktop). Notethat Conv isasynonymfor Conv$ andyoucanuse
eitheroneinterchangably.
ME.Title=Conv($sPath,System.Charset,Desktop.Charset)
Now, whatever may exist in the icon view is wiped out by calling the
iconview'sClearmethod:
ivwExplorer.Clear
Next,assigniconstothepicturevariableswedeclared.Wehaveaniconto
representfoldersandoneforfiles:
hPictDir=Picture["folder.png"]
hPictParDir=Picture["ParentFolder.png"]'addedbytheauthor
hPictFile=Picture["file.png"]
Iftheglobalpathvariableisnotsettothehighestlevel(i.e.,theparent)
indicatedbythe"/"string,thenwewanttocreateafolderthattheusercanclick
togototheparentdirectoryofthecurrentchild. Weaddthisfolderthethe
iconviewcontrolnamedivwExplorerbyusingitsAddmethod:
IF$sPath<>"/"THENivwExplorer.Add("D..","..",hPictParDir)
Inthestatementabove,the.Addmethodtakesthreeparameters.Thefirst
isthenameofthekey,inthiscaseD..whichisourkeyfordirectories. The
secondisthetextplacedbelowtheiconintheIconViewcontrol,andthefinal
14 Common string functions do not deal with UTF-8 very well. In UTF-8, a character can have 1-3 bytes. The Gambas String
class methods are able to handle UTF-8 so they should be used whenever possible.
152
A Beginner's Guide to Gambas
parameteristhenameofthevariablethatisahandletothefilenameoftheicon
wewanttodisplaywiththisentry.Now,wewillbegintoloopthrougheveryfile
inthecurrentdirectorytoseeifitisahiddenfileornotandtotageachfilename
aseitheradirectoryorafile.
FOREACHsFileINDir($sPath)
Gambasinitializesstringstonullwhencreated,sotheveryfirsttimewe
comehere,the$bHiddenvaluewillnotbeTRUEandtheIFstatementwillbe
executedinthecodebelow:
IFNOT$bHiddenTHEN
Thisnextlineofcodeisalittletrickertodecipher.TheStatfunctiontakes
afilenamestringasitsparameter. Inthiscase,thecurrentpathheldinglobal
variable $sPath is catenated with the work string sFile using the &/ symbol
combination. ThisisaspecialcatenationsymbolusedinGambasspecificallyto
catenate filenames. The Stat function is called with the catenated filename
passedasaparameterandsimultaneouslythe Stat.Hidden propertyischecked.
Ifthe Stat.Hidden propertyis set to aTRUE value,the CONTINUE statement
executes,forcingprogramflowtothenextiterationoftheFORloop.Thiswhole
processbasicallyforcestheprogramtoignoreanyhiddenfilesitencounters.
IFStat($sPath&/sFile).HiddenTHEN'isithidden?
CONTINUE'ifso,gotonextloopiteration
ENDIF'IFStat
ENDIF'IFNOT$bHidden
Ifwereachedthispointinthecode,thefilewasnothidden.Now,wewill
usethebuiltinfilemanagementfunctionIsDirtoseeifthecurrentpathandfile
string(catenatedintheStatcall)isafolderorafile.Ifwehaveafolder,wewill
addittothecDirstringarray,firsttaggingitwithaletter'D'fordirectoryor'F'for
fileandthenappendingthefilenameheldintheworkstringsFiletothe'D'or'F'
tag:
IFIsDir($sPath&/sFile)THEN'itwasadirectory
cDir.Add("D"&sFile)'weaddittothedirectorieskey
ELSE'notadirectoryandweaddittothe"F"keyasafile
cDir.Add("F"&sFile)
ENDIF
NEXT'thisistheendoftheFORloop...
OnceeverythingisloadedinthecDirarraywiththeFOR/NEXTloopwe
callthebuiltinSortmethodandsortthearrayofstrings:
153
A Beginner's Guide to Gambas
cDir.Sort
NowthatthecDirarrayissorted,wewillloopthroughthearrayusingthe
FOREACHstatementwhichisusedspecificallyforenumeratedobjectsinarrays
orcollections.
FOREACHsFileINcDir
sName=Mid$(sFile,2)
Now,wecheckthetagofthefilenameusingthestringfunctionLeft$:
IFLeft$(sFile)="D"THEN
ivwExplorer.Add(sFile,sName,hPictDir)
ELSE'otherwiseitwasafileandweadditwithafileicon
ivwExplorer.Add(sFile,sName,hPictFile)
ENDIF
WealsowanttosettheIconView .EditpropertytoTRUEsotheusercan
renameitems:
ivwExplorer.Item.Editable=TRUE
NEXT'exittheFOREACHLoop
Thestatementsbelowwerecommentedoutbutappeartohavebeenused
toalterthesortorderofthe IconViewcontrol. Wewillsimplyskipoverthese
commentsandgototheFINALLYstatement:
'ivwExplorer.Sorted=FALSE
'ivwExplorer.Ascending=TRUE
'ivwExplorer.Sorted=TRUE
FINALLY'thisisthelastinstructiontoexecuteinthesubroutine
154
A Beginner's Guide to Gambas
ThelastthingweneedtodoissettheApplication.busyflagbacktonormalstate:
DECApplication.busy
Ifanerroroccurs,wewillcatchitwiththecatchclausebelow:
CATCH
Ifanyerroroccurs,itshouldpopupaMessageBoxwiththeerrortextdisplayed:
Message.Error(Error.Text)
END'ofourRefreshExplorerroutine
ThissubroutineiscallediftheFExplorerformisresizedgeneratingaresize
event.ItwillmoveourIconViewcontroltothetopleftcornerandadjustwidth
andheighttoaccommodatethenewsizeofthewindow:
PUBLICSUBForm_Resize()
ivwExplorer.Move(0,0,ME.ClientW,ME.ClientH)
END
Iftheuserchoosesthequitoptionfromthemenu,thenthisroutineexecutes:
PUBLICSUBmnuQuit_Click()
ME.Close
END
If the user selects the Refresh option, we will call the RefreshExplorer
subroutinedescribedpreviously.
PUBLICSUBmnuViewRefresh_Click()
RefreshExplorer
END
Thissubroutineiscalledwhentheactivateeventistriggeredbyauserby
doubleclickingonafolderintheIconViewcontrol:
PUBLICSUBivwExplorer_Activate()
Asalways,wemustdeclareourlocalvariables.WedeclaresNewPathasa
stringtoholdthefilepathforthetargetpaththeuserclicked(eitheranewfolder
ortherootfolder).Also,wedeclareanewformtoshowthedestinationcontents,
hForminaseparatewindowifthecontrolkeyispressedwhenthedestinationis
155
A Beginner's Guide to Gambas
selected.
DIMsNewPathASString
DIMhFormASForm
Thisifchecklooksatthetagweputonthestringtoseeifthedestinationis
adirectoryortherootlevelofthesystem. Ifweareattherootlevel,thenwe
simplyreturn.Otherwise,thecodewillassignthecatenatedvaluesof$sPathand
thevalueheldbytheLAST.Current.KeyoftheIconViewcontrol.Thisisobtained
withtheMid$callstartingatposition2(tobypassourtagcharacter).
IFLAST.Current.Key="D.."THEN
IF$sPath="/"THENRETURN
sNewPath=File.Dir($sPath)
ELSE
sNewPath=$sPath&/Mid$(LAST.Current.Key,2)
ENDIF
Wecheckthenewlyassignedstringvaluedatatypetoensureitis,infact,
adirectoryand,ifitis,wewillsubsequentlychecktoseeiftheuserhelddown
thecontrolkey. Remember,holdingdownthecontrolkeyinourprogramwill
activateanewwindow,whichiswhywedeclaredthelocalhFormvariable.
IFIsDir(sNewPath)THEN
Ifthecontrolkeywashelddown,wewilltogglethevaluebacktoFALSE
beforeinstantiatinganewwindow.Then,wewillmoveourcontroltobeoffset
16pixelsrightandbelowthecurrentwindow,havingthesameheightandwidth
using the hForm.Move method. Finally, we show the form and refresh the
ExplorerwithourRefreshExplorersubroutine.
IF$bCtrlTHEN
$bCtrl=FALSE
hForm=NEWFExplorer(sNewPath)
hForm.Move(ME.X+16,ME.Y+16,ME.W,ME.H)
hForm.Show
ELSE
Othewise, the control key was not held down so we simply assign the
sNewPathvaluetotheglobal$sPathandrefreshtheexplorer:
$sPath=sNewPath
RefreshExplorer
ENDIF
ENDIF
156
A Beginner's Guide to Gambas
END
When the user clicks this routine, it calls our subroutine to show the
hiddenfilesor,iftheyareshowing,turnoffviewingofhiddenfiles:
PUBLICSUBmnuViewHidden_Click()
ToggleViewHidden
END
Iftheuserchoosestoshowhiddenfilesintheexplorerbyselectingthe
ShowHiddenFilesoption,thenthisnextroutineisexecuted.Thefirstlinechecks
the value of the mnuViewHidden.Checked property and toggles the value by
essentially making $bHidden become whatever the logical NOT value of
mnuViewHidden.Checked is at the moment it is checked. It then assigns the
oppositevaluetothepropertyandrefreshestheviewbycallingRefreshExplorer.
Theresultisthatthehiddenfilesareshown.
PRIVATESUBToggleViewHidden()
$bHidden=NOTmnuViewHidden.Checked
mnuViewHidden.Checked=$bHidden
RefreshExplorer
END
PUBLICSUBmnuAbout_Click()
Message("IconViewexamplewrittenby\nBenotMinisini")
END
Thenextsubroutineisexecutedwhentheusersingleclicksonanitemin
theexplorerandoptstorenametheitem.Asitwasoriginallywritten,itdoesnot
checktoseeiftherenameactuallychangedtheitem. Forexample,iftheuser
pressedESC,theitemwouldreverttoitsoriginalname.
PUBLICSUBivwExplorer_Rename()
Message("'"&Mid$(LAST.Item.Key,2)&
"'hasbeenrenamedto'"&LAST.Item.Text&"'")
END
157
A Beginner's Guide to Gambas
Wecanremedythisoversightbysimplychangingthecodetoreadlikethis:
PUBLICSUBivwExplorer_Rename()
IFMid$(LAST.Item.Key,2)<>Last.Item.TextTHEN
Message("'"&Mid$(LAST.Item.Key,2)&
"'hasbeenrenamedto'"&LAST.Item.Text&"'")
ELSE
Message('&Mid$(LAST.Item.Key,2)&'wasleftunchanged.')
ENDIF
END
Thefinaltwosubroutinestoggletheglobalvariable$bCtrlwheneverthe
controlkeyispressedorreleased.
PUBLICSUBivwExplorer_KeyPress()
IFKey.ControlTHEN$bCtrl=TRUE
END
PUBLICSUBivwExplorer_KeyRelease()
IFKey.ControlTHEN$bCtrl=FALSE
END
Thereyouhaveit.EverythingyouneedtoknowaboutusingtheIconView
controlinacoolapplication.Next,wewilllookattheListViewcontrol.
ListViewControl
DIMhListViewASListView
hListView=NEWListView(ParentASContainer)
158
A Beginner's Guide to Gambas
Figure55LayoutforourListViewexample.
From the left top of the picture, you have our ListView control named
ListView1, a Textbox named Textbox1, and the Insert Item button named
Button1. TherearetwoRadioButtons,namedRadioButton1andRadioButton2
and the Remove Itembutton named Button2. Atthe botton of the form isa
TextLabelnamedTextLabel1andtheQuitbuttonnamedButton3. Onceyou
havecreatedtheformandmadeitastartupclass,weneedtoaddthefollowing
codetothecodewindowtoseehowtoimplementaListViewcontrol:
'Gambasclassfile
sStatusasString
PUBLICSUBForm_Open()
DIMpicSquareASNEWPicture
DIMpicCircleASNEWPicture
picCircle.Load("circle.png")
picSquare.Load("square.png")
'ThiswilladdanitemtotheListViewwithastartingentry
ListView1.Add("ListItem1","ListItem1",picSquare)
TextLabel1.Text=ListView1.Item.Text
ListView1_Click
END
Whentheprogrambeginsandtheformisfirstdisplayed onscreen,the
routineaboveisexecuted.Wecreatetwolocalvariablesforouriconsthatwillbe
usedinthelistandloadthemintomemory.Next,weaddadefaultkeyanditem
tothelistusingtheListView1.Addmethod,specifyingthepicSquareicontobe
associatedwiththisitem.Don'tworryabouttheiconsfornowwewillcreate
themlast.Next,weneedtocreateaneventtorefreshthelistanytimeanitemis
addedoritisclickedonbytheuser.
PUBLICSUBListView1_Click()
ListView1.MoveCurrent
ListView1.Item.Selected=TRUE
TextLabel1.Text=ListView1.Item.Text&sStatus
END
159
A Beginner's Guide to Gambas
IntheListView1_Clicksubroutine,thefirstlineofcodemovestheinternal
cursor to the most current item and highlights it by setting the Item.Selected
property to TRUE in the second line. Finally, the third line updates our
TextLabel1.Textvaluewiththetextofthecurrent(ornewlyadded)selectionand
thecurrentstatus(heldinglobalvarsStatusASString)appended. Iftheuser
clicks on the Insert item button (we named it Button1), this next routine is
executed:
PUBLICSUBButton1_Click()
Declarealocalvariable,picToUse,forouricontobedisplayed:
DIMpicToUseASNEWPicture
Next, check which radioButton has been clicked. If the first button has been
clicked,wewillloadtheimageforsquare.png,otherwise,circle.pngisloaded.
IFTextbox1.Text<>NULLTHEN
IFRadioButton1.ValueTHEN
picToUse.Load("square.png")
ELSE
picToUse.Load("circle.png")
ENDIF
Getthecurrentitem(ordonothing)iftheListViewisempty:
ListView1.MoveCurrent()
Nowwewilladdanewentrywithakeyandnameinthetextbox:
ListView1.Add(Textbox1.Text,Textbox1.Text,picToUse)
Thisemptiesouttextbox:
TextBox1.Text=""
sStatus="current."'setstatustocurrent
This call to the ListView1_Click subroutine will update (refresh) our ListView
control:
ListView1_Click
Next,wemustensurethenewitemisinthevisibleareaofthecontrol:
160
A Beginner's Guide to Gambas
ListView1.Item.EnsureVisible
ENDIF
END
TheButton2_Clicksubroutineiscalledwhenevertheuserdecidestodelete
thecurrentlyselecteditemintheListViewcontrol.
PUBLICSUBButton2_Click()
Thisnextlineofcodegetsoutcursorlineduptothecurrentselection.The
MoveCurrentmethodmovestheinternalcursortothecurrentitem.Itreturnsa
TRUEvalueifthereisnocurrentitem,inwhichcasewewillsimplyreturnas
thereisnothingtodelete:
IFListView1.MoveCurrent()THENRETURN
Ifwereachedthispoint,wehavemovedthecursortoandneedtoremove
thecurrentcursoritem:
ListView1.Remove(ListView1.Item.Text)
CleanupourTextLabel1.Textdisplaywiththiscall:
TextLabel1.Text=""
Now,weneedtoupdatethecursorpositiontothenewcurrentitem(since
wearenowpointedatadeleteditem). Butfirst,weneedtocheckthe.Count
propertytoseeifwehavejustdeletedthelastiteminthelist. Ifthecountis
greaterthanzero,thenwehaveitemsleftinthelist.Otherwise,theIFstatement
willnotbetrueandthecodewillbebypassed:
IFListView1.Count>0THEN
ListView1.MoveCurrent
ListView1.Item.Selected=TRUE'Selectsthecurrentitem
sStatus=selected.
ListView1_Click'thiswillforceanupdate
ENDIF
END
If the user clicks their mouse on an item in the ListView control, this
161
A Beginner's Guide to Gambas
routineiscalled. WewillsimplyupdatetheTextLabel1.Textpropertywiththe
text of the item selected and refresh the ListView control by calling our
ListView1_Clicksubroutine.
PUBLICSUBListView1_Select()
TextLabel1.Text=ListView1.Item.Text
sStatus=selected.
ListView1_Click
END
IftheuserdoubleclickstheirmouseonanitemintheListViewcontrol,it
willraisethe Activateevent,indicatingtheuserhaspickedthisitemforsome
actiontooccur.Inthiscase,wewillsimplyupdatetheTextLabel1.Textproperty
withthetextoftheitemselected,appendedwiththewordactivated,andrefresh
theListViewcontrolbycallingourListView1_Clicksubroutine.
PUBLICSUBListView1_Activate()
TextLabel1.Text=ListView1.Item.Text&activated.
sStatus=activated.
ListView1_Click
END
IftheuserclickstheirmouseontheButton3(Quit)button,thisroutineis
called.Wewanttoexitcleanlysoweinvoketheclosemethodfortheformusing
theME.Closecall.
PUBLICSUBButton3_Click()
ME.Close
END
UsingtheGambasIconEditTool
Atthispoint,allthecodeiscreatedforourListViewexampleprogram.We
stillneedtocreatethecircle.pngandsquare.pngicons.WewillusetheGambas
IconEditor todothat. Tobringuptheiconeditor,wewillgototheProject
WindowintheIDE.IntheProjectTreeView,findtheDatafolderandrightclick
yourmouse.PicktheNewitemandtheImagesubMenuitem.Youwillseethis
dialogpopup:
162
A Beginner's Guide to Gambas
Figure56CreatinganewIconimageinGambas.
SimplytypesquareintheNamefieldandclickok.Now,theiconeditor
appears and you can create an icon. Use the rectangle option from the Icon
EditorToolBoxandcreateabluesquareandsaveitwiththediskshapedicon.
Figure57Oursquareicon
Figure59Ourcircleicon
image.
image.
Figure58Icon
EditorToolBox.
Repeatthisprocess,creatinganothericonnamedcircle.pngandsavethat
too.Thatisit!Yourprogramisreadytorun.TryitoutandseehowtheListView
controlworks.
TheTreeView
Control
TheTreeViewcontrolworksalmostidenticallytotheListViewcontrol.The
chiefdifferenceisthattheTreeViewsupportsnestedchildrenandallowsyouto
traversefromaninner(child)leveloutwardtotheparentofthechild,alltheway
163
A Beginner's Guide to Gambas
outtothetopofthetree. Thiscontroladdsafewmethodsspecificallyforthe
purposeofmanagingthetraversaloftheparent/childtrees.
DIMhTreeViewASTreeView
hTreeView=NEWTreeView(ParentASContainer)
ThecodeabovecreatesanewTreeViewcontrol.Thisclassactslikeareadonly
array:
DIMhTreeViewASTreeView
DIMhTreeViewItemAS.TreeViewItem
hTreeViewItem=hTreeView[KeyASString]
The line of code above will returns a TreeView item from its key. The
internal cursorismoved tothecurrentitem. Now,let'suse another example
programfromtheGambasIDE.StartGambasandselecttheExamples|Basic|
TreeViewsampleprogram. WhentheIDEopensup,youshouldseesomething
similartoFigure60onthefollowingpage.
Figure60TheTreeViewProject
window.
164
A Beginner's Guide to Gambas
Next,doubleclickontheTreeViewExampleformandbringuptheform.
Doubleclickontheformtoopenupthecodeeditwindowandyouwillseethe
followinglisting,whichwewilldissectlinebylinetounderstandhowitworks:
'Gambasclassfile
PUBLICintEventNumberASInteger
TheglobalvariableintEventNumber isusedtotrackthenumberofevents
thatoccurforoureventstack.Eachtimeweprocessanevent,wewillincrement
thisvariable.WedeclaretwolocalPicturevariables,picMaleandpicFemaleand
loadthemintomemoryfortheprogrambyusingthePicture.Loadmethod.
PUBLICSUBForm_Open()
DIMpicMaleASNEWPicture
DIMpicFemaleASNEWPicture
picFemale.Load("Female.png")
picMale.Load("Male.png")
'ThiswillpopulateourTreeViewwithourstartingentries
'Note:I'llkeeptheentriestextanditskeythesametokeep
'itsimple
Next,wewilladdthestartingvaluesofourTreeViewcontrol.Wewilladd
fouritemstothecontrol.Eachitemkeywillbethesameastheitemname.The
itemsTedandSallywillbechildrenofitemBill,whileitemFrankwillbeachild
ofSally.
TreeView1.Add("Bill","Bill",picMale)
TreeView1.Add("Ted","Ted",picMale,"Bill")
TreeView1.Add("Sally","Sally",picFemale,"Bill")
TreeView1.Add("Frank","Frank",picMale,"Sally")
165
A Beginner's Guide to Gambas
TreeView1.Item.Expanded=TRUE
END
IftheuserclicksonanitemintheTreeView,wewanttorecordtheClick
eventinoureventstackandupdatethestackdisplay(TextArea1.Text).Wethen
incrementtheeventnumberbyone.NotethatinupdatingtheTextArea1.Text
value, we simply take the new event and append everything else in the
TextArea1.Textmemoryafterthelinefeedcharacter, Chr(10). Theneteffectof
thiscallinaninsertionoftheneweventatthetopofthedisplayedtext.
PUBLICSUBTreeView1_Click()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Click"&Chr(10)&
TextArea1.Text
intEventNumber=intEventNumber+1
166
A Beginner's Guide to Gambas
DIMsParentASString
IFTextbox1.Text<>NULLTHEN
IFRadioButton1.ValueTHEN
picToUse.Load("Male.png")
ELSE
picToUse.Load("Female.png")
ENDIF
'Getstheparentitem:thecurrentitem,ornothingistheTreeView
'isvoid
IFNOTTreeView1.MoveCurrent()THEN
sParent=TreeView1.Key
ENDIF
Now,weneedtoaddthenewentrywithakeyandanameofwhatwasin
thetextbox.WewillplaceitintheTreeViewcontrolasachildofthecurrently
selected entry. Note that the key names must be unique or it will crash the
program.WecouldusetheExistmethodtofindoutifakeyexistswiththename
Textbox1.TextbeforemakingthecalltotheAddmethod,butthatwasnotdone
here.Ifwedidthat,thecodewouldmakeachecksimilartothis:
IFExist(Textbox1.Text)<>TRUETHEN
TreeView1.Add(Textbox1.Text,Textbox1.Text,picToUse,sParent)
ENDIF
Thisnextlinewillupdateourlabelandreflectthenewnumberofkids:
TreeView1_Click
ThiscalltoEnsureVisiblewillmakesurethattheitemwejustaddedtothe
listisinthevisibleareaofthecontrol.Ifnecessary,thecontrolwillscrollsothe
itemisvisible.
TreeView1.Item.EnsureVisible
ENDIF
END
167
A Beginner's Guide to Gambas
PUBLICSUBButton2_Click()
Firstofall,wemustgetthecursorlineduptoourcurrentselectionand
makesurethatthecurrentitemisn'tanemptyornullvalue.IftheMoveCurrent
method returns a true value, the list was empty and we are done. The code
invokestheRETURNcallandwejumpbacktothecallingprocess. Otherwise,
whateverthecurrentitemiswillberemovedbycallingtheRemovemethodinthe
secondline,below:
IFTreeView1.MoveCurrent()THENRETURN
'Letsremovethecurrentcursoritem
TreeView1.Remove(TreeView1.Item.Text)
Now we must move the cursor to the current item (since we are now
pointing at a deleted item). Before we do that we need to check the count
propertytomakesurewedidn'tdeletethelastiteminthelist.Ifwedid,thenwe
obviouslydon'trunthispartofthecode. The IFstatement checksforacount
greaterthanzeroand,ifTRUE, willmovetothecurrentitem,selectitsothe
cursorishighlighted,andupdatethecontrolwithacalltotheTreeView1_Click
subroutine.
IFTreeView1.Count>0THEN
TreeView1.MoveCurrent
'Thisselectsor'highlights'ourcurrentitem
TreeView1.Item.Selected=TRUE
'Thiswillupdateourlabelandreflectthenewnumberofkids
TreeView1_Click
ENDIF
END
Iftheuserclicksontheminusiconinthe TreeViewcontrol,itsetsoffa
Collapseevent.Theroutinebelowiscalled.Itsimplyupdatestheeventstack,as
describedpreviously,andincrementstheeventcounter,intEventNumber,byone.
PUBLICSUBTreeView1_Collapse()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Collapse"&Chr(10)
&TextArea1.Text
intEventNumber=intEventNumber+1
END
168
A Beginner's Guide to Gambas
Iftheuserdoubleclicksonaniteminthe TreeViewcontrol,itsetsoffa
Dbl_Clickevent.ItisbasicallythesameasanActivateevent.Theroutinebelow
is called. It simply updates the event stack, as described previously, and
incrementstheeventcounter,intEventNumber,byone.
PUBLICSUBTreeView1_DblClick()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):DoubleClick"&Chr
(10)&TextArea1.Text
intEventNumber=intEventNumber+1
END
PUBLICSUBTreeView1_Select()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Select"&Chr(10)&
TextArea1.Text
intEventNumber=intEventNumber+1
END
This next routine is dead code. It never gets executed because the
Button2_Click subroutine takes care of the removal of an item. To use it
effectively,itshouldbecalledfromtheButton2_Clicksubroutinejustbeforethe
linecallingtheTreeView1_Clicksubroutine.Ifthisisdone,thentheeventstack
wouldbeproperlyupdated,firstwiththedeleteandthentheclickevents.
PUBLICSUBTreeView1_Delete()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Delete"&Chr(10)&
TextArea1.Text
intEventNumber=intEventNumber+1
END
Iftheuserclicksontheplusiconinthe TreeViewcontrol,itsetsoffan
Expandevent.Theroutinebelowiscalled.Itsimplyupdatestheeventstack,as
describedpreviously,andincrementstheeventcounter,intEventNumber,byone.
PUBLICSUBTreeView1_Expand()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Expand"&Chr(10)&
TextArea1.Text
intEventNumber=intEventNumber+1
END
PUBLICSUBButton3_Click()
169
A Beginner's Guide to Gambas
TextArea1.Text=""
'IntEventNumber=0
END
TheHelp | Aboutmenuitemgeneratesaclickeventthatcallsthisnext
subroutine.Itsimplygivescredittotheauthorofthisexample,C.Packard.
PUBLICSUBAbout_Click()
Message.Info("TreeViewexamplewrittenbyC.Packard."&Chr(10)&
"Aug2004")
END
Iftheuserdoubleclicksonaniteminthe TreeViewcontrol,itsetsoffa
Activateevent.ItisbasicallythesameasaDblClickevent.Theroutinebelowis
called.Itsimplyupdatestheeventstack,asdescribedpreviously,andincrements
theeventcounter,intEventNumber,byone.
PUBLICSUBTreeView1_Activate()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Activate"&Chr(10)
&TextArea1.Text
intEventNumber=intEventNumber+1
END
Thisnextroutineisalsodeadcode. Itnevergetsexecutedbecausethe
nothingcreatesaneventtogethere.Touseiteffectively,amenuitem,Rename
should be added to the Help menu and it should be called from the
MenuItem.Clickevent.Ifthisisdone,thentheeventwouldbegeneratedandyou
couldwriteabitofcodetogetthenewnamefromtheuserandchangeit.The
eventstackwouldbeproperlyupdated,firstwiththerenameeventandthenwith
theclickevent.
PUBLICSUBTreeView1_Rename()
'Thisjustupdatesoureventstack
TextArea1.Text="Event("&intEventNumber&"):Rename"&Chr(10)&
TextArea1.Text
intEventNumber=intEventNumber+1
END
ThatisallthereistotheTreeViewprogram.Youcanplayaroundwiththe
code and implement the suggestions made herein. Once you are able to
understand how to use these controls effectively, your Gambas interfaces will
becomemoresophisticated. Next,wewilltakealookatthelasttwoadvanced
viewcontrols,theGridViewandColumnViewcontrols.
170
A Beginner's Guide to Gambas
TheGridViewControl
TheGridViewcontrol,likealltheothercontrolsintheToolBox,inheritsits
attributesfromtheControlclass. GridViewimplementsacontrolthatdisplays
data in a grid. This class is creatable. Standard Gambas language syntax for
GridViewis:
DIMhGridViewASGridView
hGridView=NEWGridView(ParentASContainer)
ThecodeabovewillcreateanewGridView.Thisclassactslikeareadonly
array. Toretrievethecontentsofacellinthegrid,usethiscodetodeclarea
GridCellvariablethatcanreadtheGridViewarray(theGridCellisavirtualclass):
DIMhGridViewASGridView
DIMhGridCellAS.GridCell
hGridCell=hGridView[RowASInteger,ColumnASInteger]
Thelineabovereturnsacellfromitsrowanditscolumn. Ourexample
programforthiscontrolwillcreateagridthatisfourrowsofthreecolumns.We
willpopulatethefirstthreerowswithtextandthelastrowwithpictures.Wewill
takethelastrowoftextanddemonstratehowthealignmentpropertyworksfor
textdata.Ourprogramwillhavethreebuttons,Quit,Clear,andReset.
The Quit button will simply close the program. Clear will invoke the
GridView.Clearmethodtoerasethecontentsofthegridanddisplayemptygrid
cells.TheResetbuttonwillrepopulatethecontentsofthegridwiththedatathe
program started with (i.e., the data populated when the form's constructor
methodwascalled.Ourprogramwilllooklikethis:
171
A Beginner's Guide to Gambas
Figure61WhatourGridViewwilllooklike.
To begin, start Gambas and select the New Project option, choosing to
createaGraphicalUserInterfaceproject.Maketheprojecttranslatableandform
controls public by checking the two boxes in the Wizard. Name the project
GridViewExampleandputitintheGridViewdirectory.WhentheIDEappears,
wewillneedtogototheprojectwindowandbringuptheICONEditor.Wewill
createthreeicons,namedGridPic,GridPic1,andGridPic2,asshownabove.Try
togetthemreasonablyclosetowhatyouseeinthepictureaboveifyoucan.
Create a new formthat is a startup class form and put the GridView control,
namedGridView1 on the formasshown above. Thenadd thethreebuttons,
named Button1, Button2, and Button3 to the form. Make the Button.Text
propertiesreflectwhatisshowninthepictureabove.
Now,wehavetheformdesignedanditlookslikewhatweexpect. Lets
startcoding.Doubleclickontheform,butnotonacontrol,andtheForm_Open
subroutine will display in the code window. We will set the caption to your
programhere:
'Gambasclassfile
PUBLICSUBForm_Open()
Form1.Caption="GridViewExample"
END
Whentheprogramstarts,ifaconstructorexists,itisexecutedfirst. Our
constructorwillloadourthreeiconsandpopulatethegrid. First,declarethree
localvariablesforthepictures,hPic1,hPic2,andhPic3,asshownbelow:
PUBLICSUB_new()
DIMhPic1ASPicture
DIMhPic2ASPicture
DIMhPic3ASPicture
172
A Beginner's Guide to Gambas
Now,wemustinstantiatethepicturevariablesandloadthepictures.
hPic1=NEWPicture
hPic1.Load("GridPic.png")
hPic2=NEWPicture
hPic2.Load("GridPic2.png")
hPic3=NEWPicture
hPic3.Load("GridPic1.png")
Thenextthingweneedtodoisdefinethedimensionsofthegrid. Our
gridwillhavethreecolumnsandfourrows,sowesettheColumnsandRows
propertiesusingtheirvirtualclassgridcolumnandgridrowproperty,counttoset
therowsandcolumnsasshownbelow:
GridView1.Columns.Count=3
GridView1.Rows.Count=4
Wecanalsodefinethewidthandheightdimensionsofthegridcolumns
androws.Bearinmindthatitispossibletosetdifferentheightvaluesforevery
rowanddifferentwidthvaluesforeverycolumn. WewillsetthetheWandH
propertiesforourrowsandcolumnsasshownbelow:
GridView1.Columns.Width=72
GridView1.Rows.Height=36
Next, we will populate the grid with some data, simply identifying the
row,columnpositionwithtext:
GridView1[0,0].Text="0,0"
GridView1[0,1].Text="0,1"
GridView1[0,2].Text="0,2"
GridView1[1,0].Text="1,0"
GridView1[1,1].Text="1,1"
GridView1[1,2].Text="1,2"
Forthelasttextrow,wewanttodemonstratehowtousetheAlignmentproperty:
GridView1[2,0].Alignment=Align.Center
GridView1[2,1].Alignment=Align.BottomLeft
GridView1[2,2].Alignment=Align.TopRight
Aftersettingthealignmentpropertiesforeachcellintherow,wewilladdtext:
173
A Beginner's Guide to Gambas
GridView1[2,0].Text="2,0"
GridView1[2,1].Text="2,1"
GridView1[2,2].Text="1,2"
Finally,wewilladdourthreeiconstothegrid:
GridView1[3,0].Picture=hPic1
GridView1[3,1].Picture=hPic2
GridView1[3,2].Picture=hPic3
END
Theconstructoriscomplete.Now,doubleclickontheQuitButtontoget
theButton1_Clickeventsubroutine,wherewewilladdourMe.Closecalltoshut
downtheprogram:
PUBLICSUBButton1_Click()
ME.Close
END
The Clear button is next. Doubleclick on the Clear Button to get the
Button2_Clickeventsubroutine,wherewewilladdourcodetoresetthegridto
blankvalues:
PUBLICSUBButton2_Click()
GridView1.Clear
END
Theeasiestwaytorepopulatethedataistosimplyinvoketheconstructor
onceagain.Addthiscodesothatiswhatwewilldo.
PUBLICSUBButton3_Click()
_new
END
174
A Beginner's Guide to Gambas
TheColumnViewControl
Forournextexample,wearegoingtocreateaprogramthatdisplaysdata
inaColumnView,asshownbelow:
Figure62OurColumnViewexample.
Our simple example will create three columns and five rows. We will
populatethecolumndatawiththerow,columnidoftheparticularitem.Todo
this,wewillneedtosetthewidthofeachcolumntobedynamicallycalculated
basedonthewidthofthecontrolandthenumberofcolumnsspecified.Wewill
dothisintheconstructor.Whentheprogramstartsup,allwearegoingtodo
ontheForm_Opencallissetthewindowcaption,asshownintheForm_Open()
subroutine:
'Gambasclassfile
PUBLICSUBForm_Open()
Form1.Caption="ColumnViewExample"
END
Theconstructormethodiswherealltheworktopopulatethecontrolis
done.Weneedtodeclarethreelocalintegervariables,iwidthtoholdthevalueof
thecalculatedcolumnwidth,irowcounterandicolcounter,whichareusedforour
loopstructures.
PUBLICSUB_new()
'declareourlocalvars
DIMiwidthASInteger
DIMirowcounterASInteger
DIMicolcounterASInteger
'setthenumberofcolumnsto3
ColumnView1.Columns.Count=3
'calculatethecolumnwidthbasedonthenumberofcolumnsset
iwidth=ColumnView1.Width/ColumnView1.Columns.Count
175
A Beginner's Guide to Gambas
'forthefirstcolumn,setthecolumnwidthandaddacolumntitle
ColumnView1.Columns[0].Width=iwidth
ColumnView1.Columns[0].Text="FirstCol"
'forthesecondcolumn,setthecolumnwidthandaddacolumntitle
ColumnView1.Columns[1].Width=iwidth
ColumnView1.Columns[1].Text="SecondCol"
'forthethirdcolumn,setthecolumnwidthandaddacolumntitle
ColumnView1.Columns[2].Width=iwidth
ColumnView1.Columns[2].Text="ThirdCol"
Now, we need to set up the outer (row) and inner (column) loops.
Basically,wewillloopthrougheveryeveryrowinthecontroland,ateachrow,
wewillloopthrougheachcolumn,populatingtheColumnView1[row][column]
arrayitemswithadynamicallybuiltstringoftextthatwillrepresentthecurrent
positionwithintheinnerandouterloop.
FORirowcounter=0TO4'forallfiveofourrows
'calltheAddmethodwith[row][col]toaddtoColumnView1control
ColumnView1.Add(irowcounter,icolcounter)'startouter(row)loop
FORicolcounter=0TOColumnView1.Columns.Count1
'addtexttothe[row][col]item
ColumnView1[irowcounter][icolcounter]="Col:"&icolcounter&"
Row:"&irowcounter
NEXT'column
NEXT'row
END'ourconstructor
TheQuitButtonhereworksjustlikeinthepreviousexample.Togetthe
Button1_Clickeventsubroutine,doubleclickandaddtheMe.Closecalltoshut
downtheprogram:
PUBLICSUBButton1_Click()
ME.Close
END
The Clear button is next. Doubleclick on the Clear Button to get the
Button2_Clickeventsubroutine,wherewewilladdourcodetoresetthegridto
blankvalues:
PUBLICSUBButton2_Click()
ColumnView1.Clear
END
ForourResetbutton,theeasiestwaytorepopulatethedataistosimply
invoketheconstructoronceagain.Addthiscodesothatiswhatwewilldo.
176
A Beginner's Guide to Gambas
PUBLICSUBButton3_Click()
_new
END
ThatisallthereistobuildingandpopulatingtheColumnViewcontrol.Next,we
willtakealookathowtousethevariouslayoutcontrolsinGambas.
LayoutControlsHBox,VBox,HPanelandVpanel
All of the controls in this group are similar in that they try to arrange
controls they contain automatically. They do so by using the .Arrangement
property which relies upon constants that are defined in the Arrange class.
ConstantsusedbytheArrangementpropertyofthesecontainercontrolsinclude
thefollowing:Fill,Horizontal,LeftRight,None,TopBottom,andVertical.If
youdonotspecifyan.Arrangementpropertyvalue,thenthecontroldefaultsto
whatever it is designed to do, i.e., HBox would arrange controls horizontally,
VBoxvertically,etc.
HBoxandVBox
Both of these classes are containers that arrange their children either
horizontally or vertically. Like all other ToolBox controls, they inherit their
attributesfromtheContainerclass.BothofthesecontrolsactlikeaPanelwithout
aborderwhoseArrangementpropertywouldbesettoArrange.Horizontal.These
classesarecreatable.StandardGambaslanguagesyntaxtocreateanewHboxis:
DIMhHBoxASHBox
DIMhVBoxASVBox
hHBox=NEWHBox(ParentASContainer)
hVBox=NEWVBox(ParentASContainer)
HPanelandVpanel
Bothoftheseclassesarecontainersthatarrangestheirchildrenfromtopto
bottom,andthenlefttorightfortheHpanelandlefttoright,toptobottomfor
theVPanel. Theyarebothlikeanordinary Panelcontrol withoutaborderbut
whose Arrangement property would be set to Arrange.TopBottom ( where a
containerstacksitschildrenfromtoptobottom;ifthechildrencontrolscan'tfit
vertically,anewcolumnofcontrolsisstartedjustafterthepreviouscolumn)or
Arrange.LeftRight (whereacontainerstacksitschildrenfromlefttoright;ifthe
childrencontrolscan'tfithorizontally,anewrowofcontrolsisstartedbelowthe
177
A Beginner's Guide to Gambas
previous row). Both these types of controls inherit their attributes from the
Containerclass.Thisclassiscreatable.StandardGambaslanguagesyntaxis:
DIMhHPanelASHPanel
DIMhVPanelASVPanel
hHPanel=NEWHPanel(ParentASContainer)
hVPanel=NEWVPanel(ParentASContainer)
Let'screateasimpleprogramthatwilldemonstrateeachofthese layout
controlsandshowhowtheycanbeusedinanapplication.Forthisapplication,
startGambasandcreateagraphicaluserinterfaceprogram.NameitLayoutsand
createastartupclassform,Form1.Forthisapplication,wewillneedtousesome
icons.MostLinuxbaseddistributionshaveiconfilesstoredinthefoldernamed:
file:/usr/share/icons/defaultkde/32x32/actions
Yoursystemmaybedifferent.Regardlessofwhereyoufindthem,pickoutseven
iconsandcopythemtotheLayoutfolder. Forourpurposes,anysevenwilldo
butifyoucanfindundo,redo,help,configure,colorize,printer,andexittype
iconsitwillbeeasier.HerearetheiconsIchosetouseforthisproject:
Figure63Layoutprojecticons.
Ourprogramisquitesimple.WearegoingtocreateanHBox,aVBox,an
HPanel,andaVPanelandputsomesimplecontrolsineachcontainer. Wewill
simplyupdateatextlabeltoshowwhensomethinghasbeenclicked.Hereishow
ourformwilllookindesignmode:
178
A Beginner's Guide to Gambas
Figure64Form1designmodeshowinglayoutofourcontrols.
Fromthetopleftofthefigureabove,westartwithaVBoxandaTextLabel.
BelowtheTextLabelistheHBox. Whenyoucreatethesecontrols,Gambaswill
suggestdefaultnamesforeachcontrol.Takethedefaultnamesforeachcontrol
becauseourprogramusesthosedefaults. PlacethreeToolButtonsintheVBox
and four ToolButtons in the HBox. Next, set the picture properties of each
ToolButtontotheiconsyouchosetouse(hopefullythesameasthoseabove)for
ourproject. Onceyouhavetheiconsdisplayed,weneedtostartwiththefirst
ToolButtonintheVBoxanddoubleclicktobringupthecodewindow.Youwill
needtodothisforeachoftheseveniconsandaddcodeasfollows:
'Gambasclassfile
PUBLICSUBToolButton1_Click()
TextLabel1.Text="VertUndoclicked."
END
PUBLICSUBToolButton2_Click()
TextLabel1.Text="VertRedoclicked."
END
PUBLICSUBToolButton3_Click()
TextLabel1.Text="VertHelpclicked."
179
A Beginner's Guide to Gambas
END
PUBLICSUBToolButton4_Click()
TextLabel1.Text="HorizConfigureBtnclicked."
END
PUBLICSUBToolButton5_Click()
TextLabel1.Text="HorizColorButtonclicked."
END
PUBLICSUBToolButton6_Click()
TextLabel1.Text="HorizPrinterBtnclicked."
END
PUBLICSUBToolButton7_Click()
TextLabel1.Text="HorizExitButtonclicked."
WAIT0.5
ME.Close
END
ThenextcontrolcontainerwewillcreateistheHPanel,asshowninthe
figureabove. WewilladdfourRadioButtonsandthreeregularbuttonstothis
containercontrol.Trytoarrangethebuttonsasshowninthefigure.Youwillsee
why this is important once you run the program and see how the HPanel
rearrangesthecontrols.Onceagain,doubleclickoneachradiobuttonandadd
thefollowingcode:
PUBLICSUBRadioButton1_Click()
TextLabel1.Text="RadioBtn1clicked."
END
PUBLICSUBRadioButton2_Click()
TextLabel1.Text="RadioBtn2clicked."
END
PUBLICSUBRadioButton3_Click()
TextLabel1.Text="RadioButton3clicked."
END
PUBLICSUBRadioButton4_Click()
TextLabel1.Text="RadioButton4clicked."
END
180
A Beginner's Guide to Gambas
PUBLICSUBButton1_Click()
TextLabel1.Text="Button1clicked."
END
PUBLICSUBButton2_Click()
TextLabel1.Text="Button2clicked."
END
PUBLICSUBButton3_Click()
TextLabel1.Text="Button3clicked."
END
The last thing we will do is create the VPanel with three CheckBoxes.
RemembertoarrangetheCheckBoxesinyourformlikethoseinthepictureabove
toseehowthecontrolrearrangesthemautomatically. Addthiscodewhenyou
haveplacedtheCheckBoxesintheVPanel:
PUBLICSUBCheckBox1_Click()
IFCheckBox1.Value=TRUETHEN
TextLabel1.Text="Checkbox1checked."
ELSE
TextLabel1.Text="Checkbox1unchecked."
ENDIF
END
PUBLICSUBCheckBox2_Click()
IFCheckBox2.Value=TRUETHEN
TextLabel1.Text="Checkbox2checked."
ELSE
TextLabel1.Text="Checkbox2unchecked."
ENDIF
END
PUBLICSUBCheckBox3_Click()
IFCheckBox3.Value=TRUETHEN
TextLabel1.Text="Checkbox3checked."
ELSE
TextLabel1.Text="Checkbox3unchecked."
ENDIF
END
181
A Beginner's Guide to Gambas
Figure65Layoutprogramwhenitstartsup.
NoticehowtheRadioButtonsintheHPanelhavealignedverticallyfrom
RadioButton4toRadioButton1and,becausetherewasroom,itplacedthebutton
controlstotherightandcontinuedthealignmentfromtoptobottom,lefttoright.
For the VPanel, see how the CheckBoxes aligned themselves. These types of
controlsareunpredictableinhowtheywilllayouttheirchildren.Itisbesttouse
theseincodedynamicallywhenyouhavetocreateformsontheflyanddonot
havetheopportunitytolaythemoutinafixedpanelindesignmode.
TheVBoxandHBoxcontrolsholdtheToolButtonsandallowyoutocreate
nifty little toolbars that work well with iconic driven controls, such as those
depictedwithouricons. Onceyouhavefinishedplayingaroundwithourlittle
application,closetheprogramandwewillmoveontolearnaboutTabStrips.
TheTabStripControl
TheGambasTabStripcontrolimplementsatabbedcontainercontrol.Like
all controls, it inherits its attributes from the Container class. This class is
creatable.Thisclassactslikeareadonlyarray.ThestandardGambaslanguage
syntaxis:
DIMhTabStripASTabStrip
hTabStrip=NEWTabStrip(ParentASContainer)
DIMhTabAS.Tab
hTab=hTabStrip[IndexASInteger]
Invoking the code above will return a virtual tab object from its index.
TabStripsareusefulfororganizingandpresentinginformationinselfcontained
units.TabStripsallowyoutoobtaininputfromusersbypresentingasimple,easy
tofollowinterfacethatcanliterallyguidethemthroughaconfigurationorsetup
182
A Beginner's Guide to Gambas
process.HereisasampleofaTabStripinuse:
Figure66ATabStripcontrol.
TodemonstratehoweasyTabStripsaretocreate,wewillbuildasmall
applicationthatimplementsthetabbedinterfaceyouseeabove.Ourapplication
thatwillshowyouhowtousetabbedcontrolstopresentinformationtoauser
andrespondtoitinyourapplications.StartGambasandcreateanewgraphical
userinterfaceprogram.NametheprojectTabs,clickthroughtheProjectCreation
WizardandwhenyougettotheGambasIDE,makeanewform,Form1thatisa
startupclass. Next,youwillneedtoplacea TabStripcontrol onthenewform.
OnceyouplacetheTabStrip,youwillonlyseeonetabdisplayed.Youmustgoto
thepropertieswindowandsettheCountpropertyto5tohavethecontrollook
liketheoneweshowabove.NotethattabnumberingstartsatzeroinGambas.
Eachtabactslikeacontainerforthecontrolsyouplaceonit.Wewillalsoneed
toaddaTextLabelandabuttontoourform.TheTextLabelwillbeusedtoshow
theuseractionsinresponsetoourtabbedinterface. ThebuttonwillbeaQuit
buttonwhichwewillusetoterminatetheapplication. Hereiswhatyourform
shouldlooklikeasyoustarttodesigntheinterface:
Figure67TabProjectForm1.formDesign.
183
A Beginner's Guide to Gambas
Figure68Tab0layout.
Next,doubleclickoneachRadioButtonandenterthiscode:
PUBLICSUBRadioButton1_Click()
TextLabel1.Text="Youhaveclicked:<br><center><strong>RadioButton1"
END
PUBLICSUBRadioButton2_Click()
TextLabel1.Text="Youhaveclicked:<br><center><strong>RadioButton2"
END
HereiswhatwewilldoforTab1:
Figure69Tab1layout.
DoubleclickoneachCheckBoxandenterthiscode:
PUBLICSUBCheckBox1_Click()
IFCheckBox1.Value=TRUETHEN
TextLabel1.Text="Youhavechecked:<br><center><strong>CheckBox1"
184
A Beginner's Guide to Gambas
ELSE
TextLabel1.Text="Youhaveunchecked:<br><center><strong>CheckBox1"
ENDIF
END
PUBLICSUBCheckBox2_Click()
IFCheckBox2.Value=TRUETHEN
TextLabel1.Text="Youhavechecked:<br><center><strong>CheckBox2"
ELSE
TextLabel1.Text="Youhaveunchecked:<br><center><strong>CheckBox2"
ENDIF
END
Thecodeabovewilldeterminewhethertheuserischeckinganitemor
uncheckingitbyfirstlookingattheValueproperty.IfitisTRUE,thentheboxis
already checked and we will indicate that fact in the update of the
TextLabel1.Text.Otherwise,itisbeinguncheckedandwewillupdatethelabelto
statethatfact.
ForTab2,wearegoingtoplaceaPanelcontrolontheTabandaddthree
ToolButtons. DonotmakethemistakeofplacingoneToolButtonandtryingto
copyitandmovethecopyintothepanel.Itwillnotberecognizedasachildof
thepanel control. Itwill appearonalltabs(I believethisis another quirkof
Gambas). Inorderforthe Panelcontrol toaccepttheToolButtonsaschildren,
youmustindividuallyclicktheToolButtonontheToolBoxandcreateeachone
justasyoudidwiththefirstToolButton.ForeachToolButton,assignthepicture
propertythenameoftheiconweareusingforthatbutton,asshownhere:
Figure70Tab2ToolButtonlayoutwith
icons.
ThenextstepistodoubleclickoneachToolButtonandaddthiscode:
PUBLICSUBToolButton1_Click()
TextLabel1.Text="Youclicked:<br><center>the<strong>ConfigureIcon"
END
185
A Beginner's Guide to Gambas
PUBLICSUBToolButton2_Click()
TextLabel1.Text="Youhaveclicked:<br><center>the<strong>HelpIcon"
END
PUBLICSUBToolButton3_Click()
TextLabel1.Text="Youhaveclicked:<br><center>the<strong>ExitIcon"
END
Now,wearegoingtoaddaComboBoxtoTab3. Nothingfancy,justa
simpleComboBoxwiththreeitems.SelecttheComboBoxcontrolandplaceiton
thetabasshownbelow:
Figure71Tab3layoutwithaComboBox.
Remember,inordertosettheitemsintheComboBox,youneedtogoto
thePropertieswindowandselecttheListproperty.Abuttonwiththreedotswill
appear(indicatingthatitleadstotheListEditor)andyouneedtoclickthat.Add
the following items: Pick something (to display as our default text), This
thing,Thatthing,andSomeotherthingtothelist.Finally,weneedtosetan
eventfortheComboBoxbysingleclickingonthe ComboBoxcontrol thenright
clicking themouse. Choose Events and selectthe Change event. Anytimethe
ComboBoxchanges,wewanttodisplaythechangedtextonourTextLabel.Now,
addthiscodeintheCodeEditorfortheComboBox1_Change()event:
PUBLICSUBComboBox1_Change()
DIMcomboitemASString
comboitem=ComboBox1.Text
TextLabel1.Text="Youpickeditem:<br><center><strong>"&comboitem
END
Forourlasttab,Tab4,wearegoingtosimplydisplaythecurrenttime.
ThiswillrequireuseoftheTimercontrol.WearegoingtoneedtoaddaLabel
andaTimercontroltoTab4,asshownbelow:
186
A Beginner's Guide to Gambas
Inorderforthetimertowork,wemustenableitwhentheformfirststarts.
Doubleclickontheformsomewhereexceptonacontroland youwillseethe
Form_Open() subroutine appear in the code window. Add this code to the
routine:
PUBLICSUBForm_Open()
Form1.Caption="PlayingwithTabStrips"
Timer1.Enabled=TRUE
TextLabel1.Text=""
END
Toactuallyusethetimer,weneedtosetanEvent.Wedothisbysingle
clickingontheTimercontrolthenrightclickingthemouse. Choose Events and
selecttheTimerevent.YouwillbeplacedintheCodeEditorandyouneedtoadd
asinglelineofcode:
PUBLICSUBTimer1_Timer()
Label1.Text=Str$(Now)
END
ThislineofcodewillupdatetheLabel1.Textfieldeverysecondthatthe
Tab4isdisplayed.Ineffect,youhavecreatedaclockontheTabbydoingthis.
Thatisallthereistoit.RuntheprogramandseehowTabStripswork.Next,we
movetoFileoperations.
187
A Beginner's Guide to Gambas
Access
Dir
Eof
Exist
IsDir/Dir?
Lof
Stat
Temp/Temp$
OPENandCLOSE
INPUT,LINEINPUT,andPRINT
READ,SEEK,WRITEandFLUSH
COPY,KILLandRENAME
MKDIRandRMDIR
LINK
Access
Accessisafunctionusedtodetermineifafileisaccessibleornot. The
Gambaslanguagesyntaxis
Accessible=Access(Path[,Mode])
The Access function call returns TRUE if the file specified by Path is
accessible.IfthevalueofModeisgb.Read,thenthefunctionreturnsTRUEifthe
filecanberead.Thisisthedefaultvalueforallfiles.IfModeisgb.Write,then
AccessreturnsTRUEifthefilecanbewrittento.Whengb.Execisspecifiedfor
Mode,thefunctionreturnsTRUEifthefilecanbeexecuted.Thepreviousflags
canbecombinedwiththeORoperator.Foradirectory,theexecutionflagmeans
thatthedirectorycanbebrowsed.Forexample:
PRINTAccess("/home/rabbit",gb.WriteORgb.Exec)
wouldreturn
188
A Beginner's Guide to Gambas
True
whilethestatement
PRINTAccess("/root",gb.Write)
willreturn
False
Dir
The Dir function returns a string array that contains the names of files
located in Directory that matches the specified File pattern. If no pattern is
specified,anyfilenamethatexistsinthedirectoryisreturned.Thepatternmay
containthesamegenericcharacterspermittedforthe LIKE operator. Inother
words,thosecharactersfoundinthefollowingtable:
Genericcharacter Matches
* Anynumberofanykindofcharacter.
? Anysinglecharacterofanytype.
[abc] Anycharacterspecifiedbetweenthebrackets.
[xy] Anycharacterthatlieswithinthespecifiedinterval.
[^xy] Anycharacterthatisnotfoundwithintheinterval.
Filenamearray=Dir(Directory[,Filepattern])
Hereisanexamplecodesegmenttohelpyou
'Printadirectory
SUBPrintDirectory(DirectoryASString)
DIMsFileASString
FOREACHsFileINDir(Directory,"*.*")
PRINTsFile
NEXT
END
189
A Beginner's Guide to Gambas
Eof
TheEoffunctionreturnsaBooleanvalueofTRUEifweareattheendof
thestream.StandardGambaslanguagesyntaxis:
Boolean=Eof(File)
AnexampleofhowEofisusedfollows:
...
OPENFileNameFORREADAS#hFile
WHILENOTEof(hFile)
LINEINPUT#hFile,OneLine
PRINTOneLine
WEND
CLOSE#hFile
...
Exist
Boolean=Exist(Path)
HereisanexampleofusingExisttodetermineifafileexistsbeforecallingOPEN
toreadthefile:
...
DIMsCurrentFileNameASString
sCurrentFileName="TheRaven.txt"
IFExist(sCurrentFileName)THEN
...'openthefile
ELSE
Message.Info("File"&sCurrentFileName&"doesnotexist.")
ENDIF
...
190
A Beginner's Guide to Gambas
IsDir/Dir?
TheIsDirfunctionreturnsTRUEifapathpointstoadirectory.Ifthepath
does not exist or is not a directory, this function returns FALSE. Gambas
languagesyntaxforIsDiris:
Boolean=IsDir(Path)
Some examples of how to use IsDir that were provided on the Gambas
documentationWikiare:
PRINTIsDir("/etc/password")
False
PRINTIsDir(Application.Home&/".gambas")
True
PRINTIsDir("/windows")
False
Stat
TheStatfunctionreturnsinformationaboutafileoradirectory.TheFile
objectinformationreturnedincludesthetype,size,lastmodificationdate/time,
permissions,etc.Thefollowingfilepropertiescanbeobtainedusingthisfunction:
ThestandardGambaslanguagesyntaxforStatis:
Fileinfo=Stat(Path)
Here is an example of how to use Stat and what will be returned from the
console:
WITHStat("/home")
PRINT.Type=gb.Directory
PRINTRound(.Size/1024);"K"
ENDWITH
Theconsolewillrespondwith:
191
A Beginner's Guide to Gambas
True
4K
Temp/Temp$
TheTemp$functionreturnsauniquefilenameusefultocreatetemporary
files. The filename created will be located in the /tmp directory. Gambas
languagesyntaxis:
Filename=Temp$()
Example:
PRINTTemp$()
/tmp/gambas.0/12555.1.tmp
OPENandCLOSE
OPENandCLOSEworkasateam.OPENopensafileforreading,writing,
creatingorappending data. UnlesstheCREATEkeywordisspecified,thefile
mustexist.IftheCREATEkeywordisspecified,thenthefileiscreated,orcleared
ifitalreadyexists.Ifthefileisopenedforwriting,thepathtoitmustbeabsolute
becauserelativepathsare,bydefault,assumedtorefertofilesthatexistinside
thecurrentGambasprojectorarchivefolder.GambaslanguagesyntaxforOPEN
is:
OPENFilenameFOR[READ][WRITE][CREATE|APPEND][DIRECT]
[WATCH][BIG|LITTLE]AS#Variable
Ifatleastonebytecanbereadfromthefile,theeventhandlerFile_Read()iscalled.
Ifatleastonebytecanbewrittentothefile,theeventhandlerFile_Write()iscalled.
IftheBIGorLITTLEkeywordisspecified,allsubsequentREADandWRITE
operationsonthisfilewill use bigEndian or littleEndian data representation.
Variable receives the object that represents the opened stream. CLOSE is the
reciprocalfunctionandsimplyclosesanopenedfile.SyntaxforusingCLOSEis:
192
A Beginner's Guide to Gambas
CLOSE#File
Hereisanexamplethatopensandclosesafile:
'GambasClassFile
sCurrentFileNameASString
sCurrentFileLengthASInteger
PUBLICSUBForm_Open()
DIMsInputLineASString
DIMhFileInASFile
sCurrentFileName="TheRaven.txt"
IFExist(sCurrentFileName)THEN
OPENsCurrentFileNameFORREADAShFileIn
sCurrentFileLength=Lof(hFileIn)
WHILENOTEof(hFileIn)
LINEINPUT#hFileIn,sInputLine'LINEINPUTisexplainedbelow
TextArea1.Text=TextArea1.Text&Chr(13)&Chr(10)&sInputLine
WEND
CLOSEhFileIn
ELSE
Message.Info("File"&sCurrentFileName&"doesnotexist.")
ENDIF
END
LINEINPUT
LINEINPUTreadsanentirelineoftextonthestandardinput.Itcanbe
usedontheconsoleorwithfiles.TheGambaslanguagesyntaxis:
LINEINPUTVariable
or,forfileswherethedataisreadfromthestreamFile:
LINEINPUT#File,Variable
HereisanexampleyoucantrytoseehowLINEINPUTworks:
STATICPUBLICSUBMain()
DIMhFileASFile
DIMsInputLineASString
193
A Beginner's Guide to Gambas
DIMlineCtrASInteger
OPEN"TheRaven.txt"FORREADAS#hFile
WHILENOTEof(hFile)
LINEINPUT#hFile,sInputLine
PRINTStr(lineCtr)&Chr(9)&sInputLine
INClineCtr
WEND
CLOSE#hFile
END
READ#hFile,OneLine,256
READ,SEEK,WRITEandFLUSH
TheREADfunctionreadsdatafromthestandardoutput.Ittreatstheinput
streamasbinarydatawhosedatatypeisspecifiedbythetypeofthevariablethe
dataisstoredinduringthereadoperation.Thebinaryrepresentationofthedata
shouldbethesamerepresentationcreatedbyuseoftheWRITEinstruction. If
Variableisastring,youcanspecifyalengththatindicatesthenumberofbytesto
read.IfthevalueoftheLengthparameterisnegative,thenLengthbytesareread
fromtheendofstream.IfnoLengthparameterisspecifiedforastring,theentire
stringisreadfromthestream.Thestringvaluethenmusthavebeenwrittenwith
theWRITEinstruction.StandardGambaslanguagesyntaxforREADis:
READVariable[,Length]
IfREADisusedwithfileoperations,theGambaslanguagesyntaxis:
READ#File,Variable[,Length]
TheWRITEfunctionwritesexpressionstothestandardoutputusingtheir
binary representation. If Expression is a string, you can specify a length that
indicatesthenumberofbytestowrite.Ifnolengthisspecifiedforastringvalue,
theentirestringvalueiswrittendirectly tothestream. HereistheGambas
194
A Beginner's Guide to Gambas
languagesyntaxforstandardinputstreams:
WRITEExpression[,Length]
andforwritingtoafile,thisistheconvention:
WRITE#File,Expression[,Length]
TheSEEKfunctiondefines(ormoves)thepositionofthestreampointer,
most often in preparation for the next read/write operation. If the position
specifiedbythe Length parameterisnegative,thenthestreampointerismoved
backwards Length bytesfromtheendofthefile. Tomovethestreampointer
beyondtheendofthefile,youmustusethe Lof()function. StandardGambas
languagesyntaxis:
SEEK#File,Position
HerearesomeexamplesofusingSEEK:
'Movetothebeginningofthefile
SEEK#hFile,0
'Moveaftertheendofthefile
SEEK#hFile,Lof(#hFile)
'Move100bytesbeforetheendofthefile
SEEK#hFile,100
TheFLUSHfunctioniscalledtoempty(orflush)thecontentsofabuffered
data stream.Ifnostreamisspecified,everyopenstreamisflushed. Typically,
FLUSHiscalledaftermultiplewriteoperationsandbeforeclosingoutaprogram
or routine toensure all data held in a bufferis written out to the file before
exiting.HereistheGambaslanguagesyntaxforFLUSH:
FLUSH[#File]
COPY,KILLandRENAME
195
A Beginner's Guide to Gambas
COPYSource_pathTODestination_path
HereisanexampleofhowtouseCOPY:
'Savethegambasconfigurationfile
COPYSystem.Home&/".gambas/gambas.conf"TO"/mnt/save/gambas.conf.save"
RENAMEOldnameASNewname
MKDIR,RMDIR
TheMKDIRfunctionisusedtocreate(make)afolderonyourfilesystem
andRMDIRisusedtoremoveafolder.Bothfunctionstakeasingleparameter,a
Filepathandname.TheGambaslanguagesyntaxis:
MKDIRfile:/rittingj/MyDocuments/Gambas/test
RMDIRfile:/rittingj/MyDocuments/Gambas/test
InordertodemonstratemostofthefileandI/Ofunctionsdescribedinthis
chapter,wearegoingtocreateanapplicationthatwillactasasimpletexteditor.
Theintenthereisnottocreateafullblowntexteditor,buttoshowyouhowto
usethesefunctionsinthecontextofanapplication.Theapplicationwewillbuild
inthischapterisalittlemorecomplexthanwhatwehaveseensofarinthatwe
willbecreatingtwoforms,aninputfile,ahelpfile,andusingquiteafewsystem
iconswhichwillbecopiedfromtheLinuxOSdistribution'ssystemIconfolder(s).
Hereiswhatourapplicationwilllooklikeatruntime:
Figure72TheFileOpsprogramatruntime.
196
A Beginner's Guide to Gambas
Inthisprogram,wewillcreateamainmenu,atextareatodisplayandedit
textwith,andwewillcreatestatuselementsatthebottomofthedisplay.Wewill
alsointroductuseoftheTimercontrol(shownastheclockinthepicturebelow).
Thisform,namedForm1.form,willlooklikethisindesignmode:
Tostart,loadGambasandcreateanewgraphicaluserinterfaceproject.
NameitFileOpsandwhenyougettotheGambasIDE,createanewform,Form1
andmakeisastartupclass.Whentheformdisplaysonyourscreen,wearegoing
tobeginbycreatingthemenus. Youcanpress CTRLE tobringupthe Menu
Editor.Addthefollowingmenuitemsshowninthetablesbelowusingtheeditor.
Fortheicons,youwillneedtocopyiconsfromthesamedirectorywespecifiedin
thelastchapter. Most Linuxbaseddistributionshaveiconfilesthatareusually
stored in the folders namedfile:/usr/share/icons/defaultkde/32x32/actions
orfile:/usr/share/icons/defaultkde/32x32/applications. Your particular system
maybeslightlydifferent.Regardlessofwhereyoufindtheicons,pickouticons
appropriateforourprogramandcopythemtotheFileOpsfolder.Herearethe17
iconsIchosetouseforthisproject:
197
A Beginner's Guide to Gambas
If you cannot find the exact same icon, simply pick one that is most
appropriateandsaveitwiththefilenameforthatoptionasshowninthetables
below.Itisnotcrucialthateveryiconbeexactlythesame.Infact,theSelectAll
iconwascreatedusingtheGambasIconEditor.
FileMenu
VariableName Caption IconProperty(filename)
FileNewItem "New" Picture["filenew.png"]
FileOpenItem "Open..." Picture["fileopen.png"]
FileSaveItem "Save..." Picture["filesave.png"]
FileSaveAsItem "Saveas..." Picture["filesaveas.png"]
FilePrintItem "Print" Picture["fileprint.png"]
FileExitItemMenu "Exit" Picture["exit.png"]
EditMenu
VariableName Caption IconProperty(filename)
EditSelectAllItem "SelectAll" Picture["selectall.png"]
EditUndoItem "Undo" Picture["undo.png"]
EditRedoItem "Redo" Picture["redo.png"]
EditCutItem "Cut" Picture["editcut.png"]
EditCopyItem "Copy" Picture["editcopy.png"]
EditPasteItem "Paste" Picture["editpaste.png"]
EditPrefsItem "Preferences" Picture["configure.png"]
FormatMenu
VariableName Caption IconProperty(filename)
FomatColorItem "Colors" Picture["colorize.png"]
FormatFontItem "Font" Picture["charset.png"]
HelpMenu
HelpContentsItem "Contents" Picture["contents.png"]
HelpAboutItem "About" Picture["buildingblocks.png"]
198
A Beginner's Guide to Gambas
HereisthecodeforwewilluseforForm1.Wewillgothruthislinebyline
soeverythingisfullyexplained. Westartourprogrambydeclaringtwoclass
globalvariables,sCurrentFileNameandsCurrentFileLength.
'Gambasclassfile
sCurrentFileNameASString
sCurrentFileLengthASInteger
Whentheprogramstarts,thissubroutineiscalled.Itcallsaconstructor,_new()
toinitialize.Theconstructorisexplainedinthenextsection.Whenourprogram
starts,wearegoingtohaveitautomaticallyloadourdefaulttextfile,namedThe
Raven.txt.ThisfilewascopiedofftheInternetandyoucanplaceanytextfilein
theFileOpsprojectfoldertouseforthisproject.Justrememberthatthefilename
has to be changed in the code below if you choose not to use our default
filename.
PUBLICSUBForm_Open()
DIMsInputLineASString
DIMhFileInASFile
WewillassignourfilenametothesCurrentFileNamestringvariableand
checktoseeifthefileexistsintheprojectfolder.Ifitexists,thentheprogram
willopenthefileandgettheinitialfilelength.Wewilldisplaythefilenameand
sizeintheForm1.Captionproperty.Whileitisnotcustomarytodisplaythefile
sizelikethis,itisdoneheresimplytodemonstratetheuseoftheLoffunction.
sCurrentFileName="TheRaven.txt"
IFExist(sCurrentFileName)THEN
OPENsCurrentFileNameFORREADAShFileIn
sCurrentFileLength=Lof(hFileIn)'toshowhowtogetfilesize
Form1.Caption=""&sCurrentFileName&",size:"&Str
(sCurrentFileLength)&"bytes."
Now,wewillenteraloopstructuretoreadallthelinesofthetextfileinto
ourTextArea1.Textproperty.Wewillcontinuetoloopuntilwehavereachedthe
endofthefile. Aswereadeachlineintomemoryandassignittothevariable
sInputLine,wemustremembertoaddtheCRLF(aCarriageReturn(Chr(13)and
aLineFeed(Chr(10)) totheendofthelinesoitwilldisplayproperlyinthe
control.
WHILENOTEof(hFileIn)
LINEINPUT#hFileIn,sInputLine
TextArea1.Text=TextArea1.Text&Chr(13)&Chr(10)&sInputLine
WEND
199
A Beginner's Guide to Gambas
Assoonasweexittheloop,meaningwehavereachedtheendofthefile,
wewillclosethefile.
CLOSEhFileIn
Ifourchecktoseeifthefileexistsfailed,wewouldenterthisELSEblock
ofcodeanddisplayamessageindicatingthatthefiledidnotexist.Next,wecall
ourFileOpenItem_Click()subroutinetohavetheuserpickafiletoopen.
ELSE
Message.Info("File"&sCurrentFileName&"doesnotexist.")
FileOpenItem_Click()'forceafiletobepickedifnodefault.
ENDIF
END
ThatisallthereistotheForm_Open()subroutine.Hereistheconstructorforthe
form:
PUBLICSUB_new()
Timer1.Delay=1000
Timer1.Enabled=TRUE
END
Theconstructorsimplysetsthetimerdelayto1second(1000ms)andsets
theenabledpropertytotrue. Theneteffecthereisthatthetimerwillupdate
itselfeverysecond.Wewillimplementthetimercontrollaterinthiscode.
Let'snowturnourattentiontotheFile|Newmenuoption.Foranewfile
tobecreatedbytheuser,wemustfirstblankoutthetextintheTextArea1.Text
property.Wewillprompttheuserforanewfilenameandsavetheblankfileto
disktocreateit. Whateverchangestheuserwillmakewillbesavedonexitor
whenevertheuserchoosestosavefromthemenu.Thelastthingwedointhis
subroutineissettheForm1.Captionpropertytothenewlysavedfilename.
PUBLICSUBFileNewItem_Click()
TextArea1.Text=""
Dialog.Title="Enternewfilename..."
Dialog.Filter=["Textfiles(*.txt)","Allfiles(*.*)"]
Dialog.SaveFile
Form1.Caption=Dialog.Path
END
ThenextroutineisactivatedwhentheuserclickstheFile|Openmenuitem.
200
A Beginner's Guide to Gambas
PUBLICSUBFileOpenItem_Click()
Thisroutinerequirestwolocalvariables.hFileInisthehandletotheFILEobject
wewillopenandsInputLineisastringvariablethatwewillusetoreadthetext
fileintoourTextArea1.Textproperty.
DIMhFileInASFile
DIMsInputLineASString
Justbeforethecalltothestandarddialog,wecansetthewindowcaption
(ortitle)usingtheDialog.Titleproperty.Wewillalsosetafilterforthedialogto
onlylookforfileswitha.txtextension. Asalastresort,wewilllettheuser
choosetoviewalltypesoffilesbyselectingthefilter*.*fromwithinthedialog.
Dialog.Title="Chooseatextfile"
Dialog.Filter=["Textfiles(*.txt)","Allfiles(*.*)"]
WhenthecalltoDialog.OpenFileismade,rememberthatitwillreturna
TRUEvalueiftheuserclicksontheCancelbutton,otherwise,FALSEisreturned.
WewillcheckforaTRUEvalueandreturnifthatiswhatweget.Otherwise,it
meanstheuserselectedafileandwewillprocessit.
IFDialog.OpenFile()THEN
RETURN
ELSE
The filename of the file that was selected by the user is stored in the
Dialog.Pathproperty.WewillassignthattotheglobalvariablesCurrentFileName
so other parts of the program will have access to it. We will set the
Form1.Caption property to the name of the newly opened file and clear the
currentTextArea1displaybyinvokingtheClearmethod.
sCurrentFileName=Dialog.Path
Form1.Caption=""&sCurrentFileName&""
TextArea1.Clear
Next,wewillopenthefileandreadeachlineintomemoryusingtheLINE
INPUTfunctionandourstringvariablesInputLine. Oncethedataisstoredin
sInputLine, we will add it to the end of whatever is currently stored in the
TextArea1.Textproperty(effectively concatenating ontotheendofthecurrent
textvalue)andaddourCRLFcharacters.Oncewereachtheendofthefile,we
willexittheloopandclosethefile.
201
A Beginner's Guide to Gambas
OPENsCurrentFileNameFORREADAShFileIn
WHILENOTEof(hFileIn)
LINEINPUT#hFileIn,sInputLine
TextArea1.Text=TextArea1.Text&Chr(13)&Chr(10)&sInputLine
WEND
CLOSEhFileIn
ENDIF
END
TheFile | Savemenuitem,whenclicked,willinvokethissubroutine. It
worksalmostlikethepreviousoneexceptthatwealreadyknowthenameofthe
file held in the global variable sCurrentFileName. When we return from the
standarddialogcall,weupdatetheglobalvariablewithwhateverwasreturned
notcaringifthefileisthesamenameornot.Whateveritisorhasbecomewill
bewhatissaved.
PUBLICSUBFileSaveItem_Click()
Dialog.Title="Savetextfile"
Dialog.Filter=["Textfiles(*.txt)","Allfiles(*.*)"]
IFDialog.SaveFile()THEN
RETURN
ELSE
sCurrentFileName=Dialog.Path
File.Save(sCurrentFileName,TextArea1.Text)
ENDIF
END
ThenextsubroutinewewillcodeistheFileSaveAsmenuitem.Iftheuser
wantstosavetheexistingfileunderadifferentfilename,thisistheroutineto
handle thatoption. Forthissubroutine,itwillworkalmostidenticallytothe
FileSavesubroutinebutwewillneedtochecktoseeifthefilenamereturnedfrom
thestandardfiledialogisactuallydifferentthanthecurrentfilename. Ifitis
different,thenwewillsavethefileunderthenewname.Ifthenameisthesame,
wewillpopupaMessageBoxandinformtheuserthatnosaveactionwastaken
becausethenameswereidentical.
PUBLICSUBFileSaveAsItem_Click()
DIMsTmpNameASString
WeusethelocalstringvariablesTmpNametomakeourcheck.Firstofall,
we need to the the full path to the application and concatenate the current
filenametothattogetthefullyqualifiedpathnameforourfile. Weusethe
Applicationclassforthatpurpose,checkingthePathpropertytogetthenameand
path of the running application. Note the use of the &/ operator which is
202
A Beginner's Guide to Gambas
specificallyusedtocatenatefilenames.
sTmpName=Application.Path&/sCurrentFileName
Justaswedidpreviously,wewillsetthetitleandfilterproperties,then
callthestandardfiledialog.
Dialog.Title="Savetextfileas..."
Dialog.Filter=["Textfiles(*.txt)","Allfiles(*.*)"]
IfthestandarddialogcallreturnsTRUE,theuserhascancelledoutofthe
routineandwewillsimplyreturntothecallingprocess(i.e.,ourstandardevent
loop).
IFDialog.SaveFile()THEN
RETURN
Ifthefilenamesarethesame,wewillpopuptheMessageBoxandreturn:
ELSEIFsTmpName=Dialog.PathTHEN
Message.Info("Filenotsaved:namesameascurrentfile.","OK")
RETURN
Otherwise,wesettheglobalvariabletothefilenamereturnedfromthe
standardfiledialogandcalltheSavemethod,passingthefilenameandourtext
asparameters. Weupdatethecaptionofthewindowasthelastthingwedo
beforereturningtothecallingprocess.
ELSE
sCurrentFileName=Dialog.Path
File.Save(sCurrentFileName,TextArea1.Text)
Form1.Caption=sCurrentFileName
ENDIF
END
PrintinganytypeofitemisprettyeasyinGambas.OurFile|Printmenu
itemwillinvokethissubroutinewhenclicked.Wewilldeclareourlocalvariables
first:
PUBLICSUBFilePrintItem_Click()
'integervariablestoholdourmarginvalues
DIMiLeftMarginASInteger
DIMiTopMarginASInteger
DIMiRightMarginASInteger
DIMiBottomMarginASInteger
203
A Beginner's Guide to Gambas
'stringvariableswewilluse
DIMarsTxtToPrintASString[]
DIMiTxtPosYASInteger
DIMsTxtLineASString
DIMstrMsgASString
'integervariablesourprogramusestocalculatepagedimensions
DIMiPrinterAreaWidthASInteger
DIMiPrinterAreaHeightASInteger
Thenextcallensuresthedefaultpapersizeissetto8.5by11(Letter).If
youarenotintheUnitedStates,itshouldprobablybesettoA4asthatisthe
standardusedinmostplacesoutsidetheU.S.TheGambasPrinter.Setupdialog
defaultstoA4settingseverytimeyoucallit,soifyouareusingaprinterthat
onlyusesLettersizepaper,overridingthispropertyistheeasiestwaytohandle
thatsituation.
'overridetheprinter.setupdialogsoyoudon'thave
'tosetthiseverysingletimeyouprintsomething
Printer.Size="Letter"'orA4,orwhateveryouuse
'olderprintersdonotseemtobesettoDPIslowerthan600inGB
'sowewillsetitmanuallyforanolderHPLaserjetIIIprinter
'ifyourprinterisnewer,youcancommentthislineout
Printer.Resolution=300'myHPLJIIIsettings
Fora300dpiprinter,avalueof300wouldequalaoneinchmargin.Now,
wesetthemarginvaluesbyusingthePrinterproperties(ortheonesweoverrode
above)returnedfromthePrinter.Setupcall.
'setleftmargintooneinch,equaltotheDPIoftheprinter
iLeftMargin=Printer.Resolution
'settopmargintooneinch,equaltotheDPIoftheprinter
iTopMargin=Printer.Resolution
'setrightmargintooneinch,equaltotheDPIoftheprinter
iRightMargin=Printer.Resolution
'settopmargintooneinch,equaltotheDPIoftheprinter
204
A Beginner's Guide to Gambas
iBottomMargin=Printer.Resolution
'DefinethePrintableareawidth
iPrinterAreaWidth=Printer.WidthiLeftMarginiRightMargin
'DefinethePrintableareaheight
iPrinterAreaHeight=Printer.HeightiTopMarginiBottomMargin
'showaMessageBoxwithdataobtainedfromtheprintersetupcall
message.Info(strMsg)
Next, we need to parse all of the content of the text in the TextArea1
controlintoastringarray.ItisveryeasytodoinGambasandonlytakesasingle
line of code. To do this,we willuse theSplitfunction and setthe delimiter
parametertothe'\n'characterwhichdesignatestheendofthelineoftext:
'useanarrayofstringstostoreeachlineoftextinTextArea1.Text
arsTxtToPrint=Split(TextArea1.Text,"\n")
Inourcodebelow,wehavecalledtheDraw.Rectfunctiontodrawaborderatone
inchmarginsaroundourpage.
'makeaborderaroundthepage
Draw.Rect(iLeftMargin,iTopMargin,iRightMargin,iBottomMargin)
'nowwewillloopthrougheachlineinthearrayandprintit
205
A Beginner's Guide to Gambas
FOREACHsTxtLineINarsTxtToPrint
'incrementthevertical(Y)linepositionforeachlineprinted
iTxtPosY=iTxtPosY+Draw.TextHeight(sTxtLine)
'testthelineposition...ifis>thebottomoftheprinter
'areathenweneedtoresetittozeroandperformanewpage
IFiTxtPosY>=(iPrinterAreaHeight)THEN
iTxtPosY=0'reinittheCurrentTextPositionY
Printer.NewPage
'makeaborderaroundthenewpage
Draw.Rect(iLeftMargin,iTopMargin,iRightMargin,iBottomMargin)
ENDIF'ourtesttoseeiflinefallspastbottommargin
Now,wewillmakethecalltoDraw.Texttoactuallyprintthetext. The
firstparameterDraw.TexttakesisthestringobjectsTxtLinerepresentingourline
of text to be printed from the array of string arsTxtToPrint. The next two
parameters, iLeftMargin and (iTopMargin+iTxtPosY) areused todefine theleft
marginandthecurrentverticalTextYposition.Eachlineisincrementedbythe
valueheldintheproperty Draw.TextHeight. Optionally,youcanspecifyright
andbottommargins,andanalignmentproperty.Inourcasebelow,wespecified
the right margin, defined by iPrinterAreaWidth (as we calculated above) and
omittedthebottommarginsinceitismaintainedinthecodeoftheFORLOOP
above.Finally,wehavespecifiedthealignmentofthetexttobeleftaligned.
'Nowweprintthetextlineatthenewlineposition
Draw.Text(sTxtLine,iLeftMargin,iTopMargin+iTxtPosY,iPrinterAreaWidth,,Align.Left)
NEXT'iterationoftheFORLOOP
Tofinishtheprintprocess,youMUSTremembertocallDraw.End:
Draw.End'Thenprintfinalcontentsandejectlastpage
END
Sinceourexampleprogramonlyworkswithtextfiles,thereisanalternate,
sometimeseasiermethodofprinting.Youcanusethesystem'sbuiltinpr(print)
command. ItisinvokedusingtheGambasSHELLmethod. Thiscallcanallow
youtoprintanytextfilefromwithinyourprogramdirectlytothedefaultprinter.
Toseehowthismethodworks,let'saddamenuitemtoourprogramandtrythis.
GototheForm1.formandpressCTRLEtobringupthemenueditor.Belowthe
File|Printmenuitem,addanewitem, FileSysPrintItem andgiveitthecaption
Print(systemmethod).Createaclickeventandaddthiscode:
PUBLICSUBFileSysPrintItem_Click()
206
A Beginner's Guide to Gambas
DIMaStringASString
aString="prh\""&sCurrentFileName&"\""&"o10<\""&
sCurrentFileName&"\"|lpr"
message.Info(aString,"Ok")
SHELLaString
END
Itlooksalotmoredifficultthatitreallyis.Let'sgolinebylinethroughthe
code.First,wedeclareastringvariable,aString.Nextweneedtobuildthestring
thatwillbepassedofftothesystemasaconsolecommandandassignittoyour
aString variable. Becausewemustensurethestringisbuiltexactlyasitwould
have to be typed from the console, we must ensure it contains quote marks
embeddedinit.Thefirstpartofthestring:
"prh\""
willinvokethesystemcommandpr.Thehparameterspecifiesthatwewantto
haveaheaderprintedoneachpage,inthiscase,itwillbethecurrentfilename,
heldinthevariablesCurrentFileName,which,inourprogram,isglobalinscope.
This filename has to be embedded in quote marks so we need to use the \
characterbeforetheopeningquotemarkandterminatethispartofthestringwith
anotherquotemark.Thenextpartofthestring:
&sCurrentFileName&"\""
concatenatesthefilenameandtheterminatingquoteforthefilenamepassedinas
astringvariable,onceagainprecededbya \ character. Thenextquotemark
terminates this portion of the string. The next part of the command to
concatenateis:
&"o10<\""
whichaddstheoparameter(whichspecifiesanoffset)andavalueof10spaces.
The<characterisusedonthecommandlinetodesignatetheinputstreamcomes
fromthefilenamethatfollowsthe<character.Inthiscase,weneedtodelimit
our string with quotes again, so the \ character is used to allow the quote
charactertobepartoftheoutputstring. Thenextquotecharacterbeginsthe
quotedfilenamestring.Thelastpartofourcommandis:
sCurrentFileName&"\"|lpr"
207
A Beginner's Guide to Gambas
Itspecifiesthefiletoread(andprint)andterminatesthefilenamewith
quotemarksasexplainedbefore. Thefinalpartofthestringisthe|character
which pipes (redirects)theoutputtothelineprinter(lpr). Inall,ittakesone
variabledeclarationandthreelinesofcodetoprintafileusingthistechnique.
Eithertechniquewillworksochoosetheonethatsuitsyoubest.Anothermethod
thatyoucanuseifyouhaveKDEinstalledistoprinttoapostscriptfileandsend
the.psfileto'kprinter'.ThiswillprovideyouwithaccesstotheKDEprintdialogs
andalloftheCUPSprintersandfeaturesinstalledonyoursystem.
IftheuserclicksontheFile|Exitmenuitemwecouldsimplyclosethe
program.However,wewanttogivetheuserachancetosavebeforeexitsowe
willpopupaquestiondialogtoaskiftheywanttosavethefile. Ifso,wewill
saveit.Ifnot,wesimplyexittheprogram.
PUBLICSUBFileExitItem_Click()
DIMiResultASInteger
iResult=Message.Question("Saveyourwork?","Yes","No","Cancel")
SELECTCASEiResult
CASE0
File.Save(sCurrentFileName,TextArea1.Text)
CASE1
CASE2
CASEELSE
ENDSELECT
ME.close
END
That'sitfortheFileMenu. Now,therealpowerofGambaswillbecome
obviousaswebuildthecodefortheEditmenufunctions. Fromthismenu,we
wanttheusertobeabletoselectalltext,undo,redo,cut,paste,copyorcalla
configurationroutine.Forourpurposes,theconfigurationroutinewillbepretty
simple,butitshouldbeenoughtoshowyouhowtoaccomplishthetask.
IftheuserclicksontheEdit|SelectAllmenuitem,itwillselectallthetext
in the TextArea. This is done be obtaining the length of the text using the
TextArea1.Length property and passing that value to the TextArea1.Selection
MethodwithastartingpointofzeroandanendingpointLengthcharactersfrom
thatstartpoint,asshowninthecodebelow.
PUBLICSUBEditSelectAllItem_Click()
DIMilengthASInteger
ilength=TextArea1.Length
TextArea1.Selection(0,ilength)
END
208
A Beginner's Guide to Gambas
Thecodeabovecouldalsohavebeenwritteninamoresimplifiedmanner
withoutusingtheIntegervariableiLength.Itcouldhavebeenreducedtoasingle
line,asshownbelow:
PUBLICSUBEditSelectAllItem_Click()
TextArea1.Selection(0,TextArea1.Length)
END
Eithermethodwillworkbuttheauthor'spreferenceistousethesecond
methodasitreflectsthesimplicityofGambaswhenprogramming.Thissimplicity
is seen in the use of the builtin Undo, Redo, Cut, Paste and Copy methods
providedbyGambasforTextArea1.Textaswell.Gambasprovidesthesemethods
soprovidingthiscapabilityforyourprogramusersisasimplematterofaddinga
singlelineofcodeforeachmenuitem'sclickevent,asshownbelow:
PUBLICSUBEditUndoItem_Click()
TextArea1.Undo
END
PUBLICSUBEditRedoItem_Click()
TextArea1.Redo
END
PUBLICSUBEditCutItem_Click()
TextArea1.Cut
END
PUBLICSUBEditPasteItem_Click()
TextArea1.Paste
END
PUBLICSUBEditCopyItem_Click()
TextArea1.Copy
END
OurEdit|Preferencesmenuoptionwillbeusedtoshowyouhowtobring
upasecondforminyourprogram. Wewillsavethedatagatheredfromthe
Form2.forminaconfigurationfilenamedFileOps.confandthatwillenableusto
passthosesavedvaluesbackandforthbetweenthemainform,Form1.formand
thesecondform,Form2.form.Thisistheeasiestwaytoexchangedatabetween
classes but it is possible to pass data as parameters between forms. We will
discuss that later in this book. The EditPrefsItem_Click() subroutine is pretty
simple.Wejustshowthesecondform.
PUBLICSUBEditPrefsItem_Click()
209
A Beginner's Guide to Gambas
Form2.Show
END
HereiswhatForm2.formwilllooklike:
Figure73Form2.formdesignmode.
Asyoucansee,itisprettybasic.ATextLabelisusedtodisplaythedefault
path. There are two buttons, one to change the default path by calling the
standard Dialog.SelectDirectory routine and the other to return to the calling
process,Form1.forminthiscase.Whentheformisopened,wewilldisplaythe
captionPreferencesatthetopofthewindow.Theconstructorroutine_new()is
calledautomatically.HereisthecodeforourForm2:
'Gambasclassfile
PUBLICSUBForm_Open()
Form2.Caption="Preferences"
END
TheconstructorwillcalloursubroutineReadPrefs,passingthenameofthe
configurationfileasaparameter.FileOps.confisthenamewewilluseforholding
ourapplication'sconfigdata. Next,wepopulate theTextLabel1.Textproperty
withthecurrentdefaultdirectory,whichdefaultstowheretheapplicationresides
ondisk.
PUBLICSUB_new()
ReadPrefs("FileOps.conf")
TextLabel1.Text=Application.Path&"isthedefaultdirectory."
END
WhentheuserclickstheChangeDefaultPathbutton,thefollowingroutine
iscalled:
PUBLICSUBButton1_Click()
Dialog.SelectDirectory
TextLabel1.Text=Dialog.Path
END
210
A Beginner's Guide to Gambas
MyPath=application.Path&/"FileOps.conf"
WritePrefs(MyPath)
Form2.Close
END
Asyoucanseefromabove,alocalstringvariableMyPathisdeclaredand
populatedbyconcatenatingthecurrentapplicationpathwiththeconfiguration
filenameFileOps.conf.Next,wecallourWritePrefssubroutineandpassthevalue
ofMyPathasaparameter.Thatpathwillbestoredinthefileandcanbereadby
anyotherclassthatneedstofindoutthisinformation. HereistheReadPrefs()
subroutineforaccomplishingthistask:
PUBLICSUBReadPrefs(filenameASString)
'declareourlocalvariables
DIMsInputLineASString
DIMhFileInASFile
'seeifthefilealreadyexists,ifsoopenit.
IFExist(filename)THEN
OPENfilenameFORREADAS#hFileIn
'readoursinglelineofdata
'ifthereweremorelines,wecouldsetupaWHILENOTEofLOOP
LINEINPUT#hFileIn,sInputLine
'updatethedisplaydata
TextLabel1.Text=sInputLine
'closethefile
CLOSE#hFileIn
ELSE
'therewasno.conffiletoopen
Message.Info("Nopreferences.conffilepresent.","OK")
ENDIF
END
211
A Beginner's Guide to Gambas
Thereciprocalroutine,WritePrefs()isshownbelow:
PUBLICSUBWritePrefs(filenameASString)
'declareourlocalvariables
DIMMyPathASString
DIMhFileOutASFile
'noteweareusingtheDialog.Pathvalue,notApplication.Path
MyPath=Dialog.Path&/filename
'ifthereisalreadyaconfigfile,openitforwrite
'ifnot,openforcreateandwrite
IFExist(MyPath)THEN
OPENMyPathFORWRITEAS#hFileOut
ELSE
OPENMyPathFORWRITECREATEAS#hFileOut
ENDIF
'printourdatatothefile
PRINT#hFileOut,MyPath
'closethefile
CLOSE#hFileOut
END
PUBLICSUBFormatColorItem_Click()
'first,popupamessagetoexplainhowwearegoingtowork
Message.Info("SelectBackgroundcolorfirst,textcolorsecond.","OK")
'setdialogcaptiontoremindtheuserweareselectingBACKGROUND
Dialog.Title="SelectBackgroundColor"
'callthestandarddialogroutinetoselectcolor
Dialog.SelectColor
'updateourTextArea1.Backcolorwiththevalueselected.
TextArea1.BackColor=Dialog.Color
212
A Beginner's Guide to Gambas
'setdialogcaptiontoremindtheuserweareselectingFOREGROUND
Dialog.Title="SelectTextColor"
'callthestandarddialogroutinetoselectcolor
Dialog.SelectColor
'updateourTextArea1.ForeColorwiththevalueselected.
TextArea1.ForeColor=Dialog.Color
END
Selectingthefontanditsattributesforourprogramisjustassimpleasit
wastochoosecolors.Basically,wewillsetthedialogcaption,callthestandard
Dialog.SelectFontroutine,andupdateourTextArea1.Fontproperty,likethis:
PUBLICSUBFormatFontItem_Click()
Dialog.Title="Selectfont"
Dialog.SelectFont
TextArea1.Font=Dialog.Font
END
PUBLICSUBTimer1_Timer()
'getthetimeforrightnowandconverttoastring
'toputintheTimeLabel.Textproperty
TimeLabel.Text=Str$(Now)
'wewillgetlineandcolumndatafromthe.Lineand
'.ColumnpropertiesoftheLabelcontrolandupdatethe
'PosLabel.Textpropertywiththeirvalues:
PosLabel.Text="Line:"&Str(TextArea1.Line)&"Col:"&Str
(TextArea1.Column)
END
ThelastmenuisourHelpmenu.Ithastwooptions,ContentsandAbout.
PUBLICSUBHelpContentsItem_Click()
SHELL"konqueror\"file:/root/MyDocuments/GambasforBeginners/FileOps/Help.html\""
END
213
A Beginner's Guide to Gambas
demonstrating this feature, simply copy any .html file on your system to the
programdirectoryand renameithelp.html. Asanalternative,youcancreate
yourown.htmlfileifyouknowhowtodothat.Thatiswhatrealprogrammers
woulddo.Hereisthelastthingweneedtodo:
PUBLICSUBHelpAboutItem_Click()
Message.Info("<b>SimpleTextEditor</b>by<br>J.Rittinghouse","OK")
END
Runtheprogramandwhenyouaresatisfied,let'smoveontodosomemath.
214
A Beginner's Guide to Gambas
Intrinsicfunctionsarebuiltintothecompilerofaprogramminglanguage,
usuallytotakeadvantageofspecificCPUfeaturesthatareinefficienttohandle
via external functions. The compiler's optimizer and code generator fully
integrate intrinsic functions, which can result in some surprising performance
speedups in calculation. Derived functions, on the other hand, are built in
Gambasbyusingknownmathematicalformulastoapplyspecificalgorithmsthat
implement intrinsic functions. A table of derived functions and their
correspondingalgorithmscanbefoundattheendofthischapter.
PrecedenceofOperations
WhenyouusevariousoperatorsinanexpressioninGambas,thereisa
specificprecedenceofoperationsthatGambasusestoperformtheoperation.A
welldefinedprotocolisfollowed:
Allexpressionsaresimplifiedwithinparenthesesfromtheinsideoutside
Allexponentialoperationsareperformed,proceedingfromlefttoright
Allproductsandquotientsareperformed,proceedingfromlefttoright
Allsumsanddifferencesareperformed,proceedingfromlefttoright
Bearinginmindtheorderofoperations(i.e.,theprecedence),youcanuse
themathematicalfunctionsinGambastoperformjustaboutanymathematical
operationneededforyourprograms.Wewillcovereachfunction,eitherintrinsic
orderivedinthischapterandprovideexamplesofhowtheyareused.Thereisa
tableprovidedattheendofthischapterthatshowsyoutheofficialdeveloper
version of the hierarchy of operations, as defined in the gb_reserved_temp.h
Gambassourcefile.
15 See URL: http://en.wikipedia.org/wiki/Intrinsic_function.
215
A Beginner's Guide to Gambas
Abs
Absisanintrinsicfunctionthatreturnstheabsolutevalueofanumber.
Theabsolutevalueofanumberisitsunsignedmagnitude.Forexample,Abs(1)
and Abs(1) both return 1. The number argument can be any valid numeric
expression.IfnumbercontainsNull,anerrorisreturned;ifitisaninitialized
variable,zeroisreturned.StandardGambaslanguagesyntaxis:
Abs(number)
ThefollowingexampleusestheAbsfunctiontocomputetheabsolutevalueofa
number.Trythisonyourconsole:
STATICPUBLICSUBMain()
DIMMyNumASVariant
MyNum=Abs(1.03E3)
PRINTMyNum
MyNum=Abs(2.5+6.5)
PRINTMyNum
END
Acs/ACos
Acs/ACosisaderived functionthatcomputestheinversecosine(arc
cosine)ofanumber.Y=ACos(X)returnsthearccosineforeachelementofX.
ForrealelementsofXinthedomain[1,1],ACos(X)isrealandintherange.For
real elementsof X outside thedomain [1,1], ACos(X) iscomplex. The ACos
function operates elementwise on arrays. The function's domains and ranges
includecomplexvalues.Allanglesarereturnedinradians.Syntaxis:
value=ACos(Number)
Example:
PRINTAcs(0.5)
1.047197551197
PRINTAcs(1)
3.14159265359
216
A Beginner's Guide to Gambas
Acsh/ACosh
TheAcsh/ACoshisaderivedfunctionthatcomputesthehyperbolicarc
cosine(inversehyperboliccosine)ofanumber X. Itoperateselementwiseon
arrays.Allanglesareinradians.ThedomainincludesrealnumbersXsuchthat
X >= 1. The range of the hyperbolic arccosine function is limited to non
negativerealnumbersYsuchthatY>=0.Gambaslanguagesyntaxisasfollows:
value=Acsh(Number)
value=ACosh(Number)
Hereisanexampletotryontheconsole:
STATICPUBLICSUBMain()
DIMyASVariant
Y=2
PRINTAcsh(Y)
END
Theconsolerespondswith:
1.316957896925
Asn/ASin
Asn/ASinisaderivedfunctionthatcomputesthearcsineofanumber.
TheASin()functioncomputestheprincipalvalueofthearcsineofx.Thevalueof
xshouldbeintherange[1,1]. Uponsuccessfulcompletion,Asn()returnsthe
arcsineofx,intherange[p/2,p/2]radians.Ifthevalueofxisnotintherange
[1,1]0.0isreturned.TheASin()functionwillfailifthevalueusedforxisnot
intherange[1,1].StandardGambaslanguagesyntaxis:
value=Asn(Number)
value=ASin(Number)
Hereisanexample:
STATICPUBLICSUBMain()
DIMyASVariant
Y=0.5
PRINTAsn(Y)
Y=1.0
PRINTAsn(Y)
217
A Beginner's Guide to Gambas
END
Theconsolerespondswith:
0.523598775598
1.570796326795
Asnh/ASinh
Asnh/ASinhisaderivedfunctionthatcomputestheinversehyperbolic
sine (hyperbolic arcsine)for eachelementof X. The ASinh function operates
elementwise on arrays. The function's domains and ranges include complex
values.Allanglesareexpressedinradians.StandardGambaslanguagesyntaxis:
value=Asnh(Number)
value=ASinh(Number)
Anexampleisasfollows:
STATICPUBLICSUBMain()
DIMyASVariant
Y=2
PRINTAsnh(2)
END
Theconsolerespondswith:
1.443635475179
Atn/ATan
value=Atn(Number)
value=ATan(Number)
Example:
218
A Beginner's Guide to Gambas
STATICPUBLICSUBMain()
DIMyASVariant
Y=0.5
PRINTATan(Y)
END
Theconsolerespondswith:
0.463647609001
Atnh/ATanh
value=Atnh(Number)
value=ATanh(Number)
HereisanexampleyoucantryontheconsoleusingAtanh():
STATICPUBLICSUBMain()
DIMMyResultASFloat
DIMMyNumASFloat
MyNum=0.5
MyResult=ATanh(0.5)
PRINT"Thehyperbolicarctangentof"&MyNum&"is:"&MyResult
END
Theconsolerespondswith:
0.549306144334
Cos
Cos()inanintrinsicfunctionthatreturnsthecosineofanangle.TheCos
functiontakesanangleandreturnstheratiooftwosidesofarighttriangle.The
ratioisthelengthofthesideadjacenttotheangledividedbythelengthofthe
hypotenuse.Theresultliesintherange1to1. Toconvertdegreestoradians,
219
A Beginner's Guide to Gambas
multiplydegreesby /180.Toconvertradianstodegrees,multiplyradiansby
180/ .StandardGambaslanguagesyntaxis:
Result=Cos(number)
Thenumberargumentcanbeanyvalidnumericexpressionthatexpresses
anangleinradians. ThefollowingexampleusestheCosfunctiontoreturnthe
cosineofanangle:
STATICPUBLICSUBMain()
DIMMyAngleASFloat
DIMMySecantASFloat
MyAngle=1.3'Defineangleinradians.
MySecant=1/Cos(MyAngle)'Calculatesecant.
PRINT"Secantofangle"&MyAngle&"(inradians)is:"&MySecant
END
Theconsolerespondswith:
Secantofangle1.3(inradians)is:3.738334127075
Cosh
Value=Cosh(Number)
Hereisanexampletotryontheconsole:
STATICPUBLICSUBMain()
DIMMyAngleASFloat
DIMMyResultASFloat
MyAngle=1.0'Angleexpressedinradians.
MyResult=Cosh(MyAngle)
PRINT"Cosh()ofangle"&MyAngle&"(inradians)is:"&MyResult
END
Theconsolerespondswith:
220
A Beginner's Guide to Gambas
Cosh()ofangle1(inradians)is:1.543080634815
DegandRad
Degisanintrinsicconversionfunctionthatconvertsradianstodegrees.
Rad isa reciprocal conversion function thatconvertsdegreesto radians. The
GambaslanguagesyntaxforDegandRadis:
Value=Deg(Angle)
Value=Rad(Angle)
Anexampletotryontheconsoleis:
STATICPUBLICSUBMain()
PRINTDeg(Pi/2)
PRINTRad(90)
PRINTRad(180)Pi
END
Theconsolerespondswith:
90
1.570796326795
0
Exp
Expisanintrinsicfunctionthatcomputestheexponentialofanumber.It
returns e (thebaseofnaturallogarithms,wheretheconstant e isapproximately
2.718282)raisedtoapower.Thenumberargumentcanbeanyvalidnumeric
expression.Ifthevalueofnumberexceeds709.782712893,anerroroccurs.The
Exp function complements the action of the Log function and is sometimes
referredtoastheantilogarithm.TheGambaslanguagesyntaxis:
Value=Exp(Number)
Hereisanexample:
STATICPUBLICSUBMain()
PRINTExp(1)
END
221
A Beginner's Guide to Gambas
Theconsolerespondswith:
2.718281828459
HereisanotherexamplethatusestheExpfunctiontoreturneraisedtoapower:
STATICPUBLICSUBMain()
DIMMyAngleASFloat
DIMMyHSinASFloat'Defineangleinradians.
MyAngle=1.3'Calculatethehyperbolicsine
MyHSin=(Exp(MyAngle)Exp(1*MyAngle))/2
PRINTMyHSin
END
Theconsolerespondswith:
1.698382437293
FixandFrac
Fixisanintrinsicfunctionthatreturnstheintegerpartofanumber.Frac
isanintrinsicfunctionthatcomputesthefractionalpartofanumber.Notethat
intheexamplebelow,Frac()returnstheabsolutevalueofthefractionalresultof
.ThestandardGambaslanguagesyntaxis:
Value=Fix(Number)
Value=Frac(Number)
Example:
STATICPUBLICSUBMain()
PRINTFix(Pi)
PRINTFrac(Pi)
PRINTFix(Pi)
PRINTFrac(Pi)
END
Theconsolerespondswith:
3
0.14159265359
3
0.14159265359
222
A Beginner's Guide to Gambas
Int
Int(Number)returnsthemathematicalintegerpartofanumber,i.e.,the
greaterintegersmallerthanNumber.
Value=Int(Number)
Herearesomeexamplesyoucantryontheconsole:
PRINTInt(Pi)
3
PRINTInt(Pi)
4
Log
Logisanintrinsicfunctionthatcomputesthenaturallogarithmof e.The
logarithmhavingbase e.Theconstant eisapproximately2.718282whereeisa
unique number with the property that the area of the region bounded by the
hyperbola y = 1/x,the xaxis, and the vertical lines x=1 and x=e is 1. The
notationlnxisusedinphysicsandengineeringtodenotethenaturallogarithm,
whilemathematicianscommonlyusethenotationlogx.TheNumberargument
canbeanyvalidnumericexpressiongreaterthan0.StandardGambaslanguage
syntaxis:
value=Log(Number)
Hereisanexample:
STATICPUBLICSUBMain()
PRINTLog(2.71828)
PRINTLog(1)
END
Theconsolerespondswith:
0.999999327347
0
Youcancreateaderivedfunctiontocalculatebasenlogarithmsforany
numberxbydividingthenaturallogarithmofxbythenaturallogarithmofnas
223
A Beginner's Guide to Gambas
follows:
Logn(x)=Log(x)/Log(n)
Hereisanexampletotry:
STATICPUBLICSUBMain()
DIMnASFloat
DIMxASFloat
DIMlognASFloat
n=2
x=10
logn=Log(x)/Log(n)
PRINTlogn&"istheresultofLogn("&x&")"
END
Theconsolerespondswith:
3.321928094887istheresultofLogn(10)
Log10
value=Log10(Number)
Example:
PRINTLog10(10)
1
MaxandMin
Maxreturnsthegreaterexpressionofthelist.Expressionsmustbenumbers
ordate/timevalues.Minreturnsthesmallerexpressionofthelist.Expressions
mustbenumbersordate/timevalues.
value=Max(Expression[,Expression...])
value=Min(Expression[,Expression...])
224
A Beginner's Guide to Gambas
Examples:
STATICPUBLICSUBMain()
PRINTMax(6,4,7,1,3)
PRINTMax(Now,CDate("01/01/1900"),Cdate("01/01/2100"))
PRINT
PRINTMin(6,4,7,1,3)
PRINTMin(Now,CDate("01/01/1900"),CDate("01/01/2100"))
END
Theconsolerespondswith:
7
01/01/2100
1
01/01/1900
Pi
Pireturnsp*Number.IfNumberisnotspecified,itisassumedtobeone.
StandardGambaslanguagesyntaxis:
Result=Pi([Number])
Examples:
PRINTPi
3.14159265359
PRINTPi(0.5)
1.570796326795
RandomizeandRnd
Randomize(Number)
wherethenumberargumentcanbeanyvalidnumericexpression. Randomize
uses the parameter Number to initialize the Rnd function's randomnumber
225
A Beginner's Guide to Gambas
generator,givingitanewseedvalue.Ifyouomitnumber,thevaluereturnedby
thesystemtimerisusedasthenewseedvalue.IfRandomizeisnotused,theRnd
function(withnoarguments)usesthesamenumberasaseedthefirsttimeitis
called,andthereafterusesthelastgeneratednumberasaseedvalue. Inother
words,foranygiveninitialseed,thesamenumbersequenceisgeneratedbecause
eachsuccessivecalltotheRndfunctionusesthepreviousnumberasaseedfor
thenextnumberinthesequence.
Inordertorepeatsequencesofrandomnumbers,callRndwithanegative
argumentimmediatelybeforeusingRandomizewithanumericargument.Before
callingRnd,usetheRandomizestatementwithoutanargumenttoinitializethe
randomnumber generator with a seed based on the system timer. Using
Randomize with the same value for number does not repeat the previous
sequence.
Rndcomputesapseudorandomfloatingpointnumber,usingtheLehmer
algorithm.Ifnoparametersarespecified,Rndreturnsapseudorandomnumber
intheinterval[0,1].Ifonlyoneparameterisspecified,Rndreturnsapseudo
randomnumberintheinterval[0,Min].Ifbothparametersarespecified,Rnd
returnsapseudorandomnumberintheinterval[Min,Max].StandardGambas
languagesyntaxforRndis:
Rnd([Min[,Max])
The number argument can be any valid numeric expression. The Rnd
functionreturnsavaluelessthan1butgreaterthanorequalto0.Thevalueof
numberdetermineshowRndgeneratesarandomnumber. Toproducerandom
integersthatfallwithinanygivenrange,usethisformula:
Int((upperboundlowerbound+1)*Rnd+lowerbound)
Here, upperbound is the highest number in the range, and lowerbound is the
lowestnumberintherange.Hereisanexampleprogramtotryontheconsole:
STATICPUBLICSUBMain()
DIMDiceASInteger
PRINT"Between0and1:";
PRINTRnd
PRINT"Between0and2:";
PRINTRnd(2)
PRINT"BetweenPiandPi*2:";
226
A Beginner's Guide to Gambas
PRINTRnd(Pi,Pi(2))
PRINT
Randomize
DOWHILEDice<>1
Dice=Int(Rnd(1,7))
'producearandomnumberbetween1and6tosimulatethedicethrow
PRINT"Youthrewa"&dice
LOOP
END
Theconsolerespondswith:
Between0and1:7.826369255781E6
Between0and2:0.263075576164
BetweenPiandPi*2:5.515396781706
Youthrewa6
Youthrewa4
Youthrewa1
Round
RoundroundsanumbertoitsnearestintegerifDigitsisnotspecified.If
Digitsisspecified,roundsto10^Digits.
Value=Round(Number[,Digits])
Example:
STATICPUBLICSUBMain()
PRINTRound(Pi,2)
PRINTRound(1972,2)
END
Theconsolerespondswith:
3.14
2000
Sgn
Sgnreturnsanintegerindicatingthesignofanumber. Ifthenumberis
zero, it returns zero. If the number is strictly positive, it returns the integer
227
A Beginner's Guide to Gambas
number+1.Ifthenumberisstrictlynegative,itreturnstheintegernumber1.
Gambaslanguagesyntaxis:
Sign=Sgn(Number)
Example:
STATICPUBLICSUBMain()
PRINTSgn(Pi)
PRINTSgn(Pi)
PRINTSgn(0)
END
Theconsolerespondswith:
1
1
0
Sin
Sinisanintrinsicfunctionthatcomputesthesineofanangle.Theangleis
specified in radians. The sine function sin x is one of the basic functions
encounteredintrigonometry(theothersbeingthecosecant, cosine,cotangent,
secant,andtangent).Let beananglemeasuredcounterclockwisefromthex
axisalonganarcoftheunitcircle.Thensinistheverticalcoordinateofthearc
endpoint.Asaresultofthisdefinition,thesinfunctionisperiodicwithperiod2.
BythePythagoreantheorem,sinalsoobeystheidentitysin2 + cos2 = 1. The
standardGambaslanguagesyntaxforSinis:
Value=Sin(Angle)
Example:
STATICPUBLICSUBMain()
PRINTSin(Pi/2)
END
Theconsolerespondswith:
1
228
A Beginner's Guide to Gambas
Sinh
Sinhisaderivedfunctionthatcomputesthehyperbolicsineofanumber.
StandardGambaslanguagesyntaxforSinhis:
Value=Sinh(Number)
ThefollowingexampleusestheExpfunctiontocalculatehyperbolicsineofan
angle:
STATICPUBLICSUBMain()
DIMMyAngleASFloat
DIMMyHSinASFloat'Defineangleinradians
MyAngle=1.3'Calculatehyperbolicsine
MyHSin=(Exp(MyAngle)Exp(1*MyAngle))/2
PRINTMyHSin
END
Theconsolerespondswith:
1.698382437293
Sqr
Sqrisanintrinsicfunctionthatreturnsthesquarerootofanumber.The
numberargumentcanbeanyvalidnumericexpressiongreaterthanorequalto0
(nonnegative).TheGambaslanguagesyntaxis:
Value=Sqr(Number)
Hereisanexample:
PRINTSqr(2)
1.414213562373
STATICPUBLICSUBMain()
DIMMySqrASFloat
229
A Beginner's Guide to Gambas
MySqr=Sqr(4)'Returns2
PRINTMySqr&"istheresultofSqr(4)"
MySqr=Sqr(23)'Returns4.795831523313
PRINTMySqr&"istheresultofSqr(23)"
MySqr=Sqr(0)'Returns0
PRINTMySqr&"istheresultofSqr(0)"
'MySqr=Sqr(4)'Generatesaruntimeerror
'PRINTMySqr&"istheresultofSqr(4)"
END
Theconsolerespondswith:
2istheresultofSqr(4)
4.795831523313istheresultofSqr(23)
0istheresultofSqr(0)
Tan
Tanisanintrinsicfunctionthatcomputesthetangentofanangle.The
angleargumentcanbeanyvalidnumericexpressionthatexpressesananglein
radians.Tantakesanangleandreturnstheratiooftwosidesofarighttriangle.
Theratioisthelengthofthesideoppositetheangledividedbythelengthofthe
sideadjacenttotheangle.Toconvertdegreestoradians,multiplydegreesbypi/
180. To convert radians to degrees, multiply radians by 180/pi. Standard
Gambaslanguagesyntaxis:
Value=Tan(angle)
ThefollowingexampleusestheTanfunctiontoreturnthetangentofanangle:
STATICPUBLICSUBMain()
DIMMyAngleASFloat
DIMMyCotangentASFloat
MyAngle=1.3'Defineangleinradians.
MyCotangent=1/Tan(MyAngle)'Calculatecotangent.
PRINTMyCotangent
PRINTTan(Pi/4)
END
Theconsolerespondswith:
0.277615646541
230
A Beginner's Guide to Gambas
Tanh
Value=Tanh(Number)
Example:
STATICPUBLICSUBMain()
PRINTTanh(1)
END
Theconsolerespondswith:
0.761594155956
DerivedMathFunctions
Thenonintrinsic(derived)mathfunctionsshowninthetablebeloware
providedinGambasfromthebuiltinintrinsicmathfunctions.
Belowisatablelistingotherderivedmathfunctionsthatcanbebuiltusingthe
formulasshowninthetablebelow:
231
A Beginner's Guide to Gambas
Since Gambas does not directly provide you with builtin functions for
theseotherderivedfunctions,wearegoingtobuildamodulethatwillextend
Gambascapabilitiesbyprovidingallofthefunctionslistedinthetableaboveasa
finalexerciseinthischapter.OurmodulewillbenamedDerivedandyouwillbe
able to access all of the functions in your code by using the format
Derived.function_namewherefunction_namewillbeoneofthefunctionswebuild
in the next section. Start Gambas and create a terminal application named
MyMath. Createanewclass,Class1fromtheIDEandmakeitastartupclass.
NextcreateanewmoduleandnameitDerived.Openthenewcodewindowfor
theClass1.classfileandenterthefollowing:
'Gambasclassfile
STATICPUBLICSUBMain()
DIMmyValASFloat
myVal=51.5
WHILEmyVal<>0.0
PRINT"Enteranumber>1orenter0toquit:";
LINEINPUTmyVal
IFmyVal=0.0THENBREAK
IFmyVal<=1.0THEN
PRINT"Numberwas<=1.0"
CONTINUE
ENDIF
232
A Beginner's Guide to Gambas
PRINTDerived.Sec(myVal)&"issecant"
PRINTDerived.CoSec(myVal)&"iscosecant"
PRINTDerived.CoTan(myVal)&"iscotangent"
PRINT
PRINTDerived.ArcSec(myVal)&"isarcsecant"
PRINTDerived.Arccosec(myVal)&"isarccosecant"
PRINTDerived.Arccotan(myVal)&"isarccotangent"
PRINT
PRINTDerived.HSec(myVal)&"ishyperbolicsecant"
PRINTDerived.HCoSec(myVal)&"ishyperboliccosecant"
PRINTDerived.HCoTan(myVal)&"ishyperboliccotangent"
PRINT
PRINTDerived.HArcSec(myVal)&"ishyperbolicarcsecant"
PRINTDerived.HArcCoSec(myVal)&"ishyperbolicarccosecant"
PRINTDerived.HArcCoTan(myVal)&"ishyperbolicarccotangent"
PRINT
PRINTDerived.LogN(myVal,2)&"isLogNof:"&myVal&"tobase2"
PRINT"ofmyVal:"&myVal
WEND
END
Now,openthecodewindowfortheDerived.modulefileandenterthiscode:
'GambasDerived.modulefile
PUBLICFUNCTIONSec(xASFloat)ASFloat
DIMresultASFloat
result=1.0/Cos(x)
RETURNresult
END
PUBLICFUNCTIONCoSec(xASFloat)ASFloat
DIMresultASFloat
result=1.0/Sin(x)
RETURNresult
END
PUBLICFUNCTIONCoTan(xASFloat)ASFloat
DIMresultASFloat
result=1.0/Tan(x)
RETURNresult
END
PUBLICFUNCTIONArcSec(xASFloat)ASFloat
DIMresultASFloat
result=Atn(x/Sqr(x*x1))+(Sgn(x)1)*(2*Atn(1))
RETURNresult
END
233
A Beginner's Guide to Gambas
PUBLICFUNCTIONArccosec(xASFloat)ASFloat
DIMresultASFloat
result=Atn(x/Sqr(x*x1))+(Sgn(x)1)*(2*Atn(1))
RETURNresult
END
PUBLICFUNCTIONArccotan(xASFloat)ASFloat
DIMresultASFloat
result=Atn(x)+(2*Atn(1))
RETURNresult
END
PUBLICFUNCTIONHSec(xASFloat)ASFloat
DIMresultASFloat
result=2.0/(Exp(x)+Exp(x))
RETURNresult
END
PUBLICFUNCTIONHCoSec(xASFloat)ASFloat
DIMresultASFloat
result=2.0/(Exp(x)Exp(x))
RETURNresult
END
PUBLICFUNCTIONHCoTan(xASFloat)ASFloat
DIMresultASFloat
result=(Exp(x)+Exp(x))/(Exp(x)Exp(x))
RETURNresult
END
'thisroutinecurrentlyproducesanerrorinGambas
'ifyoutrytousetheformularesult=Log((Sqr(x*(x+1))+1)/x)
'becausetheLogfunctiononlyworkswithnonnegativenumbers
'bydesign.Thisisaworkaroundtogetyouthesameresults
PUBLICFUNCTIONHArcsec(xASFloat)ASFloat
DIMresultASFloat
DIMTemp1ASFloat
DIMTemp2ASFloat
DIMTemp3ASFloat
Temp1=((x*1)*(x+1))+1
Temp2=Sqr(Abs(Temp1))
Temp3=Log(Temp2)
result=Temp3*1
'thiscallwillgenerateanerrorbecausethe
'Sqrfunctionwillnotworkwithnegativevalues
'result=Log((Sqr(x*(x+1))+1)/x)
234
A Beginner's Guide to Gambas
RETURNresult
END
PUBLICFUNCTIONHArccosec(xASFloat)ASFloat
DIMresultASFloat
result=Log((Sgn(x)*Sqr(x*x+1)+1)/x)
RETURNresult
END
PUBLICFUNCTIONHArccotan(xASFloat)ASFloat
DIMresultASFloat
result=Log((x+1)/(x1))/2
RETURNresult
END
PUBLICFUNCTIONLogN(xASFloat,nASFloat)ASFloat
DIMresultASFloat
result=Log(x)/Log(n)
RETURNresult
END
Whenyouruntheprogram,youwillreceiveaprompttoenteranumber>
1or0toquit.Enter4andyoushouldseethefollowingresults:
Enteranumber>1orenter0toquit:4
1.529885656466issecant
1.321348708811iscosecant
0.863691154451iscotangent
0.85707194785isarcsecant
0.801529994232isarccosecant
2.896613990463isarccotangent
0.036618993474ishyperbolicsecant
0.036643570326ishyperboliccosecant
1.000671150402ishyperboliccotangent
1.472219489583ishyperbolicarcsecant
0.247466461547ishyperbolicarccosecant
0.255412811883ishyperbolicarccotangent
2isLogNof:4tobase2
ofmyVal:4
Enteranumber>1orenter0toquit:
235
A Beginner's Guide to Gambas
thischapteranditistimetotakeabreaknow.Inthenextchapter,wearegoing
tocoverthebasicconceptsofobjectoriented(OO)programmingandshowyou
howpowerfulGambascanbewhenyoutakeadvantageoftheseOOfeatures.
236
A Beginner's Guide to Gambas
Objects promised reuse, and the programming community has not seen
237
A Beginner's Guide to Gambas
much success with that. The ability to maintain a program once it has been
writtenandtodolocalizeddebuggingandtodomuchlargerdevelopmentefforts
arealso reasonscited assignificant advantagesgained withtheuseofobject
oriented programming languages (OOPLs). In the 1990s, overoptimism
regarding the benefits of OO programming led businesses to expect miracles.
When software developers could not deliver on the outrageous business plans
basedonthosepromises,2001sawbusinessesfalllikedominos,leavingtheentire
techindustry inarecession. DefunctcompanieslitteredSilicon Valleylikeso
manybleachedbonesinadesert.
OOPisoftencalledaparadigmratherthanastyleortypeofprogramming
toemphasizethepointthatOOPcanchangethewaysoftwareisdevelopedby
changingthewaythatprogrammersandsoftwareengineersthinkaboutsoftware.
Much ofthe evolution of any language depends on theOS thatsupports that
language. Withtheadventof Linux andthehugegroundswellofsupportfor
opensourcesoftware,thefuturelooksverybrightforGambas.Now,let'stakea
lookatsomeofthebasicOOconceptsthatGambassupports.
FundamentalsofObjectOrientedProgramming
Objectorientedprogrammingisbaseduponseveralkeyconcepts:objects,
data abstraction, encapsulation, polymorphism, and inheritance. One
distinguishing feature of OOP is the methods used for handling data types.
Objecttypedataisgenerallyrequiredtosatisfyprogrammerdefinedconstraints.A
datatyperestrictedtoaspecificobjectisconsideredtobea private datatype.
Thistypeoflanguageimposedconstraintrestrictingdatatypestospecificobjects
forcesprogrammers(bydesign)tocodewithoutrelyingoncreatingalaundrylist
ofvariablesvisibletoeveryobjectintheprogram(globalvariables). Variables
canbeusedanddisposedofwithintheobjectorclassinwhichtheyareneeded
and they do not affect other parts of a program. The actions taken by the
program where such variables are used are referred to as methods. In more
traditionallanguages,methodsequatetofunctionsorsubroutines.InOOP,these
constraints also may extend to the use of methods and are not exclusive to
variables.
238
A Beginner's Guide to Gambas
Objectorientedlanguagesprovideinternalmechanismsforensuringthat
variablesandmethodsareonlyvisibleandavailablewithinthescopeoftheclass
ormethodinwhichtheyaredeclared.Albeit,somevariablesandmethodsare
designed to be visible to all other methods or classes of a project. In those
instances, they are referred to as public variables and methods. In Gambas,
variablesandmethodsthatarepublicareglobalinscopetotheclassinwhichthey
aredeclared.Variablesmeanttobevisibleonlytothemethodsinwhichtheyare
declaredas private withinagivenclassarecreatedwiththeDIMkeywordin
Gambas.
Objects
Objects arecomprisedofallthedataandfunctionalitythatexistwithin
distinct units in a running (executing) computer program. Objects are the
foundation of modularity and structure in an OOPL. They have two basic
attributes: they are selfcontained and they are uniquely identifiable. Having
thesetwoattributesallowsallofthevariousprogramcomponentstocorrelate
variablesinaprogramwithvariousrealworldaspectsofaproblemforwhicha
programisintendedtosolve.
DataAbstraction
DataAbstractionDataabstractionisamethodologyusedinOOPLsthat
enablesaprogrammertospecifyhowadataobjectisused.Abstractionallowsa
programmertoisolatedataobjectsfromtheunderlyingdetailsofhowthedatais
created(usuallybyusingevenmoreprimitivedataobjects).Inotherwords,the
useofadataobject,comprisedofoneormoreprimitivedataobjects, allowsa
programmer to structure his or her code to use data objects that operate on
abstractdata.
Dataobjectsthatarecomprisedofoneormoreprimitivedataobjectsare
called compound data objects. With abstraction, the program can use data
withoutmakinganyassumptionsaboutit(i.e.,theunderlyingdetailsofhowor
wherethatdatacamefrom)thatisn'tnecessaryforperformingagiventask. A
concretedatarepresentationisdefinedindependentofanyprogramsthatusethe
data.Theinterfacebetweentheconcreteandabstractdataisasetofprocedures,
called constructors, that implement abstract data in terms of the concrete
representation.Methods(subroutinesandfunctions)mayalsobesoabstractedin
theOOPparadigm.
239
A Beginner's Guide to Gambas
Encapsulation
EncapsulationEnsuresthatusersofanobjectcannotchangetheinternal
state of the object in unexpected ways; only the object's internally defined
methodsareallowedtoaccessitsstate(orattributes). Eachobjectexposesan
interfacethatspecifieshowotherobjectsmayinteractwithit.Otherobjectswill
not know of this object's internal methods and must therefore rely upon this
object'sinterfaceinordertointeractwithit.
Polymorphism
Polymorphismmeanstheabilitytotakemorethanoneform.InOOPLs,it
refers to a programming language's ability to process objects differently
depending on the datatype or class. More specifically, polymorphism is the
abilitytoredefinemethodsforderivedclasses.Anoperationmayexhibitdifferent
behaviorsindifferentcircumstances.Thebehaviorisdependentuponthedata
type used in the operation. For example, given a base class named shape,
polymorphism enables the programmer to define different methods of area
calculation for any number of derived classes, such as circles, rectangles and
triangles.Nomatterwhatshapeanobjectis,applyingtheareamethodtoitwill
return the correct results. Polymorphism is used extensively in OOPLs when
implementing inheritance and is considered to be a requirement of any true
OOPL.
Inheritance
Inheritance istheprocessbywhichobjectscanacquirethepropertiesof
objectsthatexistinanotherclass.InGambas,allofthecontrolsoftheToolBox
inheritthepropertiesoftheclassnamedControl. InOOP,inheritanceprovides
reusability and extensibility (adding additional features to an existing class
withouttheneedtomodifyit).Thisisachievedbyderivinganewclassfroman
existingclassandmakingchangestothenewinstanceofthatclass.Thenewclass
willhavecombinedthefeaturesofbothclasses.Inheritanceallowsobjectstobe
defined and created that are specialized implementations of alreadyexisting
objects. They can share (and extend) the existing object's behavior without
havingtoreimplementit.
240
A Beginner's Guide to Gambas
TheGambasApproachtoOOP
AnOOprogramisgenerallydesignedbyidentifyingalloftheobjectsthat
willexistinasystem.Thecodewhichactuallydoestheworkisirrelevanttothe
objectduetoencapsulation. ThebiggestchallengeinOOPisofdesigningan
objectsystemthatisunderstandableandmaintainable. Itshouldbenotedthat
therearedistinctparallelsbetweentheobjectorientedparadigmandtraditional
systems theory. While OOP focuses on objects as units in a system, systems
theory focuses on the system itself. Somewhere in between, one may find
software design patterns or other techniques that use classes and objects as
building blocks for larger components. Such components can be seen as an
intermediate step from the objectoriented paradigm towards the more
pragmaticallyorientedmodelsofsystemstheory.SuchappearstobetheGambas
approachtoOOP.Itisanelegant,pragmaticsolutionthattakesthebestofboth
approachesandmakesprogrammingeasyandsimple.
Gambashastriedtokeepsimplicityattheforefrontofanapproachthat
leverages OO concepts and compromises with systems theory where it makes
goodsense. Inthatregard,Gambashastakena classbasedapproach toOOP.
TheclassbasedOOPapproachisanOOPparadigmwheretheconceptofaclassis
central.Inthisapproachencapsulationpreventsusersfrombreakinginvariantsof
theclass.Classinvariantsareestablishedduringconstructionandareconstantly
maintained between calls to public methods. Temporarily breaking class
invariancebetweenprivatemethodcallsispossible,althoughitisnotencouraged.
Sometimes,itisusefulbecauseitallowstheimplementationofaclassofobjects
to be changed for aspects not visible to or exposed inside the class interface
withouthavinganimpactonusercodethatmayhaveimplementedfeaturesof
thatclass.
ThedefinitionofencapsulationinaclassbasedOOPparadigmfocuseson
groupingandpackagingofrelatedinformation(cohesion).OOPlanguagesdonot
normallyofferformalsecurityrestrictionstotheinternalobjectstate. Usinga
methodofaccessisamatterofconventionfortheinterfacedesign.Inheritanceis
typicallydonebygroupingobjectsintoclassesanddefiningclassesasextensions
ofexistingclasses. Thisgroupingofclassesissometimesorganizedintotreeor
latticestructures,oftenreflectingacommonsetofbehaviors.
GambasClasses
InGambas,youcandefineyourownclasses. Rememberthataclassis
241
A Beginner's Guide to Gambas
merelytemplatethatisusedbytheprogramatruntime. Theclassitselfisnot
useddirectly.Touseaclass,youmustmakeavariabledeclarationoftheclass
datatype,createacopyoftheclassfortheprogramtouse,theninstantiatethe
copy.Theinstantiatedcopyiscalledanobject.Sinceaclassisarealdatatype,
thedeclarationoftheobjectlookslikeanyothernormalvariabledeclaration:
object_nameASClass_name
Instantiatinganobjectmeanstocreateanewinstanceofthetemplateandassign
that instance the name on the left side of the equal sign. In GB, this is
accomplishedusingtheNEWkeyword:
object_name=NEWClass_name
Whenobject_nameisinstantiatedasanewcopyofthetemplatedefinedby
Class_name,theprogramminglanguageallows object_name toinheritallofthe
methods and attributes of Class_name. When the new object is created, it
automaticallyinvokesaconstructortoinitializeitselfwithdefaultvariables.Itis
important to note that the current version of Gambas does not support the
conceptofvirtualdispatch.Inotherwords,whenyouinvokeamethod(orset/get
a property value) for an object reference using the dot notation (i.e.,
class.object.method),themethodthatisactuallyexecutedisthemethodbelonging
tothedatatypeofthevariablethatownstheobjectreference,notthemethodof
therealdatatypeoftheobject.InGambas2,thisissuehasbeencorrected.
Sampleprogram:Contacts
ToillustratetheuseofaclassinGambas,wearegoingtocreateasample
programthatimplementsacontactsbook.Itisgoingtobefairlysimplebutwill
beusefultomaintaincontacts.Tobegin,createanewprojectnamedClassesand
whenyougettotheIDE,createaclass(notastartupclass)namedContact.This
iswherewewillstartwithourprogram,buildingaclassdefinitionforaContact.
TheContactclass
'GambasContact.classfile
PUBLICFirstNameASString
PUBLICLastNameASString
PUBLICInitialASString
PUBLICSuffixASString
PUBLICStreet1ASString
242
A Beginner's Guide to Gambas
PUBLICStreet2ASString
PUBLICCityASString
PUBLICStateASString
PUBLICZip5ASString
PUBLICZip4ASString
PUBLICAreacodeASString
PUBLICPrefixASString
PUBLICLast4ASString
PUBLICRecordIDASInteger
Wewantourclasstoprovidetwomethods,onetoretrieveourcontactdata
fromthefileitisstoredinandonetoputdataintothatfile.Appropriately,the
twomethodswillbenamedContact.GetDataandContact.PutData.
Contact.GetDataMethod
Thecollectionvariableispassedinasaparameterfromtheconstructorcall
inForm1.classsoitisnotnecessarytodeclareitseparately. Thefunctionwill
returnacollectionvariablesoweadd ASCollection totheendofthefunction
declaration.WewillshowhowthecollectionvariablecTheDataispassedtothis
functionwhenitiscalledfromtheForm1.classfile.
PUBLICFUNCTIONGetData(cTheDataASCollection)ASCollection
'thisstringvarwillholdeachlineofdatareadfromthefile
DIMsInputLineASString
'weneedafilehandleandtwostringvarsforbuildingfilenames
DIMhFileInASFile
DIMfilenameASString
DIMfullpathASString
'thisclassvariableisusedtoconvertthestringdatawereadin
'fromfileintoacontactrecord.Wedeclarethevariablehereand
243
A Beginner's Guide to Gambas
'willinstantiateitbelow
DIMMyContactRecordASContact
'alocalintegervartokeeptrackofhowmanyrecordsweadded
DIMRecordNumASInteger
'thisvariablewilltakethestringreadinandconvertallthefields
'thatarecommadelimitedintoanarrayusingthesplitstatement
DIMarsInputFieldsASString[]
'thiscounterisusedtoloopthroughthearrayandassignvalues
'tothecontactrecords
DIMcounterASInteger
filename="contacts.data"'hardcodedbecauseitwillnotchange
'wewillusethecurrentdirwheretheappistobuildfullpathname
fullpath=Application.Path&/filename
'now,seeifthefilealreadyexists,ifsoopenitforREAD.
IFExist(fullpath)THEN
OPENfullpathFORREADAS#hFileIn
'startwithrecord1
RecordNum=1
'wewillloopthrougheverylineofdatauntilwereachEndoffile
WHILENOTEof(hFileIn)
'everycontactaddedtothecollectionmustbeinstantiated
'eachtimearecordisaddedtothecollection.YouCAN
'reusethesameclassvarforeachreinstantiationthough.
MyContactRecord=NEWContact'hereiswhereitrenewsitself
'readthelineinfromfileandstoreinstringvarsInputLine
LINEINPUT#hFileIn,sInputLine
'usedforconsoledebugging
PRINT"Reading:"&sInputLine
'now,fillourarrayofstringsusingSplittoconverttheline
'ofstringdatareadintofieldsinanarray
arsInputFields=Split(sInputLine,",")
'fordebugonlytoshowthatallfieldsconvertcorrectly
FORcounter=0TO14
PRINT"Loading:"&arsInputFields[counter]
NEXT
'now,weputthefielddataintoourlocalcontactclassvar
244
A Beginner's Guide to Gambas
'andwilladdthatcontactrecordtothecollectionofcontacts
MyContactRecord.FirstName=arsInputFields[0]
MyContactRecord.Initial=arsInputFields[1]
MyContactRecord.LastName=arsInputFields[2]
MyContactRecord.Suffix=arsInputFields[3]
MyContactRecord.Street1=arsInputFields[4]
MyContactRecord.Street2=arsInputFields[5]
MyContactRecord.City=arsInputFields[6]
MyContactRecord.State=arsInputFields[7]
MyContactRecord.Zip5=arsInputFields[8]
MyContactRecord.Zip4=arsInputFields[9]
MyContactRecord.Areacode=arsInputFields[10]
MyContactRecord.Prefix=arsInputFields[11]
MyContactRecord.Last4=arsInputFields[12]
MyContactRecord.RecordID=CInt(arsInputFields[13])
MyContactRecord.Deleted=CBool(arsInputFields[14])
'fordebugoutputtotheconsole
PRINT"Addingdataforrecord:"&RecordNum&"";
PRINTMyContactRecord.FirstName&""&MyContactRecord.LastName
'allrecordfieldsareassigneddata,soweaddtocollection
cTheData.Add(MyContactRecord,CStr(RecordNum))
'fordebugoutputtotheconsole
PRINTcTheData[CStr(RecordNum)].LastName&"stored."
'incrementourrecordcounterandclearthesInputLinevariable
INCRecordNum
sInputLine=""
WEND'loopformorerecords
'closethefilewhennomorerecordsexistinthefile
CLOSE#hFileIn
ELSE'nofilefound,putupamessagetotheuser
Message.Info("Nocontacts.datafilepresent.","OK")
ENDIF
'fordebugonly,wewilllistalltherecordsinthecollection
PRINT"HereiswhatisstoredincTheData:"
FOREACHMyContactRecordINcTheData
PRINTMyContactRecord.FirstName&""&MyContactRecord.LastName
NEXT
RETURNcTheData'returnthecollection(nowfilled)withdata
END'ofGetData
245
A Beginner's Guide to Gambas
Contact.PutDataMethod
PUBLICSUBPutData(cTheDataASCollection)
'thisstringvarwillholdeachlineofdatareadfromthefile
DIMsInputLineASString
'weneedafilehandleandtwostringvarsforbuildingfilenames
DIMhFileOutASFile
DIMfilenameASString
DIMfullpathASString
'thisclassvariableisusedtoconvertthestringdatainto
'acontactrecord.Wedeclarethevariablehereand
'willinstantiateitbelow
DIMMyContactRecordASContact
'alocalintegervartokeeptrackofhowmanyrecordsweadded
DIMRecordNumASInteger
'instantiateanewrecordthatisblank.Notethatsincewearenot
'addingthisrecordtoacollection,itisnotnecessarytorenew
'itbyreinstantiatingiteachtime.
MyContactRecord=NEWContact
'startatrecord1
RecordNum=1
'wehaveahardcodedfilenamesoweonlyneedthepathtotheprogram
'becausewewillstorethedatawheretheprogramresides.
filename="contacts.data"
fullpath=Application.Path&/filename
'wehavetospecifyWRITECREATEwhenweopenthefile.Ifthefile
'exists,itwillbeopenedforWRITE.Ifitdoesnotexist,thenwe
'willcreateanewfileandwritetothat.
OPENfullpathFORWRITECREATEAS#hFileOut
'now,weloopthrougheachrecordinthecollection.Notethatwe
246
A Beginner's Guide to Gambas
'usetheFOREACHconstructtodothis.
FOREACHMyContactRecordINcTheData
'weconcatenateeachfieldtothelast,insertingcommas
'tobeusedasfielddelimitersforthereadoperation
sInputLine=sInputLine&MyContactRecord.FirstName&","
sInputLine=sInputLine&MyContactRecord.Initial&","
sInputLine=sInputLine&MyContactRecord.LastName&","
sInputLine=sInputLine&MyContactRecord.Suffix&","
sInputLine=sInputLine&MyContactRecord.Street1&","
sInputLine=sInputLine&MyContactRecord.Street2&","
sInputLine=sInputLine&MyContactRecord.City&","
sInputLine=sInputLine&MyContactRecord.State&","
sInputLine=sInputLine&MyContactRecord.Zip5&","
sInputLine=sInputLine&MyContactRecord.Zip4&","
sInputLine=sInputLine&MyContactRecord.Areacode&","
sInputLine=sInputLine&MyContactRecord.Prefix&","
sInputLine=sInputLine&MyContactRecord.Last4&","
sInputLine=sInputLine&MyContactRecord.RecordID&","
sInputLine=sInputLine&CStr(MyContactRecord.Deleted)&","
'fordebugonly,toshowwhatisbeingstored
PRINT"Storing:"&sInputLine
'thiscallisactuallywhatputsthedataintothefile
PRINT#hFileOut,sInputLine
'clearoutourstringvartobereusedinthenextiteration
sInputLine=""
NEXT'iterationofthelooptoenumerateobjects
'gotthemallwrittennow,soclosethefile
CLOSE#hFileOut
RETURN'withoutpassingavariableback,hencesubroutine
END
Form1.classfile
Save the Contact.class file and close it. Our contact class definition is
completesonowwewillneedtocreateaformnamedForm1.Form1willserve
asthemaininterfacebetweentheuserandtheprogramandit'sdata. Hereis
whatourfinishedformwilllooklike:
247
A Beginner's Guide to Gambas
Figure74FinishedContactsprogram.
Ourprogramwillallowausertoadd,changeordeleteacontactandstore
thatdatatoadatafile.Contactdataismanagedinourprogramasacollectionof
objectsthatareoftypeContact,whichwedefinedintheContact.classfileabove.
Wewillallowtheusertomovetotheveryfirstiteminthecollection,scrollto
nextorpreviousitems,gotothelastitem,updatedataonthecurrentform,save
thecurrentdatatofile,andexit.Allinall,itdoesmostofthebasicsnecessaryfor
contactmanagement. Wewillalsoaddasearchfeature(usingamodule)that
willfindthefirstinstanceofacontactbysearchingforalastname.Amazingly,to
accomplishallofthistakesverylittlecodeinGambas!
Now,let'slookattheprogramthatwillusethecontactclass.Theprogram
willrequirefourpublicvariables,asshownbelow. Our constructorroutine will
automatically look for and load the default contact file, which we named
contacts.data.Itisnotnecessaryfortheusertoknoworusethisfilenamesoitis
hardcodedintothemethodswhereitisused.Iftheconstructorroutine_new()
cannotloadafile,itwillcreateonedummyrecordsotheuserneverseesablank
startupscreen.
'GambasForm1classfile
'Contactswillrepresentthecollectionofrecordsfortheaddrbook
PUBLICContactsASCollection
'representsasinglecontactrecordusedbyallsubroutines
PUBLICContactRecordASContact
'indexthatpointstothecurrentrecord
PUBLICRecordPointerASInteger
'wewillneedastringvartousewhentheusersearchesbylastname
PUBLICSearchKeyASString
Form1Constructor
248
A Beginner's Guide to Gambas
'theconstructorroutinecalledwhenform1_open()iscalled
PUBLICSUB_new()
'instantiatethecollectionthatwillholdouraddressrecords
Contacts=NEWCollection
'instantiateanewcontact(record)thatisblank
ContactRecord=NEWContact
'fordebugonly
PRINT"CallingGetData..."
'calltheGetDatamethoddefinedinthecontactclassdefinition
ContactRecord.GetData(Contacts)
'settherecordpointertothelastrecordfoundinthedataset
RecordPointer=Contacts.Count
'fordebugonly
PRINT"In_new(),rtnfmGetDatawith:"&RecordPointer&"records."
'thedefaultconstructorwillensureatleastonerecordexists
'iftheContactscollection'scountpropertyshows<1record.
IFRecordPointer<1THEN
'addourdummydata
ContactRecord.FirstName="John"
ContactRecord.Initial="Q"
ContactRecord.LastName="Public"
ContactRecord.Suffix="II"
ContactRecord.Street1="12345GambasDrive"
ContactRecord.Street2="Apt101"
ContactRecord.City="Dancer"
ContactRecord.State="TX"
ContactRecord.Zip5="77929"
ContactRecord.Zip4="0101"
ContactRecord.Areacode="888"
ContactRecord.Prefix="666"
ContactRecord.Last4="4444"
ContactRecord.RecordID=1
ContactRecord.Deleted=FALSE
RecordPointer=ContactRecord.RecordID
Contacts.Add(ContactRecord,CStr(ContactRecord.RecordID))
ENDIF
'checkourcollectiontomakesurerecordsexist
IFContacts.Exist(CStr(RecordPointer))THEN
'fordebugonly
249
A Beginner's Guide to Gambas
PRINT"Recorddataexistsfor"&CStr(RecordPointer)&"records."
'thisforloopisfordebugonly
FOREACHContactRecordINContacts
PRINTContactRecord.FirstName&""&ContactRecord.LastName
NEXT
ELSE
'ifnorecords,putupaMessageBoxtoinformuser
Message.Info("Recordsdonotexist!","Ok")
ENDIF
END
Form_OpenSubroutine
Our program will automatically open the form using the Form_Open()
subroutine below. Since Form1.form is defined as a startup form, it is not
necessarytocalltheForm1.Showmethod.Allwearegoingtodohereissetthe
captiontodisplayatthetopofthewindowwhentheprogramrunsandgetthe
recordpointedtobythecurrentrecordpointer.Inthiscase,thepointershould
pointtothelastrecordloadedfromthecontactsfileafterprogramflowreturns
fromtheconstructor.
PUBLICSUBForm_Open()
'settheprogramcaption
Form1.Caption="ContactsManager"
'startwiththerecordpointedtoaftertheconstructorcall
'whichshouldbethelastrecordinthecollection
ContactRecord=Contacts[CStr(RecordPointer)]
'thissubroutinewillrefreshallfieldswithcurrentrecorddata
UpdateForm
END
AddingControlstoForm1.Form
Itistimetoputallofthecontrolsontheformandgivethemnames.We
willbeusingnineToolButtons,oneregularButton,14labelsand13TextBoxes.
We will also need to use nine icons, which we can obtain from the
usr/share/icons/defaultkde/32x32folder(NOTE:yoursystemmaybedifferentso
browsearoundtofindwheretheiconsarestoredifneeded).TheiconsIusedfor
thisprogramareasfollows:
250
A Beginner's Guide to Gambas
The ToolButtons
The nine ToolButtons that use these icons in their Picture property are
named:
CreatenineToolButtonsandarrangethemontheformasshowninthe
figureatthebeginningofthischapter. Assignthenamesshownabovetothe
ToolButtonsandsettherespectivebuttonPicturepropertiestothenamesofthe
icons you chose for your program, based on what your system distribution
provides. Worst case scenario is that you can use the builtin icon editor in
Gambastocreateyourownicons.
OnceyouhavecompletedtheToolButtons,wewilladdtheregularbutton
asourQuitbutton.SelectaButtonfromtheToolBoxandplaceitontheform
inthelowerrightcorner,ascloseasyoucantoFigure74.SettheTextproperty
forthisbuttontoQuit.Aslongaswearehere,wecancodetheprogram'sexit
routine,whichwillbecalledwhenthisbuttonisclicked.DoubleclickontheQuit
buttonandyouwillbeplacedinthecodeeditor.Addthiscode:
PUBLICSUBQuitBtn_Click()
'prompttosavedatabeforewequit
SELECTMessage.Question("Savebeforeexit?","Yes","No","Cancel")
CASE1
'iftheusersaysyes,wesave
SaveAllBtn_Click
CASE2'wedon'tsave,justclose
251
A Beginner's Guide to Gambas
CASE3'theycanceled,sowereturntotheprogram
RETURN
CASEELSE'wedonothingbutclose
ENDSELECT
ME.Close'hereweclosethewindow
END'programstops
Probablythemosttediouspartofdevelopingthisprogramisnext,adding
theLabelandTextBoxcontrolstotheform.Trytoarrangethemasyouseein
Figure74above.FortheLabelcontrols,youcantakethedefaultvariablenames
providedbyGambasforallofthelabelsexcepttheoneatthebottomoftheform
where we will display our Record n of n data. That label should be named
StatusLabel. TheTextboxfields,asshownfromtoplefttobottomrightonthe
form,shouldbenamedasfollows:
FirstName
MI
LastName
Suffix
Street1
Street2
City
State
Zip5
Zip4
AreaCode
DialPrefix
DialLast4
252
A Beginner's Guide to Gambas
Figure75Form1seenindesignmode.
UpdateForm()Subroutine
TheUpdateForm()routinewillbecalledeverytimedataontheformhas
changedandneedstoberefreshedsotheuserwillseetheupdatesastheyoccur.
This routine posts each field on the form with the current data found in the
collection based on the current record pointer. Also, the label StatusLabel is
updatedwiththecurrentrecordnumberofnrecordsinthecollectionfromhere.
Let'swalkthroughthecode:
PUBLICSUBUpdateForm()
'checktoensuretherearerecordsbeforewedoanything
IFContacts.Exist(CStr(RecordPointer))THEN
'wefoundrecordssonowwemovetotherecordatcurrentpointer
ContactRecord=Contacts[CStr(RecordPointer)]
'fordebugonly
PRINT"InUpdateFormwithRecordPointerof:"&RecordPointer
'assignTextbox.Textvalueswhateverisstoredinthecontactrecord
FirstName.Text=ContactRecord.FirstName
MI.Text=ContactRecord.Initial
LastName.Text=ContactRecord.LastName
Suffix.Text=ContactRecord.Suffix
Street1.Text=ContactRecord.Street1
Street2.Text=ContactRecord.Street2
City.Text=ContactRecord.City
State.Text=ContactRecord.State
Zip5.Text=ContactRecord.Zip5
Zip4.Text=ContactRecord.Zip4
AreaCode.Text=ContactRecord.Areacode
253
A Beginner's Guide to Gambas
DialPrefix.Text=ContactRecord.Prefix
DialLast4.Text=ContactRecord.Last4
'updatethecurrentrecordstatusfieldwithcurrentdata
StatusLabel.Text="Record:"&CStr(RecordPointer)
StatusLabel.Text=StatusLabel.Text&"of"&CStr(Contacts.Count)
'calltheRefreshmethodtorepainttheformcontents
Form1.Refresh
'selectthecontentsoftheFirstNamefield
FirstName.Select
'setthecursorfocustotheFirstNamefield
FirstName.SetFocus
ELSE'norecordsexist!
'fordebugonly
PRINT"InUpdateForm,Record:"&RecordPointer&"notfound."
ENDIF
'fordebugonly
PRINT"LeavingUpdateForm..."
END
The first ToolButton we will code is the one that will move us to the
beginningofthedata. DoubleclickonthefirstToolButtonandyoushouldbe
takentothecodewindowwheretheFirstRecordBtn_Click()routineawaits.Add
thiscode:
PUBLICSUBFirstRecordBtn_Click()
'movetothefirstrecord
RecordPointer=1
'retrievethatrecordfromthecollection
ContactRecord=Contacts[CStr(RecordPointer)]
'updatetheformdisplaywiththenewdata
UpdateForm
END
Asyoucansee,movingtothefirstrecordwasprettysimple.Now,wewill
codethePrevandNextbuttons.DoubleclickonthesecondToolButton()and
youwillbetakentothePrevRecordBtn_Click()subroutine.Addthiscode:
PUBLICSUBPrevRecordBtn_Click()
254
A Beginner's Guide to Gambas
'fordebugonly
PRINT"inPrev:currentpointeris:"&RecordPointer
'wearemovingtoalowerrecordsowedecrementtherecordpointer
DECRecordPointer
'ifwemovedpastrecord1thenresettorecord1
IFRecordPointer=0THEN
RecordPointer=1
ENDIF
'updateourcontactvaraiblewiththenew(prev)recorddata
ContactRecord=Contacts[CStr(RecordPointer)]
'ifwearealreadyatthebeginningofthedatanotifytheuser
IFRecordPointer=1THEN
'fordebugonly
PRINT"Atfirstcontactalready!"
ELSE
'fordebugonly
PRINT"inPrevnowcurrentpointeris:"&RecordPointer
ENDIF
'updateourformwiththenewdata
UpdateForm
END
Now,wewillcodetheNextbutton.DoubleclickonthethirdToolButton
()andyouwillbetakentotheNextRecordBtn_Click()subroutine. Addthis
code:
PUBLICSUBNextRecordBtn_Click()
'fordebugonly
PRINT"inNext:currentpointeris:"&RecordPointer
'wemoveforwardthroughthecollectionsoweincrementthepointer
INCRecordPointer
'ifwemovedpastthelastrecord,resettothelastrecord
IFRecordPointer>Contacts.CountTHEN
RecordPointer=Contacts.Count
ENDIF
'updatethecontactrecordwiththenewdata
ContactRecord=Contacts[CStr(RecordPointer)]
'ifwearealreadyatthelastrecord,telltheuser
IFRecordPointer=Contacts.CountTHEN
255
A Beginner's Guide to Gambas
'fordebugonly
PRINT"AtLastcontactalready!"
ELSE
'fordebugonly
PRINT"inNext,thecurrentpointeris:"&RecordPointer
ENDIF
'updateourformagainwiththenewdata
UpdateForm
END'nextrecordmove
ThelastToolButtonweneedtocodeformovingaroundinthedataisfor
theLastRecordBtn_Click()subroutine.Thissubroutinewillplaceusattheendof
thedatacollection,atthelastrecord.DoubleclickonthefourthToolButtonand
addthiscode:
PUBLICSUBLastRecordBtn_Click()
'setrecordpointertolastrecordusingcollection.countproperty.
RecordPointer=Contacts.Count
'updateourrecordvarwiththenewdataforthelastrecord
ContactRecord=Contacts[CStr(RecordPointer)]
'updatetheformwiththenewdata
UpdateForm
END
Now,let'sgothroughhowtoaddanewcontacttothecollection.Double
clickonthefifthToolButton,thelittlepersonicon,andyouwillbeputinthecode
windowattheAddBtn_Click()subroutine.Let'sgothroughthecode:
PUBLICSUBAddBtn_Click()
'declarealocalcontactvaraiblejustforuseinthissubroutine
DIMMyContactRecordASContact
'instantiatethecontactrecordsowecanuseit
MyContactRecord=NEWContact
'ifthereisnofirstname,wewillnotaddarecord
IFFirstName.Text<>""THEN
'fordebugonly
PRINT"Adding"&FirstName.Text&"tocollection."
'weareheresowefoundafirstname.AssigntheTextboxdata
'tothefieldsstoredintherecord:
MyContactRecord.FirstName=FirstName.Text
256
A Beginner's Guide to Gambas
MyContactRecord.LastName=LastName.Text
MyContactRecord.Initial=MI.Text
MyContactRecord.Suffix=Suffix.Text
MyContactRecord.Street1=Street1.Text
MyContactRecord.Street2=Street2.Text
MyContactRecord.City=City.Text
MyContactRecord.State=State.Text
MyContactRecord.Zip5=Zip5.Text
MyContactRecord.Zip4=Zip4.Text
MyContactRecord.Areacode=AreaCode.Text
MyContactRecord.Prefix=DialPrefix.Text
MyContactRecord.Last4=DialLast4.Text
'incrementtherecordkeysoeachkeyisuniquewhenaddedto
'thecollection.Gambasrequiresthatthisbeconvertedtoa
'stringvariablewhenweactuallyadditbelow.
MyContactRecord.RecordID=Contacts.Count+1
'ifweaddingarecorditisnottaggedasdeleted
MyContactRecord.Deleted=FALSE
'setglobalrecordpointertothevalueoftheincrementedkey
RecordPointer=MyContactRecord.RecordID
'now,calltheCollection.Addmethodtoaddtherecord
Contacts.Add(MyContactRecord,CStr(RecordPointer))
'thisisfordebugonlytoshowwhathasbeenadded
IFContacts.Exist(CStr(RecordPointer))THEN
'fordebugonly
PRINT"Record"&CStr(RecordPointer)&"added!"
ELSE
'fordebugonly
PRINT"Recorddoesnotexist!"
ENDIF
ELSE'cannotaddacontactwithoutafirstname,telluser
Message.Info("Cannotaddwithoutafirstname","Ok")
ENDIF
'updatetheformwiththenewdata
UpdateForm
'thisisfordebugpurposes,showallrecordsinthecollection
FOREACHMyContactRecordINContacts
PRINT"Record"&CStr(RecordPointer)&":";
PRINTMyContactRecord.FirstName&""&MyContactRecord.LastName
NEXT
END'addroutine
257
A Beginner's Guide to Gambas
ThesixthToolButtonisusedtoclearthedataontheformtoallowusersto
startwithafresh,blankformtoenterdata. ItsimplyblanksouteachTextbox
field.DoubleclickontheClearBtnandenterthiscode:
PUBLICSUBClearBtn_Click()
FirstName.Text=""
MI.Text=""
LastName.Text=""
Suffix.Text=""
Street1.Text=""
Street2.Text=""
City.Text=""
State.Text=""
Zip5.Text=""
Zip4.Text=""
AreaCode.Text=""
DialPrefix.Text=""
DialLast4.Text=""
END
ValidatingUserInput
WhentheuserentersdataintheInitialfield,andalsointheSuffix,State,
Zip5,Zip4,AreaCode,DialPrefixandDialLast4fields,wewanttoensurethatthe
data fits and they cannot enter extraneous letters or characters. Each of the
routinesbelowareactivatedonachangeevent.Inotherwords,ifthetextinthe
TextBox.Textfieldchanges,itwillgototherespective_Change()routinebelow.
Eachroutineworksalmostidenticallytolimitthenumberofcharacterstheuser
can type. If they type more, the extra characters are truncated at the length
specifiedbytheprogram.Forexample,anareacodecanbenomorethanthree
digits.Wecouldalsoaddcodetoensureonlydigitsareenteredinnumericfields,
etc.,butthatisnotwhywearebuildingthisprogram.WIwillleavethattoyou
toaddasanexerciseattheendofthischapter.Foreachcheckbelow,wewill
need a temporary string var, sTemp. If the length of the TextBox.Text data
exceedsthelengthweallow,weuseMID$tocopythefirstnletterstosTempand
thencopythatvaluebackintotheTextBox.Textproperty.
PUBLICSUBMI_Change()
DIMsTempASString
IFLen(MI.Text)>1THEN
sTemp=Mid$(MI.Text,1,1)
MI.Text=sTemp
258
A Beginner's Guide to Gambas
ENDIF
END
PUBLICSUBSuffix_Change()
DIMsTempASString
IFLen(Suffix.Text)>3THEN
sTemp=Mid$(Suffix.Text,1,3)
Suffix.Text=sTemp
ENDIF
END
PUBLICSUBState_Change()
DIMsTempASString
IFLen(State.Text)>2THEN
sTemp=Mid$(MI.Text,1,2)
State.Text=sTemp
ENDIF
END
PUBLICSUBZip5_Change()
DIMsTempASString
IFLen(Zip5.Text)>5THEN
sTemp=Mid$(MI.Text,1,5)
Zip5.Text=sTemp
ENDIF
END
PUBLICSUBZip4_Change()
DIMsTempASString
IFLen(Zip4.Text)>4THEN
sTemp=Mid$(MI.Text,1,4)
Zip4.Text=sTemp
ENDIF
END
PUBLICSUBAreaCode_Change()
DIMsTempASString
IFLen(AreaCode.Text)>3THEN
sTemp=Mid$(AreaCode.Text,1,3)
AreaCode.Text=sTemp
ENDIF
END
PUBLICSUBDialPrefix_Change()
259
A Beginner's Guide to Gambas
DIMsTempASString
IFLen(DialPrefix.Text)>3THEN
sTemp=Mid$(DialPrefix.Text,1,3)
DialPrefix.Text=sTemp
ENDIF
END
PUBLICSUBDialLast4_Change()
DIMsTempASString
IFLen(DialLast4.Text)>4THEN
sTemp=Mid$(DialLast4.Text,1,4)
DialLast4.Text=sTemp
ENDIF
END
Asyoucansee,lotsofrepetitivebutnecessarycode.Youcangobacklater
andbulletprooftheinputofthisprogrambyaddingadditionalvalidationchecks
foreverypossiblethingyoucanthinkofbutIwillshowyoulaterinthisbooka
better way, building a customized InputBox that will perform the validation
processautomatically.
AddingaSearchFeature
Wewanttheusertobeabletofindacontactbysearchingforalastname.
There are so many controlson ourformnow that adding another onewould
detractfromtheoverallaestheticsandmakeitappearlessthanelegant.Abetter
solutionistouseamouseclickanywhereontheformitself.Itgeneratesanevent
andwillallowustocapturethateventandinitiateasearchprocess.Whenthis
happens,wearegoingtopopupacustomizedsearchformandprompttheuser
toenteralastnametowhichwewilluseasakeyforoursearch.Createanevent
forMouseDownontheform.HereisthecodefortheMouseDownevent:
PUBLICSUBForm_MouseDown()
SearchForm.ShowModal
Message.Info("Backtomainformwith:"&SearchKey,"Ok")
DoFind
END
NotethatweshowtheformusingtheShowModalmethodinsteadofjust
callingShow.Thisisbecausewewanttheusertoentersomethingandclickthe
Searchbutton.Hereiswhattheformitselflookslikeindesignmode:
260
A Beginner's Guide to Gambas
Prettybasic,justalabel,aTextbox,andabutton.FromtheIDEcreatea
newform,named SearchForm and add thelabel and buttonas shown below.
NamethebuttonSearchBtnandtheTextBoxshouldbenamedSearchInput.Here
isallthecodethatisneededfortheSearchForm:
'GambasSearchFormclassfile
PUBLICSUBSearchBtn_Click()
'thisisacalltoourcustommodule,search,whichhas
'asinglemethod,SearchOn,thatisexplainedbelow
Search.SearchOn(SearchInput.Text)
'fordebugonly
PRINT"returning:"&SearchInput.Text
'assignthesearchkeytotheglobalvarwenamedinForm1
Form1.SearchKey=SearchInput.Text
'nowcloseoursearchform
SearchForm.Close
END
PUBLICSUBForm_Open()
'setthecaptionforthesearchwindow
SearchForm.Caption="Findbylastname"
'highlightandselecttheSearchInputTextbox
'sincethereisonlyoneinputfield,ithasfocusalready
SearchInput.Select
END
Atthispoint,youmightbewonderingwhatexactlyisgoingon.Basically,
in Gambas, public variables are public to a class file. When we want to pass
parameters between classes,wecanusethemethodofpassingparameterswith
261
A Beginner's Guide to Gambas
functions like we did when we started the program and passed an empty
collectionvariabletotheGetDatamethod.
'Gambasmodulefile
PUBLICFUNCTIONSearchOn(sKeyASString)ASString
RETURNsKey
END
Atthispoint,wehavepoppeduptheform,obtainedtheuserinputofalast
nametosearchfor,andhavepassedthatvariablebacktoourprogramusingthe
moduleconduitmethoddescribedabove.Now,wearereadytoactuallysearch
thecollectionandfindtheentry.Hereisthecodetodothat:
PUBLICSUBDoFind()
'declareacontactobjectforlocaluse
DIMMyContactRecordASContact
'instantiateit
MyContactRecord=NEWContact
'settherecordpointertothefirstrecordinthecollection
RecordPointer=1
'fordebugonly
PRINT"InDoFindwith:"&SearchKey
'useFOREACHtoiteratethrougheachobjectinthecollection
FOREACHMyContactRecordINContacts
262
A Beginner's Guide to Gambas
'assigneachtemprecordtoourglobalcontactobject
ContactRecord=Contacts[CStr(RecordPointer)]
'ifthelastnamematchessearchkey,updatetheformandleave
IFContactRecord.LastName=SearchKeyTHEN
'fordebugonly
PRINT"Found:"&MyContactRecord.LastName
'nowupdatetheform
UpdateForm
BREAK'forcereturnwiththisstatement
ENDIF
'nomatchsoweincrementtherecordpointerandmovetothenext
INCRecordPointer
NEXT
END
ToolButtonsagain:UpdatingaRecord
Iftheuserhappenstoeditdataonanexistingrecordwhenitisdisplayed,
wewantthedatatobesavedtothesamerecord. Toaccomplishthisusinga
collectionobjectiscomplicatedbythefactthateachobjectinthecollectionmust
haveauniquekey.Togetaroundthis,wewilldeletetheobjectwiththecurrent
keyusingthebuiltinmethodRemove,andreaddtheobjectusingthesamekey
butwithupdateddata. Sortofsneaky,butitgetsthejobdonewithoutmuch
effort.Hereishowitworks:
PUBLICSUBUpdate_Click()
'declarealocalcontactobjectforustoworkwith
DIMMyContactRecordASContact
'instantiateit
MyContactRecord=NEWContact
'nowremovetheexistingrecordinthecollection
Contacts.Remove(CStr(RecordPointer))
'thenwepopulateourworkrecordwiththeformdata
MyContactRecord.FirstName=FirstName.Text
MyContactRecord.LastName=LastName.Text
MyContactRecord.Initial=MI.Text
MyContactRecord.Suffix=Suffix.Text
MyContactRecord.Street1=Street1.Text
MyContactRecord.Street2=Street2.Text
MyContactRecord.City=City.Text
MyContactRecord.State=State.Text
MyContactRecord.Zip5=Zip5.Text
MyContactRecord.Zip4=Zip4.Text
MyContactRecord.Areacode=AreaCode.Text
263
A Beginner's Guide to Gambas
MyContactRecord.Prefix=DialPrefix.Text
MyContactRecord.Last4=DialLast4.Text
'addtheworkcopytothecollectionwiththesame
'keythatbelongedtotherecordwedeletedabove
Contacts.Add(MyContactRecord,CStr(RecordPointer))
IFContacts.Exist(CStr(RecordPointer))THEN
'fordebugonly
PRINT"Record"&CStr(RecordPointer)&"updated!"
ELSE
PRINT"Recordnotupdated!"'wewantthisoutputififfailed
ENDIF
'updatetheformwiththenewdata
UpdateForm
END
Toolbuttonsagain:DeletingaRecord
Iftheuserwantstodeletearecordinacollectionwealsohavetothink
abouthowtohandlethat.Managingwhichkeysareavailableandwhicharenot
couldbeaprogrammer'snightmaresoaneasierapproachistosimplymarkthe
recordasdeletedandblankit.Thatway,itisavailableforreusewiththesame
key.Itblanksoutthedataand,whenthesaveoccurs,doesnotstoretheolddata,
effectivelydeletingit.Onlydifferenceis,wecanreusethekeybyhavingtheuser
simplyenterdatainanemptyrecordandclicktheupdatebutton.Hereishow
thisisaccomplished:
PUBLICSUBDeleteRecordBtn_Click()
'declareourlocalcontactobject
DIMMyContactRecordASContact
'instantiateit
MyContactRecord=NEWContact
'removethecurrentrecordusingthebuiltinRemovemethod
Contacts.Remove(CStr(RecordPointer))
'clearallthefieldsontheform
ClearBtn_Click
'setthefirstfieldwithanindicatorthattherecordisdeleted
MyContactRecord.FirstName="<DeletedRecord>"
'leavetherestblankbysimplyassigningthemafterclearing
MyContactRecord.LastName=LastName.Text
264
A Beginner's Guide to Gambas
MyContactRecord.Initial=MI.Text
MyContactRecord.Suffix=Suffix.Text
MyContactRecord.Street1=Street1.Text
MyContactRecord.Street2=Street2.Text
MyContactRecord.City=City.Text
MyContactRecord.State=State.Text
MyContactRecord.Zip5=Zip5.Text
MyContactRecord.Zip4=Zip4.Text
MyContactRecord.Areacode=AreaCode.Text
MyContactRecord.Prefix=DialPrefix.Text
MyContactRecord.Last4=DialLast4.Text
'markrecordasdeleted
MycontactRecord.Deleted=TRUE
'addtheblanked,deletedrecordasitexiststothecollection
Contacts.Add(MyContactRecord,CStr(RecordPointer))
IFContacts.Exist(CStr(RecordPointer))THEN
'fordebuggingonly
PRINT"Record"&CStr(RecordPointer)&"markeddeleted!"
ELSE
'ifitfails,wewantamessage
Message.Info("Recordnotmarkeddeleted!","Ok")
ENDIF
'updatetheform
UpdateForm
END
ToolButtonsagain:SavingData
Thelastthingweneedtocodeisthesavebutton. Thisisreallysimple
becausewehavealreadybuiltamethodinourContactclassfiletodothat.Here,
allwedoiscallthePutDatamethod:
PUBLICSUBSaveAllBtn_Click()
'invokethePutDatamethod
ContactRecord.PutData(Contacts)
'fordebugonly
PRINT"Contactssavedtocontact.datafile."
END
Thatisallwehavelefttodo.Runtheprogramandentersomedata.Be
suretotryalltheoptionsandcreateafewrecords. Saveyourdatatofileand
reloadit.Whenyouaresatisfiedthatitworksasweplanned,itisoktogoback
andcommentoutalltheconsoleoutput(thePRINTstatements)sotheywillnot
265
A Beginner's Guide to Gambas
displayatruntime. Foralltheotherprogramswehavecreated,wehavebeen
contenttosimplyexecutethemfromwithintheIDE.Sincethisprogramcanbea
usefuladditiontoyourdesktop,wewillnowshowyouhowtocreateastand
aloneexecutableandallowittorunindependentoftheGambasprogramming
environment.
CreatingaStandaloneExecutable
Itisveryeasytocreatetheexecutable.Simplymakesureyourprogramis
readyforrelease(testitfirst!)andthengototheProjectmenuandchooseMake
Executable.TheGambasIDEwillcreateanexecutionscriptthatwillinvokethe
GambasInterpreterandallowyoutoexecuteyourcode.Icreatedadesktoplink
totheprogramandusedthisfortheapplicationpathonmysystem:
'/rittingj/MyDocuments/GambasforBeginners/Classes/Classes'
Of course, your system will be different. You will need to point the
desktoplinktotheapplicationtowhereeveryouhadtheIDEsavetheexecutable
file.OntheLinuxdistributionIusedforthisprogram,itwouldnotworkuntilI
enclosedthefullpathwithtickmarks,asshownabove. Becausethe Gambas
Interpreter isinvokedasasystemcall,theticksareneededtokeepthesystem
from thinking it is passing parameters to /rittingj/My (where the first space
characteroccurs).Hereisthefinalresult,ourprogramexecutinginstandalone
modeonthedesktop:
Figure76ContactsManagerrunningstandaloneonmydesktop.
266
A Beginner's Guide to Gambas
DrawProperties
EachitemyouwishtodrawinGambasissupportedwithseveralcommon
attributes,suchasbackgroundcolorandforegroundcolor,afillcolor,fillstyle,
etc. SomepropertiesinGambas,suchasClip,arereadonlyandsimplyreturn
datatoyouforuseinyourcode.
BackColor/BackgroundandForeColor/Foreground
BackColorisdefinedasPROPERTYBackColorASInteger
ForeColorisdefinedasPROPERTYForeColorASInteger
Thisintegervaluerepresentsthecolorusedforthecurrentdrawingbackground
or foreground color. It is synonymous with the Background/Foreground
properties. Note that PROPERTY is a predefined datatype used internally in
Gambas. You can usetheGambas predefined constantsfor color tosetcolor
value:
267
A Beginner's Guide to Gambas
TosettheBackColorpropertytored,youwouldusethiscode:
Draw.BackColor=Color.Red
Alternatively,aswestatedpreviously,ifyouknowtheRGBorHSVvalues
foraspecificcolor,GBprovidesameanstoconvertthosevaluestoaninteger
valuethatcanbepassedtotheBackColor(orothercolorrelated)property.The
Colorclass providestwomethods,RGBandHSVthatyoucan use. The RGB
functionreturnsacolorvaluefromitsred,greenandbluecomponents. HSV
returnsacolorvaluefromitshue,saturationandvaluecomponents.Touseone
ofthesefunctionstosetthebutton'sbackgroundcolor,hereiswhatyoucould
code:
Draw.BackColor=Color.RGB(255,255,255)
ThiswouldsettheDrawobject'sbackgroundcolortowhite.Thisismostuseful
whenyouaretryingtosetcolorswhosevaluesfalloutsidethedefaultconstants
valuesprovidedinGB.
Clip
STATICPROPERTYREADClipAS.DrawClip
Thisclasscanbeusedasafunction.Toinvokethefunctiontodefineaclipping
area,usethisGambaslanguagesyntax:
STATICSUB.DrawClip(XASInteger,YASInteger,WASInteger,HASInteger)
FillColor,FillStyle,FillX,FillY
268
A Beginner's Guide to Gambas
capableoffillingapolygonwithacolororpatternorboth. Thisclassisstatic.
TheFillStylepropertyreturnsorsetsthestyleusedbydrawingmethodscapable
offillingapolygonwithacolororpatternorboth.TheFillclasssupportsseveral
predefinedFillStyleconstantsusedtorepresentfillpatternsfordrawing:
GambaslanguagesyntaxforFillColorandFillStyleisasfollows:
STATICPROPERTYFillColorASInteger
STATICPROPERTYFillStyleASInteger
The FillX property and the FillY property are used to return or set the
horizontal/vertical origin of the brushes used by drawing methods capable of
fillingapolygonwithacolororpatternorboth. Gambaslanguagesyntaxfor
FillXandFillYis:
STATICPROPERTYFillXASInteger
STATICPROPERTYFillYASInteger
Font
The Font class returns or sets the font used for rendering text on the
drawingsurface.Gambaslanguagesyntaxis:
STATICPROPERTYFontASFont
Tosetcontrolfontattributes,thiscodecanbeused:
Draw.Font.Name="Lucida"
Draw.Font.Bold=TRUE
Draw.Font.Italic=FALSE
Draw.Font.Size="10"
Draw.Font.StrikeOut=FALSE
Draw.Font.Underline=FALSE
Invert
The Invert property is used to stipulate that all drawing primitives will
combinetheirpixelcolorswiththepixelcolorsofthedestinationusinganXOR
operation.Gambaslanguagesyntaxis:
269
A Beginner's Guide to Gambas
STATICPROPERTYInvertASBoolean
LineStyle/LineWidth
The LineStyle property returns or sets the style used for drawing lines.
LineWidthreturnsorsetsthewidthusedfordrawinglines.TheLineclassisstatic
anddefinestheconstantsusedbytheDraw.LineStyleproperty.Theseconstants
include:
StandardGambaslanguagesyntaxis:
STATICPROPERTYLineStyleASInteger
STATICPROPERTYLineWidthASInteger
Transparent
STATICPROPERTYTransparentASBoolean
DrawMethods
OneofthebestwaystolearnhowtouseGambasdrawingmethodsisto
writecodethatdemonstratestheuseofeachmethod. Inthismanner,youcan
seehowtoprogramthemethodandgetimmediategratificationbyseeingthe
results.Wearegoingtobuildademoapplicationthatwillshowyouhowtouse
nearlyallofthemethodsthataresupportedbytheDrawclass.
Wewillstartbecreatinganewgraphicaluserinterfaceapplication.Name
theprojectgfxDemoandwhentheIDEappears,createaform,Form1.Makesure
youspecifyitasastartupclassandensurethecontrolsarepublic.Hereiswhat
theForm1layoutwilllooklikeatruntime:
270
A Beginner's Guide to Gambas
Figure77gfxDemoForm1layout.
Settheformwidthto530andtheheightto490.Thedefaultsettingsfor
allotherpropertiesshouldbefineforourpurposes. Createeightbuttonsand
label them as shown in the picture above. The button names are TextBtn,
InvRectBtn, EllipseBtn, FillRectBtn, PolygonBtn, PolyLineBtn, TileBtn, and
QuitBtn.Eachbuttonshouldhaveawidthof60andaheightof25.Placethem
aslowontheformasyoucanwithoutcuttingoffthebottomofthebutton.For
eachbuttonyouhavecreated,wewillneedtocreateaclickeventbydouble
clickingonthebutton.
Aswegothroughtheexplanationsofeachofthefollowingmethods,we
willbeaddingcodewhereappropriate.Beforewegettothemethodsthemselves,
thereareacoupleofthingsweneedtodowithourprogram.First,weneedto
addaDrawingAreacontrol,nameddatotheform.Placeitatthetopleftcorner
ofForm1andmakeitabout1inchby1inch.Wewilldynamicallyresizeitinour
program.Next,wewilluseaconstructortostartthedrawingprocess,invoking
the Draw.Begin method and setting the parameters that will be used for our
program.Hereistheconstructorsubroutineyouneedtoadd:
PUBLICSUB_new()
'establishwidthofthedrawingarea
da.W=form1.W10
'establishheightofthedrawingarea
da.H=form1.H45
'makethemandatorycalltostartdrawoperations
Draw.Begin(da)
'setadefaultlinewidthof2pixels
271
A Beginner's Guide to Gambas
Draw.LineWidth=2
END
When the form opens at program start, it will first call the constructor
above,thenexecutethecodeintheForm_Opensubroutine.Allwearegoingto
doforthissubroutineissetthecaptionatthetopoftheform:
PUBLICSUBForm_Open()
Form1.Text="DrawingExamples"
END
ThefinalroutinewewillcreatebeforeexploringtheDrawmethodsisthecode
neededtostopourprogram.DoubleclickontheQuitbuttonandaddthiscode:
PUBLICSUBQuitBtn_Click()
Draw.End'closedrawingoperations
ME.Close'closeForm1
END
Now,wearereadytobeginaddingcodetoexploreourvariousdrawingtools,the
methodsoftheDrawclass.
Text/TextHeight/TextWidth
We will begin with Draw.Text and the two readonly text properties,
TextHeightandTextWidth.TheTextHeightpropertyreturnstheheightofatext
drawing while the TextWidth property returns the width of a text drawing.
StandardGambaslanguagesyntaxis:
STATICFUNCTIONTextHeight(TextASString)ASInteger
STATICFUNCTIONTextWidth(TextASString)ASInteger
DoubleclickontheTextbuttonandaddthiscode:
PUBLICSUBTextButton_Click()
'thisvarwillbeusedforourloopcounter
DIMcounterASInteger
'clearthecurrentdrawingarea
da.Clear
'setforegroundcolortoblack
Draw.ForeColor=color.Black
272
A Beginner's Guide to Gambas
'setcurrentfonttoArial
draw.Font.Name="Arial"
'turnonboldface
draw.Font.Bold=TRUE
'turnoffitalic
draw.Font.Italic=FALSE
'turnoffunderline
draw.Font.Underline=FALSE
'settextsizeto16points
draw.Font.Size="16"
'startaloopandcontinueuntilweiterate10times
FORcounter=0TO9
'outputtextandincrementtheypositionby40*counter
'theoptionalwidth,heightparametersaregivenas100,60
draw.Text("SampleText",10,10+40*counter,100,60)
NEXT'iterationoftheloop
'nowsetfontto24points
draw.Font.Size="24"
Draw.ForeColor=color.Blue'andchangecolortoblue
FORcounter=0TO9'loopanother10times
'allwechangeisxpositiontomovethetextright200pixels
draw.Text("MoreSampleText",200,10+40*counter,100,60)
NEXT'iteration
'refreshthedrawingareatoseewhatwasdone
da.Refresh
END'wearedonewithtextstuff!
Onceyouhaveaddedthecodeabove,saveyourworkandclicktheRUNbutton.
Hereiswhatyoushouldsee:
273
A Beginner's Guide to Gambas
Figure78ResultsofclickingtheTextButton.
DrawPrimitives:Point/Rect/Ellipse/Line
TheDraw.PointmethoddrawsasinglepixelwhiletheDraw.Rectmethod
drawsarectangle.Gambaslanguagesyntaxforthesetwomethodsis:
STATICSUBPoint(XASInteger,YASInteger)
STATICSUBRect(XASInteger,YASInteger,WidthASInteger,HeightASInteger)
WearegoingtousetheInvRectbuttontoillustratehowthesemethodsareused.
DoubleclickontheInvRectbuttonandenterthefollowingcode:
PUBLICSUBInvRectBtn_Click()
'usethisvarforourloopcounter
DIMcounterASInteger
'clearthedrawingarea
da.Clear
'makesurefillstyleissettoNone
draw.FillStyle=fill.None
'setcolortocyan
draw.ForeColor=color.cyan
'thiswillmakethecyanrectangleappearred
draw.Invert=TRUE
FORcounter=0TO15'loop16times
'drawarect,incthestartx,yandendx,ypositions5*counterval
Draw.Rect(5+5*counter,5+5*counter,da.W/2+5*counter,da.H/2+5*counter)
274
A Beginner's Guide to Gambas
'ifwehitanevennumber,invoketoggleInvertpropertyon/off
IFcounterMOD2=0THEN
draw.Invert=FALSE
ELSE
draw.Invert=TRUE
ENDIF
NEXT'iterationoftheloop
'ensureinvertissettooff
draw.Invert=FALSE
'setcurrentfgdcolortoblack
draw.Forecolor=color.Black
'setapointmidscreen
draw.Point(da.W/2,da.H/2)
'nowwewillmakeatinycrosshairfromthefirstpoint
'bymovingonepixelup,down,leftandrightofthecenter
'dotwesetwiththefirstdraw.pointcall
draw.Point(da.W/21,da.H/2)
draw.Point(da.W/2+1,da.H/2)
draw.Point(da.W/2,da.H/21)
draw.Point(da.W/2,da.H/2+1)
'updatethedisplaytoseewhatwedid
da.Refresh
END'oftherect/pointdemocode
Saveyourworkandruntheprogram.WhenyouclicktheInvRectbutton,
youshouldseesomethingsimilartothis:
Figure79ResultsofInvRectbuttonclick.Note
thetinyblackcrosshaircenterscreen.
275
A Beginner's Guide to Gambas
TheDraw.Linemethoddrawsaline.Thex1,y1pointsrepresentthestart
vertexoftheline,x2,y2representtheendvertexoftheline. Thelinemethod
uses properties from the Line class to establish line style and thickness. The
constantsusedbytheDraw.LineStyleproperty are Dash,DashDot,DashDotDot,
Dot,None,andSolid.LinethicknessissetusingtheDraw.LineWidthpropertyand
widthissetinpixels.TheGambaslanguagesyntaxforthismethodis:
STATICSUBLine(X1ASInteger,Y1ASInteger,X2ASInteger,Y2ASInteger)
TheDraw.Ellipsemethodwilldrawanellipseorcircle.Remember,acircle
isanellipsewithequalwidthandheightparameters,whichiswhyyoudonotsee
aDraw.CirclefunctioninGambas.TheGambaslanguagesyntaxforDraw.Ellipse
is:
STATICSUBEllipse(XASInteger,YASInteger,WidthASInteger,HeightAS
Integer[,StartASFloat,LengthASFloat])
XandYrepresentthecenterpointofthecircleorellipse. Widthcanbe
thoughofasaradiusalongthehorizontalplane, heightisaradiusalong the
verticalplane. Ifyouspecifytheoptionalparametersofstartandlength,these
representstartingangles(indegrees)wherethedrawingwillstartandstop.We
willillustratethisinourexamplebelowusingtheEllipsesbutton.Doubleclickon
theEllipsesbuttonandenterthiscode:
PUBLICSUBEllipseBtn_Click()
'declaresomevariablestoworkwith
DIMx1ASInteger
DIMx2ASInteger
DIMy1ASInteger
DIMy2ASInteger
'wewillneedacountervariable
DIMiASInteger
'andavartoholdthevalueoflinewidthaswechangeit
DIMlwidthASInteger
'clearourdisplaybeforewebegin
da.Clear
'setinitialvectors
x1=50
y1=50
x2=100
y2=100
276
A Beginner's Guide to Gambas
'changethecolortodarkblue
Draw.ForeColor=color.DarkBlue
'setupforasolidfill.Anyfillablecontainerthatiscalledafter
'thiscallwillbefilledwiththepatternspecifiedbelow
draw.FillStyle=fill.Solid
'setupaloopthatwillcreate12increments
FORi=0TO360STEP30
'ifwefallona90degreeincrement,switchcolors
IFiMOD45=0THEN
draw.FillColor=color.Yellow
ELSE
draw.FillColor=color.Red
ENDIF
'drawafilledellipseof12segments,startingateachvalueofi
'andsweepingfor30degrees,asspecifiedintheoptionalparms
Draw.Ellipse(x1,y1,x2,y2,i,30)
NEXT
'now,turnoffthefillstyle
draw.FillStyle=fill.None
'setourfgdcolortoblack
draw.ForeColor=color.Black
'letsdrawsomelines,startxatmidscreenhorizaxis25pixels
x1=da.W/225
'startouryatmidscreenontheverticalaxis
y1=da.H/2
'startwithalinewidthofasinglepixel
lwidth=1
'loop8times,movingdownalongtheyaxisin25pixincrements
FORi=10TO200STEP25
'drawaline
draw.Line(da.W/2,i,da.W/2+150,i)
'increaselinethicknessvariable
INClwidth
'setthenewwidth
draw.LineWidth=lwidth
NEXT'iterationoftheloop
277
A Beginner's Guide to Gambas
'outoftheloop,resettoadefaultof2pixwide
draw.LineWidth=2
'now,letsstartanotherloopanddrawsomeellipses
FORi=1TO40STEP3'letsmake13ofthem
'movingthisoneleftalongthehorizaxis
Draw.Ellipse(x1i*5,y1,75,200)
'andmovingthisonerightalongthehorizaxis
Draw.Ellipse(x1+i*5,y1,75,200)
'ifwehitanevennumberinourloopchangecolors
IFiMOD2=0THEN
draw.ForeColor=color.Red
ELSE
draw.ForeColor=color.Black
ENDIF
NEXT'iterationoftheloop
'refreshthedrawingareatoseeourwork
da.Refresh
END'endoftheellipsesandlinesdemocode
Saveyourworkandruntheprogram.WhenyouclicktheEllipsesbutton,
youshouldseesomethingsimilartothis:
Figure80Ellipsesdemonstratesdrawinglinesand
ellipses.
278
A Beginner's Guide to Gambas
OurnextcodesegmentwillusetheFillRectbutton.Wearerevisitingthe
Draw.Rect method to show you how to use the Draw.FillStyle to create filled
objects.Createaclickeventandenterthefollowingcode:
PUBLICSUBFillRectBtn_Click()
'createsomelocalvarstoworkwith
DIMx1ASInteger
DIMx2ASInteger
DIMy1ASInteger
DIMy2ASInteger
'clearthedrawingarea
da.Clear
'settherecttopleftcorner
x1=20
y1=80
'settherectbotrightcorner
x2=x1+50
y2=y1+50
'setfgdcolortored
draw.FillColor=color.Red
'specifyahorizstylefillpattern
draw.FillStyle=fill.Horizontal
'drawarect,ifafillpatternisspecified,itisautofilled
Draw.Rect(x1,y1,x2,y2)
'settherecttopleftcorner
x1=220
y1=180
'settherectbotrightcorner
x2=x1+50
y2=y1+50
'setfgdcolortoblue
draw.FillColor=color.Blue
'specifyacrossstylefillpattern
draw.FillStyle=fill.Cross
'drawarect,ifafillpatternisspecified,itisautofilled
Draw.Rect(x1,y1,x2,y2)
279
A Beginner's Guide to Gambas
'turnoffthefill
draw.FillStyle=fill.None
'refreshtoseeourwork
da.Refresh
END
Saveyourworkandruntheprogram.WhenyouclicktheFillRectbutton,
youshouldseesomethingsimilartothis:
Figure81OutputafterclickingtheFillRectbutton.
DrawPrimitives:PolygonandPolyline
STATICSUBPolygon(PointsASInteger[])
ThePointsparameterisanarrayofIntegercontainingthecoordinatesof
thepolygonvertexes.Thecoordinatesareassumedtobeinx,yformatsothere
mustbetwointegersinthearrayforeachvertexofthepolygon.
280
A Beginner's Guide to Gambas
joinedfromonetothenextbyaline.Thelinewilldrawfromthelastvertexto
thenextvertexspecifiedinthearray.TheGambaslanguagesyntaxforPolyline
is:
STATICSUBPolyline(PointsASInteger[])
PUBLICSUBPolygonBtn_Click()
'declaresomeworkvariablestocreateapolygon
DIMx1ASInteger
DIMy1ASInteger
DIMx2ASInteger
DIMy2ASInteger
DIMx3ASInteger
DIMy3ASInteger
'wearegoingtocreateatriangleforourpolygon
'andstoretheverticesintheintegerarraytriangle
DIMtriangleASInteger[]
'clearthedisplayarea
da.Clear
'settheverticesforeachlegofthetriangle
'startingwiththetoppartofanequilateraltriangle
x1=da.w/2'setthehorizaxistomidscreen
y1=10'setverticalaxistotop+10pixels
'now,wewilldotheleftlegofthetriangle
'startingontheextremeleftedgeplus10pixels
x2=da.Left+10
'andsettingourypositiontodrawingareaheight200pixels
y2=da.H200
'therightlegsetshorizpositionfarright20pixelsin
x3=da.W20
'andthevertaxiswillbesameasthesecondleg
y3=y2
'allverticesdefined,loadtheintegerarraywiththetriangle
281
A Beginner's Guide to Gambas
triangle=Array(x1,y1,x2,y2,x3,y3)
'setafillstyle
draw.FillStyle=fill.Dense63
'andafillcolor
draw.FillColor=color.DarkMagenta
'anddrawthepolygonusingthetrianglearraydata
draw.Polygon(triangle)
'remembertosetfillstyletoNone
draw.FillStyle=fill.None
'callrefreshtoseeourwork
da.Refresh
END'andwearedonewiththepolygonroutine
Saveyourworkandruntheprogram.WhenyouclicktheFillPolybutton,
youshouldseesomethingsimilartothis:
Figure82UsingDraw.Polygontodrawa
triangle.
PUBLICSUBPolyLineBtn_Click()
'declaresomevariablestocreateourvertices
DIMx1ASInteger
DIMy1ASInteger
DIMx2ASInteger
282
A Beginner's Guide to Gambas
DIMy2ASInteger
DIMx3ASInteger
DIMy3ASInteger
DIMx4ASInteger
DIMy4ASInteger
'declareanintegerarraytoholdthepolylinedata
DIMlinesASInteger[]
'clearthedrawingarea
da.Clear
'startourfirstpointmidscreenabout10pixelsfromthetop
x1=da.w/2
y1=10
'thenextpointwillbe10pixelsinfromfarleft,down200pixels
x2=da.Left+10
y2=da.H200
'our3rdvertexwillbedeadcenterofthedrawingareaonhorizaxis
'andverybottomofthedrawingareaforvertaxis
x3=da.W20
y3=da.H20
'andthe4thvertexwillbedeadcenterxandyofthedrawingarea
x4=da.W/2
y4=da.H/2
'loadtheverticesintothearray
'ifwewantedtoclosethepolygon,allweneedtodoisaddthe
'x1,y1verticestotheendofthearray
'uncommentthenextlinetotryitandsee
'lines=Array(x1,y1,x2,y2,x3,y3,x4,y4,x1,y1)
lines=Array(x1,y1,x2,y2,x3,y3,x4,y4)
'ensureanyfillstylesareturnedoff
draw.FillStyle=fill.None
'setthecolortodarkgreen
draw.ForeColor=color.DarkGreen
'drawthelines
draw.Polyline(lines)
'refreshtoseeourwork
da.Refresh
END'ofthepolylinedemoroutine
283
A Beginner's Guide to Gambas
Saveyourworkandruntheprogram.WhenyouclickthePolylinebutton,
youshouldseesomethingsimilartothis:
Figure83UsingDraw.Polylinetodrawlines.
Image/Picture/Tile
The Image class draws an Image, or part of it. The image contentsare
storedintheprocessmemory,notinthedisplayserverlikeaPicture.Thisclassis
creatable. If Width and Height are not specified, then the new image is void.
Gambaslanguagesyntaxis:
STATICSUBImage(ImageASImage,XASInteger,YASInteger[,SrcX
ASInteger,SrcYASInteger,SrcWidthASInteger,SrcHeightAS
Integer])
Thefollowingcodewouldcreateanewimage:
DIMhImageASImage
hImage=NEWImage([WidthASInteger,HeightASInteger])
Thisclassactslikeanarrayofpixels. ThinkofXasrowsandYascolumnsof
imagepixels.Hereishowthecodetogetorsetapixelofanimagewouldwork:
DIMhImageASImage
DIManIntegerASInteger
anInteger=hImage[XASInteger,YASInteger]
ThecodeabovewillreturnthecolorofanimagepixelatX,Ywhilethefollowing
284
A Beginner's Guide to Gambas
codewillsetthecolorofanimagepixeltothevalueofanInteger:
hImage[XASInteger,YASInteger]=anInteger
Image allows you to use the following properties: Depth, Height, Picture, and
Width.
PROPERTYDepthASInteger
Heightisareadonlyattributethatreturnstheheightoftheimageasaninteger.
Itisdeclaredas:
PROPERTYREADHeightASInteger
Widthisareadonlyattributethatreturnsthewidthinpixelsoftheimage.Itis
declaredas:
PROPERTYREADWidthASInteger
Picture (readonly) converts the image into a picture, and returns it. It is
declaredas:
PROPERTYREADPictureASPicture
TheImageclasssupportsseveralmethods.Theseinclude:Clear,Copy,Fill,Flip,
Load,Mirror,Replace,Resize,Rotate,Save,andStretch.
Clearwillcleartheimage,settingallpixelvaluestozero.
Copyreturnsacopyoftheimage,oracopyofapartofit.Thecopymethodis
declaredasafunction,asshownbelow:
FUNCTIONCopy([XASInteger,YASInteger,WidthASInteger,Height
ASInteger])ASImage
Fillfillstheimagewithaspecifiedcolor.Gambaslanguagesyntaxis:
SUBFill(ColorASInteger)
285
A Beginner's Guide to Gambas
Flipreturnsamirroredcopyoftheimage.Themirroredcopyiscreatedusingthe
horizontalaxisoftheimage.
FUNCTIONFlip()ASImage
LoadandSaveloadorsavesanimagefromafileortoafilerespectively.The
fileextensionof Path willspecifythegraphicsfileformatusedwiththesaved
image. CurrentlysupportedfileformatsareJPEG,PNG,BMP,GIFandXPM.
Gambaslanguagesyntaxis:
SUBLoad(PathASString)
SUBSave(PathASString)
Mirrorreturnsamirroredcopyoftheimage.Themirroredcopyiscreatedusing
theverticalaxisoftheimage.
FUNCTIONMirror()ASImage
ReplaceswapsanexistingOldColorvaluewiththecolorspecifiedbyNewColor,as
shownbelow:
SUBReplace(OldColorASInteger,NewColorASInteger)
ResizeResizestheimagetothesizespecifiedbythewidthandheightparameter
given:
SUBResize(WidthASInteger,HeightASInteger)
FUNCTIONRotate(AngleASFloat)ASImage
Stretchreturnsastretchedcopyoftheimage.IftheoptionalparameterSmooth
isspecifiedasTrue,asmoothingalgorithmisappliedtothereturnedresult.The
Gambaslanguagesyntaxis:
FUNCTIONStretch(WidthASInteger,HeightASInteger[,SmoothAS
Boolean])ASImage
286
A Beginner's Guide to Gambas
ThePictureclassdrawsapicture,orpartofapicture.Thepicturecontents
arestoredinthedisplayserver,notintheprocessmemorylikeanImage.Evenif
XWindowdoesnotmanagetransparencyyet,eachpicturecanhaveamask.This
featurecanbesetexplicitlyatpictureinstantiation,orimplicitlywhenloadingan
imagefilethathastransparencylikePNG.Whendrawingonapicturehavinga
mask, the picture and the mask are modified accordingly. Gambas language
syntaxis:
STATICSUBPicture(PictureASPicture,XASInteger,YASInteger[,
SrcXASInteger,SrcYASInteger,SrcWidthASInteger,SrcHeightAS
Integer])
Thisclassiscreatable.ThefollowingcodeshowsyouhowtocreateaPicture:
DIMhPictureASPicture
hPicture=NEWPicture([WidthASInteger,HeightASInteger,
TransparentASBoolean])
IftheoptionalWidthandHeightparametersarenotspecified,thenewpictureis
void.YoucanspecifyifthepicturehasamaskwiththeTransparentparameter.
Thisclassactslikeanarray.
DIMhPictureASPicture
hPicture=Picture[PathASString]
Thecodeabovewillreturnapictureobjectfromtheinternalpicturecache.
If the picture is not present in the cache, it is automatically loaded from the
specifiedfile. Inordertoinsertapictureintheinternalpicturecache,usethis
code:
DIMhPictureASPicture
Picture[PathASString]=hPicture
PROPERTYDepthASInteger
Heightisareadonlyattributethatreturnstheheightofthepictureasaninteger.
Itisdeclaredas:
287
A Beginner's Guide to Gambas
PROPERTYREADHeightASInteger
Widthisareadonlyattributethatreturnsthewidthinpixelsofthepicture.Itis
declaredas:
PROPERTYREADWidthASInteger
Imageisareadonlypropertythatconvertsthepictureintoanimageandreturns
it.Itisdeclaredas:
PROPERTYREADImageASImage
Wewilluseaverysimpleexampletoshowyouhowthisworks.Wewill
showyouhowtotakeascreenshotwithcodeandsavetheimage.Theimageof
thedesktopistakenasapictureobjectwhenthebuttonontheformisclicked.
Thispictureobjectissubsequentlyconvertedintoanimageobjectanddisplayed
asanimageinaDrawingArea. StartGambasandcreateanewgraphicaluser
interfaceproject, namedgfxDemo2. Make theproject translatablewithpublic
controlsand whentheIDEappears,createastartupclassformnamedForm1.
FromthepropertieswindowforForm1,settheresizepropertytoTruesoyoucan
stretchtheformtoseetheimagewhenitisadded.AddabuttonnamedButton1
andaDrawingAreanamedDrawingArea1.PlacetheDrawingAreaatthetopleft
corneroftheformandmakeitaboutoneinchwideandoneinchhigh.Now,put
thebuttonatthebottomrightcorneroftheform.AddthecaptionSnapshotto
thebutton.Doubleclickonthebuttontocreateaclickeventandaddthiscode:
'Gambasclassfile
PUBLICSUBButton1_Click()
'declareavarforourpicture
pASNEWPicture
'andoneforourimage
iASNEWImage
'getthepictureojbectfromthedesktopusing.Grabmethod
p=Desktop.Grab()
'assignthepictureusingtheimagepropertyto
'convertscreenshottoanimage
i=p.image
'specifythatthecontentsofthedrawingareaarecachedinmemory
Drawingarea1.Cached=TRUE
288
A Beginner's Guide to Gambas
'resizedrawingareatosizeoftheimageconvertedfmpicture
DrawingArea1.Resize(i.Width,i.Height)
'clearthedrawingarea
DrawingArea1.Clear()
'calltheDraw.Begin(mandatory)methodtostarttodraw
Draw.Begin(DrawingArea1)
'puttheimageinthedrawingareastartingatorigin0,0
Draw.Image(i,0,0)
'callthe(mandatory)Draw.Endmethodtoquitdrawing
Draw.End
'maketheimagevisible
DrawingArea1.Visible=TRUE
'refreshthedrawingareatoseewhatwasdone
DrawingArea1.Refresh
END
Saveyourworkandruntheprogram.Clickthebuttonandascreenshotofyour
desktopwillbeplacedonthedrawingareaoftheform. Prettyeasyusingthe
Gambasmethods,isn'tit?
TransparentisaBooleanflagthatcanbereadorset.Itindicateswhetherornot
thepicturehasamask.Gambaslanguagesyntaxis:
PROPERTYTransparentASBoolean
MethodssupportedbyPictureincludeClear,Copy,Fill,Flush,Load,Resize,and
Save.
Clearwillclearthepicture,settingallpixelvaluestozero.
Copyreturnsacopyofthepicture,oracopyofapartofit.Thecopymethodis
declaredasafunction,asshownbelow:
FUNCTIONCopy([XASInteger,YASInteger,WidthASInteger,Height
ASInteger])ASImage
Fillfillsthepicturewithaspecifiedcolor.Gambaslanguagesyntaxis:
289
A Beginner's Guide to Gambas
SUBFill(ColorASInteger)
FlushFlushestheinternalpicturecache.Themethodtakesnoparametersandis
calledusingthisconvention:
STATICSUBFlush()
LoadandSaveloadsorsavesapicturefromafileortoafilerespectively.The
fileextensionof Path willspecifythegraphicsfileformatusedwiththesaved
picture. CurrentlysupportedfileformatsareJPEG,PNG,BMP,GIFandXPM.
Gambaslanguagesyntaxis:
SUBLoad(PathASString)
SUBSave(PathASString)
Resizeresizestheimagetothesizespecifiedbythewidthandheightparameter
given:
SUBResize(WidthASInteger,HeightASInteger)
STATICSUBTile(PictureASPicture,XASInteger,YASInteger,Width
ASInteger,HeightASInteger)
Let'snowgobacktoouroriginalgfxDemoprogramandfinishcodingthelast
button. StartGambasandloadthegfxDemoproject.OpenForm1anddouble
clickontheTileImgbutton.Whenthecodewindowappears,addthiscode:
PUBLICSUBTileBtn_Click()
'declareourlocalvarshere
'wewillneedapicturevartoholdthepictureweload
DIMmypicASPicture
'weneedacountervarforourloopwork
DIMcounterASInteger
'wearealsogoingtoneedsomeintegervars
DIMiASInteger
DIMjASInteger
'setiandjtozerotostart
i=0
290
A Beginner's Guide to Gambas
j=0
'instantiatepicturevariable,setwidth,heightsoitisnotvoid
mypic=NEWPicture(170,105,FALSE)
'clearthedrawingarea
da.Clear
'nowloadthepictureusingtheloadmethod
mypic.Load("GambasShrimp.png")
'wewilltilethepictureicolumnsacrossperjrowsdown
'inourcasewewillhave4rowsof3imagesperrow
'sowewillneedtoloop12times
FORcounter=0TO11
'drawthetile
draw.Tile(mypic,i*175,j,170,105)
'incrementourcolumncounter
INCi
'checktoseeifwehavethreeacross
IFiMOD3=0THEN
'ifso,movevalueofj(ouryaxis)image.height+5pixelsdown
j=j+110
'resetcolumncountertozero
i=0
ENDIF'ourchecktoseeif3across
NEXT'iterationoftheloop
'refreshthedisplaytoseethework
da.Refresh
END'oftheTileImgbuttoncode
Thelastthingweneedtodoisgetanimagetouseforourprogram.For
ourprogarm,IhavechosentheGambasmascot,whichweusedfromanearlier
project.YoucancopythisimagefromourFirstProject.Fromtheprojectwindow,
ontheTreeViewDatafolder,selectNewImage.Whenthewindowappears,you
canselecttheExistingtabandbrowsetothefolderFirstProject(assumingyou
named your projects as we specified in the book) and choose the Gambas
mascot.pngimage.SaveittothegfxDemoprojectasGambasshrimp.pngand
thatisallthereistoit.If,forsomereason,youcannotfindtheimageonyour
system,simplygototheGambaswebsiteandusetherightmousebuttonoverthe
mascotimagetosaveacopytoourgfxDemoprojectfolder.Now,saveyourwork
291
A Beginner's Guide to Gambas
andruntheprogram. ClicktheTileImgbuttonandyoushouldseesomething
similartothis:
Figure84Usingtiledimageswiththe
TileImgbuttonofourdemoprogram.
DrawingwithaDrawingobject
Inkscape17isapopularprogramusedintheLinuxcommunityforcreating
SVGimagesandiswhatthisauthorhaschosentousewiththisbooksinceitis
freelyavailableontheInternet.Inkscapeisanopensourcevectorgraphicseditor,
withcapabilitiessimilartoIllustrator,Freehand,CorelDraw,orXaraXusingthe
W3CstandardScalableVectorGraphics(SVG)fileformat.
In Gambas, you can load, save, clear, or copy an SVG image. The
16 See URL http://www.w3.org/TR/SVG/intro.html for more details on SVG.
17 See URL http://www.inkscape.org/ for more details on Inkscape.
292
A Beginner's Guide to Gambas
properties that you have available to you are the most basic, namely width,
height,anddepth. GambasisnotdesignedtobeanSVGeditor. Itsimplyhas
provisions for you to use SVG images in your program. Once you have the
drawinginyourprogram,itisuptoyoutodosomethingwithit.Asanexample,
wewillcreateanewprogramtosimplyloadanSVGimageanddisplayit.First,
wewillneedtofindanSVGimage.Ihavedownloadedafreelyavailablepublic
domainlicensedimagefromtheInternetathttp://openclipart.orgtouseforour
demo.Youcanchooseanyimageyouwishforthisdemo,solongasitisanSVG
formatted file. Now, we will create a new graphical user interface project in
Gambas named gfxDemo3. Make the project controls public and translatable.
Next,createanewstartupclassform,namedForm1.Wearegoingtoaddseveral
controls: Scrollview, DrawingArea, HBox, and two buttons. Your form should
looklikethisindesignmode:
293
A Beginner's Guide to Gambas
PUBLICSUBQuitBtn_Click()
ME.Close
END
Now,doubleclickontheLoadBtnandaddthis:
PUBLICSUBLoadBtn_Click()
'declareourDrawingobjectfortheSVGfile
DIMdraASDrawing
'instantiateit
dra=NEWDrawing
'nowloaditusingtheLoadmethod
dra.Load("floppy.svg")
'setcachedpropertytoTRUEtocacheitinmemory
daSvg.Cached=TRUE
'setvisiblepropertytoTRUEsowecanseethepicture
daSvg.Visible=TRUE
'movethedrawingareaobjecttostartattopleft(0,0)origin
dasvg.Move(0,0,dra.Width,dra.Height)
'callthemandatoryDraw.Begintostarttodraw
draw.Begin(daSvg)
'dothedraw
draw.Drawing(dra,0,0)
'calltheDraw.Endmethodtoquitdrawing
draw.end
'refreshourformtoseewhatwasdone
Form1.Refresh
END
Onceyouhavedownloadedorcreatedthefloppy.svgfile,saveittothe
projectdirectory.ThatisallthecodeweneedtoaddtoviewanSVGfile.Save
294
A Beginner's Guide to Gambas
yourworkandruntheprogram.Whentheprogramstarts,clicktheLoadbutton
andyoushouldseeapicturesimilartothis:
Figure85LoadinganSVGfileinGambas.
IhopeyouhaveenjoyedourshortlittletourdeforceofGambasdrawing
capabilities. ThischapterhaspresentedallofthebasicsneededtouseGambas
foralmostanygraphicsrelatedneeds.Attheendofthisbook,inAppendixA,we
presentaspecialgraphicsprogramthatyoucanusetodrawevenmoreadvanced
2D/3DrenderedobjectsusingaGKStypegraphicsclasscreatedinGambas.
295
A Beginner's Guide to Gambas
ContentsofSVGfilefloppy.svgdownloadedfromhttp://openclipart.org:
296
A Beginner's Guide to Gambas
transform="matrix(1.000000,0.000000,0.000000,1.152582,0.000000,-6.413116)"/>
<rect height="185.694977" id="rect553" style="font-size:12;fill:#ffffff;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="321.362518" x="89.879768" y="249.862976"/>
<rect height="9.32714844" id="rect554" style="font-size:12;fill:#808080;fill-rule:evenodd;stroke-width:1pt;"
width="0.00000000" x="410.394348" y="240.535797"/>
<path d="M 334.929 76.0389 C 334.081 76.0389 282.358 76.0389 282.358 76.0389 L 282.358 165.071 L 334.929
165.071 L 334.929 76.0389 z " id="path555" style="fill:#00007b;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-
width:2.5;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;"/>
<rect height="55.1149292" id="rect556" style="font-size:12;fill:#dd8080;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="321.362549" x="89.8797607" y="249.862946"/>
<rect height="6.783386" id="rect557" style="font-size:12;fill:#dd8080;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="287.445648" x="105.142365" y="335.503052"/>
<rect height="5.935455" id="rect558" style="font-size:12;fill:#dd8080;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="287.445648" x="104.294426" y="371.115822"/>
<rect height="5.935455" id="rect559" style="font-size:12;fill:#df8080;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="286.597717" x="105.142365" y="406.728516"/>
<rect height="5.08750916" id="rect567" style="font-size:12;fill:#000000;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="78.8567657" x="159.409393" y="75.1909637"/>
<rect height="5.08754730" id="rect568" style="font-size:12;fill:#000000;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="58.5066528" x="161.105225" y="87.9097748"/>
<rect height="5.08750916" id="rect569" style="font-size:12;fill:#180003;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="76.3130035" x="161.105225" y="100.628624"/>
<rect height="5.93548584" id="rect570" style="font-size:12;fill:#ffffff;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="114.469490" x="105.990288" y="261.733826"/>
<rect height="5.08752441" id="rect571" style="font-size:12;fill:#ffffff;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="44.0919495" x="106.838211" y="277.844360"/>
<rect height="5.087512" id="rect572" style="font-size:12;fill:#ffffff;fill-rule:evenodd;stroke-width:1pt;fill-opacity:1;"
width="33.916901" x="178.063675" y="277.844386"/>
<path d="M 150.317 158.228 C 151.899 153.481 148.734 63.2911 155.063 63.2911 C 161.392 63.2911 292.722
61.7089 292.722 61.7089 C 232.595 68.038 164.557 66.4557 150.317 158.228 z " id="path566"
sodipodi:nodetypes="cccc" style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-opacity:1;stroke-width:1pt;stroke-
linejoin:miter;stroke-linecap:butt;fill-opacity:0.5;"/>
</svg>
297
A Beginner's Guide to Gambas
GeneralConceptsofErrorManagement
Errorscanhavemanycauses.Dependingonthecause,theerrormightbe
recoverable.Arecoverableerrorisoneforwhichyourapplicationcanidentifythe
errorcauseandtakesomeactiontoresolveormitigatetheproblem.Someerrors
mightberecoverablecanbehandledwithouttheneedtoindicatetotheuserthat
an error was even encountered. For example, an error generated when a
requestedfiledoesnotexistisrecoverable.Theapplicationcanbeprogrammedto
displayanerrormessageinsuchanevent. Errorssuchasvalidationerrors,for
whichtheapplicationcannotcontinueprocessingbutcanprovideerrorspecific
feedbackcanalsobeconsideredrecoverableifhandledproperly.Forexample,an
error that occurs when a user enterstextwhere a number is required can be
considered recoverable because the application can recognize the error and
redisplaythedatafieldalongwithamessagethatprovidesinformationaboutthe
causeoftheerror,allowingtheusertoreenterdatausingcorrectinput.
ErrorHandling
Therearethreekeyfactorstoconsiderwhenprogrammingtoavoiderrors:
prevention,detection,andrecovery.Takingadequatestepstopreventerrorswill
certainlyhelptoensureyouhaveahappyusercommunity. However,howdo
youpreventerrorsiftheycannotbedetectedbytheprogrambeforetheuserwill
suffertheconsequences?Haveyouandyourteamtakenthetimetoinvestigate
andaccountforeverypossiblekeystroke,input,anddatatypethatausercould
enter?Reallythinkaboutthiswhileyouarestillinthedesignphaseandagain
298
A Beginner's Guide to Gambas
duringtheinitialdevelopmentofthetestplansbecauseitcancomebacktohaunt
youformany,manybuildandretestiterations.Finally,iftheerrordoesoccur,
whatcanbedonetogettheprogrambacktothestateofusabilityitwasinbefore
theerroroccurred?
BoundaryRelatedErrors
Whenaprogramexecutes,theprogramcursormovesfromonepartofthe
programtothenextexecutingthecodedinstructionssequentially.Thetransition
fromoneareatothenextintheprogramisdefinedbytheexitofoneboundary
condition and theentrytothenext. Thistransitional state,or boundary, can
includenumeric,text,andoperatorboundaries. Iftheuserisaskedtoentera
numberfrom0to99inaprogram,whathappensiftheuserenterstheletterB
ortypesin123instead?Whatiftheuserentersthenumber84andthesystem
tellsyouthenumberistoolarge,promptingtheusertotryenteringanumber
from099onceagain?Doestheprogramfailtovalidateinputandattemptto
processbadinput?Haveallpossibleboundaryconditionsbeenaccountedforin
designandtest?Really?
CalculationErrors
299
A Beginner's Guide to Gambas
InitialandLaterStates
Whenaprogramexecutessubroutinesandusesvariables,thesevariables
oftenmustbeinitializedwithdefaultvalues.InGambas,suchdefaultsgenerally
take the form of a zero value or a NULL value. If initialization is not done
specifically by a developer, it is anyones guess as to what the value of that
variablewillbewhenfirstcalledunlessthevariableisoneofthedatatypesthat
Gambasinitializesautomatically.Remember,thesetypesoferrorsarearesult
ofprogrammersnotdoingthejobcorrectly.Asanexample,letusassumethat
inthepreviousexampleabovenovariable initialization iswhathashappened
when a routine calls for a variable to increment. The program processed 50
records,incrementingthevalueofthevariableeachtimetheroutineisexecuted.
When the value is output at the end of processing, it should be equal to 50.
However,theuninitializedvariablehadavalueof122(orsomeotherrandom
number) and the output shown to the user was 172. This describes what
constitutesaninitialstateerror.
Todemonstratelaterstateerrors,considerthesamesituationasabove,but
instead of passing the expected value of 50 to another module to use for
processing,thevalueof172ispassedalong. Theseerrorsareabitharderto
detectbecausetheoutputfromthecalledmoduleiswheretheuserthinksthe
error occurred. Programmers assigned to debug this problem have to trace
throughtheexecutionpathandfollowthechangingstateofthevariableuntilitis
discoveredtobeaprobleminthecallingmodule,notthecalledone.Theresult
ofthisisagreatdealoftimeandeffortwentintodiscoveringaproblemthatwas
avoidable. If the user reported this from a production system, project team
credibilityagaintakesahit.Asaprogrammanager,youmustensurethesetypes
of situations are prevented by facilitating adequate, indepth discussion in the
designphase.
ControlFlowErrors
Previously,westatedthatwhenaprogramexecutes,theprogramcursor
movesfromonepartoftheprogramtothenext,executingthecodedinstructions
sequentially. Someexecutioninstructionsforcetheprogramtojumpfromone
routine to another. This movementin execution isreferred to as programor
control flow. When a program does something wrong in control flow, it is
generallyaproblemwiththeprogramlogicoraprogrammererrorincodingthe
design. Such logic errors are often uncovered during code reviews in the
implementationphase.Sometimes,intestingtheyarediscoveredbybuildingtest
300
A Beginner's Guide to Gambas
cases to validate program flow based on the design specifications built in the
designphaseandthetestplansbuiltintheimplementationphase.Anyofthese
typesoferrorsdiscoveredbyauserwhenasystemisinproductionreflectsa
failureofthetestteamtoadequatelytesttheproduct. Asaprojectleader,you
areultimatelyresponsibleforpreventingthissituationfromoccurring. TRYto
workwiththedesignteamandtestcasedevelopersasearlyintheprocessas
possible to set proper expectations for the type of testing and the level of
thoroughnessyouexpect.
ErrorsinHandlingorInterpretingData
There are many ways data can become chock full of errors in a
developmentprocess.However,almostallofthesemyriadwaysdatacangoawry
are attributed to human error. These types of errors can be a result of
miscalculation, errors in logic, parameter passing errors, use of incorrect data
types,etc. Almostanythingthataprogrammercandotomakeamistakecan
causeanerrorindata.Thebestmeansofpreventingsucherrorsisacontinual
checkoflogic,reviewofexpectedandactualvalues,reviewofinputandoutput
data,etc.Thisisanongoingprocessanditinvolvesbothuseranddeveloper.
Fromtheuserperspective,thedatashouldbebenchmarkedagainstcurrent
meansofproducingthedata. Theusershouldcontinuallyreviewtheresultsof
outputtoensuresomethinghasnotrunafoulandcauseddatatobecomebad.
Fromthedeveloperperspective,basiccodingdisciplineshouldbeenforced;range
andboundaryconditionsneedtobechecked,parametricvaluesneedvalidation,
datatypevalidationmustoccur,anduseoftestdatamustbevalidatedtobeof
the right format, current and in sync with production data, and usable for
productionoutput. Itisalwaysgoodforteamleadstoreinforcetheseconcepts
withdevelopersandensureperiodiccodereviewstakeplace. Itisessentialto
teamsuccess.
RaceandLoadConditions
Araceconditionisbestdefinedasoneeventprecedinganother.Thetrick
ismakingsurethefirstconditionshouldbefirstorthelastconditionissupposed
to be last. Few programmers think about or even check for race conditions.
Theseconditionsaresometimesidentifiedonlyaftergreatmanpowerhasbeen
expended in doing traces into executable code, step by step, to see what is
happening.Whenyouhearthewordsirreproducibleastestersaretalkingabout
thistypeofbug,interpretittomeanapossibleraceconditionandasksomeoneif
301
A Beginner's Guide to Gambas
theyhavecheckedforit.
Loadconditions arecommonandaretheresultofputtingmoreworkon
thecomputerthanitcanbeartohandle.Asimplepointofillustrationishavinga
computerprocessmillionsofrecords. Itistheperfectjobforacomputerbut,
whenthetimetoprocesseachrecordismorethanafewmilliseconds,themillion
recordstobeprocessedcantakeagreatdealoftime.Forexample,letsassume
an ideal situation where your application does some complex validation,
necessary to properly process a record, and that it takes 10 milliseconds to
process each of these records in a perfectly managed test environment. This
translatestoaprocessingrateof100recordsasecond.Notbad,butwhenyou
divide100into1,000,000 records,youquicklyfindoutthatthisjobwilltake
10,000 secondsor2.7 hourstoruntocompletion. Again,acceptable inmost
cases,exceptthatyoumustrememberthemachineiscompletelytiedupwith
processing. Noreportscanbeproduced,noqueriescanberun,etc. Intodays
moderncomputingenvironment,thisisnotacceptable.
Letstakeanotherviewwhererealworldconditionsareapplied.Inatest
environment,wherethe10millisecondsareidealcomputingconditions,wewill
compoundtheproblemwithuserinteractionandsystemoverhead.Letslookat
recordretrievaltimesandfactorthatintotheequation.Your10millisecondsare
now 14.5 milliseconds per record. User queries and other user interactions
interactioncouldeasilyaddanother10orsomillisecondsperactivityandnow
weareat25millisecondsofprocessingtimeforjustasinglerecord.Wearenow
lookingat6.75hourstorunthesamejobthatranin2.7hoursinthetestlab.
The point here is that testing should account for such load conditions before
releaseintoproduction.Ifauserknowsbeforekickingoffaproductionjobthatit
willtake7hourstorun,theycangooffanddootherthingsorrunthejobat
night. However, if the EXPECTATION is a 2.5 hour job, they will always be
dissatisfiedwithperformancebecauseitisnotwhattheyexpected.
PlatformandHardwareIssues
Hardwareissuesareamongthemostfrustratingausercanencounter.An
examplewouldbehavingauserselecttoprintareportandwatchitscrollbyon
thescreen,atamillionwordsasecond. Theprinterdevicewasnotspecified
correctly or not specified at all. The user assumed a printer would print the
reportbutdeviceerrorsorlackofdevicehandlingcausedthesituationabove.
Therearemanytypesofdeviceswhichaprogrammermustaccountforandthe
testingprocessneedstoaccountforuserinteractiononallofthem.Asidefrom
302
A Beginner's Guide to Gambas
theconditioncitedabove,programscansendthewrongcodestotherightdevice,
overrunthedevicewithdata,etc. Programmersandtestersareresponsiblefor
ensuring these conditions are accounted for and tested before your user
communityareexposedtothem.Allthesetypesoferrorscandoisgiveyouabad
markincredibilityasyourusersrateyourperformance.
Source,Version,andIDControlErrors
Thesetypesoferrorsaregenerallyduetopoorconfigurationmanagement
and an internal lack of enforcement of existing configuration management
policiesandprocedures.Anexampleofthisishavinganewprogrammerinserta
betaversionofcodeintoaproductionstablereleaseforanormalbugfixandthen
nottellinganyoneachangehasbeenmadeinthatmodule.Normaltestingofthe
maintenancereleasewilllikelynotcatchtheproblemanditmaygounnoticed
forseveralsubsequentreleases.
Asanotherexample,thissituationcould besomethingasinsidiousas a
dataerrorthatonlyshowsuponlywhenquarterlyfinancialsareproduced.When
thereisnoreasontobefoundastowhythecompanybalancesheetisoffby
several hundred thousand dollars, much effort is expended in having senior
developers perform code traces to find a problem. Someone will eventually
discoverthatthereissomebetacodeinaproductionmodulethathaserrantly
roundedeverythingtothenearestdollarorsomeothersimilarstupidmistake.
Good intentions aside, the best cure for these types of problems is good
programmerdisciplineforconfigurationmanagementandtohavestrongpolicy
enforcementingrainedintoanorganizationscorporateculture.
TestingErrors
Eventestersmakemistakes. Theycaninterpretthelogicofatestcase
improperly,theycanmisinterprettestresults,failtoreportglitches,etc.Testers
mayforgettoexecutetestcasesorreportbugsthatreallydontexist.Thesefolks
arehumantoo.Thatmeanstheirresultsarealsosubjecttoquestioning.When
yourteamshaveworkedhardtodevelopsomethingand thetestresultscome
backskewedbadlyonewayoranother,questionthetestprocess.
TestPlanReviews
Forallbutthemostsimpletypesofprojects,aformalreviewprocessis
generally required. This also requires participation from the users, the
303
A Beginner's Guide to Gambas
developers, the systems analysts, data analysts, and testers. It is best for all
concerned if the formal test review include the most experienced users and
developers present in an organization. Some users may not have the proper
experiencewithasystemtoproperlyidentifyproblemsbeforetheyoccurandthis
addedexperiencecanonlybenefitareviewprocess. Ensureparticipationina
formaltestplanreviewisbased lesson theavailability ofuserand developer
personnelandmoreonthecontributionsthebestqualifieddevelopersandusers
canbringtothetable.Nowthatwehaveagoodunderstandingofthehowand
whyoferrors,letstalkabouthowwecanmanagesucherrorsinGambas.
GambasErrormanagement
TRYstatement...IFERROR
TheTRYcommandprovidesaprogrammerwiththemeanstoperforman
errorcheckanywhereheorshesuspectsanerrormayoccur.Itis,ineffect,away
totestthewaterbeforejumpingin.Youcantrytoexecutethestatementand,if
anerroroccurs,itwillberecordedbythe Errorclass. Thisisdonebysetting
propertyvaluesthatyoucancheck.Thesepropertyvaluesinclude:
Error.Class
Error.Code
Error.Text
Error.Where
TheError.Classpropertywillreturntoyouthenameoftheclasswherethe
erroroccurredandthe Error.Codeproperty willtellyouwhatthespecificerror
code was. Thetextassociated withtheError.Code isstored inthe Error.Text
304
A Beginner's Guide to Gambas
TRYaStatement
ifERRORTHEN
Message.Error(error.text)
endif
'endoftry
Let'screateaquickexampletodemonstratehowtousetry. OpentheGambas
IDEandcreateanewgraphicaluserinterfaceproject.Createastartupclassform
andputanExitbuttonontheform,namedExitBtn.Doubleclickonthebutton
andaddthiscode:
PUBLICSUBExitBtn_Click()
DIMaASInteger
DIMbASInteger
a=2
b=0
TRYPRINTa/b
IFERRORTHEN
Message.Error("CLASS:"&Str(Error.class)&",CODE:"&error.code&
",="&error.text&"AT:"&error.where,"OK")
ENDIF
END
Saveyourworkandexecutetheprogram.ClicktheExitbuttonandyoushould
seesomethingsimilartothis:
Figure86ErrorresultscaughtwithTRY.
305
A Beginner's Guide to Gambas
CatchandFinallyStatements
'Gambasclassfile
PUBLICSUB_new()
TextLabel1.Text="<center><strong>Noerrorspresent."
END
STATICPUBLICFUNCTIONRun()ASBoolean
DIMhFormASForm
hForm=NEWForm1
RETURNhForm.ShowModal()
END
PUBLICSUBQuitBtn_Click()
ME.Close(TRUE)
END
PUBLICSUBErrBtn_Click()
DIMaASInteger
DIMbASInteger
a=2
b=0
PRINTa/b'willgenerateadividebyzeroerror
306
A Beginner's Guide to Gambas
FINALLY
TextLabel1.Text="CLASS:"&Str(Error.class)&",CODE:"&
error.code&",="&error.text&"AT:"&error.where
TextLabel1.Refresh
CATCH
IFERRORTHEN
Message.Error("CLASS:"&Str(Error.class)&",CODE:"&
error.code&",="&error.text&"AT:"&error.where,"OK")
ENDIF
Message.Info("ClearedtheError","OK")
TextLabel1.Text="<center><strong>Errorhasbeencleared."
END
Whenyouruntheprogram,youshouldseethisastheopeningscreen:
Figure87CATCHtestprogramopeningscreen.
Now,clicktheerrorbuttontogenerateourerrorandyoushouldseethis:
Figure88DivbyZeroerrorcaughtbyCATCH.
YoushouldalsonoticethatthemainscreenTextLabelhaschangedtothis:
307
A Beginner's Guide to Gambas
Figure89TheTextLabelupdatedwitherrorinfo.
OnceyouclicktheOkbuttonfortheErrorMessagedialog,youwillseethis:
Figure90Infomessagethattheerroris
cleared.
Now,clicktheOKbuttonontheInfomessageandtheTextAreaisupdatedlike
this:
Figure91Mainscreenaftererrorhasbeencleared.
ThisshouldgiveyouaprettygoodideaofhowtousetheGambaserror
managementfeaturestohelpmanageerrorswhentheyoccurinyourcode(and
theyinevitablywilloccur). Nothandlingerrorslikethedivbyzeroweusedin
ourexamplewillbeashowstopperinmostcircumstances.Asaquickexample,
308
A Beginner's Guide to Gambas
gobacktoourcode,intheErrBtn_Clicksubroutineandcommentouttheselines:
'FINALLY
'TextLabel1.Text="CLASS:"&Str(Error.class)&",CODE:"&
error.code&",="&error.text&"AT:"&error.where
'TextLabel1.Refresh
'CATCH
'IFERRORTHEN
'Message.Error("CLASS:"&Str(Error.class)&",CODE:"&
error.code&",="&error.text&"AT:"&error.where,"OK")
'ENDIF
'Message.Info("ClearedtheError","OK")
Now,runtheprogramagainandclicktheErrorbutton.Hereiswhatyouget:
Figure92DefaultGambaserrordialog.
Youcantrytocontinue,butthereisnoguaranteethatyourprogramwill
workcorrectlyorthatitwillevencontinue.Thisisdefinitelynotwhatyouwould
wantyouruserstosee. Itjustmakesgoodsensetousethetoolsavailablein
Gambastopreventthiswhenyoucan.Now,letsmoveontoseehowwecanuse
eventstohelpwritebettercode.
GambasEventmanagement
309
A Beginner's Guide to Gambas
EVENTIdentifier([Parameter#1[,Parameter#2...])[ASBoolean]
AuniquefeatureofGambasisthatanobjectcanraiseanevent.Inorder
toraiseanevent,theobjectmustbegivenaname(orhandle)atthetimeitis
createdwiththeNEWkeyword.Withoutbeingassignedaname,eventsraisedby
anobjectareignored.Eventsarecaughtbytheparentofanobject.Theparentis
actuallyanobject'suniqueeventobserver.Theparentactsasthedefaultobserver
fortheobjectwhenaneventisraised.Thisparentcanbeaclass,inwhichcase
theeventhandlermustbeastaticmethod.Inthiscase,thehandleandtheparent
bothcanbechangedatruntimeusingtheObject.Attach()andObject.Detach()
methodsoftheObjectclass.Thehandleoftheobjectisnotstoredwithanobject
andthereforecannotberetrieved.
InGambas,thestandardcallingconventionforaneventhandlerwouldbe
InstanceName_EventNametoinvokethemethodtobecalledbytheeventlistener
310
A Beginner's Guide to Gambas
whensuchaneventisraised.Let'saddtoourpreviousexampletodemonstrate
theuseofevents. Addanotherbuttontotheformforourpreviousexample,
namedEventBtn.Doubleclickandaddthiscodetotheprogram:
EVENTMyEvent(MsgASString)ASBoolean
PUBLICSUBEvent1Btn_Click()
DIMbResultASBoolean
RAISEMyEvent("Raiseanevent")ASbResult
IFbResultTHEN
TextLabel1.Text="Cancelledtheevent"
ELSE
TextLabel1.Text="Raisedtheevent"
bResult=NOTbResult
STOPEVENT
ENDIF
END
Saveyourworkandruntheprogram. ClicktheEventbuttonandyourdisplay
shouldlooklikethis:
Figure93Oureventwasraised.
311
A Beginner's Guide to Gambas
MouseOperations
Mostofthesepropertiesareselfexplainedbytheirname,butafewneed
furtherexplanation. The Alt, Control, Meta and Shift propertiesall return a
TRUEvalueifthoserespectivekeysarepressed.Normalcanbechecked(tested)
toseeifanyotherspecialkeywaspressed. Button canbeusedtoseeifany
buttonispressedbutyoucanuse Left,Right,and Middle todetermineifany
specificmousebuttonhasbeenpressed.AllofthesepropertiesreturnTRUEifa
button is pressed. Delta returns the (offset) value of the mouse wheel while
Orientation can be used to check the direction (forward, backwards) of the
wheel'sturn.ScreenXandScreenYreturntheabsolutevalueofthecursorbased
onthedesktopwhileXandYreturnthepositionrelativetothewindow.
ThereisonlyonemethodfortheMouseclass,Move.TheMovemethod
simply repositionsthemousecursor totheX,Y coordinatesspecified. Mouse
eventsyoucanmonitorinyourprogramareMousemove,MouseDown,Mouseup,
312
A Beginner's Guide to Gambas
andMousewheel. Anychangeinthecurrentstateofthoseeventsallowyouto
create a coded response for that event. When coding mouse (or keyboard)
operations,itisveryimportanttoalwaysusethepredefinedconstants. Usingany
other method of getting or setting properties is not guaranteed to be upward
compatible from one Gambas version to the next. The Mouse class uses the
followingconstantstospecifytheshapeofthemousecursor:
Let'screateashortGambasprogramtodemonstratehowtousethemouse
now.FromtheGambasIDE,createanewprojectnamedMouseOpsandmakeit
agraphicaluserinterfaceproject,translatablewithpubliccontrols.Createanew
form,Form1andmakeitastartupclassform.Next,addadrawingareanamed
da tothetopleftcorneroftheForm1window. Resizeittobeaboutoneinch
square. Now,let'saddsomecode. Firstofall,whentheprogramrunsandthe
windowopens,wewanttosetacaptionthattellstheuserhowtoclearorexitthe
window.Wealsoneedtoresizethedrawingareatofittheformfullyandsetthe
cachedbufferpropertytoTRUEsoourdrawingcanbeseenbytheuser.Hereis
howtodothis:
'Gambasclassfile
'whenformopensatruntime,setacaptionandresizethedrawingarea
PUBLICSUBForm_Open()
ME.Caption="Pressspacetoclear,mousewheelexits..."
da.W=ME.W5
da.H=ME.H5
da.ForeColor=color.Black'settheforegroundcolortoblack
'setcachedpropertytotruesowecanstorethedrawingbuffer
da.Cached=TRUE
draw.Begin(da)'starttodraw
'wewilldrawahorizandvertlinetosectionfourquadrants
draw.Line(1,da.h/2,da.W1,da.h/2)
draw.Line(da.W/2,1,da.W/2,da.H1)
draw.End
END
Ifthemousemoves,wewanttochangethecursorshape,dependingon
whichquadrantofthedrawingareathemouseisin.WewillusetheMousemove
eventandcodethis:
313
A Beginner's Guide to Gambas
'ifthemousemoves,wewillupdatethecursorshapedependingonthe
'quadrantthemouseislocatedat
PUBLICSUBda_MouseMove()
'checkthetopleftquadrant
IFmouse.X<=da.W/2ANDmouse.Y<=da.H/2THEN
da.Mouse=mouse.Pointing
'elsewecheckthebottomleftquadrant
ELSEIF
mouse.X<=da.W/2ANDmouse.Y>=da.H/2THEN
da.Mouse=mouse.Cross
'elsewecheckthetoprightquadrant
ELSEIF
mouse.X>=da.W/2ANDmouse.Y<=da.H/2THEN
da.Mouse=mouse.SizeNWSE
'otherwise,itmustbeinthebottomrightquadrant
ELSEIF
mouse.X>=da.W/2ANDmouse.Y>=da.H/2THEN
da.Mouse=mouse.SizeNESW
'ifitisanywhereelse,makeitthedefault
ELSE
da.Mouse=mouse.Default
ENDIF
Nowthatwehavesetthecursorshape,wewillchecktoseeiftheuseris
pressing a mouse button to draw. If the left buttonis pressed, we will draw
points.Ifitistherightbutton,wewilldrawtinyboxes.
'checkmousebuttonispressedtoseewhichoneispressedand
'drawpointsforleftbtn,boxesfortheright
IFMouse.LeftTHEN
'starttodraw
Draw.Begin(da)
'littletinydots
Draw.Point(Mouse.X,Mouse.Y)
Draw.End
ELSE'ifitisrightbutton
Draw.Begin(da)
Draw.Rect(Mouse.X,Mouse.Y,3,3)
Draw.End
ENDIF
END
Whenevertheusermovesthemousewheel,wewillterminatetheapplication.
'iftheusermovesthemousewheel,wewillterminatetheapplication
PUBLICSUBda_MouseWheel()
ME.Close
END
314
A Beginner's Guide to Gambas
Finally,iftheuserpressesanykey,wewillresetthedrawingareabyclearingit
andredrawthequadrantbycallingthesameroutineusedtoopentheform:
'checkkbdeventstoclearthedrawingareaandredrawthequadrants
PUBLICSUBForm_KeyPress()
da.Clear
Form_Open()
END
That'sit.Whenyouruntheprogram,youshouldseesomethinglike
this:
Figure94MouseOpsprogramrunning.
Asyoumovethemousefromquadranttoquadrant,noticehowthecursor
changes. Tryboththeleftandrightmousebuttonsandpressthespacebarto
clearthedrawingandrestart.Whenyouaresatisfiedeverythingworks,movethe
mousewheelandtheprogramwillterminate. Now,let'slearnaboutkeyboard
operations.
315
A Beginner's Guide to Gambas
KeyboardOperations
DIMMyIntegerASInteger
MyInteger=Key[KeyASString]
PropertiesthataresupportedfortheKeyclassincludeAlt,Code,Control,
Meta,Normal,Shift,StateandText.Statecanbeusedtotestwhetherornota
specialkeyispressedandTextwillreturnthesinglecharacterrepresentationfor
agivenkey. AlltheotherpropertiesworklikethoseusedwiththeMouseclass
we described in the previous section. The Key class supports the following
predefinedconstants:
Forcursorkeys: Up,Down,Left,andRight
Forfunctionkeys: F1F2F3F4F5F6F7F8F9F10F11F12
ForshiftedFkeys: F13F14F15F16F17F18F19F20F21F22F23F24
Let'screateanothershortGambasprogramtodemonstratehowtousethe
keyboard.FromtheGambasIDE,createanewprojectnamedKbdOpsandmake
itagraphicaluserinterfaceproject,translatablewithpubliccontrols. Createa
newform,Form1andmakeitastartupclassform.Wewillonlyneedtousetwo
labelsinthisprogram,aTextLabelandaLabel.First,createaTextLabelnamed
TextLabel1andmakeitabout1/2highandstretchitacrossthewidthofthe
form. SettheTextLabel1.Alignmentpropertyto center. Now,createaLabel
named Label1 and place it below the TextLabel1 control. Make it about two
316
A Beginner's Guide to Gambas
incheswideand1/2tall. SettheLabel.TextpropertytoPressanykey...and
setthecontrolfontsizeto14pointandmakeitbold.Doubleclickontheform
andthecodewindowappears.Hereisthecodewewilladdtoourprogram:
'Gambasclassfile
'wewillcheckthekeyreleaseeventtoseewhattodo
PUBLICSUBForm_KeyRelease()
'wheneverakeyisreleased,checkthecode
SELECTkey.code
CASEkey.Tab'ifitisatabkey
textlabel1.Text="Keycodeis:"&key.Code&",TAB."
CASEkey.BackSpace'orbackspace
textlabel1.Text="Keycodeis:"&key.Code&",Backspace."
CASEkey.CapsLock'orcapslock
textlabel1.Text="Keycodeis:"&key.Code&",CapsLock."
CASEkey.F1'oraFkey
textlabel1.Text="Keycodeis:"&key.Code&",F1key."
CASEkey.F2
textlabel1.Text="Keycodeis:"&key.Code&",F2key."
CASEkey.F3
textlabel1.Text="Keycodeis:"&key.Code&",F3key."
CASEkey.F4
textlabel1.Text="Keycodeis:"&key.Code&",F4key."
CASEkey.F5
textlabel1.Text="Keycodeis:"&key.Code&",F5key."
CASEkey.F6
textlabel1.Text="Keycodeis:"&key.Code&",F6key."
CASEkey.F7
textlabel1.Text="Keycodeis:"&key.Code&",F7key."
CASEkey.F8
textlabel1.Text="Keycodeis:"&key.Code&",F8key."
'ifnoneoftheabove,isitprintable?Ifso,showcodeandvalue
CASEELSE
IFkey.Code>32ANDkey.Code<128THEN
textlabel1.Text="keycodeis:"&key.Code&","&Chr(key.Code)
ELSE'otherwisejustthecode
textlabel1.Text="keycodeis:"&key.Code
ENDIF
ENDSELECT
END
'checkkeydowneventtofilteroutshift,control,alt,etc.
PUBLICSUBForm_KeyPress()
IFkey.ShiftTHEN
textlabel1.Text="Keycodeis:"&key.Code&",SHIFT"
ELSEIFkey.AltTHEN
317
A Beginner's Guide to Gambas
textlabel1.Text="Keycodeis:"&key.Code&",ALT"
ELSEIFkey.ControlTHEN
textlabel1.Text="Keycodeis:"&key.Code&",CTRL"
ELSEIFkey.Code>32ANDkey.Code<128THEN
textlabel1.Text="keycodeis:"&key.Code&","&Chr(key.Code)
ELSEIFkey.EscTHEN'ifanESCkeyispressed
textlabel1.Text="keycodeis:"&key.Code&",ESC"
ELSE
textlabel1.Text="keycodeis:"&key.Code
ENDIF
END
PUBLICSUBForm_Open()
ME.Caption="KeyboardOperations"
END
As you can see, the code above is pretty straightforward and simple.
Whenyouruntheprogram,youshouldseesomethinglikethis:
Figure95KbdOpsprogramrunning.
BitOperations
Bits are the smallest elements used in computer operations. They are
indivisibleatomsofmemoryclusteredingroupscalledbytes.Abyteiscomposed
of n number of bits, which is dependent upon the machine word size. For
example,inaneightbitsystem,onebyteiscomposedofeightbits.Formodern
computingsystemsusedtoday,theoperatingsystemisbuiltusing32or64bit
word sizes. The word size increases in order to accommodate a larger
addressablememoryspace.Inanoldereightbitsystemforexample,thesystem
canonlyaddressmemorythatcanbeexpressedinbinaryformas11111111.In
318
A Beginner's Guide to Gambas
otherwords,thememoryspaceislimitedtoasizethatcanbeexpressedwith
thoseeightbits.Foraneightbitsystemsmemoryrangesextendfromthesingle
bytedecimalrepresentationof65537to+65538.Inamodern32bitsystem,it
takesthebinaryformof11111111111111111111111111111111 whichcanbe
expressedindecimalnotationas2,147,483,648to+2,147,483,647.Asyoucan
see,theaddressablerangeofmemorywith32bitsystemsishuge!
Inapplicationslevelprogramming,thereisgenerallynotmuchoccasionto
operate at the bitlevel when but occasionally the need does arise. Gambas
providesallofthetoolsyouneedtotestabit,clearit,change(invert)it,orsetit.
Additionally,bitwiseoperationsyoucanperformincluderotatingabitrightor
leftandshiftingabitrightorleft.Thetablebelowsummarizesthebitoperations
youcanperforminGambas:
319
A Beginner's Guide to Gambas
aboveontheform,asshowninthefigurebelow:
Figure96TheBitOpsprogramindesignmode.
Once you have finished laying out the controls as shown in the figure
above,doubleclicksomewhereontheformandthecodewindowwillappear.
AddthefollowingcodefortheForm_Opensubroutine:
'Gambasclassfile
PUBLICSUBForm_Open()
ME.Caption="bitOpns"
END
Now,theprogramwilldisplaythecaptionbitOpnswhenitisexecuted.
Let's code an exit procedure so the user can terminate the application next.
DoubleclickontheQuitbuttonandaddthis:
PUBLICSUBQuitBtn_Click()
ME.Close'closethewindow
END
IftheuserentersanyvalueintheTextBox2fieldtochangeabit,weneed
toupdatetheformandreflectthechangedvalues.Wewillworryaboutwhatto
dowiththenewvaluealittlelateroninthecode.Fornow,itisasimplecallto
theRefreshmethodweneed:
PUBLICSUBTextBox2_Change()
form1.Refresh'refreshourdisplayanytimethebitvaluechanges
END
WhentheuserspecifiesanintegervalueintheTextBox1field,wewillonly
reacttotheentrywhentheTABkeyispressed. ThatcausesaLostFocusevent,
whichiswhatwewillcodefor.Hereiswhatweneedtodonext:
320
A Beginner's Guide to Gambas
PUBLICSUBTextBox1_LostFocus()
'weneedalocalintvartoworkwith
DIMmyIntASInteger
'convertourstringtextvaluetoanint
myInt=CInt(textbox1.text)
'checktoseeifitisin8bitrange
IFInt(myInt>=0)AND(myInt<256)THEN
Label2.Text="Hex:"&Hex(myInt)'converthexvalue
label3.Text="Bin:"&Bin(myInt)'convertbinvalue
label7.Text=Str$(myInt)'updateourtextfields
form1.Refresh'refreshtheform
ENDIF
END
Whentheuserpressestheclearbutton,wewanttoclearthebitspecifiedforthe
integerrepresentedbythefirstparameter.
PUBLICSUBClearBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
'convertourstringtextvaluetoanint
myInt=CInt(textbox1.text)
'iftheintegerisbetween0and255process,otherwiseignore
IFInt(myInt>=0)AND(myInt<256)THEN
'convertstringvaluetoanint
result=CInt(TextBox2.Text)
'clearthebit
i=BClr(myInt,result)
'updatethelabeldisplays
label5.Text="Bclr:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
WhentheuserpressestheSetbutton,wewanttosetthebitspecifiedforthe
integerrepresentedbythefirstparameter.Thisisessentiallytheoppositeofclear
discussedabove.
PUBLICSUBSetBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
'convertourstringtextvaluetoanint
myInt=CInt(textbox1.text)
'iftheintegerisbetween0and255process,otherwiseignore
IFInt(myInt>=0)AND(myInt<256)THEN
'convertstringvaluetoanint
321
A Beginner's Guide to Gambas
result=CInt(TextBox2.Text)
'setthebit
i=BSet(myInt,result)
'updatethelabels
label5.Text="Bset:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
TheBchgfunctionisreallyjustaninvertoperation. Whenouruserclicksthe
Changebutton,wewillexecutethiscode:
PUBLICSUBChangeBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=BChg(myInt,result)
label5.Text="Bchg:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
The Shl function is will shift the value of MyInt n bits left where n is
specifiedbythesecondparameter.WhenouruserclickstheShlbutton,wewill
executethiscode:
PUBLICSUBSHLBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=Shl(myInt,result)
label5.Text="SHL:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
322
A Beginner's Guide to Gambas
PUBLICSUBSHRBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=Shr(myInt,result)
label5.Text="SHR:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
Inolder8bitsystems,itwasimpossibletoprocessnumberslargerthan
255unlesstheyweresplitupinto8bitchunks.Operationswerethenperformed
oneachpieceofanumber.Aftertheoperationswerecompleted,itwasnecessary
toreassembleeachnumberbacktogethertorecreatethewholenumber. Allof
thiswasaccomplishedbyusingonetinybit,thecarrybit.TheGambasfunctions
ROL(rotateleft)andROR(rotateright)areusedtoshiftbitsinbinarynumbers.
Thesefunctionsworkconceptuallylikethis:
7 6 5 4 3 2 1 0
C
ROLandRORworksuchthatthecarrybitisshiftedintotheendbitthatis
leftemptybytherotationprocessinsteadofinsertingazerovalue.ROLshiftsthe
contentsofabyteoneplacetotheleft. ROLdoesnotplaceazerointobit0.
Instead,itmovesthecarrybitfrombitposition7intobitposition0ofthenumber
beingshifted. The0bitpositionwasvacatedbytheshiftrotationandtheROL
instructionplacesbit7intothecarrybitposition.RORworksjustlikeROL,but
intheoppositedirection.Itmoveseachbitofabyterightoneposition,placing
thecarrybitintobit7andbit0intothecarrybit.
323
A Beginner's Guide to Gambas
'rotateleft
PUBLICSUBROLBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=Rol(myInt,result)
label5.Text="ROL:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
'rotateright
PUBLICSUBRORBtn_Click()
DIMiASInteger
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=Ror(myInt,result)
label5.Text="ROR:"&Bin(i)
label7.Text=Str$(i)
ENDIF
END
Ifyouwantyourprogramtocheckifabithasbeenset,youcancallBtst.This
functionwillreturnTRUEifthebitspecifiedinoperand2ofoperand1isTRUE.
PUBLICSUBTestBtn_Click()
DIMiASBoolean
DIMresultASInteger
DIMmyIntASInteger
myInt=CInt(textbox1.text)
IFInt(myInt>=0)AND(myInt<256)THEN
result=CInt(TextBox2.Text)
i=BTst(myInt,result)
label5.Text="Btst:"&i
ENDIF
END
That is all we have to do for our bitfiddling program. Save your work and
324
A Beginner's Guide to Gambas
executetheprogram.Yourresultsshouldbesimilartothis:
Figure97OurbitOpsprogramrunning.
Whenyouaresatisfiedthattheprogramworksasweplanned,saveyour
work.Itwouldbeagoodexerciseatthistimetogobackandmodifythecodeto
ensureonlyintegervaluesareinputintothetwoTextboxfields.Also,youcould
allownegativenumberstobeenteredtoseewhatresultswouldbeproduced.I
willleavethatexercisetothoseamongyoueagerandambitiousenoughtotryit
isreallynotverydifficultandwehavealreadyshownyouhowtodovalidation
routines(remember,backinthecollectionschapter?). Inthenextchapter,we
willcoverbasicdatabaseoperationswithGambas.Theabilitytoworkwithdata
in your programs is essential and we cannot overlook this vital aspect of
programminginourjourneythroughGambas.
325
A Beginner's Guide to Gambas
The MySQL database package consists of the MySQL server and many
clientprograms.TheMySQLserverisaprogramthatstoresandmanagesallof
your databases within the MySQL environment. The client programsthat are
includedwithMySQLaretoonumeroustolistherebutitisimportantforyouto
understandthateachclientapplicationservesaspecificpurposerelatedtothe
managementand/or administration of data or metadata stored on theMySQL
server.Theclientprogramwewillbedealingwithinthischapteriscalledmysql
(noteitisspelledinlowercaseletters). Thisclientprogramprovidesa command
line interface (CLI) you can use to issue SQL statements interactively to the
MySQLserverandseetheresultsdisplayedimmediately. Themaindifference
between MySQL and mysql isthat MySQL isusedtorefertotheentire MySQL
distributionpackageortorefertothe MySQL serverwhile mysql referstothe
clientCLIprogram.
Whatpurposedoesitservetohavebothaclientandaserverinsteadofa
singleprogram?Theserverandclientprogramsaredividedintodifferententities
soyoucanusetheclientprogram(s)onyoursystemtoaccessdataonaMySQL
serverthatcouldberunningonanothercomputer. Byseparatingthepackage
into a server and n clients, it serves to separate data from the data retrieval
interface. Beforeyoubeginworkingonthischapter,itishighlyrecommended
thatyoufamiliarizeyourselfwithMySQLbydownloadingthelatestmanualfrom
theofficialMySQLwebsite18.Ataminimum,completethetutorialinChapter3
oftheMySQLUserManualbeforeproceedingwiththischapter. Onceyouare
326
A Beginner's Guide to Gambas
familiarwithhowbasicSQLoperationsworkwithintheMySQLenvironment,you
arereadytocontinuewiththischapter,whichfocusesmoreonhowtoaccomplish
thesametypesofthingsthe MySQL tutorialdemonstrated, but fromwithina
Gambasprogram.
InordertoaccessdatabaseswithintheGambasenvironment,youneedto
ensureyourprojectusesthegb.dbcomponent.Whenyoucreateanewproject,
you need to go to the project properties dialog and you will find a tab for
components.Fromwithinthistabbeddialog,youcanselectthecomponentsyou
needforyourprogram. Inthecaseofdatabases,youwillneedtocheck gb.db
beforeyoucanuseanyoftheclassesdefinedbythiscomponent. Aswestated
previously, the gb.db component allows you to access the following database
managementsystems:PostgreSQL,MySQLandSQLite.BecausePostgreSQLand
MySqlareclient/serverdatabases,itmeansyourprogramwillneedtomakea
connectiontoadatabaseserver.SQLiteisaflatfilebaseddatabasesothereisno
serverprocessforyourprogramtoconnectwith.However,thisalsomeansthat
yourprogrammayneedtousefullyqualifiedpathnamesforanydatabasefileit
usesifthedefaultpath(i.e.,theapplicationpath)isnotused.
ConnectionClass
TheConnectionclassestablishesyourconnectiontothedatabase.Inorder
tosuccessfullyconnecttoadatabase,youmustfirstcreatea connectionobject
andsetthenecessarypropertiesthatwillbeusedbythedatabase.Nextyoumust
calltheOpenmethod.IfyouareconnectingtoaSQLitedatabaseandtheName
327
A Beginner's Guide to Gambas
propertyisnull,adatabaseisopenedinmemory. IftheNamespecifiedisan
absolutepath,thepathnameisused.IftheNamespecifiedisarelativepathand
theHostpropertyisnull,thedatabaseislocated intheapplicationtemporary
directory /tmp/gambas.$UID/sqlite. Otherwise, Host will contain the database
directorynameandthedatabasefilepathistheresultofconcatenatingtheHost
andNamepropertyvalues.Thisclassiscreatableandthecallingconventionis:
DIMhConnectionASConnection
hConnection=NEWConnection()
ConnectionProperties
Charset
Databases
PROPERTYDatabasesAS.ConnectionDatabases
The resulting collection of data (which is enumerable using the FOR EACH
328
A Beginner's Guide to Gambas
statement)wouldbethesameasifyoutypedSHOWDATABASESfromthemysql
clientCLI.
Host
PROPERTYHostASString
Login
TheLoginpropertyisusedtosetorgettheuserlogindatathatisusedfor
establishingtheconnectiontothedatabase. Onceagain,thisappliestoMySQL
andPostgreSQL,notSQLite. SinceSQLitehasnoconceptofusers,accesstoa
SQLitedatabaseiscontrolledbythefilepermissionsettingsofthedatabasefile
itself.ThismeansthattheLoginpropertyisalwaysgoingtobesettotheuserid
oftheuserthatisexecutingtheGambasprogramthatusestheSQLitedatabase.
Syntaxis:
PROPERTYLoginASString
Name
The Name property setsor gets the name of the database you want to
connectto.Ifyoudonotspecifyaname,adefaultsystemdatabaseisused.For
PostgreSQLthedefaultdatabaseisnamed template1andformySQLitisnamed
mysql.ForSQLite,thedefaultnameis/tmp/sqlite.db.Foranydatabaseaccess,
however,theuserneedstohaveatleastreadandconnectaccessprivilegestouse
these databases. Sqlite will locate the database first by trying to use the full
pathnameifithasbeengiven.Ifnot,itwillchecktoseeiftheHostvariablehas
beenset.Ifthatisthecase,SQLitewilllookatthepathnamethatwassetinthe
variable.IftheenvironmentvariableGAMBAS_SQLITE_DBHOMEhasbeenset,
thenSQLitewillusethatasthecurrentworkingdirectory.Itisalsopossibleto
create and use a database in memory by setting the Name property to
:memory:ratherthanmysqlorpostgresqlorsqlite.Syntaxis:
329
A Beginner's Guide to Gambas
PROPERTYNameASString
Password
ThePasswordpropertywillreturnorsetthepasswordusedforestablishing
aconnectiontothedatabase.Callingconventionis:
PROPERTYPasswordASString
Port
ThePortpropertyisusedtogetorsettheTCP/IPportusedforestablishing
theconnectiontoadatabase.ThedefaultportdependsontheconnectionType.
Syntaxis:
PROPERTYPortASString
Tables
TheTablespropertyisusedtoobtainavirtualcollectionthatcanbeused
formanagingallofthetablesofadatabase.Syntaxis:
PROPERTYTablesAS.ConnectionTables
Type
TheTypepropertyrepresentsthetypeofthedatabaseserveryouwantto
connectto. InGambas,thecurrentlysupporteddatabasetypeare:"postgresql",
"mysql",and"sqlite".Thetypepropertyusesthissyntax:
PROPERTYTypeASString
Users
PROPERTYUsersAS.ConnectionUsers
Version
The Versionproperty isareadonlyvaluethatreturnstheversionofthe
330
A Beginner's Guide to Gambas
databasethatthedriverhasconnectedwith.Syntaxis:
PROPERTYREADVersionASInteger
TheConceptofaTransaction
Therearetimeswhentheorderinwhichdatabaseactions(orqueries)are
executedisimportant.Sometimes,aprogrammustensureallqueriesinagroup
arerunsuccessfullyandinorderorprocessnoneofthematall.Aclassicexample
is taken from the banking environment. If a given amount of money (for
example,100dollars)istakenfromoneaccountandpostedtoanotheraccount,
wewouldexpectthefollowingactionstooccur:
UPDATEaccount1SETbalance=balance100;
UPDATEaccount2SETbalance=balance+100;
Bothqueriesmustexecutesuccessfullyorneithermustexecute. Money
cannot be transferred out of one account and fail to be posted to the other
account.Bothofthesequeriesformasingletransactionthatiscomposedoftwo
separate actions (debit 100 from account1 and credit 100 to account2). A
transaction issimplyoneormoreindividualdatabasequeriesgroupedtogether
between BEGIN and COMMIT statements. WithoutaCOMMITstatement,the
transactionisnotpermanentandcanbereversedwiththeROLLBACKstatement.
MySQLautomaticallycommitsstatementsthatarenotpartofatransaction
process. The results of any SQL UPDATE or INSERT statement that is not
preceded with BEGIN will immediately be visible to all connections to the
database because the commit is automatically performed. Within MySQL,
transactionsareonlyknownwithtransactionsafetables(i.e.,BDBandInnoDB).
The other table types COMMIT immediately. Mostdatabasesthat are able to
accomplishthisaresaidtobe ACIDcompliant. TheACIDmodelisoneofthe
oldestandmostimportantconceptsofdatabasetheory.Thefourgoalsthatmust
be met for any database to be considered reliable are Atomicity, Consistency,
Isolationand Durability(ACID).Letsexamineeachofthesefourcharacteristics
indetail.
Atomicity meansdatabasemodificationsmustfollowanallornothing
rule. Every transaction is considered an atomic unit. If any part of the
transactionfails,theentiretransactionfails.ItiscriticaltheDBMSmaintainthe
atomicnatureoftransactionsinanycircumstance.
331
A Beginner's Guide to Gambas
Durabilityensuresanytransactioncommittedtothedatabasewillnotbe
lost. This is accomplished via database backups and transaction logs that
facilitaterestorationofcommittedtransactionsdespiteanysubsequentfailures.
Now,let'stakealookatGambasConnectionclassmethodsavailabletoyouin
yourprograms.
ConnectionClassMethods
The Connection class provides most of the methods you will need to
establishaconnectiontoadatabaseandexecuteoneormoretransactionstofind,
add,change,ordeletedata.
Open/Close
TheOpenmethodisusedtoopenaconnectiontothedatabase.Priorto
makingthecalltoOpen,youshouldsettheconnectionpropertieswiththedata
necessarytousethedatabase.Generally,ataminimumyouwillneedtospecify
thetypeofdatabase,thehost,aloginIDandpassword,and thenameofthe
databaseyouwishtouse.Thesyntaxforopenis:
FUNCTIONOpen()ASBoolean
ThecodeexamplebelowshowshowtousetheOpenmethodtoconnect
user jrittinghouse toaMySQLdatabasenamedGambasBugsthatisstoredon
Hostlocalhost:
DIM$hConnAsNEWConnection
332
A Beginner's Guide to Gambas
WITH$hConn
.Type="mysql"
.Host="localhost"
.Login="jrittinghouse"
.Password="ab32e44"
.Name="GambasBugs"
ENDWITH
TRY$hConn.Open
IFErrorTHENPRINT"Databasecannotbeopened.Error=";Error.Text
Toclosetheconnection,simplyinvoketheClosemethod.Inourexampleabove,
youcouldusethiscode:
$hConn.Close
andtheconnectionwouldbeclosed.Inordertosubsequentlyuseanydatastored
inthedatabase,youwouldneedtoreopenthedatabaseusingtheOpenmethod.
Begin/Commit/Rollback
Aswestatedpreviously,atransactionisoneormoreindividualdatabase
queries that are grouped together between BEGIN and COMMIT statements.
Without a COMMIT statement, the transaction is not permanent and can be
reversed with a ROLLBACK statement. Remember thatMySQL automatically
commitsstatementsthatarenotpartofatransactionprocess(definedbyBEGIN
andCOMMIT).InGambas,itisrecommendedthatyouusetheFind,Create,and
Edit methods to make changes to the database. This helps to maintain code
independenceanditallowsyoutowriteasinglepieceofcodethatwillworkwith
anydatabasesupportedbyGambas. Gambasusesa resultobject toreturnthe
resultsofaSQLquery.
Find
The Find method returns a readonly Result object used for querying
recordsinthespecifiedtable.ThecallingconventionforFindis:
FUNCTIONFind(TableASString[,RequestASString,ArgumentsAS,...])ASResult
333
A Beginner's Guide to Gambas
case.UsingtheFindmethodallowsyoutowriterequeststhatareindependentof
theunderlyingdatabase,meaningitwillworkwithPostgreSQLorMySQLwithout
anycodechangerequired.
Create
TheCreatemethodisusedtobuildaread/writeResultobjectwhichcan
usedtocreaterecordsinatable.Standardcallingconventionis:
FUNCTIONCreate(TableASString)ASResult
Edit
TheEditmethodreturnsaread/writeResultobjectusedforeditingrecords
inthespecifiedtable.RequestisaSQLWHEREclauseusedforfilteringthetable,
andtheArgumentsarequotedasneededbytheSQLsyntaxandsubstitutedinthe
Requeststringasweexplainedpreviously.Standardcallingconventionis:
FUNCTIONEdit(TableASString[,RequestASString,ArgumentsAS,...])ASResult
HereisacodesampletoshowhowEdit()works:
DIMMyResultASResult
DIMsQueryASString
DIMiParmASInteger
sQuery="Select*fromtblDEFAULTwhereid="
'wewillinsertaparametervalue(12)attheendofthequerystring
iParm=12
$hConn.Begin
MyResult=$hConn.Edit("tblDEFAULT",sQuery,iParm)
MyResult!Name="MrRittinghouse"'Setafieldvalue
$hConn.Update'Updatewiththenewvalue
$hConn.Commit'makethechangespermanent
$hConn.Close'closethedatabaseconnection
Exec
TheExecmethodexecutesaSQLrequestandreturnsareadonlyResult
objectcontainingtheresultoftherequest.Standardcallingconventionis:
FUNCTIONExec(RequestASString,ArgumentsAS,...)ASResult
334
A Beginner's Guide to Gambas
Quote
FUNCTIONQuote(NameASString)ASString
Thequotingmechanismisdependentupontheparticulardatabaseserver
driver which makes this method necessary if you need to write database
independentcode.HereisanexampleofhowtouseQuote:
'Returnsnumberofrecordsinaquery
'sDBTableisthenameofthetable.Sincethenamecanincludereserved
'charactersitneedstobesurroundedbyquotemarks
rResult=$hConn.Exec("SELECTCOUNT(*)ASiNumRecsFROM"&DB.Quote(sDBTable))
PRINTrResult!iNumRecs
ResultObjects
TheresultobjectisaclassthatisusedtoreturntheresultofaSQLrequest.
Thisclassisnotcreatableanditactsjustlikeareadonlyarray.Itisenumerable
usingtheFOREACHstatement.Declareanditeratearesultobjectasfollows:
DIMhResultASResult
FOREACHhResult
'dosomethingwiththedata
NEXT
Thecodesnippetbelowshowshowyoucangetthevalueofafieldinthecurrent
recordofaResultobject:
DIMMyResultASResult
DIMMyVariantASVariant
MyVariant=MyResult[FieldASString]
TheResultFieldclassrepresentsoneofthefieldsofaResultobject.You
canusetheFindmethodtoselectaparticularfieldbeforeusingit.Theproperties
this class supports are Length, Name, Result andType. It is also possible to
335
A Beginner's Guide to Gambas
enumeratetheResultFielddatawiththeFOREACHkeyword. Thisclassisnot
creatable. Thecodebelowshowsyouhowtomodifythevalueofafieldinthe
currentrecordofaResultobject:
DIMMyResultASResult
DIMMyVariantASVariant
MyResult[FieldASString]=MyVariant
Properties that you can use with a result object include Available,
Connection,Count,Fields,Index,andLength.AvailablewillreturnaTRUE
valueiftheresultpointstoanexistingdatabaserecord.Connectionreturnsthe
parentconnectionobject.Counttellsyouthenumberofrecords(rows)returned
withtheresultobject. Fieldsreturnsacollectionofthefieldsinthedatabase
table returned with the result object. Index returns the index (current row
pointerorcursor)ofthecurrentrecord,startingatzero. Lengthisthesameas
countandisusedinterchangeably.
DBClass
Thisclassrepresentsthecurrentdatabaseconnection.Thisclassisstatic
andallofitsmembersarealsostatic.Mostofthepropertiesofthisclassarethe
same as those of the Connection class so we will only cover those that are
different, namely Current, Databases, and Debug. Current returns or sets the
currentconnection.Databasesreturnsacollectionofallofthedatabasesthatare
managedbythedatabaseserver. DebugsetsorreturnsTRUE ifthedatabase
componentisindebuggingmode.Whenthedebugflagisset,eachquerysentto
any database driver is printed on the standard error output (generally, the
console). ThemethodsusedintheDBclassarethesameasthoseusedinthe
Connectionclass(Begin,Close,Commit,Create,Edit,Exec,Find,Open,Quote
andRollback)sowewon'trepeatthatinformationhere.
336
A Beginner's Guide to Gambas
Database
Field
TheFieldclassisusedtorepresentdataforatablefield.Thisclassisnot
creatable. PropertiesthatthisclasssupportsareDefault,Length,Name,Table,
andType. Defaultreturnsthedefaultvalueofafield. Lentghwillreturnthe
maximum length of a text field. If the text field being checked has no limit
specified,azerovalueisreturned. NamewillreturnthefieldnameandTable
returnsthetableobjectinwhichthefieldwascreated.Typereturnsthedatatype
thatthefieldrepresents.Gambaswillreturnoneofthefollowingconstants:
gb.Booleangb.Integergb.Floatgb.Dateorgb.String
Index
TheIndexclassrepresentsatableindex.Thisclassisnotcreatable.The
properties this class supports are Fields, Name, Primary, Table, and Unique.
Fieldsreturnsacommaseparatedlistofstringsrepresentingthefieldsthatmake
uptheindex. NamereturnstheindexnamewhilePrimarywillreturnaTRUE
valueifanindexistheprimaryindexofthetable. Tablewillreturnthetable
objectthatownsthisindex.UniquereturnsTRUEiftheindexisunique.
Table
TheTableclassrepresentsthedefinitionofadatabasetable.Thisclassis
not creatable. The properties that are supported by the Table class include
Connection,Fields,Indexes,Name,PrimaryKey,SystemandType. Connection
canbeusedtoobtaintheparentconnectionobject.Fieldswillreturnacollection
ofthefieldsofthetablewhileIndexeswillreturnacollectionoftheindexesof
thetable.Namewillreturnthenameofthetable.PrimaryKeywillreturnorset
theprimarykeyofthetable. Theprimarykeyisastringarraycontainingthe
337
A Beginner's Guide to Gambas
nameofeachprimarykeyfield.SystemwillreturnaTRUEvalueifthedatabase
isasystemdatabase. Typereturnsorsetsthetypeofatable. Thispropertyis
uniquetoMySQLandisonlyusedwithMySQLdatabases. Thisclassonlyhas
onemethod,Update,whichiscalledtoactuallycreatethetableinthecurrently
connecteddatabase.
User
TheUserclassisusedtorepresentusersofadatabase. Thisclassisnot
creatable. The properties User class supports are Administrator, Connection,
NameandPassword.AdministratorisareadonlypropertythatreturnsTRUEif
a user is a database administrator. Connection returns the parent connection
objectoftheuser.NamewillreturnthenameoftheuserandPasswordwillget
orsetthepasswordassociated withauser. Whenyoureadtheproperty,you
should get the password in an encrypted form. The User class has a single
method,Deletewhichisusedtodeleteauserfromthedatabase.
TheDatabaseExampleProgram
The previous sections of this chapter have explained about the Gambas
database component and the features provided therein. However, nothing
substitutesworkingwithrealcodeinarealapplication. Gambasshipswithan
example database program that we are going to explore. Writtenby Gambas
founderBenoitMinisini,thisprogramisanexcellentexampleofhowtocodeyour
program to use database within the Gambas environment. To begin, start
GambasandchoosetheDatabaseprogramfromtheExamplesmenu.Whenthe
IDE appears, you will see that the program contains two forms, FMain and
FRequest.FMainshouldlooklikethefigurebelow.
Thisprogramwillallowyoutochoosewhatdatabaseplatformtouse(i.e.,
PostgreSQL,MySQL,orSQLite)andspecifythehostname,databasename,user
ID and password. An option to automatically create a database exists and is
activated whenever the checkbox is checked. Once you have successfully
connectedtothedatabase,youhavetheoptionofcreatingatable,deletingit,or
fillingitwithsometestdata.TheSQLrequestboxatthebottomoftheformwill
allowyoutoperformSQLqueriesagainstthedatabase. Allinall,thisprogram
demonstratesalmosteverythingyouneedtoknowtoconnecttoanydatabase
usingGambas.
338
A Beginner's Guide to Gambas
Figure98TheFMainformindesignmode.
TheFRequestformismuchsimplertobuild.Itisshowninthefigurebelow:
Figure99FRequestFormindesignmode.
TheFRequestformcontainsasinglecontrol,whichwehavenotpreviously
introduced,theTableViewcontrol. ThiscontrolisfoundintheQTtoolsetwe
discussedpreviously.Wewillshowyouhowtousethiscontrolwhenwediscuss
theFRequestformcodebelow.Fornow,let'sjumpintothecodefortheFMain
formandseehowthingswork.
'Gambasclassfile
$hConn isdeclaredasaprivatevariableandwillbeusedbyallsubroutinesin
thisclassfile.Notethatthevariableisprefixedwitha$symboltoindicateitisa
339
A Beginner's Guide to Gambas
privateclassvariable.Whilenotrequired,itisagoodprogrammingconvention
tofollow.
PRIVATE$hConnASConnection
Whenevertheuserhasfilledoutthedataatthetopoftheformwiththeir
username,host,password,etc.,andclickstheconnectbutton,theprogramwill
cometothissubroutineandtrytousethatdatatoestablishaconnectiontothe
database.
PUBLICSUBbtnConnect_Click()
'weneedtohaveastringtoworkwithsodeclaresNameaslocal
DIMsNameASString
'nowwegetalittletricky.ifadatabasewaspreviouslyopened
'andisstillopen,thisnextlinewouldcloseit.UsingTRY
'wouldallowanyerrortobecaught(seeCATCHbelow).
'Ifthereisnotanopendatabasetoclose,noharmwasdone
'andthecodeexecutionproceeds.
TRY$hConn.Close
'weassignthedataintheTextboxtxtNametoourstringvarsName
'andsetthedatabaseconnectionpropertiestothevaluesprovided
'bytheuserbyusingtheWITH/ENDWITHconstruct.
sName=txtName.Text
WITH$hConn
.Type=cmbType.Text'thetypeofdatabaseplatformtouse
.Host=txtHost.Text'hostnameofthedatabase
.Login=txtUser.Text'USERID
.Password=txtPassword.Text'USERpassword
ENDWITH
Atthispoint,alltheconnectionpropertiesaresetbutwehavenotopened
theconnectionyet. Thefollowingcodesegmentwillseeifadatabasewiththe
namespecifiedbysNameexistsand,ifnot,itwillcreateitifthecheckboxto
createdatabaseischecked.
IFchkCreate.ValueTHEN
$hConn.Open'opentheconnection
'seeifadatabasesNameexistsandifnot,addittotheserver
IFNOT$hConn.Databases.Exist(sName)THEN
$hConn.Databases.Add(sName)
ENDIF
'nowclosetheconnection
$hConn.Close
340
A Beginner's Guide to Gambas
ENDIF
Now,wearereadytoopenthedatabase.Eitheritalreadyexistedandwe
openthatdatabaseorwewillopenthenewonewecreatedifthecheckboxwas
checked.First,settheNamepropertyfortheconnectiontosNameandthencall
theOpenmethod:
$hConn.Name=sName
$hConn.Open
'wesettheenabledpropertiesforbothprogramformstoTRUE
'andplacesomedefaulttextintheSQLrequestboxatthe
'bottomoftheFMainform:
frmDatabase.Enabled=TRUE
frmRequest.Enabled=TRUE
txtRequest.Text="SHOWTABLES"
'ifourTRYfailedorifanyerroroccurredduringthissubroutine,
'theCATCHstatementwoulddisplayanERRORdialogwiththetextof
'theerrormessage.
CATCH
Message.Error(Error.Text)
END'ofconnectBtn_Clicksubroutine
If,afterthedatabaseconnectionisestablished,theuserwouldclickthe
Createtabletestbutton,thissubroutinewouldbeexecuted.Ihavemodifiedit
slightly to avoid using hardcoded strings and to use the same name as the
database.Theoriginalcodeiscommentedoutsoyoucanuseeithermethod.
PUBLICSUBbtnCreate_Click()
'declarealocalTablevariable
DIMhTableASTable
'addthetabletothedatabaseusingtheAddmethod
'hTable=$hConn.Tables.Add("test")
'thisisthecodeIchangedtoavoidhardcodingthestring
'aswasdoneinthepreviouslineofcode
hTable=$hConn.Tables.Add(txtName.text)
'nowaddthefieldsofthetabletothetablewejustadded
'notethatwespecifythefieldnameanddatatypeforeach
'ofthefieldsweinsertintothetable.Forstringdata,
'wealsospecifythemaximumlengthofthestringfield.
hTable.Fields.Add("id",gb.Integer)
hTable.Fields.Add("firstname",gb.String,16)
341
A Beginner's Guide to Gambas
hTable.Fields.Add("name",gb.String,32)
hTable.Fields.Add("birth",gb.Date)
hTable.Fields.Add("active",gb.Boolean)
hTable.Fields.Add("salary",gb.Float)
'wecanspecifyaprimarykeyforthedatabasetable.Inthis
'case,theidfieldisusedaswecancreateuniqueintegerindex
'data
hTable.PrimaryKey=["id"]
'thecalltotheUpdatemethodcommitsthechangestothedatabase
'andmakesthempermanent.
hTable.Update
'nowweputupasimpledialogtoinformtheuserwehave
'successfullycompletedthecreationtask.
Message.Info("Table"&txtName.Text&"hasbeencreated.")
'next,weaddsomedefaulttexttotheSQLquerybox
txtRequest.Text="ShowTABLES"
'theCATCHstatementwoulddisplayanERRORdialogwiththetextof
'theerrormessageifanyerroroccursinthissubroutine.
CATCH
Message.Error(Error.Text)
END'ofthecreatebuttonsubroutine
If,afterthedatabaseconnectionisestablished,theuserwouldclickthe
Delete table test button, this subroutine would be executed. I have also
342
A Beginner's Guide to Gambas
modifieditslightlytoavoidusinghardcodedstringsandtousethesamenameas
thedatabase.Theoriginalcodeiscommentedoutsoyoucanuseeithermethod.
PUBLICSUBbtnDelete_Click()
'removethetable
'$hConn.Tables.Remove("test")
$hConn.Tables.Remove(txtName.Text)
'putupamessagetoinformtheuserthetableisgone
Message.Info("Table"&txtName.Text&"hasbeenremoved")
'enableordisablethebuttonstomakesense.Ifthetable
'hasbeenremoved,itcannotbedeletedagainanditcannot
'befilledsinceitdoesnotexist.Allthatisleftisto
'recreateitandthatbuttonisenabled.
btnDelete.Enabled=FALSE
btnFill.Enabled=FALSE
btnCreate.Enabled=TRUE
'notableexiststoquerysoblankouttheSQLquerytext.
txtRequest.Text=""
'ifanerroroccursinthesubroutinecatchithereandshowadialog
'messagetotheuser.
CATCH
Message.Error(Error.Text)
END'thedeletebuttonsubroutine
Ifthedatabaseconnectionhasbeenestablishedandtheuserhascreated
thetable,thereneedstobesomedataaddedtomakeituseful.Thissubroutineis
executedandwilladdsemiarbitrarydatatothetable.Itwillrandomlyselecta
firstnamefromthearrayoffivenamesprovidedand concatenatethecounter
numbertothestringName#toserverasthelastname. Thebirthdateis
createdrandomlybypickingavaluethataddsarandomnumberfrom110,000
tothebasedateofJanuary1st,1970.Therecordhasanactiveflag,randomlyset
aswell.Salaryfiguresarerandomlyselectedwithintherangeof1,000to10,000.
Finally, the Update method will put all the data in the table and make the
COMMITtothedatabase.Let'slookateachlineofcodetoseehoweasythisis
accomplishedinGambas:
PUBLICSUBbtnFill_Click()
'weneedanintegercounteriIndtobeourindexandwe
343
A Beginner's Guide to Gambas
'needaResultobjecttostoreourresults
DIMiIndASInteger
DIMrTestASResult
'settheBusyflagtopreventinterruptionstoourprocess
INCApplication.Busy
'wearegoingtostartthedatabasetransactionprocesswithBEGIN
$hConn.Begin
'createthedatabasetablefirst
'rTest=$hConn.Create("test")
rTest=$hConn.Create(txtName.Text)
'now,setupalooptocreate100records
FORiInd=1TO100
'maketherecordidbethecountervariablevalue
rTest!id=iInd
'randomlysetthefirstnametobeoneofthefiveinthearray
rTest!firstname=["Paul","Pierre","Jacques","Antoine","Mathieu"][Int(Rnd(5))]
'makethelastnameacatenatedvaluewiththeintegerindexvalue
rTest!name="Name#"&iInd
'randomlychooseadatebyaddingavaluefrom110,000tothe
'basedateofJan1,1970
rTest!birth=CDate("01/01/1970")+Int(Rnd(10000))
'settheactiveflagtoeither0or1(TRUEorFALSE)
rTest!active=Int(Rnd(2))
'randomlychooseasalaryfigurefrom1,000to10,000
rTest!salary=Int(Rnd(1000,10000))
'updatethisrecordwiththedatasemiarbitrarydatavalues
rTest.Update
NEXT'iterationoftheloop
'commitalladdedrecordstothedatabase
$hConn.Commit
'lastthingtoexecutebeforeleavingthesubroutine
FINALLY
'decrementthebusyflag
DECApplication.Busy
'popupamessagetoinformtheuserwhatwedid
Message.Info(txtName.Text&"hasbeenfilled.")
344
A Beginner's Guide to Gambas
'putadefaultSQLqueryintheSQLQuerytextbox
txtRequest.Text="select*from"&txtName.Text
'fixourbuttonstomakesense
btnFill.Enabled=FALSE
btnDelete.Enabled=TRUE
btnCreate.Enabled=FALSE
'ifsomethinggoeswrong,abortallchangeswiththeRollbackand
'showtheerrormessagetotheuser
CATCH
$hConn.Rollback
Message.Error(Error.Text)
END'ofthefilldatasubroutine
IftheuserentersanarbitrarySQLrequestintheSQLqueryboxatthe
bottomoftheform,wewillusetheExecmethodtoperformthequeryanddisplay
theresultsoftherequestusingtheFRequestform.Hereishowthatisdone:
PUBLICSUBbtnRun_Click()
'declarearesultobjecttoholdtheresultsofthequery
DIMrDataASResult
'declareaformvariablesowecanshowtheFRequestform
DIMhFormASFRequest
'executethequeryusingtheExecmethodandassigntheresultsto
'theresultobjectrData
rData=$hConn.Exec(txtRequest.Text)
'passthedatabaseconnectionhandleandtheresultdatatothe
'FRequestformwhenitisinstantiated
hForm=NEWFRequest($hConn,rData)
'nowdisplaytheformtotheuserwiththeresultdata
hForm.Show
'comehereifthereisaprobleminthesubroutineanddisplayamsg
CATCH
Message.Error(Error.Text)
END'ofsqlquerysubroutine
Whenever our program runs and the FMain form opens, we need to
instantiateourconnectionvariable$hConn.Whenevertheformisclosed,wewill
closetheconnection.
PUBLICSUBForm_Open()
345
A Beginner's Guide to Gambas
$hConn=NEWConnection
END
PUBLICSUBForm_Close()
$hConn.Close
END
Next,weneedtotakealookattheFRequestformandseehowthatcode
displaystheresultobjectdatawhenitisinvoked.Hereisthecodeforthat:
'Gambasclassfile
'fRequest.classdeclarestwoprivatevariablestouseinthisclass
'onefortheconnection,onefortheresultdata.
PRIVATE$hConnASConnection
PRIVATE$rDataASResult
'aconstructorroutinewillbeusedtoreceivetheconnectionhandle
'andtheresultsofaqueryasparameterswhenFRequestiscalledby
'theFMainform.
PUBLICSUB_new(hConnASConnection,rDataASResult)
'assignthehConnparametertoourprivate$hConnvariable
$hConn=hConn
'assigntherDataparametertoour$rDataprivatevariable
'theseassignmentsaremadesothe$prefixedvariablesare
'visibletotheentireclass,notjusttheconstructorroutine.
$rData=rData
'callourlittlesubroutinetodisplaythetitleintheformwindow
RefreshTitle
'theReadDatasubroutineisusedtopopulateourTableViewcontrol
ReadData
'resizethewindowtocenteronthedesktop
ME.Move(Int(Rnd(Desktop.WME.W)),Int(Rnd((Desktop.HME.H))))
END'oftheconstructor
'thissubroutinesimplyupdatesthewindowcaption
PRIVATESUBRefreshTitle()
'weneedalocalstringvariable
DIMsTitleASString
'wewillconcatenatetheconnectionnametothetextforthecaption
sTitle=("SQLQueryResults")&""&$hConn.Name
346
A Beginner's Guide to Gambas
'andsetthetitlepropertytobethestringvariablevalue
ME.Title=sTitle
END
PRIVATESUBReadData()
'thisvariableisdeclaredbutneverused,youcancommentitout
DIMhTableASTable
DIMhFieldASResultField
'thisvariableisdeclaredbutneverused,youcancommentitout
DIMsFieldASString
DIMiIndASInteger
'thisvariableisdeclaredbutneverused,youcancommentitout
DIMiLenASInteger
'settheapplicationbusyflagtoavoidinterruptions
INCApplication.Busy
'resetrowcountoftheTableViewcontroltozero
tbvData.Rows.Count=0
'setthenumberofcolumnstobethesamenumber
'asthenumberoffieldsintheresultobject
tbvData.Columns.Count=$rData.Fields.Count
'nowwewilliteratethrougheachfieldoftheresultobjectand
'getthenameofthefieldandthedatatypeandsettheTableView
'columnheadingsandfieldtype/sizeasappropriate
347
A Beginner's Guide to Gambas
FOREACHhFieldIN$rData.Fields
WITHhField
'thisisadebuglinethatwascommentedout
'PRINT.Name;":";.Type;"";.Length
'thisnextlinesetsthecolumnnametobethefieldname
tbvData.Columns[iInd].Text=.Name
'here,thecalltoWidthFromTypeisusedtodeterminewhatdata
'typethefieldisandwhattheappropriatewidthshouldbe
tbvData.Columns[iInd].Width=WidthFromType(tbvData,.Type,.Length,.Name)
ENDWITH
'incrementourindexcounter
INCiInd
NEXT'iterationofresultdata
'setthenumberofTableViewrowstobethesameasthenumber
'ofrowsofdataintheresultobject
tbvData.Rows.Count=$rData.Count
'lastthingwedointhissubroutineisdecrementthebusyflag
FINALLY
DECApplication.Busy
'iftherewereanyerrorsinthissubroutinewewouldshowamessage
CATCH
Message.Error("Cannotexecrequest."&"\n\n"&Error.Text)
END'ofReadDatasubroutine
Thenextbitofcodeisactivatedwheneverdataispresent.TheDataevent
oftheTableViewcontrolisusedasthedriverforactivationofthissubroutine.It
insertsarowofdatafromtheresultsobjectintothecurrentrowandcolumnof
the TableView control. Bear in mind that you don't ever call the data event
directly.ThereisverylittledocumentationavailablefortheTableViewcontrolso
nothingstatedhereinshouldbeconsideredasthedefinitiveanswerforusingit.
However,thegeneralapproachtousingtheTableViewcontrolistofirstloadall
datathatistobedisplayedintoanarrayandpreparetheTableViewcontrolwith
rows and columns as was done in the ReadData subroutine above. The very
processoffillingthearrayanddefiningthecolumnsinthismannerforcestheQt
widgetthatisusedintheTableViewcontroltomakeaninternalcalltotheData
eventthatactuallydoesfillthecellswithdatafromyourarray.Itisuptoyouto
codetheassignmentstatement(s)thatmovedatafromtheresultsobjecttothe
TableViewrowandcolumnwhereyouwantthedatadisplayed.Thekeythingto
remember is that you must have an event handler, tbvControl_Data( ... )
somewhereinyourclassfiletodothis.InaTableViewcontrol,thedatathatis
348
A Beginner's Guide to Gambas
refreshedisonlywhatisvisibleinthecontrol. Thecontrolcandisplayahuge
amountofdatawithoutholdinganyofthedatavaluesdirectlyinstorageitself.
Thatiswhatyourprogramarrayisusedfor.Whileitsoundsabitawkward,itis
apragmaticsolutionthatallowsGambastodisplaydatafromadatabaseina
prettyefficientmanner.
PUBLICSUBtbvData_Data(RowASInteger,ColumnASInteger)
'thisgetstothecorrectrow
$rData.MoveTo(Row)
'thisactuallyassignsdatafromtheresultsobjecttothetableview
tbvData.Data.Text=Str($rData[tbvData.Columns[Column].Text])
END
Iftheformisresizedbytheuser,weneedtoresizethecontrol.Thissubroutine
willdothetrick.
PUBLICSUBForm_Resize()
tbvData.Resize(ME.ClientW,ME.ClientH)
END
Whendataisbeingreadfromtheresultsobject,thissubroutineiscalledto
determinewhatthedatatypeisforeachfieldofarow.Thepropertiesfromthe
Field class are passed as parameters to this function and used in the select
statement.ThisensuresthedataplacedintheindividualcellsoftheTableView
controlisnottruncatedandwilldisplayproperly,regardlessofthefontproperty
settingestablishedbytheTableViewcontrolitself.
PRIVATEFUNCTIONWidthFromType(hCtrlAScontrol,iTypeASInteger,
iLengthASInteger,sTitleASString)ASInteger
DIMiWidthASInteger
SELECTCASEiType
CASEgb.Boolean
iWidth=hCtrl.Font.Width(Str(FALSE))+32
CASEgb.Integer
iWidth=hCtrl.Font.Width("1234567890")+16
CASEgb.Float
iWidth=hCtrl.Font.Width(CStr(Pi)&"E+999")+16
CASEgb.Date
iWidth=hCtrl.Font.Width(Str(Now))+16
CASEgb.String
349
A Beginner's Guide to Gambas
IFiLength=0THENiLength=255
iLength=Min(32,iLength)
iWidth=hCtrl.Font.Width("X")*iLength+16
ENDSELECT
iWidth=Max(iWidth,hCtrl.Font.Width(sTitle)+8)
RETURNiWidth
END
Finally,iftheuserclicksonthexatthetoprightcornerofthewindowto
closetheprogram,wecometothisroutineandclosethingsdown.
PUBLICSUBForm_Close()
ME.Close
END
When you execute the example Database program, it requires that you
haveadatabasesystemlikePostgreSQLorMySQLinstalledonyoursystem.You
musthaveauseraccountandpasswordtousethedatabasesystems.Giventhose
caveats,runtheprogramandlogintothedatabase.Youcanplayaround,create
andfillthetesttable,andmakequerieswiththeprogram.Atthispoint,youhave
learnedallthebasicsforconnectingtoandusingadatabaseinGambas.Inthe
nextchapter,wewillcovertheessentialsofmakingyourprogramavailableto
users globally, a process of globalization that involves two processes,
internationalization(I18N)andlocalization(L10N).
350
A Beginner's Guide to Gambas
Internationalization
Internationalization istheprocessofdesigninganapplicationsothatit
canbeadaptedtovariouslanguagesandregionswithoutengineeringchanges.
Sometimestheterminternationalizationisabbreviatedasi18n,becausethereare
18lettersbetweenthefirst"i"andthelast"n."Aninternationalizedprogram,with
theadditionoflocalizeddata,canusethesameexecutableworldwide.Textual
elements,suchasstatusmessagesandGUIcomponentlabels,arenothardcoded
inthe program.Instead theyarestoredoutsidethesourcecode and retrieved
dynamically. Support for new languages does not require recompilation.
Culturallydependentdata,suchasdatesandcurrencies,appearinformatsthat
conform to the end user's region and language. In this manner, an
internationalizedapplicationcanbelocalizedveryquickly.
Localization
351
A Beginner's Guide to Gambas
UniversalCharacterSet(UCS)
ISO/IEC 10646 defines a very large character set called the Universal
Character Set (UCS), which encompasses most of the world's writing systems.
Thesamesetofcharactersisalsodefinedbythe Unicode standard. Todate,
changesinUnicodeandamendmentsandadditionstoISO/IEC10646havebeen
madeinunisonsothatthecharacterrepertoiresandcodepointassignmentshave
stayedsynchronized.Therelevantstandardizationcommitteeshavecommittedto
maintainthisapproach.
Unicode
Unicodecurrentlydefinesjustunder100,000characters,buthasspacefor
1,114,112codepoints19.Thecodepointsareorganizedinto17planesof216
(65,536) characters, numbered 0 through 16. Plane 0 is called the Basic
MultilingualPlaneorBMPandcontainssymbolsfoundtobeuseful.Generally
speaking,itcontainseverycharacteravailabletoaprogrammerbeforeUnicode
came along. The characters in the BMP are distributed in a West to East
fashion,withtheASCIIcharactershavingtheirfamiliarASCIIvaluesfrom0to
127,theISOLatin1charactersretainingtheirvaluesfrom128to255.Then,the
charactersetsmoveeastwardacrossEurope(Greek,Cyrillic),ontotheMiddle
East(Arabic,Hebrew,etc.)andacrossIndiaonwardtoSoutheastAsia,endingup
withthecharactersetsfromChina,Japan,andKorea(CJK). BeyondthisBMP
existsplanes1through16.Theyaresometimesreferredtoastheastralplanes
because they are typically used for exotic, rare, and historically important
characters.
352
A Beginner's Guide to Gambas
ASCIIfilescanbeconvertedintoaUCS2filebyinserting0x00infrontof
everyASCIIbyte. Tomakea UCS4 formattedfile,youmustinsertthree0x00
bytesbeforeeveryASCIIbyte. UsingeitherUCS2orUCS4onUnixplatforms
can lead to some very significant problems. Strings used with these encoding
schemescancontainpartsofmanywidecharacterbyteslike\0or/thathave
specialmeaninginfilenamesandotherClibraryfunctions.Thevastmajorityof
UNIXtoolsexpecttooperatewithASCIIbasedfilesandsimplycannotread16bit
wordsascharacters. Simplyput,UCS2/UCS4arenotsuitableforUnixwhen
usedwithfilenames,textfiles,environmentvariables,codelibraries,etc.
ThereareseveralotherencodingformscommontobothUCSandUnicode,
namelyUTF8,UTF16,andUTF32. Ineachoftheseencodingformats,each
character is represented as one or more encoding units. All standard UCS
encodingformsexceptUTF8haveanencodingunitlargerthanoneoctet. For
manyapplicationsandprotocols,anassumptionofan8bitor7bitcharacterset
makestheuseofanythingotherthanUTF8nearlyimpossible.SinceUTF8hasa
oneoctetencodingunit,itusesallbitsofanoctetbutcanstillcontainthefull
rangeofUSASCIIcharacters,allofwhichhappentobeencodedinasingleoctet.
AnyoctetwithsuchavaluecanonlyrepresentaUSASCIIcharacter.
UTF8
20 http://www.cs.bell-labs.com/who/ken/
21 http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
22 http://64.233.167.104/search?q=cache:U4zV7dcaq0EJ:www.faqs.org/ftp/rfc/pdf/rfc2279.txt.pdf+Greger+Leijonhufvud&h
l=en
23 USENIX Technical Conference held in San Diego, CA, January 25-29, 1993, published in the Conference Proceedings, pp.
43-50.
353
A Beginner's Guide to Gambas
UTF8encodesUCScharactersasavaryingnumberofoctets.Thenumber
of octets and the value of each depend on the integer value assigned to the
characterinISO/IEC10646(thecharacternumber,a.k.a.,it'scodeposition,code
point or Unicode scalar value). This encoding form has the following
characteristics24(valuesinhexadecimal):
CharacternumbersfromU+0000toU+007F(USASCIIset)correspond
tooctets00to7F(7bitUSASCIIvalues).Adirectconsequenceisthat
aplainASCIIstringisalsoavalidUTF8string.
RoundtripconversioniseasybetweenUTF8andotherencodingforms.
Thefirstoctetofamultioctetsequenceindicatesthenumberofoctets
inthesequence.
TheoctetvaluesC0,C1,F5toFFneverappear.
ThebytevaluelexicographicsortingorderofUTF8stringsisthesame
asiforderedbycharacternumbers.Ofcoursethisisoflimitedinterest
sinceasortorderbasedoncharacternumbersisalmostneverculturally
valid.
TheBoyerMoorefastsearchalgorithmcanbeusedwithUTF8data.
TheUTF8encodingisformallydefinedinISO106461:2000AnnexD.It
isalsodescribedinRFC3629aswellassection3.9oftheUnicode4.0standard.
354
A Beginner's Guide to Gambas
InordertouseUnicode underUnixstyleoperatingsystems,UTF8isthebest
encodingschemetouse. ThisisbecauseUCScharactersU+0000toU+007F
(ASCII)areencodedasbytes0x00to0x7F(forASCIIcompatibility).Thismeans
files and strings that contain only 7bit ASCII characters will have the same
encodingunderbothASCIIandUTF8.AllUCScharactersthatfallintherange
greaterthanU+007Fareencodedasamultibytesequence,eachofwhichhas
themostsignificantbitset.Therefore,noASCIIbyte(0x000x7F)canappearas
partofanyothercharacter.
Thexxxbitpositionsarefilledwiththebitsofthecharactercodenumber
inbinaryrepresentation.Therightmostxbitistheleastsignificantbit.Onlythe
shortestpossiblemultibytesequencewhichcanrepresentthecodenumberofthe
charactercanbeused.Notethatinmultibytesequences,thenumberofleading
1bitsinthefirstbyteisidenticaltothenumberofbytesintheentiresequence.
HowtotranslateinGambas
TotranslateGambasintoyourownlanguage,opentheGambasprojectin
theIDE,and click onTranslate...in theProjectmenu,asshowninthefigure
below:
355
A Beginner's Guide to Gambas
Figure100ChoosingtheTranslate
optioninGambas.
Next,youmustselectthetargettranslationlanguageinthecomboboxof
thetranslatedialogbox,asshownbelow:
Figure101TheTranslateDialoginGambas.
Selectastringfromthelistofuntranslatedstringsandenteritstranslation
inthetextfieldshownatthebottomofthedialog. Youneed torepeatthis
processuntileverystringinyourapplicationhasbeentranslated.Whenyouhave
finished, click on the Closebutton. Itis not necessary to complete all of the
strings at one sitting. You can translate the projectin several attempts. The
toolbariconsyouseeatthetopoftheTranslatedialogallowyouto:
356
A Beginner's Guide to Gambas
Savethecurrenttranslation.
Reloadthecurrenttranslation(Note:changesarelostwhenyoureload).
Deletethecurrenttranslation.
Duplicateanexistingtranslation.
Exportthecurrenttranslationtoa.pofile.
Mergeatranslationfile.
Verifyatranslationbycheckingifeverysymbolcharacterispreserved.
Therearecertainoccasionswhereyoumaynotwanttoevertranslatea
string.InGambas,youcanindicateastringshouldnotbetranslatedbyentering
aminussigncharacterasthetranslatedstring. Yourtranslationisstoredina
*.pofileinthe.langdirectoryoftheproject.Thenameofthe.pofiledependson
thelanguagetranslated.Forexample,theFrenchtranslationfileisnamedfr.po.
WheneverthelatestGambasversionchanges,anyuntranslatedstringsin
yourprogramcouldchange.However,anystringsyouhavetranslatedstringswill
bepreserved.Ifanuntranslatedstringdisappearscompletely,thetranslationwill
alsodisappearandifanewuntranslatedstringisadded,itgetsanemptyornull
translation string assigned to it. All other untranslated stringswillkeep their
correspondingtranslationstrings.WhilethestringtranslationfeatureofGambas
allowsyoutoeasilymaintainstringconversions,otherlocalespecificthingssuch
as dates, number formats, etc. are left to you to manage. It is hoped that
Gambas2willaddressthesefeatureswhenitisreleased.Untilthattimearrives,
hereisashort,generalizedchecklistforhelpingyoulocalizeyourapplication:
Ensureallmessages,icons,andhumanreadablecontentarestoredin
externalresourcefilesandcanbeeasilytranslated.
Thetranslatedmessageorresourcefilesshouldbedynamicallyloaded
by the application, depending on the current language and locale
settingsforthesession.
Date/time,sortorder,numericandmonetaryformattingetc.areinthe
targetlanguage.Thesortordershouldbeconfigurable,dependingon
357
A Beginner's Guide to Gambas
thelanguageoftheuser.
Targetlanguagecharacterscanbecorrectlyenteredanddisplayedby
theuserandtheycanbereadfromandwrittentothenativefilesystem
ofthetargetplatform.
AccordingtoHuanget.al.,25youshouldconsidercreatinganI18Ntesting
checklist for your application. Some of the questions they recommend you
considerincludethefollowing:
1.Doesprogramdesignaccountforinternationalconsiderations?
2.Canauserentertext,accelerators,andshortcutkeycombinationsonan
internationalkeyboard?
4.Canausersuccessfullycut/pastetextwithaccented (ordoublebyte)
characters?
5.Cantheapplicationworkcorrectlyondifferenttypesofhardwaresoldin
thetargetmarket?
6.Doestheapplicationworkcorrectlyonlocalizedoperationssystems?
7.CanausertypeEuropeanaccented(orAsiandoublebyte)charactersin
documentsanddialogboxes?
9.Canuserssaveandprintfileswithaccented(ordoublebyte)characters?
Whilethereisnosinglechecklistthatcanaccountforthewidedegreeof
variationfromapplicationtoapplication,considerationofthesebasicissueswill
likelygofarinhelpingyoutoreachaglobalaudience.TheInternethasmadethe
worldamuchsmallerplaceandtheaudienceforapplicationshavebecomemuch
25 Huang, E., Haft, R. and Hsu, J. Developing a Roadmap for Software Internationalization, Whitepaper dated October
2000, retrieved fromURL www.symbio-group.com/doc/Developing a Roadmap for Software Internationalization.pdf on
October 5th, 2005.
358
A Beginner's Guide to Gambas
359
A Beginner's Guide to Gambas
360
A Beginner's Guide to Gambas
Alphabetical Index
Accessfunction................................................................(188) Consistency......................................................................(332)
ACIDcompliant..............................................................(331) Constant.............................................................................(34)
Activateevent...............................................(155,162,169p.) Constructorroutine...............................(150,210,213,248p.)
Addmethod...............................(89,152,154,159,167,176) Containerclass...................................................................(62)
ANDoperator.....................................................................(41) Controlclass.......................................................................(61)
APPENDkeyword...........................................................(192) ControlGroups................................................................(100)
Applicationpath..............................................................(327) Controls..............................................................................(58)
Arithmeticoperators..........................................................(36) COPYfunction.................................................................(195)
Assignmentstatement........................................................(35) Copyrightnotice..................................................................(3)
Atomicity.........................................................................(331) CopyrightNotice..............................................................(2p.)
BackColorproperty.............................................(62,67,268) Cursorproperty..................................................................(65)
Backgroundproperty.........................................................(62) Dataabstraction...............................................................(239)
BenotMinisini..............................................(1,19,149,157) Databasesproperty...........................................................(328)
BigEndian.......................................................................(192) Datedatatype....................................................................(32)
Bitfunctions.....................................................................(319) Dblclickevent...................................................................(78)
Bits...................................................................................(318) DECoperator.....................................................................(43)
Booleandatatypes.............................................................(31) Defaultbutton....................................................................(61)
Borderproperty..................................................................(63) Defaultproperty.................................................................(66)
Builtinconstants...............................................................(34) Deletemethod....................................................................(70)
Busyproperty................................................................(151p.) Designproperty..................................................................(66)
Byte......................................................................... .........(318) Desktop.Charset.......................................................(142,152)
Bytedatatype.................................................................(31p.) Dialogclass...................................................................... (103)
Cachedproperty...............................................................(267) DialogTitleproperty.......................................................(103)
Cancelbutton.....................................................................(61) Dirfunction...................................................................... (189)
Cancelproperty..................................................................(63) DIRECTkeyword............................................................(192)
Captionproperty..........................................................(64,81) Divisionbyzero..............................................................(39p.)
Carrybit...........................................................................(323) DivisionbyZero................................................................(40)
CASEELSEblock.............................................................(49) DO[WHILE]LOOP..........................................................(51)
CASEstatement.................................................(48,103,114) Dotnotation.......................................................................(36)
CASEStatement................................................................(48) Doubleclickevent.............................................................(77)
CATCHstatement............................................................(305) Dragmethod.......................................................................(70)
CheckBoxclass..................................................................(93) Drawclass.......................................................................(267)
CheckBoxcontrol.........................................................(92pp.) Draw.Ellipsemethod.......................................................(276)
Checkedproperty..................................................(100p.,157) Draw.FillStyle..................................................................(279)
Chr(10).............................................................................(166) Draw.Linemethod...........................................................(276)
Chr(13).............................................................................(199) Draw.LineWidthproperty................................................(276)
Chr(9).......................................................................(136,194) Draw.Pointmethod..........................................................(274)
Classevent.......................................................................(310) Draw.Polygonmethod..................................................(280p.)
Classhierarchy...................................................................(28) Draw.Polylinemethod.............................................(280,282)
Classinvariants................................................................(241) Draw.Rectmethod..................................................(274,279)
ClassbasedOOPapproach..............................................(241) DrawingAreacontrol.......................................................(271)
Clickevent.........................................................................(76) Dropproperty.....................................................................(66)
ClickNRun....................................................................(22) Durability.........................................................................(332)
Clipclass..........................................................................(268) Enabledproperty................................................................(66)
Clippingarea....................................................................(268) Encapsulation...................................................................(240)
Cohesion..........................................................................(241) ENDkeyword....................................................................(37)
Collections.........................................................................(55) ENDWITHinstruction......................................................(35)
Colorclass........................................................................(268) Enterevent.........................................................................(74)
ColumnViewcontrol.......................................(170,174,177) Eoffunction.....................................................................(190)
ComboBoxarrays..............................................................(89) Errorclass........................................................................(304)
ComboBoxcontrol...............................................(85pp.,186) Errormanagement............................................................(298)
ComboBoxitems...............................................................(89) Error.Classproperty.........................................................(304)
Commandlineinterface...................................................(326) Error.Clear........................................................................(305)
COMMITstatement.........................................................(331) Error.Codeproperty........................................................(304)
Comparisonoperators........................................................(36) Error.Raise.......................................................................(305)
Conditionals.......................................................................(46) Error.Textproperty..........................................................(304)
Connectionclass......................................................(327,332) Error.Whereproperty.......................................................(305)
Connectionobject............................................................(327)
361
A Beginner's Guide to Gambas
Errorsinlogic..................................................................(301) Html....................................................................................(70)
Eventdrivenlanguage.......................................................(46) HTML..............................................................(26,81p.,84p.)
Eventhandler.....................................................................(77) HungarianNotation...........................................................(31)
Eventdrivenprogramming..............................................(309) IconEditor.........................................................................(28)
Eventdrivensystem........................................................(309) IconViewcontrol........................................(149,154pp.,158)
Execmethod....................................................................(327) IFstatement...............................................(47,101,161,168)
Existfunction...................................................................(190) IFStatement.......................................................................(47)
Existmethod....................................................................(167) IFTHENELSE................................................................(110)
Expandproperty.................................................................(67) Imageclass....................................................................(284p.)
FileSystemSafeUCSTransformationFormat(FSS/UTF).... INCoperator......................................................................(43)
(353) Infiniteloop........................................................................(51)
Fillclass...........................................................................(269) Inheritance........................................................................(240)
FillColorproperty............................................................(268) Inkscape...........................................................................(292)
FillStyleconstants............................................................(269) Integerdatatype................................................................(32)
FillStyleproperty.............................................................(269) Internationalization....................................................(22,351)
FillXproperty..................................................................(269) Intrinsicandderivedfunctions........................................(215)
FillYproperty..................................................................(269) Invertproperty.........................................................(269,275)
Finally..............................................................................(306) IsDirfunction...................................................................(191)
Floatdatatype...................................................................(32) ISO/IEC10646.................................................................(352)
FLUSHfunction..............................................................(195) Isolation............................................................................(332)
Focuscontrol......................................................................(72) Java......................................................................(19,53,237)
Fontclass............................................................(108pp.,269) Javalikearrays..................................................................(53)
Fontproperty......................................................................(67) Keyclass..........................................................................(316)
FOREACH........................................................................(50) KILLfunction..................................................................(196)
FOREACHconstruct.......................................................(55) LABEL............................................................................ ...(49)
FORstatement..........................................................(49p.,55) Layoutcontrols.............................................................(177p.)
ForeColorproperty............................................................(67) Leaveevent........................................................................(74)
Foregroundproperty..........................................................(67) Leftproperty......................................................................(68)
Frameclass.........................................................................(92) LIKE....................................................................(43,45,189)
GambasCodeEditor..........................................................(28) LineStyleproperty...................................................(270,276)
Gambascodingenvironment.............................................(29) Linspire...........................................................................(22)
Gambascomponentlibrary................................................(91) Linux......................................(19,142,178,196p.,238,266)
Gambasconstants..............................................................(34) ListEditor........................................................................(186)
GambasConstants..............................................................(34) ListBoxcontrol...............................................................(89p.)
Gambasdatatypes.......................................................(30,33) ListViewcontrol.........................................................(158pp.)
GambasDevelopmentEnvironment..................................(66) LittleEndian....................................................................(192)
GambasIconEditor.................................................(162,198) Loadconditions...............................................................(302)
GambasIDE.................................................................(27,58) Localization.....................................(138pp.,142p.,145,351)
GambasInterpreter..............................................(19,21,266) Lof()function...................................................................(195)
GAMBASinterpreter.......................................................(141) Loginproperty................................................................(329)
Gambaskeywords..............................................................(46) Loopingstructures.............................................................(49)
Gambasmascot..................................................................(38) Lowermethod....................................................................(71)
GambasToolBox...............................................................(57) MenuEditor............................................................(98p.,197)
GambasWiki.............................................................(20,165) MenuItems.........................................................................(99)
Gb.dbcomponent.............................................................(327) Messageclass...................................................................(112)
GNUPublicLicense..........................................................(19) MessageBoxcontrol........................................................(112)
GOTOinstruction..............................................................(49) MicrosoftVisualBasic...................................................(19)
Grabmethod.......................................................................(71) MIMETYPE......................................................................(70)
GraphicalUserInterfaceclasses........................................(58) MKDIRfunction..............................................................(196)
GridCell............................................................................(171) MODfunction....................................................................(40)
GridViewarray................................................................(171) MODoperator....................................................................(40)
GridViewcontrol..........................................................(171p.) Mouseclass...................................................................... (312)
GTK+.................................................................................(21) Mouseproperty..................................................................(68)
Hproperty..........................................................................(68) Movemethod.....................................................................(71)
Handleproperty.................................................................(68) MoveCurrentmethod...................................(161,165p.,168)
Handles...............................................................................(61) MySQL.............................................................................(326)
Heightproperty.........................................................(68,272) MySQLmanual................................................................(326)
Hidemethod.......................................................................(71) MySQLserver..................................................................(326)
Hostproperty...................................................................(329) Nameproperty................................................................(329)
HSVfunction.....................................................................(63) Nativearray........................................................................(53)
362
A Beginner's Guide to Gambas
NEWkeyword...................................................................(30) ScreenYproperty..............................................................(69)
NewProjectWizard.....................................................(37,72) ScrollViewcontrol........................................................(293p.)
Nextproperty.....................................................................(69) SELECTstatement............................................(48,105,114)
NEXTstatement.................................................................(50) SelectColorDialog..................................................(103,105)
NEXTStatement................................................................(49) SelectDirectoryDialog............................................(104,119)
NOToperator.....................................................................(44) SelectFontDialog.......................................................(108pp.)
Objectdatatype.................................................................(33) SelectionTool....................................................................(28)
Objectorientedprogramming.........................................(237) SetFocusmethod................................................................(72)
Objecttypedata...............................................................(238) SetFocus()method.............................................................(69)
OOconcepts.....................................................................(238) Shortdatatype...................................................................(32)
OOparadigm....................................................................(237) Showmethod.....................................................................(71)
OOP..................................................................................(237) SQLWHEREstatement.................................................(333)
OOPL...............................................................................(238) SQLite..............................................................................(326)
OpenContentLicense.......................................................(2p.) Standaloneexecutable.......................................................(20)
OpenFileDialog...................................................(104,117p.) Statfunction.....................................................(150,153,191)
ORoperator................................................................(41,188) STATICkeyword...............................................................(30)
Panelclass.......................................................................... (95) StatusBar...........................................................................(26)
Panelcontrol......................................................(95,177,185) STEPkeyword...................................................................(50)
Parameterpassingerrors..................................................(301) Stringconstants...............................................................(34p.)
Parentproperty...................................................................(69) Stringdatatype.............................................(32,34,55,126)
Passwordproperty............................................................(330) Stringfunctions................................................................(125)
Pictureclass...............................................................(69,287) Stringoperators..................................................................(36)
Picturecontrol....................................................................(78) SubMenus..........................................................................(99)
Pictureobject...............................................................(65,79) SVG..................................................................................(292)
Pictureproperty..................................................................(69) SVGspecification............................................................(292)
PNGfile.............................................................................(79) Systemclass...............................................................(91,150)
Polymorphism..................................................................(240) Tablesproperty................................................................(330)
Portproperty....................................................................(330) TableViewcontrol...........................................................(348)
PostgreSQL......................................................................(326) TabStripcontrol............................................................(182p.)
Poweroperator...................................................................(41) Tagproperty.......................................................................(69)
Predefinedconstants....................................(62,67,103,148) Temp$function................................................................(192)
Previousproperty...............................................................(69) Terminalapplication..........................................(37,125,232)
PRINTstatement...................................................(38,46,51) Textproperty...............................................................(64,69)
PRINTStatement...............................................................(46) Textboxcontrol..........................................................(83,166)
PRIVATEkeyword............................................................(30) TextBoxcontrol......................................................(82p.,252)
ProgressBarcontrol............................................................(73) TextHeightproperty.........................................................(272)
ProjectExplorer...................................................(25pp.,37p.) TextWidthproperty.........................................................(272)
ProjectMenu......................................................................(27) Timerevent......................................................................(187)
PUBLICkeyword........................................................(30,34) ToggleButtoncontrol......................................................(92p.)
Qt.........................................................................(21,58,142) ToolBar..............................................................................(28)
QT................................................................................(58,60) ToolBox.............................................................................(27)
QTlibrary.........................................................................(347) ToolBoxwindow......................................................(27p.,60)
QUITcommand.................................................................(37) ToolTip..............................................................................(28)
Quotemethod...................................................................(335) ToolTipproperty................................................................(69)
Racecondition.................................................................(301) Topproperty.......................................................................(70)
RadioButtonclass..............................................................(95) Transaction.......................................................................(331)
RadioButtoncontrol..........................................................(95) Transparentproperty........................................................(270)
Raisemethod......................................................................(71) Treeview...........................................................................(105)
Recoverableerror.............................................................(298) TreeView......................................(25,28,37,57pp.,64,163)
Refreshmethod..................................................................(72) TreeViewcontrol...........................................(163pp.,167pp.)
Removemethod...............................................................(168) Trolltech......................................................................... ..(347)
REPEATandUNTIL.........................................................(53) TRY..................................................................................(304)
Resizemethod....................................................................(72) TRYstatement.................................................................(305)
Resultobject............................................................(333,335) Typeproperty...................................................................(330)
RETURNcommand...........................................................(37) UCS2...............................................................................(353)
RGBfunction.....................................................................(63) UCS4...............................................................................(353)
ROLLBACKstatement....................................................(331) Unicodestandard.............................................................(352)
SaveFileDialog.......................................................(104,118) Usersproperty..................................................................(330)
ScalableVectorGraphics................................................(292) UTF8............................................................................ ...(353)
ScreenXproperty...............................................................(69) UTF8charset..........................................................(135,141)
363
A Beginner's Guide to Gambas
Validationerror................................................................(298) WHILE...WEND..............................................................(52)
Valueproperty...................................................................(70) Widthproperty...................................................(68,272,276)
Variantdatatype.........................................................(33,55) Wikipedia.........................................................................(215)
VB....................................................................(19,32,37,59) Windowproperty...............................................................(70)
Versionproperty..............................................................(330) WITH.................................................................................(35)
Virtualclass.DrawClip...................................................(268) WITHkeyword..................................................................(35)
Virtualdispatch................................................................(242) Xproperty..........................................................................(68)
Visibleproperty.................................................................(70) XWindows........................................................................(78)
Wproperty.........................................................................(68) X/OpenJointInternationalizationGroup........................(353)
WAIT.................................................................................(71) XORoperator.....................................................................(42)
Warningmessages...........................................................(115) Yproperty..........................................................................(68)
WATCHkeyword............................................................(192)
364