author: harry stahl delphi and firemonkey are registered...

225

Upload: others

Post on 02-Jan-2021

4 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission
Page 2: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Author:HarryStahlPublisher:HarryStahlLocation:BonnCopyright(2015),Allrightsreserved

DelphiandFireMonkeyareregisteredtrademarksofEmbarcadero.Apple,OSX,iOS,iPad,andiPhonearetrademarksofApple.WindowsisaregisteredtrademarkofMicrosoft.

ShouldIhaveusedthisbookatrademark,withoutreferringtotheowner,pleasesendmeashortmessage,Iwilladditimmediately.

1stedition

Page 3: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Content

Foreword

Introduction

Thebook

Theauthor

Contactinformation

Chapter1:UsingtheFireMonkeycomponents

Section1:GettingStarted

Section2:NewFireMonkeyproject

FireMonkeydesktopapplication(MultiDeviceApplication)

UsingtheMultiDeviceDesigner(FireUI)

ForminheritancewiththeMultiDeviceDesigner

Reverttoinheritedsettings

CreatingaPlatform-specificeventhandlerwiththeMultiDeviceDesigner

Section3:SelectedFireMonkeycomponents

TButton(mitTrimming)

Page 4: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TEdit(withoutPasswordChar)

TForm(furthermorewithcaption)

TFrame

TPanel

TCheckbox,TRadioButton(IsChecked)

TSwitch

TImage

TImageControl

TImageViewer

TImageViewer(tousewithLiveBindings-Designer)

TLabel(NewpropertyFontColor)

TImageList(Notavailable-butcompensationpossible)

TListBox(noTCheckListbox,butShowCheckboxes)

AllComponents(excepttheform)

SeveralComponents(Propertieswithadditionaltype-qualifying)

TMenuItem(withoutImageIndex)

TMainMenu(HandlingMACmenus)

TMemo(CaretPosition,noModified,FindNext-replacement)

Page 5: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TDropTarget(howDrag&DropworksinFireMonkey)

TRichEdit(Notavailalbe-butreplacementvia3rd-partypossible)

TPageControl(Notavailable-butreplacementavailable)

TStringGrid(worksdifferent)

TGrid(ImageandotherelementsintheGrid)

TStringGrid-alternative(TMSFMXGrid)

THeader(nosections,butitems)

THeaderControl(isnotavailableunderFireMonkey)

TProgressBar(not“position”butvalue)

TTabControl(noOwnerdraw)

TTrackbar(helpfulproperty“tracking”)

TSpeedButton(withoutBitmap)

TStatusbar(awaytocompensatethemissing“Panels”)

MessageDlg(e.g.notdirectlyusablewithmtWarning)

Section4:TheFireMonkeyStyle-Designer

a)UsingtheStylesEditor

b)StylesinFireMonkey-anoverview

Page 6: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

c)ConvertVCLStylestoFireMonkeyStyles

d)UsingFireMonkeyStyles

Section5:ConvertVCLprogramsintoFireMonkeyprograms

a)WorkingwiththeMidaBasicEdition

b)WorkingwiththeMidaPro/StudioVersion

c)StrategicapproachtoworkingwiththeMidaConverter

Chapter2:TipsandtricksforCross-PlatformDevelopment

Section1:startingotherprograms

Section2:Gettheprogramdirectoryandprogramdatadirectory

Section3:Catchtotheprogrampassedstart-upparameters

Section4:“HelloWorld”-Multilingualprogramsandnewmarkets

Section5:ApplysandboxingandEntitlementsproperly

Section6:SandboxingandpersistentaccesstoBookmarks

Section7:UseMACAPIs(POSIX,COREandCocoa)inDelphi

Chapter3:RequirementsforCross-PlatformDevelopment

Page 7: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section1:SettingupWindowsPCandMACPC

Section2:EnablingMACOSXPlatform

Section3:Provisioninganddeployment

1.SubmissiontotheAPPLEAppStore

2.Createa.dmgfilefordistributionoutsidetheAppleAppStore

3.CreateyourownsetuppackagewithApplicationDeveloperID/Installer

a)RequestaDeveloperIDcertificateandanApplicationDeveloperInstallerID

b)WorkingwiththecodesigningtoolandPackageMaker

Chapter4:WorkingwithGraphicsinFireMonkey

1.FireMonkeyTBitmapversusWindowsTBitmap

2.TBitmapDatainsteadScanLineforbitmapmanipulation

3.ChangethealphachannelofaTBitmap

4.Drawonthecanvasofabitmap

5.Turngraphics,flip,invertorcolortogray

6.Drawingabitmapscaled

Chapter5:UsefulthirdpartycomponentsforFireMonkey

1.TMS-Components

Page 8: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

2.ReportgeneratorFastReportFMX

3.RemObjects-ApplicationFramework(Hydra)

4.Othercomponents

Chapter6:Howto-tips&tricksforFMX

R1…Getthedisplayresolution?

R2…CheckiftheEscape,CtrlorAltkeyispressed

R3…UsefoldernamesunderWindowsandMACproperly

R4…Usesearchmaskfor“allfiles”inWindowsandMACproperly

R5…Avoidloopingsymlinkfolders(Alias)

R6…Inwhichsituationsfilesymlinksfunctionsplayaroleotherwise

R7…Determinethecontrolunderthemouseposition

R8…findoutonwhichMACOSXoperatingsystemtheprogramisrunning

R9…determinethecurrentusernameinMacOSX/Windows

R10…Sendfilesasanattachmentofane-mailwiththesystemmailprogram

R11…providetheuserwithhelpfilesunderWin&MAC

R12…AfteruploadingtoAppStore:Invalidbinary-causesandremedies

R13…Applicationrejected:Somereasonsforrefusal,whichyoucanavoid

Page 9: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

R14…UsingActiveControl

R15…ReplaceOnDrawItemeventoftheListBoxfromVCLwiththeOnPaintingeventoftheTListBoxItems

R16…LoadBitmapfromresourcefile(forretinadisplay)

R17…Swapitemsinalistbox

R18…SwapitemsinaListboxviaDrag&Drop

R19…UsingFMXfunctionsinaVCLapplicationviaDLL

R20…DrawtextinTGridright,orcentered

R21…DrawtextinTStringGridright,orcentered

R22…Dealingwiththe“visible”propertyofcontrols

R23…PreventunintendedshorteningofTLabeltext

R24…UsehintsinFireMonkey:Howitgoes

R25…Determinethedocumentdirectory

R26…Improvethefontquality(especiallyonWindows)

R27…Selectafolderwithadialog

R28…GetaccesstoacellcontrolofTGrids

R29…Showpop-upmenuataspecialposition

R30…Storeadditionalinformationinstandardobjects

R31…Draganddroptextfromexternalsource(egbrowser)toaTEditbox

Page 10: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

R32…Acolumninastringgridshouldoccupytheremainingspace

Chapter7:UpgradingfromDelphiXE3-XE6toXE7

Chapter8:Outlook

Attachment1:UnitHSW.FMXSandbox.pas

Atachment2:NewlyimplementedOpenandSavedialogsforsandboxing

Page 11: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Foreword

AfterthefirstversionofDelphiwithFireMonkeyinDelphiXE2inlate2011,ithappenedinquicksuccession:attheendof2012alreadyXE4waspublishedandatendofSeptember2013itwasfollowedbyDelphiXE3,April2014thenXE5,April2014XE6andinSeptember2014thenXE7.AndXE8willbeexpectedinApril2015.

WithXE7youcan’tonlydevelopprogramsforWindowsandMacOSX,butalsoforIOSandAndroid.Thesearefantasticopportunitiesthatarenowpossiblewithasingledevelopmentenvironment.Nevertheless,theIOSandAndroiddevelopmentisnotthesubjectofthisbook.ItremainsasinthepreviousversionofthebooktoDelphiXE3-XE5incross-platformdevelopmentforWindowsandMACOSX.ForIOSandAndroid,Imuststillrefertootherdeals(wheretheyexist).

WhetheryouarestillbeginnersforFireMonkeyprogrammingorhavealreadygainedexperienceinthisfield,Iamassumingthatyouwillfindinformationinthebookthatwillhelpinthedevelopmentofyourprojects.

IfyouarestillworkingwithDelphiXE3-XE6,Irecommendthatyoupurchasethepreviousversionofthisbook,becausefromthebeginningofXE7alothaschangedinFireMonkeyandDelphi.Itwouldbebest,ifyouwouldhavethecurrentcompilerversionXE7available(orXE8,whenitisout).

ExperienceduserswhopreviouslydevelopedforWindowsarefaced-whenmigratingtoFireMonkey-withaseriesofquestionsthataresometimesnoteasytoanswer.Firstofall,thereistheestablishmentoftheconnectionbetweenWindowsPCandMACandthevarioussettingdialogsthatneedtobefoundout.

OftenthereareonlysmalldifferencesbetweenFireMonkey-andVCLcomponents,butbecauseofthat,onefailsindevelopmentwork.Itconsumesalotoftimetofindthedifferences.Thisiswhatthebookismadefor.Itexplainsthesmallandlargedifferencesamongthemostimportantofthewell-knownVCLcomponents.

TheuseofFireMonkeycomponentsmakesespeciallysense,iftheyareusedforcross-platformdevelopment(besidethis,ifexceptionalgraphicsprocessingisrequired).ButunderWindowsandMACsomefunctionsarecompletelydifferent,forexamplepassingparametersatthestartoftheprogram.

Page 12: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Tosaveyouhoursofsearch,besuretofindsomeoftheanswersyouneedinthisbook.Thisbookisalso“underconstruction”foranextendedperiodoftime(usuallyuntilthereisanewDelphiXExversionpublished).

IftheMACisnewtoyou,aswellyouwon’tevenknowbasicinformationaboutthehandlingoffiles,availablestoragelocationsorotherwiserequireddevelopertools.It’sallhereinthebook,atleastwiththemostimportantinformation.

Ifyouhaveanysuggestionsontopicswhichshouldbeincludedhere,writeanemailtotheauthor.

Theonlywarning:Thisbookisnotaboutthetopic“databases”.Thisisduetothepersonalcircumstancethattheauthordoesn’tusedatabasecomponentsofDelphibutapersonalsolutionforworkwithdatabases.

Onelastnote:ThebookwasoriginallywrittenbymeinGermanlanguage.AfterthatIhavetranslateditintoEnglishbymyself.Pleaseexcuse,ifoneortheothertranslationisnotasgallantasitshouldbe.Iwouldbepleasedtoreceivehintsconcerningpossibleimprovements.

BonninApril2015

Page 13: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IntroductionTheInternetisablessingandacurse.Youwillfindeverything,butatthesametimeyouarelost.Inadditiontosearchingtheinternet,personalstudiestothesourcesofDelphiandtheMACAPIlibrarieswerenecessarytointroducethesolutionsofferedinthebookhere.I’musingthesesolutionsinmyownprograms,suchasin“TEditorforMAC”

http://www.hastasoft.de/TEditor.htm,

withwhichonecanreadandwriteANSItextandUNICODEindifferentformats.Formeitisanindispensabletool,becauseforexampletheMACtexteditorcan’treadWindowsANSItexts(German“Umlaut”problem).

ThebookThisbookwillbeonceagainonlyavailableinanelectronic-kindle-version(lateraprintversionisplanned).ButitwillbealsoavailableinPDFformattodownloadfrommyDevpagewebsite(http://www.devpage.de).TheKindleversionhasgottheadvantagethatyoucanusethebookacrossmultipledevices.

Howtoreadthebook:IfyouhavenotsetupyourMactoworkwithDelphiyet,maybeyoustartwiththerelevantchapter(Chapter3,Section1).Ifyouhavealreadycompletedthesetup,youcanjuststartreadingfromthebeginning.

Note:Tofacilitatethesearchofspecificissues(e.g.informationonupdatesofthisbook),insomeplacesaheading“Quickfinderxxx”wasbeinsertedasreference(wherexxxisanumber).

TheauthorI’malittlelongertimeunderwaywithsoftwaredevelopment.IstartedwithTurboPascalversion3.0intheeighties,thenIbought5.0TurboPascalfor700DM,whichwasatthattimealotofmoneyforme.ApartfromasmalldetourtoVisualBasic,afterthisIremainedfaithfultoDelphiwithanyversionfromnumber1tothecurrentversionXE7.AllDoberenz/KowalskiDelphibooksareinmylibrary,aswellasanythingyoucangetaboutDelphibyElmarWarkenandprettymucheverythingfromtheC&LPublishing.AlsobooksbyMarcoCantuandBobSwartIcallmyown.

Page 14: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

BynowI’vewrittendozensofprogramswithDelphi.Withityoucandeveloprobustandsophisticatedprogramswhichmorethan5,000customerswith10,000userscanacknowledge.

Page 15: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Contactinformation

Youcanfindmygeneralwebpageatwww.hastasoft.de,aspecialsitefordevelopersatwww.devpage.de,whereyouwillalsofindabriefdescriptionofsomeofmytoolsthatcanyouassistinprogramdevelopment.

Bye-mail,[email protected].

Page 16: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter1:UsingtheFireMonkeycomponents

Section1:GettingStarted

ThisbookisnotsomuchtodescribetoyouthemanynewcomponentsthatoffersFireMonkey.Forthatyoucanusethesuppliedprogramexamplesthatgiveagoodoverviewhere.Forexample,opentheincludeddemo“ControlDemo”.TheFireMonkeydemoscanbefoundas:

FromtheStartmenuselecttheEmbarcaderoprogramgrouptogotothedemodirectory(examples).

Page 17: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thisbookismoreabouttoremovethestumblingblocks,ifyouplantoconvertapreviouslydevelopedVCL-programintoaFireMonkey-programorstartnewprojectswithFireMonkey.

IfyouwanttohaveprogrammatichelptoconvertexistingVCLapplications,youcanusetheMidaconverter.ForawhiletheconverterwasasafreegiftwithpurchaseofDelphiXE7inaBASICversionhere:

InthepaidProversion(fromabout90,-€)alsothirdcomponentswillbeconverted(forexampleTMScomponents).Inaddition,thesourcecodeisrestatedasfaraspossible(siteofthemanufacturer:http://www.midaconverter.com).

InChapter1,Section5,IpresentthebasicuseoftheprogramandhavealookatthespecificsofPro/Studioversionoftheprogram.

Page 18: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section2:NewFireMonkeyproject

DoubtlessthequestionarisesofhowandwhentogointodetailabouttheindividualdifferencesbetweenWindowsandFireMonkey.

ThebestwayisprobablytosimplydescribetheusualstepsofprogramdevelopmentandemphasizethedifferencesbetweentheknownVCLcomponentsandFireMonkeycomponentsattherelevantpoints.

FireMonkeydesktopapplication(MultiDeviceApplication)

So,thereyougo.AswithanyWindowsprojectyoustartdevelopingaFireMonkeyprogramtorunbothonWindowsandtheMacunderthe“File”menuwiththecommand“NewMultiDeviceApplication”.

NewsinceDelphiXE7:Therewillbeshownatemplatesdialog,whichallowsyoutogenerateeitheran“EmptyApplication”,a“3Dapplication”oranapplicationthatalreadyhascertaincontrolsintheform:

The“EmptyApplication”correspondstotheformerHDapplicationfromDelphiXE6orearlier.Theothertemplatesyouwouldnormallyuseratherformobileapplications(i.e.iOSandAndroid).Butherewewantdevelopanormaldesktopapplication,soselectthe

Page 19: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

“BlankApplication”.ThenclickOK.

Result:

Bydefaultthe“TargetPlatforms”ontherightsideofthenodearecollapsed.Unfolded,itlookslikethis:

The32-bitWindowsplatformisenabledbydefault.Ifyouwouldcompiletheprogramnow,youwillgeta32-bitWindowsprogram.DelphihasalsobeenautomaticallyaddedaMACOSplatformandthemobileplatformsiOSandAndroid(butyoucanignorethemobileplatforms,ifyoudon’tneedit).

Page 20: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Youcouldsimplyselectoneofthelistedtargetplatformsbydoubleclickandcompileit,andyouwouldhaveacorrespondingtargetplatformapplication.TheprogramwillbeableactuallytorunonaMacoronamobiledevice,butyoustillhavetosetuptheenvironmentaccordingtoDelphi.HowtodothisfortheMAC,describedlaterinthisbook.

UsingtheMultiDeviceDesigner(FireUI)

Hereyoucannowgetstartedtoaddcomponents,settheirproperties,andwriteeventhandlerstointeractwiththeuser.Ifyoudevelopacross-platformproject,itisgenerallyrecommendedtoaddattheverybeginningaviewfortheMACOSPlatform.SoyoucanalsocompiletheMAC-versionfromtimetotimeandlook,howitworks.

However,youshouldworkasmuchaspossibleattheview“Master”andonlyusetheotherviewstomakespecificsettingsfortherelevantoperatingsystem.

Withtheleftdrop-downlist,youcanalsousethemasterviewwithdifferentstyles.

Inthevariouscreatedviews(OSX,Windows,etc.)youcanaddingcomponentsandchangetheirproperties,butnotdeletethem.Ifyouwanttoremoveacomponent,youhavetoactivatethemasterviewandthenremovethecomponent.Logically,itisthenremovedfromtheotherviews.Thesameprocedureisvalidforthenameofthecomponent:Herealsoyoucan-becausethenamemustbeunique-changeitonlyintheMasterView.

TheuseoftheMultiDeviceDesignerfacilitatesthedevelopmentofcrosscompile

Page 21: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

applicationsenormous.Forexample,thebuttonsindialogboxesarelocatedatthebottomleftonWindows,andunderMACOSatthebottomright.Also,buttonsonMACOSnormallydonothavegraphics.

SohereistheviewofadialogfrommyaccountingprogramthatisavailableforWindowsandMacOSX:

Atthebottomleftarethebuttonswiththeimages.NowtotheMACOSXview:

Page 22: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Here,thebuttonsaremovedtotherightsideandimagesintheObjectinspectoraresettoVisible=false.Thecheckboxhasbeenmovedtotheleftside.

Thenicethingis,thatyousimplycanusethedesignerhereandnothavetomakeanyprogrammatictransformationsforthedialogatruntime.Inthepastthatwasthecommonandrathertime-consumingworking-method.

ForminheritancewiththeMultiDeviceDesigner

Also,itisaspace-savingmethod,becauseDelphicreatesforeachviewaseparateformandonlythisisincludedfortheappropriateplatform.Ifyoulookatthefilescreatedonceinafilemanager,thenthislooksasfollows:

FMandant.fmxisthemasterformfile.Thisfileservesasamasterfortherespectivegeneratedplatform.SoifwehadonlythismasterformandcreatetheprogramforMACOSX,thenonlythismasterformisused.

Page 23: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

SincewewanttocreatebothaWindowsprogramaswellasoneforMACOSX,wehavehereselected“OSXDesktop”asviewintherightdrop-downlistsothatDelphithencreateaformforthisplatform.Thisisthefile“FMandant.Macintosh.fmx“.

Thespecificplatformformsworkontheprincipleofforminheritance(similarlikethe“TFrame”).WhenweopentheMACforminatexteditor,thenitlookslikethis:

Whiletheformmasterfileconsistsof250lines,thederivedMAC-formfilehasonly42lines.Thereasonis,thatonlythechangesinrelationtotherecognizedmasterformwillbesavedhere.Thebuttonisnowattherightside,insteadoftheleft,soithasadifferenthorizontalpositionandthisvalue(hereingreen)willbedetected.TheimagesymbolinthebuttonshouldbevisibleunderWindows,butnotunderMACOSXsoeventhisisnotedaccordingly(bluebackground).

Soyoucansimplymodifyforaparticularplatformtheposition,thecolor,thesizeorothercontent(e.g.textoflabels,buttons).

Reverttoinheritedsettings

Ifyouhavemadechangestoacontrolonadifferentplatformview,youcanpartiallyorcompletelyrevertthesettings,tothevaluesthatareinthemasterview.Example:

Page 24: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

HerethebuttonhasbeenmovedontheMACviewtotherightandthetextwaschangedto“MAC”.

Ifyouwanttorestoreallsettingsofthebuttonsbacktotheinitialstate,clickwiththerightmousebuttononthebuttonandselectthe“ReverttoInherited”command:

ThebuttonisthenintheMACviewagainontheleftsideandhasagainthecaption“Button1”.

Doyouwante.g.onlyrestoretheoriginaltextofthebutton,clickonceonthebuttonwiththeleftmousebuttontoselectit.Then,intheObjectinspector,right-clickontheword“Text”(ieleftsideandnotintheeditbox)andselectthecommand“Reverttoinherited”.

Thebuttonstaysontheright,buthislabelwaschangedfrom“MAC”in“Button1”.

Soitispossibleonlytobringbackindividualpropertiestotheinitialstate,ifnecessary.

CreatingaPlatform-specificeventhandlerwiththeMultiDeviceDesigner

However,theMultiDeviceDesigneroffersyetafurthersimplification:Untilnowyou

Page 25: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

haveeditedinanOnClickeventthesourcecodefortheusefordifferentplatforms.NormallyyouusetheIFDEFswitchtomakethesourcecodecompileableforeitherWindowsorforMac.Evenactuallyitmightbetherightway,ifyouhaveonlyafewdifferentplatform-specificstatementsinthecode.Butshouldthecodeverydifferentforeachplatform,youhavealotoftextintheeventhandlerandthemattercanbecomeunmanageable.ItlendsitselfdirectlytocreateaseparateeventhandlerfortheMACplatform.SoifyouhavecreatedanOnClickeventalreadyinthemaster,gototheView“MACOSDesktop”.

ThenselectthebuttonandaddintheOnClickeventsimplythewords“Mac”asviewableintheimageaboveandpresstheenterkey.AlreadyDelphicreatesanewemptyeventhandler,andyoucanfillitwithspecificsourcecodefortheMAC.

Smalldrawback:Ifthesourcecodecontainsplatform-specificcalls,youstillhavetoworkagainwithIFDEF,butonlyonce,becauseyoucansouroundthewholeinnerframewith{$IFDEFMACOS}…{$ENDIF}.

Overall,itisalwaysamatterofthecase,whichapproachisthebetter.

ThereisanotherinnovationinXE7:Foranumberofcomponentsyoucanforcertainproperties,e.g.insteadof“Top”or“Bottom”intheTTabPositionaTabControlsselecttheproperty“PlatformDefault”asinitialsetting.

SoevenifyouhaveonlyoneMasterViewanddonotgenerateplatform-specificviews,becauseofthe“PlatformDefault”anallplatformseverythingwouldbeoninitsproperplace.ThefunctionalitymentionedinthisexamplewouldbemorerelevantforiOSandAndroid,becausetherethetabsshouldbeinastandardequipmentdownorup.

Page 26: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section3:SelectedFireMonkeycomponents

Onthebasisoftheindividualcomponentsandfeaturesthatyounormallyusehere,I’mnowgoingonebyonetotheindividualcomponents.

TButton(withTrimming)

Unfortunately,theFireMonkeybuttonhasnotsomanyskills,suchasthisonefromtheVCL,whowoninthelastfewyearsenormouspossibilities.

ButthereisalsosomethingthattheVCLbuttondoesnothave:Theproperty“Trimming“.Withthatyoucanspecifyhowtodealwiththedisplayedtextofthebutton,ifthetextistoolongtodisplay.

ThedefaultsettingisnowttCharacter.Soifthetextwillbedisplayedwithaletterand3pointsbetweentheouterbuttonborder.E.g.inthetext“Repetition”like“Repet…”.

IfyouselectttNone,soitbehavesasdescribedintheVCL,textisdisplayeduntiltheborderofthebutton,thencutoff.

WithttWordifavailable,thebordertodrawingsissetatafullword-border.

So“PrintandClose”wouldbeshortenedto“Printingand…”whentheword“Close”wouldnotfitinthedisplayareaofthebutton.

Finally,aTButtoncanhavealsoaconstantlypresseddownstatus.Youcandothisbysettingtheproperty“IsPressed“,butalsotheproperty“StayPressed”mustbeenabled.

Youcan’tassignanimagetothebutton(aswellastheTSpeedButtonnot).Soyouneedtoaddanextraimageintothebuttonwhenitistohaveasymbol.

Unfortunately,theTButtonandallotherFireMonkeycomponentshasnottheproperty“Hint”.Again,initiallyremainstheprincipleofhope,thathereacorrespondingpropertywillbeaddedinthefollowingupdates.

ButyoucanusemyHS_FMXHints.pasunitwithwhichyoucaneasilyaddhintstothecontrols.LookhereinChapter6,athint24attheendofthebook.

Page 27: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TEdit(withoutPasswordChar)

Ifaneditfieldshallnotdisplayitscontents,youwillnotreachthisasintheVCLwith

Edit.passwordchar:=‘#’;

butwith

Edit.password:=True;

NewsinceXE7:Thereisanewfeature“ControlType”,whichissetbydefaultto“Styled”.Ifyousetthisto“Platform”thenativeelementistusedontheplatforminyourform(currentlyonlyoniOS).Thiscanbeanadvantageforsomethings,whenitcomesaboutbytheuseofascreenreaderorsimilarthings,oreventogeta100%integrationplatformappearance.Ifyouchoosethisoption,itisalreadyshowingthiscontrolchangesatdesigntime:

InadditiontotheTEdit,the“ControlType”propertyisalsoavailablefortheTCalendarcontrol,effectiveonlyforiOS.Imentionthisfunctionalityhere,soyouknownowthemeaning,anontheotherhand,Iassumethatovertime,furthercontrolsareprovidedwiththispropertyandifyoualsouseiOSandAndroidnexttotheMACOSplatform,thisisanimportantinformationforyou.

TForm(furthermorewithcaption)

WhileactuallyallFireMonkeycomponentsarenotusingthe“caption”property,butthe“Text”property,theformalsohasfurthermoretheproperty“caption”.

FireMonkeyformshas(currently)noKeyPreviewproperty,asintheVCLform.However,theFormcangetalsotheFormKeyDown-info,evenifanothercontrolhasthefocus.Soifyouwriteaprogramwhereitisimportanttohaveacentrallocationwherethekeyboardinputwillbechecked,soyoucouldusetheKeyEventroutineofthefocusedcontrolandthenforwardittotheform.

Withtheproperty“FullScreen”youcanhavetheformdirectlystartinfullscreenmode.

Page 28: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thispropertyisnottobeconfusedwith“WindowState”,whereyoucanbringasunderWindowsasusualthewindowtothemaximumsizeofthefreedesktoparea(wsMaximize).The“ShowFullScreenIcon”option,activatethefullscreenicononMAC(underWindowsithasnoeffect,becausethereisnofullscreeniconforthewindowarea).Atruntime,youcan-underbothWindowsandMACOSX-withthe“FullScreen:=True”or“FullScreen:=false”switchbetweenthetwomodes.

TFrame

SinceXE4framesarealsoavailable,basicallyitworkslikeinWindows.Under“File”,“New”,“Other”menu,youcanfirstcreateaTFrame.Thenyoucanclickfromthecomponentpaletteontheframeiconandattachtotheformaregioninwhichtheframeistobeinserted.Thiswillopenadialogwhereyoucanselectoneoftheavailableframes.

TPanel(nocaptionortext-property,alignwithqualifier)

Aspecialityhasthecomponent“TPanel”whichdoesnothavetheproperty“Caption”northe“Text”property.ToachievetheresultsknownunderWindows,youhavetopasteaTLabelcomponentintoit.

IfyouwanttoalignaTPanelobjectatruntime,itisnotenoughasintheVCLfrom,forexample,tosettoAlign-propertyto“alClient”.Evenhereyouhavetouseaqualifier,theterm“TAlignLayout”.

Example:Panel.Align:=TAlignLayout.alClient;

TCheckbox,TRadioButton(IsChecked)

WhenusingtheTCheckbox-componentortheTRadioButton,youdonotevenneedtosearchfortheproperty“Checked”,lookinsteadfor“IsChecked”.

Likethe(newer)VCLcomponentsalsotheFireMonkeycomponentswithtextelementshavetheproperty“Wordwrap”,whichisactuallyquiteuseful.LikeallFireMonkeycomponents,thediscussedcontrolshere,hasseveralfeaturestorepresentitsappeareance(“Styles”,e.g.“StyledSettings”,“StyleLookup”and“StyleName”,butmoreonthatlater).

TSwitch(AlternativetotheTCheckbox)

ThiscomponenthasnoequivalentintheVCL.UnderFireMonkeyyoucanuseitasanalternativetoTCheckBoxtorepresentanONorOFFstate.Theseswitchescanbefoundveryofteninmobileapplications,butnowfindtheirwayalsotothedesktop.

Thus,thecomponentlookslikethis:

Page 29: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TImage(WrapModefordisplay-modi)

WiththeVCLTImagecomponent,youcanusetheproperty“Picture”toloadanimageandinfluencethewayofdisplayitwiththeproperties“Stretch”and“Proportional”.UnderFireMonkeythereisalsoaTImagecomponent.Hereyoucanusetheproperty“MultiResBitmap”toloadtheimageintothecomponent:

Thismeans,thatyoucandirectlysaveasmanybitmapsasyouneedfortheseresolutionsaccordingtouse.Ifyoucallherethewizardforediting,youmaygetthefollowingdialog:

Hereyoucanaddindividualbitmapsbyfirstclickonthefirsticononthetopleft(forneworadd).Thenyoucanclicktheopeniconinthetextinputlinetoselectaimagefile.Bydefault,thepreviewwillnotbedisplayedontherightsideofthedialog.Thiscanbeenabledbyclickingonthemagnifyingglassiconinthetoolbar.

Note:Ifyouclickonthegreencheckarrow,aqueryarise,whethertheinformationavailableatdesigntime,aretobedeleted.Ifyouconfirmthiswith“Yes”,theinformationtothesourcedirectoryofthebitmapswillnotbedisplayedatthenexttimewhenusingthedialog.Aslongasyouarestillneedthisinformation,youshouldclosethedialogueontheredwindowclosebutton.

Atruntime,youaccesstheindividualbitmapsondemandviatheitemsproperty,egasfollows:

Page 30: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

MyBitmap.assign(Image1.MultiResBitmap.Items[0].bitmap);

Itisnotnecessarytosaveinthiscomponentimageswithvariousresolutions.Youcanalsosavedifferentpictureswithsameresolution,thusquasiachieveareplacementfortheVCLImageList.However,youcan’tenter2timesthesamescalevalue.

ItishandythatyoucandragfromWindowsExploreroranyotherfilemanagerfilesdirectlyintothisimageeditor.

Detailsandfurtherinformationyoucandisplay,bypressingtheF1keyintheopenbitmapeditordialog,yougetafairlydetaileddescriptionofthedialog.

Theproperty“WrapMode”youcanusetoinfluencethetypeofpresentation.

Thefollowingmodesareavailablehere:

WrapMode:

iwFit (Default)-adjuststheimagetothesquareofthecomponentbytheimageproportions(theratiobetweenthewidthandheight)aremaintained.

iwOriginal Displaystheimagewiththeoriginaldimensions.

iwStretch Enlargestheimagesothatitfillstheentirerectangleofthecomponent

iwTile Tilestheimagesothatitfillsthewholerectangleofthecomponent.

iwCenter Centerstheimagehorizontallyandverticallycenteredinthecomponent

TImageControl(automaticscaling)

Agraphicthatisloadedbyusingtheproperty“bitmap”,isscaledautomatically.Whenyouclickatruntimeatthedisplayedimage,afile-opendialogwillbeopened,whereyoucanloadanimageintothecomponent.Ifthisdefaultbehaviorshouldnotbegivenasastandard,youcanavoidthiswiththefollowingassignment:

Imagecontrol1.EnableOpenDialog:=false;

Page 31: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TImageViewer(picturesscaledbyuser)

TheImageViewerisaveryinterestingcomponent.Again,youloadthegraphicswiththeproperty“bitmap”intothecomponent.Bydefault,theproperties“MouseScaling”and“Mousetracking”areactivatedhere.Asaresult,theusercanscalethesizeofthegraphicwiththemousewheel,whenheiswiththemouseoverthedisplayedelement.Ifyouwanttodisablethisbehavior,youmustdisablethelast-mentionedproperties.

TImageViewer (tousewiththeLiveBindings-Designer)

Thecomponentisidealforproducingadynamiclinktoanothercomponentusingtheso-called“livebindings”.Hereisoncedemonstratedhowsuchathinggoeswiththetrackbarcomponent:

HereintheObjectinspectorwehaveclicked“Bindvisually”ontheproperty“LiveBindings”.Thiswillautomaticallyshowthe“LiveBindings-Designer”.Thereyoucannowusetheproperty“BitmapScale”fromthe“ImageViewer1”withtheproperty“Value”toconnectthe“Trackbar1”component.

JustclickontheImageViewer1elementonthe3dots,itwillpopupthenadialog“BindableMembers”.Thereselecttheproperty“BitmapScale”andconfirmwith“OK”:

Page 32: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thenclickatthe“Trackbar1”withthemouseonthe“Value”anddragitwiththemouseontothe“BitmapScale”of“ImageViewer1”andthenreleasethemousebutton.

Result:

Ifyoudothisforthefirsttime,youcanalsousealsothe“LiveBindings-Expert”.Todothis,clickintheLiveBindingsdesignerontheitem“ImageViewer1”.Thenclickontheiconwiththemagicwand.Thisopensadialogwhereyoucanspecifythesettings:

Page 33: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Select“Linkacomponentpropertywithacontrol,”andthenclick“Next”.

Inthedropdownlistselectthecomponent“ImageViewer1”.Selectthenasproperty“BitmapScale“:

Thenclick“Next”andselectonthenextpagethecontrol“Trackbar1”.Thenclick“Finish”.

Inthedesignernowyoucansee,thattheproperty“BitmapScale”fromthe“ImageViewer1”islinkedtothe“Value”propertyof“Trackbar1”.

Becausetheproperty“BitmapScale”withvalueof1standsfor100%imagesize,setthepropertyvalue“Max”ofthe“trackbar”componentalsoto“1”(ifyouwantallowmagnifications,setittoe.g.2or3).Atruntime,youcanchangethedisplaysizeofthegraphicwithusingtheslider.

Thisisveryeasytodo,andtherewasnoneedtotocreateasinglelineofsourcecodeforit.Belowtheruntimeresult:

Page 34: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TLabel(NewpropertyFontColor)

Ifyouwantedtochangethecolorofalabel,forexample,inthefirstversionofFireMonkey,youhadtocreateacustomstyleandthensettheproperty“Fill”ofthetextelementwiththedesiredcolor.SinceFireMonkey2,thisismucheasier.JustusethepropertyintheObjectinspector“TextSettings”andthen“FontColor”andselectthedesiredcolor.

Note:TheselectioninFontColoronlyworksif“StyledSettings”inthe“FontColor”optionisdisabled:

Whetherthismixingofthevarioussettings(directviaStylesandsettingsintheObjectinspector)isusefulornot,Ijustletstandthere.Anyway,youshouldknowthis,becauseotherwiseyoumaybelookingquitelong,whythecolorthatyouchoosein“FontColor”isnotdisplayed.Theproperty“StyledSettings”referstothecurrentstyle.Thiscanbethedefaultstyle,butthiscanalsobeauser-definedstyle.ThesettingsofthestyleoverrideanyothersettingswhenitisenabledhereinStyledSettings.

Page 35: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TImageList(Notavailable-butcompensationpossible)

ThesoextremelyusefulVCLTImageListthatservesasacontainerforgraphicsandiseditableatdesigntimeviaaconvenientdialog,doesnotexistunderFireMonkey.Aworkaroundcouldbe,totakeanextraformthatyoucanprovidewithmanyTImagecomponents.

IfyouboughttheFireMonkeyPackfromTMSsoftware,thereisthe

componentTMSFMXBitmapContainerofinterest.Thisgivesnamelyaneasywaytoloadonaslipmultiplegraphicsfilesatthecomponentoraddsomeone’stoit.

Todothis,clicktherightmousebuttononthecomponentandselectoneofthetoptwocommandsfromthepop-upmenu.Ifyouhavealreadyloadedfilesandwantmoretoadd,select“Addfiles”andNOT“Loadfiles”,otherwiseexistingentriesareremovedandonlythenewonesareaddedandstaysinthelist:

Youcanselectabitmapanddeleteit,usingthedeletekeyhereinthetreeview.IntheObjectinspector,youcancheckbyname,ifyou’vehitthecorrectbitmap:

Page 36: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Warning:Donotusethedialog“BitmapEditor”.Whenyoudeletethebitmapinthisdialog,thebitmapisnotremoved,butthecontentisdeleted!

Atruntime,youcanusethebitmapsfromthecontaineregtodisplaytheminagrid,hereisanexample:

Forthispurpose,theappropriatecodewouldbe:

procedureTF_MainImg.Grid1GetValue(Sender:TObject;constCol,Row:Integer;

varValue:TValue);

var

aCol:TColumn;

begin

aCol:=Grid1.ColumnByIndex(Col);

ifaCol=StringColumn1then

Value:=intToStr(Row+1)

elseifaCol=ImageColumn1thenbegin

ifRow<=TMSFMXBitmapContainer1.Items.Count-1thenbegin

Page 37: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Value:=TMSFMXBitmapContainer1.Items[Row].Bitmap;

end;

end;

end;

Anotherusefulfeatureofthecontaineris“FindBitmap”,withthatyoucanaccessthestoredbitmapbyname:

Bitmap:=TMSFMXBitmapContainer1.FindBitmap(‘computer.bmp’);

Ilikethisverymuch.ItisbetterthantheTImageListwhereyoucouldaccessthebitmapsonlywithintegervalues.

Thedemocanbedownloadedat:

http://www.devpage.de/download/fmbook3/ImageListDemo.zip

ButyouneedtheTMSFMXStringGridinstalledoraninstalledTMSPackforFireMonkey.

TListBox(noTCheckListbox,butShowCheckboxes)

Don’twastetimesosearchaTCheckListBox,thereisnotsuchacomponentforFireMonkey.Ifyouwanttodisplayalistboxwithcheckboxes,selectinsteadthe“ShowCheckBoxes”option.Quiteinterestingisperhapstheproperty“ListStyle”,herebyyoucandisplaytheentriesinthelistboxnexttoeachother(lshorizontal).

Here’sanexample:

Page 38: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AlthoughthelistboxworksingeneralthingsalsoliketheVCLcomponent(egItems.LoadfromFile,etc.),however,istodistinguishwhetheryouareworkingatthedesignoratruntimeusing“Items”or“ListItems”:

Intheillustratedlistboxontheleftside,theentrieswereaddedbyusingthe“Strings”propertyofthelistbox.InthesecondlistboxIhadclickedwiththerightmousebuttononthelistboxandthenselectthecommand“AddListBoxItem”.

Asyoucanseeinthestructure-overview,onlythesecondlistboxhasindividualentriesforeach“ListBoxItems”.SoonlyinthesecondlistboxyoucanatdesigntimeselecttheindividualListBoxItemsbymouseclickandmaketheappropriatechangestothesettingsintheObjectinspector.

Warning:ifyouinthesecondlistboxnowedittheentriesovertheproperty

“Strings”andtakethechanges,allListBoxItemswouldbeconvertedtonormalstrings,sothatalltheirprevioussettingswouldbelosttotheindividualListBoxItems.Sohereyouhavetotakecarehowtoproceed.

Hereanexamplehowtoaccesstheitems.Atdesigntime:

Page 39: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Atruntime,youcanaddresstheindividualitemsofaListBoxbothontheproperty“ltems”(=listofstrings)andthepropertiesof“ListItems”(listofTListboxItems).Seetheexamplesourcecodewiththisresult:

procedureTForm19.FormCreate(Sender:TObject);

begin

Listbox1.Items[0]:=‘Textsetvia“Items”-property’;

Listbox1.ListItems[1].Text:=‘Textsetvia“ListItems”’;

Listbox2.Items[1]:=‘Textsetwith“Items”-property’;

end;

ToreadifinaListBoxItemstheproperty“IsChecked”isset,doitlikethis:

ifListbox1.items[0].isCheckedthen…

Listbox1.items[0].isChecked:=True;

EnhancementoftheListbox-Items

BeginningwithDelphiXE4:Ifyouclicktherightmousebuttononthelistbox,youcanaddnotonlysimpletextentries,buthaveachoice:

Page 40: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

WithaTListboxGroupHeaderyoucane.g.useinthelistboxsubheadings.VeryusefulistheTSearchBox.Whenyouentertextthere,thelistboxitemswillbefilteredanddisplayedsothatonlythematchingentriesareshown.Forexample,ifthelistboxofferquitealotofoptions,theusercanenterakeywordandheimmediatelyreceivestheappropriatesettingoption.Thatissomethingcomfortable,whattheVCLlistboxdoesnotoffer!

AlistboxwithagroupheaderandaSearchBox:

AndnowthislistboxaftertheuserhasmadesometextinputintotheSearchBox:

IfyouclickatdesigntimewiththerightmousebuttonontheSearchBox,youcan,forexample,addaClearEditbuttonthatclearstheinputatruntimeinthetextSearchBoxagain.Asthefilteringhappensallautomatically,youneednotwriteasinglelineofsourcecode!

Page 41: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

NoOwnerdrawforlistboxes

Sincethereisno“OnDrawItemevent”forthelistbox,youhavetoworkwiththeappropriatesettingsfortheListBoxItemtogetthewantedrepresentation.

Explorethesuppliedexample“CustomListbox”intheexampledirectory.Youwillfinditusuallyhere:

C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\ObjectPascal\FireMonkeyDesktop\CustomListBox

Hereisthecompiledsample:

Ifyoulookatthesourcecode,youcanseehowalistboxentryisgenerated:

procedureTfrmCustomList.Button2Click(Sender:TObject);

var

Item:TListBoxItem;

begin

//createcustomitem

Item:=TListBoxItem.Create(nil);

Item.Parent:=ListBox1;

Item.StyleLookup:=‘CustomItem’;

Item.Text:=‘item‘+IntToStr(Item.Index);//setfilename

ifOdd(Item.Index)then

Item.ItemData.Bitmap:=Image1.Bitmap//setthumbnail

else

Item.ItemData.Bitmap:=Image2.Bitmap;//setthumbnail

Page 42: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Item.StylesData[‘resolution’]:=‘1024x768px’;//setsize

Item.StylesData[‘depth’]:=‘32bit’;

Item.StylesData[‘visible’]:=true;//setCheckboxvalue

//setOnChangevalue

Item.StylesData[‘visible.OnChange’]:=TValue.From<TNotifyEvent>(DoVisibleChange);//setOnClickvalue

Item.StylesData[‘info.OnClick’]:=TValue.From<TNotifyEvent>(DoInfoClick);

end;

Alsonotehoweasyitis,toassignaneventhandlertotheentry:

Item.StylesData[‘visible.OnChange’]:=TValue.From<TNotifyEvent>(DoVisibleChange);

Itisthereforeveryflexible,itmightevenbepossibletoassigntothoseentries,differenteventhandlers,dependingonthecontentormeaning.

Youwillunderstandthewholethingright,whenyouviewthepropertiesthatareintheTStyleBookused.Todothis,double-clicktheTStyleBookcomponenttotakeacloserlooktotheproperties.Inthestructureview,youcanselecttheindividualelements:

However,thereisalsoanotheroption,todrawthelistboxelement(textcolorandbackground).CheckoutHint15hereinthebook“OnDrawItemeventoftheListBoxfromVCLreplacewithOnPaintingeventoftheTListBoxItems”

Page 43: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AllComponents(excepttheform)

WhiletheTFormcontainspropertiessuchas“Left”and“Top”,allothercomponentsdoesnothavethat.Rather,hereusingtheproperty“Position”withtheXandYvaluesfortheleftandtopposition.Itshouldalsobenotedthatnoneofthemareintegervaluesbuthasthetype“extended”.

SeveralComponents(Propertieswithadditionaltype-qualifying)

InmanycomponentsyoucanuseknownpropertiesasintheVCLcomponentsintheObjectinspector.InaTMemoyoucanusetheproperty“Align”toassignthevalue“alClient”.However,atruntimeyoumustprovideadditionaltypequalifiers.

Not:memo1.Align:=alClient;

But:memo1.Align:=TAlignLayout.alClient;

Evennot:memo1.FontColor:=clRed;

But:memo1.FontColor:=TAlphaColors.Red;

Thewell-known“clColorName”oftheVLCcomponentsworkshereunderFireMonkeyalwayswithout“cl”,butwithTAlphaColorsbeforeit.

Soifyou’regoingtomakeyousupposedlycommonassignmentsandtheprogramdoesnotacceptthat,trytofigureoutwhetheranadditionaltypequalifierisrequired.

TAlphaColorsitselfisdeclaredintheunit“System.UITypes”:

TypeTAlphaColors=TAlphaColorRec;

Butifyouknowthisonce,itisOK.

However,there’salsoatricktobypasstheuseofthisqualifier:Simplylinktheunit“System.UIConsts”,thenyoucanusecolorvaluessuchas“claRed,”“claBlack”.

Uses

System.UIConsts;

memo1.FontColor:=claRed;//Alternative:

Page 44: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TMenuItem(withoutImageIndex)

Youdonotneedtosearchfortheproperty“ImageIndex”,whichdoesnotexisthere.Butyoucanusetheproperty“Bitmap”(intheVCLcomponentitis“Glyph”)toassignaimage.ItshouldalsobenotedherethatinFireMonkeycomponent“IsChecked”isusedinsteadif“Checked”.

TMainMenu(HandlingMACMenus)

Ifyoucompileyourprogram,youhaveintheWindowsversionusuallythe“File”menu.IntheMACforthecompiledversionthenameoftheprogram(thatisthe“.exefile”-withoutextension)isusedtosetthefirstmenuname.Inthis“SystemMenu”oftheprogramareusuallyonlycommandstoexittheprogramoracommandtocallasettingsdialogorthencommand“Informationabout…”.Soitisrecommendedtocreateanothermenunameasafirstentry:

IntheWindowsversionyouhavetoselect“TEditor”invisible,intheMACversion,youmakeitvisibleandhide“Exit”fromFile-menu.Heretheimplementationinthesourcecode:

procedureTF_Main.FormCreate(Sender:TObject);

begin

{$IFDEFMACOS}

mTEditor.Visible:=True;

mFileExit.Visible:=false;//fromMenuFile

{$ENDIF}

//…

end;

AndsoitlookslikeontheMac:

Page 45: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thissolutionyoucanuse,ifyouonlyhaveonemasterviewandnospecificviewfortheMACplatform.However,ifyouhaveaspecificformfortheMac,youcanalsodirecteditthepropertiesofthemenubytheObjectinspector.Inthe“OSXDesktop”viewyouchangeyousetthetextforthe“TEditor”-menutovisibleandhidethe“Exit”-entryunderfile-menu,becausetheexit-commandnormallyisinthesystem-menuunderMAC.Don’tforget,thatthenameofthefirstvisiblemenuitemisreplacedwithMACOSalwaysbytheprogramname(executable).Therefore,youshouldchoosetheprojectnameoftheapplicationcarefully.

TMemo(CaretPosition,noModified,FindNext-replacement)

UnderWindowsyoucandeterminethecurrentrowandcolumninthememoasfollows:

Line:=SendMessage(memo.handle,EM_LINEFROMCHAR,Memo.SelStart,0);

column:=Memo.SelStart-SendMessage(memo.handle,EM_LINEINDEX,line,0);

UnderFireMonkeyitworkslikethat(useproperty“caretposition”):

line:=Memo.CaretPosition.Line+1;

column:=Memo.CaretPosition.Pos+1;

ThepropertyoftheVCLcomponent“Modified”doesnotexistunderFireMonkey.Youmustinsteadmanageitbyyourselfundertheevent“OnChange”or“OnChangeTracking”.Hereyoucansetavariable(e.g.the“Tag”variableoftheTMemo),whetherthememohasbeenalteredornotandthen,forexample,resetit,forexample,ifyouhavesavedthecontentsofthememoontheharddisk.

Clipboard.HasFormat(CF_Text)-replacement

UndertheVCLthereisthe“Clipboard”,underFireMonkeynot.Althoughforthememocomponentareexistingfunctionssuchas“Memo.CopyToClipboard”or“Memo.CutToClipBoard”and“Memo.PasteFromClipboard”.Buthowtodetermineiftheclipboardcontainstext(forexample,tomakeabuttonenabled)?HereyouhavetouseaPlatformService.

Page 46: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Example(unit“FMX.Platform”isrequired):

procedureTF_Main.Timer1Timer(Sender:TObject);

var

s:String;

ClipService:IFMXClipboardService;

begin

try

ifTPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,IInterface(ClipService))

thenbegin

try

s:=ClipService.GetClipboard.ToString;

bnPaste.Enabled:=(s<>”)and(s<>‘(empty)’);

finally

end;

end;

finally

end;

end;

Spellchecking

AwholenewpossibilityarisessinceXE5withtheabilitytomakeaspellcheckforthetexthasbeenentered.

AnditworkswithaservicethatisautomaticallyavailableunderMAC.

Youenableordisablethespellcheckerjustwiththebooleanvariable“CheckSpelling”(eitherintheObjectInspectororatruntime).ForthespellcheckingaPlatformserviceisused.Thus,itcouldbeagoodideatocheckfirstwhethertheserviceforthePlatformcurrentlyusedisavailable.Toquerythis,youneedtoincludetheunits“FMX.Platform”and“FMX.SpellChecker”.Thequerylookslikethis:

IFTPlatformServices.Current.SupportsPlatformService(IFMXSpellCheckerService)thenbegin

memo1.CheckSpelling:=True;

end;

Page 47: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ForWindowsnoSpellCheckerserviceisavailable.Butinprincipleitshouldnotbedifficulttoimplementanown.Asatemplate,youcantaketheimplementationfortheMACplatformandrewriteitaccordinglyforWindows.Well,thedictionaryfunctionassuch,onemustofcoursealsocreate,buttherearealsoseveralsolutionsonthemarket.

FindNext-Replacement

UnfortunatelyfortheFireMonkeyMemocomponentwehavenotthemostusefulfunction“Memo.FindNext(Memo.text,StartPos,EndPos,SearchOptions)”available,asitexistsintheVCL.Eveninthestandardactions,thereisnocorrespondingaction.Soyouhavetouseaownsolution.Subsequently,Idemonstrateasimpleapproach,whichIhaveusedinmyprogram“TEditor”fortheMacandWindows(http://www.hastasoft.de/TEditor.htm).HereisasimplifiedversionoftheTEditorprogramfortheFindReplaceDemo:

Whenyouclickonthesearchicon(magnifyingglass),thefollowingroutineisexecuted:

procedureTF_MainFindReplace.SearchEditButton1Click(Sender:TObject);

var

P,L:Integer;

cp:TCaretPosition;

begin

forL:=0toMemo1.lines.count-1dobegin

ifcbGreat.IsCheckedthenbegin

P:=Pos(edfind.Text,Memo1.lines[L]);

Page 48: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

endelsebegin

P:=Pos(ANSIUPPERCASE(edfind.Text),ANSIUPPERCASE(Memo1.lines[L]));

end;

ifP<>0thenbegin

cp.Line:=L;

cp.Pos:=P-1;

break;

end;

end;

ifP<>0thenbegin

Memo1.SetFocus;

Memo1.CaretPosition:=cp;

Memo1.SelStart:=Memo1.PosToTextPos(cp);//-(cp.Line)-1;

Memo1.SelLength:=Length(edfind.Text);

ifcbReplace.IsCheckedthenbegin

bnReplace.Enabled:=True;

bnReplaceAll.Enabled:=True;

end;

endelsebegin

ifcbReplace.IsCheckedthenbegin

bnReplace.Enabled:=false;

bnReplaceAll.Enabled:=false;

end;

end;

end;

Thiswasthefunctionforthefirstsearchrun.Ifyouwanttosearchafterthatdirectlythenextitem,youhavetostartfromthecurrentposition,behindtheselection.

Thesourcecodeforthisisasfollows:

procedureTF_MainFindReplace.bnFindNextClick(Sender:TObject);

var

P,L:Integer;

cp:TCaretPosition;

part:String;

Page 49: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

begin

forL:=Memo1.CaretPosition.linetoMemo1.lines.count-1dobegin

ifcbGreat.IsCheckedthenbegin

ifL=Memo1.CaretPosition.linethenbegin

P:=Instr(Memo1.CaretPosition.pos+Memo1.selLength,Memo1.lines[L],edFind.Text);

endelsebegin

P:=Pos(edfind.Text,Memo1.lines[L]);

end;

endelsebegin

ifL=Memo1.CaretPosition.linethenbegin

P:=Instr(Memo1.CaretPosition.pos+Memo1.selLength,ANSIUPPERCASE(Memo1.lines[L]),ANSIUpperCase(edFind.Text));

endelsebegin

P:=Pos(ANSIUPPERCASE(edfind.Text),ANSIUPPERCASE(Memo1.lines[L]));

end;

end;

ifP<>0thenbegin

cp.Line:=L;

cp.Pos:=P-1;

break;

end;

end;

ifP<>0thenbegin

Memo1.CaretPosition:=cp;

Memo1.SetFocus;

Memo1.SelStart:=Memo1.PosToTextPos(cp);;

Memo1.SelLength:=Length(edfind.Text);

ifcbReplace.IsCheckedthenbegin

bnReplace.Enabled:=True;

bnReplaceAll.Enabled:=True;

end;

endelsebegin

ifcbReplace.IsCheckedthenbegin

bnReplace.Enabled:=false;

bnReplaceAll.Enabled:=false;

end;

Page 50: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

end;

end;

//Note:TheexampleusedintheInstrfunctionisitsownhelpfunctionthatlookslikethis:

functionInstr(AtPos:Integer;S:String;toFind:String):Integer;

var

R:Integer;

begin

S:=Copy(S,AtPos,(Length(S)-AtPos)+1);

R:=Pos(toFind,S);

ifR<>0thenResult:=R+AtPos-1elseResult:=0;

end;

Ifyouwanttoreplacetheselectedtext,clickon“OK”,thenthefollowingroutineisexecuted:

procedureTF_MainFindReplace.bnReplaceClick(Sender:TObject);

begin

ifMemo1<>NILthenbegin

ifAnsiuppercase(Memo1.SelText)=Ansiuppercase(edFind.text)thenbegin

Memo1.DeleteSelection;

Memo1.InsertAfter(Memo1.CaretPosition,edReplace.Text,[TInsertOption.ioSelected]);

end;

end;

end;

Hereisatypicalcliffbythewayonceagain.Ittakessometime,untilIfindoutthatIhavetouse“TInsertOption”asaqualifier.Anyway,youcandownloadthesimplifiedFindReplaceDemo(whichthenalsocontainsthesourcecodefortheclickonthebutton“ReplaceAll”)frommyhomepage.Intheroutine,youwillthenfind3positionswhere“Application.ProcessMessages”isexecuted.Sometimesthisfunctionisneeded,whenanyinteractionshastotakeplacewiththehostsystem,e.g.tosetthepositionofthecursor.

Here’sthelinktodownloadthedemos:

http://www.devpage.de/download/fmbook3/FindReplaceDemo.zip

Page 51: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ofcourse,italsoworksontheMAC.

Bytheway,aREDOfunction(likeonVCL)isnotavailable.

PrintingaTMemo

PrintingamemoisunderFireMonkeyunfortunatelyabitmorecomplicated.WhileundertheVCLcomponentfunctionssuchas“Canvas.textout(x,y,‘Text’)”,etc.wereavailableandhavefunctionsthatcauseanautomaticlinebreakforlongertexts,hereyoumustcalculatethisbyyourown.

ThefunctiontouseunderFireMonkeyisCanvas.Filltext().

ItshouldbenotedthatthedataforthepagewidthandheightaredifferentontheMacbyafactorof10,whichistakenintoaccountinthecalculationwithcorrespondingIFDEF’s.SohereisasimpleexamplethatworksonbothWindowsandtheMac(theunitFMX.Printerrequired):

procedureTF_Main.mPrintClick(Sender:TObject);

var

r,rPage:TRectF;

i:Integer;

tf:tfilltextflags;

a:TTextalign;

T,th:Extended;

sl:TStringList;

z:Integer;

functionGetFormattedLines(s:string):TStringList;

var

x,L,p:Integer;

pw:Extended;

label

StartAgain;

begin

sl.Clear;

ifS=”thenbegin

Page 52: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

sl.Text:=#13#10;

Result:=sl;

exit;

end;

{$IFDEFWin32ORWin64}

pw:=(rPage.Right-rPage.Left)-100;

{$ENDIF}

{$IFDEFMACOS}

pw:=(rPage.Right-rPage.Left)-1;

{$ENDIF}

StartAgain:

forL:=1toLength(s)dobegin

ifPrinter.Canvas.TextWidth(Copy(S,1,L))>pwthenbegin

forP:=LDownto1dobegin

ifS[P]=‘‘thenbegin

sl.Add(Copy(S,1,P-1));

S:=Copy(S,P+1,Length(s));

GotoStartAgain;

end;

end;

sl.Add(Copy(S,1,L-1));

S:=Copy(S,L,Length(s));

GotoStartAgain;

end;

end;

ifS<>”thenbegin

sl.Add(s);

end;

Result:=sl;

end;

Page 53: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

begin

ifActiveMemo<>NILthenbegin

ifPrintDialog1.Executethenbegin

tf:=[];

a:=TTextAlign.taLeading;

sl:=TStringList.Create;

withPrinterdobegin

{$IFDEFWin32ORWin64}

r:=RectF(200,200,(Pagewidth-200),(PageHeight-200));

rPage:=RectF(200,200,(Pagewidth-200),(PageHeight-200));

{$ENDIF}

{$IFDEFMACOS}

r:=RectF(20,20,(Pagewidth-20),(PageHeight-20));

rPage:=RectF(20,20,(Pagewidth-20),(PageHeight-20));

{$ENDIF}

BeginDoc;

th:=canvas.TextHeight(‘Test’);

T:=0;

fori:=0toActiveMemo.Lines.Count-1dobegin

sl:=GetFormattedLines(ActiveMemo.Lines.Strings[i]);

forz:=0tosl.Count-1dobegin

T:=T+Th;

ifT+th+th>=rpage.Bottom-rpage.Topthenbegin

T:=0;

r.top:=rPage.top;

Printer.NewPage;

end;

r.top:=r.top+th;

Page 54: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Canvas.FillText(r,sl[z],True,1,tf,a,a);

end;

end;

Canvas.Font.Family:=ActiveMemo.Font.Family;

Printer.ActivePrinter;

EndDoc;

end;

end;

end;

end;

TDropTarget(howDrag&DropworksinFireMonkey)

WhohasbeenprogrammedwithWindowsandtheVCLcomponentsmayknowthatonehadtoactivatedraganddropwiththeWindowsExplorerintheapplicationonlyoncebycallingthefunction“DragAcceptFiles”.ThenwehadtoensurethatthemessageWM_DROPFILESwasprocessedintheformandwriteaneventhandlerforit.Alittlebitcomplicated,Imean.

Soherewetakealookatthesupplied“ControlsDemo”,Imentionedbefore.Generally,itisthought,thatoneusestheTDropTargetcomponentinitsapplication,wheretheusercandrag&droponeormorefiles(butyoucanalsousenormalcomponentsonwhichyoucandraganddropanything).Soatruntime,movetherectangleorthecircleonthedroptargeticonandreleasethemousebutton.Intheeditboxisthendisplayedasaresulttheclassnameofthedraggedelement.

Let’sseeintheDragOvereventoftheDropTargetinside:

procedureTfrmCtrlsDemo.DropTarget1DragOver(Sender:TObject;

Page 55: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

constData:TDragObject;constPoint:TPointF;varOperation:TDragOperation);

begin

Operation:=TDragOperation.Link;

end;

Withthatwetelltheprogram,thatthedropoperationis“allowed”.Bydefaultthedefaultvalueof“Operation”is“None”,whichmeans,thatitisnotallowed.Inadditionitexistsyet“Move”and“Copy”.Aspecialvisualfeedbackyouhave(underWindows)onlywhenyoudragafilefromExplorerontothetarget:

ForMacOSX,anappropriateiconappearsevenwhenyoudragthecomponentsinsidetheform.

Bytheway,doesthedemoworksonlysinceXE7,inallpreviousversionsofthedemo,theproperty“HitTest”ofaparentcomponentwasdisallowed,sonoevaluationofthecorrespondingmouseactionswasprocessed.

Whentheproperty“Filter”isempty,alldraggedfilesareaccepted.Doyouwant,thatonlycertainfiletypescanbedraggedonthedroptarget,enteranappropriatefilter.Soyouchangethesettingofthefilterto“*.txt”inWindowsorMAC,ifonlytextfilesshallbeallowedfordrag&dropactions.

Butdonotusethepipesymboltoseparategroups,useinsteadonlythesemicolon:“*.EXE;*.DOC;*.PAS”.

Note:Currently(03/10/2015)thefilterdoesnotwork,duetoabuginDelphi.IhavemadehereaentryforQualityCentral,IhopetherewillsoonbeaBugFix.

Thearrowisanimatedanditappearsthesymbol“Link”(or“Copy”or“Move”),whichmeans,thattheDropTargetwillacceptthefiles.Nowthequestionis,howtoevaluateit,whentheuserreleasedthemousebutton.Unfortuanallyforthedemowasnotcreateda

Page 56: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedurethatshowstheevaluationoftheDragDropeventonce.Iherebydeliverit:

procedureTfrmCtrlsDemo.DropTarget1DragDrop(Sender:TObject;

constData:TDragObject;constPoint:TPointF);

var

I:Integer;

begin

forI:=Low(Data.Files)toHigh(Data.Files)do

ShowMessage(Data.Files[i]);

end;

Theonthetargetdroppedfilesareincludedin“Data.Files”,where“Files”anisanarrayofstrings.IntheprocedureaboveIshowyouhowtogetaccesstoit.OfcourseitwillworkalsoontheMac:

UnfortunatelyIcannotcopythelinkarrowthatappearssimilartoWindows,withtheMACscreenshotprogram.Itcanbeseenhereonlyweakthenameofthedraggedfile.

Hereagain,thefilenameisdisplayedwhenyouhavedroppedthefilesontheDropTarget.

Page 57: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ofcourseyoucanalsodraganddropsomefilesonanormaleditbox.Toseehowtodothis,lookattipR31below.

So,nownothingshouldpreventyou,tousedraganddropinyourapplications.

TRichEdit(Notavailalbe-butreplacementvia3rd-partypossible)

ARichEditcomponentisforFireMonkeynotyetavailable,youhavetouseacomponentfromthirdparties.Mygreathopeishere,thattheTRichViewcomponentsusedbyme(withthatisalsowrittenmywordprocessorprogram“Tipptext”)willsoonbeavailableforFireMonkey.Accordingtothemanufacturer(withwhomIamine-mailcontactforyears),itisplannedtoimplement,butitisbe“notsoon”.Update:(03/10/2015)ThemanufacturerhasnotyetstartedtodevelopaFireMonkeyimplementation.Itmightbeworthwhile,therefore,tolookaroundforalternatives.

Andinfact,thereisrecentausefulRichEditcomponentfromTMSavailable,theTAdvRichEditor:http://www.tmssoftware.com/site/advricheditor.asp.

IdepositedashortvideoonYoutube:

https://www.youtube.com/watch?v=_BjlRX_CjX4

Recently,thereisevenaspellcheckeroffered,whatisreallyhelpful.

TPageControl(Notavailable-butreplacementavailable)

ThisunderWindowssoextraordinarilyusefulcomponentcannotbefoundatFireMonkey,however,theTTabControlcomponentprovidesareasonablecompensation(seebelow).

TStringGrid (worksdifferent)

ThiscomponentisalsoveryoftenusedinVCLprograms.LiketheFireMonkeylistboxalsotheFireMonkeyStringGriddoesnothaveanOwnerDrawevent(butanOnPainting-event,latermoreonthat).

WhenyouinsertanewStringGridintheform,youwillgetthissituation:

Page 58: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Asyoucansee,thegridelementcontainsnocolumns.YouwillalsointheObjectinspectornotfindaproperty“Columns”.

Youcanaddcolumns,byclickingontheStrinGrid-componentwiththerightmousebuttonandfromthecontextmenu,selecteithertheentry“ItemsEditor”or“AddTStringColumn”command.

Howyoucanseebelow,wehaveaddtwocolumnswiththeentryeditor.Youcannowclickona“StringColumn”andsetdifferentproperties,forexample,theproperty“header”.Theheaderisactuallynottherownumberzeroofthegrid,butaseparateelement.Theheaderyoumayshoworhidewiththeproperty“ShowHeader”.

Theproperty“RowCount”existsalsointheFireMonkeyStringGrid.Bydefault,agridhasinitially100lines.Therefore,theassignmentshereinthe“FormCreate”shown,areworkingcorrect:

Page 59: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Assignmentsmade,withoutaddingColumnsbefore,wouldnotwork.Thecolumnscanofcoursealsobegeneratedonlyforthedurationoftheprogram,ifnecessary.

Buthowcanthefontdisplay(e.g.bold,font,fontcolor)bechanged?

TheStringColumncomponenthasnotafont-property,buttheStringGrid-componenthasoneunder“Textsettings”.Butallthesettingsyoucanmakehere,arevalidforthewholegrid.Ifyouwantitdifferentforoneormorecolumnsorcells,youcanusethe“OnDrawColumnCell”event.

Example:

procedureTForm9.StringGrid1DrawColumnCell(Sender:TObject;

constCanvas:TCanvas;constColumn:TColumn;constBounds:TRectF;

constRow:Integer;constValue:TValue;constState:TGridDrawStates);

var

Flags:TFillTextFlags;

ar:TRectF;

begin

Flags:=[TFillTextFlag.ftRightToLeft];

canvas.BeginScene;

ar:=bounds;

ar.Inflate(-1,-1);

Page 60: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

canvas.ClearRect(ar);

canvas.Font.Style:=[TFontStyle.fsBold];

canvas.Fill.Color:=TAlphaColors.Red;

canvas.FillText(bounds,Value.ToString,True,1,flags,TTextAlign.taTrailing,TTextAlign.taCenter);

canvas.EndScene;

end;

Theresultlookslikethis:

Soasrequested,thetextoutputisinboldandinredtextcolor.Onenote:thereisaseparateeventfordrawingonthecolumnheader:“OnDrawColumnHeader”.

Youcanthendrawthetextofthecolumnleftorright,orcentered,dependingontheprogramlogic.Andyousetthisbyusingthedifferent“TTextAlign”parameters,eg“TTextAlign.taCenter”forcenteredtext.

TGrid(ImageandotherelementsintheGrid)

WhatyouhavedoneinVCL(String-)Gridcomponent,withthe“OwnerDraw”events,forexample,displayingimagesorcheckboxesyoucandoeasilywiththeTGrid.BesideTStringColumnsyoucanalsouse“TImageColums”or“TCheckBoxColums”.

ClickwiththerightmousebuttonontheTGridandselecttherequiredentry:

Page 61: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

InXE7(andalreadyinXE6)isnewherethe“TDateColumn”and“TTimeColumn”.Theremarkablethingis,whenyoueditthesefields,specificeditorsareofferedtherefore(aTDateEditandaTTimeEdit).

Todisplaytextorimages,youdonotuse“OnApplyStyleLookUp”eventbutthe“GridGetvalue”event.

Thefirstpictureshowstheformindesignstateandthesecondatruntime:

Hereyoucanseethesourcecodeused:

procedureTForm2.Grid1GetValue(Sender:TObject;constCol,Row:Integer;

Page 62: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

varValue:TValue);

var

aCol:TColumn;

begin

aCol:=Grid1.ColumnByIndex(Col);

ifaCol=StringColumnTextthen

Value:=intToStr(Row+1)

elseifaCol=ImageColumn1thenbegin

ifodd(Row)then

Value:=Image1.Bitmap

elseValue:=Image2.Bitmap;

end;

end;

Dependingontheprogram-logicyouneed,youcanshowimages,textorcheckboxes.SowiththeTGridaveryflexiblecomponentisprovided,whichisultimatelymuchmorepowerfulthantheVCLTStringGrid.

TStringGrid-alternative (TMSFMXGrid)

Asalong-timeuseroftheTMScomponentsIwillgladlyreferyoutoanalternativethatcouldmakethethetransitionfromtheVCLStringGridtoaFireMonkeyGridmoreeasyly:TheTMSFMXGridwhich,inadditiontotheusualVCLproperties(ColCountDefaultRowHeight,etc.)hasmanyotherskills(suchasexporttoanExcelfile),youusuallycanhardlyfindelsewhereanyway.Formoreinfo:

http://www.tmssoftware.com/site/tmsfmxpack.asp.

Thereareprovidedanumberofdemosthatyouwillfindafterinstallingthegrid-componentunder

C:\Users\Public\Documents\tmssoftware\TMSFMXPackDemos

WiththeexporttoExcel,youcan,forexample,lookhowthisworkswiththeXLSIOdemounder

Page 63: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

C:\Users\Public\Documents\tmssoftware\TMSFMXPackDemos\TMSFMXGridFeatureDemos\XLSIO

TheExcel-filegeneratedbytheTMSFMXGrid:

Icanopenexactlyinmyspreadsheetprogram(PC-Spreadsheet-andofcourseinExcelitself):

ToaddressthecapabilitiesoftheGridmoreindetailhere,isbeyondthescopeofthebook.Butthat’salsonotnecessary,becauseintheWindowsprogramgroupyouwillfindalinktoadetailedPDFdocumentationofthegrid(over130pages):

Page 64: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

THeader(nosections,butitems)Thecomponentherealsoexists.IntheVCLwehavesections,hereinFireMonkeywehave“Items”instead,whichare“THeaderItems”.

THeaderControl(isnotavailableunderFireMonkey)

ThiscomponentdoesnotexistunderFireMonkey.UseTHeadertherefore.SincetheindividualTHeaderitemsalsoworksasacontainer,youcaneasilyinserthererequiredelements,suchascheckboxesorbitmaps.

TProgressBar (not“position”butvalue)ThiscomponentworksinessentialliketheVCLcomponent,butyoudonotuseinFireMonkeycomponentstheproperty“Position”,but“Value”.Positionis,afterall,usedwithPosition.xandPosition.ytosetthehorizontalandverticaloffsetofthecomponent.

TTabControl(noOwnerdraw)

ThiscomponentworksmuchliketheVCLversion.SothismeansthatyougenerateindividualTTabItemelementsandtheninserthereyourcomponents.YoucanTTabItemsofcoursefirstcreateatruntimeandthenpasteintotheTTabControl.

An“OwnerDraw”propertyandan“OnDrawTab”eventdoesnotexist,butyouhavea“OnPaint”andan“OnPainting”event,whereyoucanusethecanvastodrawtext.BesidethisthereexistalsothecorrespondingStyles“TabControlStyle”and“TabItemStyle”throughwhichyoucanmakethecorrespondingopticaladjustmentsviathe“OnApplyStyleLookup”event.

TTrackbar (helpfulproperty“tracking”)

TheFireMonkeycomponentcontains,incontrasttotheVCLcomponent,theproperty“Tracking”.Ifyousetthisto“False”,thismeans,thattheOnChangeeventisonlytriggeredwhenthemoveoftheTrackbuttonhasbeencompleted.Thiscanbeespeciallyhelpful,ifeventheslightestchangeinpositionisassociatedwithaprogramtaskthattriggersaveryintensiveprocess(e.g.complexgraphicsroutines).Thentheeventisfiredonlyjustwhenthemovingofthetrackbuttonisdone(theuserhasreleasedthemousebutton).

Page 65: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TSpeedButton(withoutBitmap)

WhileintheVCLcomponentwiththeproperty“Glyph”ofthespeedbutton,animagecanbeassigned,thisisunderFireMonkeyunfortunatelynotpossible.ButtheFireMonkeybuttonworksasakindofcontainer,youcaninsertaTImagecomponent,andthenusethisasbuttonimage.

Tomakethejobeasier,youcancreateacomponenttemplatefromtheFireMonkeycomponents.Soselectthebutton,whichincludestherelevantitemsandchoosefromthemenu“Component”thecommand“CreateComponentTemplate”.Inthedialogthatappears,enterthenanappropriatenameandclickOK.

Asofnow,thenewcomponentisavailableontheToolPalette.Ingeneratingthetemplate,youshouldensure,thattheindividualelementsarenotyetconnectedtoeventhandlers.Foreventhesourcecodewouldotherwisecopied(whichmightbeusefulonlyinspecialcases).

TStatusbar(awaytocompensatethemissing“Panels”)

IntheVCLstatusbaryoucandisplayatexteitherontheproperty“Panels”orviathe“SimpleText”property.IntheFireMonkeystatusbarthereisnothingofthesort,notextproperty.Soyoucouldusethestatusbarascontainerandthere,forexample,insertLabels.

Bettersolution:JusttakeaTGrid!Asyoucanseeinthescreenshotshownbelow,IhaveincludedintheStatusBaraTGrid.IntheTGridIhave2TStringColumns,aTImageColumn,againaTStringColumnandaTProgressColumnadded.

IntheObjectinspector,IhavesetfortheTGrid:

ShowHeader=false

Page 66: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Canfocus=false

HitTest=false

ShowHorzLines=false

ShowScrollbars=false

ShowSelectedCells=false

DisableMouseWheel=true

Furthermore,onemusthaveauserdefinedstyleforthegridtocreateandchangethesettingsthereunder“content”for“focus”and“selection”fortheFillColor,otherwisethegridwillappearinasortofbluishcolor:

Page 67: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AtruntimeyoucanthensettherequiredvaluesforthecorrespondingTColumnsinthe“OnGetValue”eventoftheTGrid.Inthefollowingexample,wecallthefunction“Grid.Repaint”inatimer(callevery500ms).Thiscausesthen,thatthe“OnGetValue”eventistriggeredwhereyoucandothefollowing:

procedureTF_Main.gStatusGetValue(Sender:TObject;constCol,Row:Integer;

varValue:TValue);

var

aCol:TColumn;

begin

aCol:=gStatus.ColumnByIndex(Col);

ifaCol=StrPosthenbegin

Value:=‘Row,Col:‘+IntToStr(Memo1.CaretPosition.Line+1)+‘,‘+IntToStr(Memo1.CaretPosition.pos+1);

end;

ifaCol=strSizethenbegin

value:=‘Len:‘+intToStr(length(memo1.text));

end;

ifaCol=ImgInfothenbegin

iflength(memo1.lines.text)>10thenbegin

Value:=Image1.Bitmap;

endelsebegin

Value:=NIL;//ImgINfo.Width:=0;

end;

end;

ifACol=progressInfothenbegin

VAlue:=Memo1.PosToTextPos(Memo1.CaretPosition);

end;

end;

Atruntime,itlookslikethis:

Page 68: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Intheexampleabove,therow,thecolumnandthelengthofthetextaredisplayedinthestatusbar.Ifthetextislongerthan10characters,theyellowwarning-imageappears.Thegreenprogressbarshowsalwaysthetotallengthofthetext.

Note:Thisdemoisusedonlytodemonstratethebasicoperations.Whetherthiscouldreallybeausefulsolutionforyou,willdependonyourneeds.

TheStatusbarwithTGridsolutionisalittleeffort,butitismucheasiertohideaTColumn,insteadofworkingwithagroupofTLabels.Alsoitisaneasywaytoshowimages,processindicatorsortext.

Theprogramcanbedownloadedasademo,under

http://www.devpage.de/download/fmbook3/StatusbarDemo.zip

MessageDlg (e.g.notdirectlyusablewithmtWarning)

Withthisdialog,thereisaproblem,ifyoutrytouseitlikeintheVCL.

WhatworkedhereunderWindows:

ifMessageDlg(‘Info’,mtWarning,[mbYes,mbNo],0)=mrYesthenbegin

//dosomethingornot

end;

doesnotworkwithFireMonkeyso.

Page 69: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Hereitshouldlookasfollows:

ifMessageDlg(‘Info’,TMsgDlgType.mtWarning,[TMsgDlgBtn.mbYes,TMsgDlgBtn.mbNo],0)=mrYesthenbegin

//dosomethingornot

end;

Soheretoo,thequalifiersareagainrequired…

Ihavesometimeneededtofigureouthowitworks.Thisshouldbesparedtoyouwiththisinformation.

Page 70: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section4:TheFireMonkeyStyle-Designer

a)UsingtheStylesEditor

Double-clickonapossiblyexistingStyleBookorright-clickonacontrolandselectthecommand“EditCustomStyle”ifyouonlywanttochangethestyleforacomponentorselect“EditDefaultStyle”,ifyouwanttochangethedefaultforallcomponentsofthistypeinthecurrentproject.

Youwillthenseethefollowingscreen:

Ontheleftside,inthetreeview,youcanselecttheindividualstylesandassignappropriatevaluesintheObjectinspector.Overthetreeviewontop,thereisabutton,whichallowsyoutodeletelayoutelementsfromthetreeview.

Page 71: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Anddeletingelementsworksonlywiththisbutton,thedeletekeydoesnotworkhere.

TheStyleBookandthestyleshavefortheworkwithFireMonkeyaverygreatimportance,sincethiswayisoftenusedtoachievethesameopticalresultsthatcouldbeachievedintheVCLcomponentsusingtheOwnerDraweventsotherwise.

WhenyouhavecalledthestyleeditorunderDelphiXE2,thecontrolwasthenselectedinthetreeviewandinthemiddleoftheIDE-windowthecontrolitselfwasdrawn.UnfortunatelythatissinceXE3notmoreso.Onthelefthandside,onlythestructurelistisshownandnoitemisselected.Accordingly,thestyleelementisnotdisplayedinthemiddleofthewindow.Ifthestructurelistisslightlylonger,it’snotsoeasytofindthedesireditemquickly.Manyuserunderstandsnotatallwhattheycandohereatthisplace.

AlittlehelpyoucangetwiththeusingofDDevExtensionsbyAndreasHausladen.ThisisafreeDelphiextensionthatintegrateinDelphia“StructureViewSearch”:

Overthetreeviewasearchboxisinstalled,whereyoucansearchforthenameoftheelement.Soifyouaresearchingfor“listboxItem7style1”inthesearchline,itissufficientwhenapartterm“7style1”isenteredandyougetdirectlythedesiredelement.Byclickingtheentrywiththemouseorpressingenter,theitemwillbeselectedinthetreelistandthecorrespondingobjectisdisplayedinthecenterofthewindow

ClickheretodownloadtheDDevExtensions.:

http://andy.jgknet.de/blog/ide-tools/ddevextensions/

b)StylesinFireMonkey-anoverview

A“Style”describesaparticulartypeofrepresentationofacontrol,aform,oranentireapplication.SuchstylesalsoknownintheVCL.SinceXE2inaVCLapplication,thereisunder“Project,options,applicationappearance,”theabilitytoselectaparticularstyleforWindowsapplication.WiththefollowingXEversionsthethingsofarhasbeenrefinedonVCLside,becauseeachcontrolhasreceivedtheproperty“StyleElements”.Thisallows

Page 72: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

youtospecifyhowtodisplayelements(clientarea,borders,fonts)andifthestyleshouldbeapplied-ornot.AsimilarpropertyofcomparablemeaningisalsoavailableforanumberofcomponentsinFireMonkey:“StyledSettings”

FireMonkeyandVCLhavesofarmovedcloserbythetime,thatsinceXE3theBitmap-StyleDesignerisavailabletoedittheVCLstylesandyoucansavetheseVCL-stylesasFireMonkeyStyles,too.

Let’slookfirstofallatthebasicsoftheFireMonkeystyles.FireMonkeystylesareincludedwithDelphiandshippedasstylefiles.YoucanfindtheseinXE7e.g.under

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\Redist\styles\Fmx

Thesearetextfiles,whichyoucanloadintoatexteditor.Loaditonce,togetanideaofsuchafile.InyourprogramyoucanloadthisstylefileseitheratdesigntimeinaStyleBookcomponentoratruntime.

Inaddition,thestandardstylesareintegratedalongsidealreadyfixedinDelphi.Evenifyouputnostylebookonyourform,thereisalreadyastandardstyle,whichalwaysisusedwhenyoudon’tloadanotherstyle.ThisstandardstylethenensuresthatyourprogramlooksasatypicalWindowsprogramunderWindowsandundertheMacasatypicalMACOSXprogram.

Howdoesitworknow,thataTButtonwillbedrawnwiththehelpofstyles,sothatitreflectsanormalstate,afocusedorapressedstate?

Well,beforeIanswerthat,letmeremarkthathereisshownthehighdynamicsinthedevelopmentoftheFireMonkeyframework.InXE2toXE4therewasalwaysanothertechnicalsolutionforthat.I’llspareyouthedetails(referifnecessaryonmybookstothecorrespondingversions)andshowhereonlyasitproceedsunderXE7:

ThebackgroundofTButtonsisdefinedin“background”,wherethebackgroundisa“TButtonStyleObject”.Thisobjectcontainsareferencetoasectionofabitmap.Ifyouclickon“background”,thenyoucanfindintheObjectinspectortheitems“NormalLink”,“Focusedlink”,“HotLink”and“PressedLink”thatallas“TBitmaplinks”aredefined:

Page 73: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifyouclickonsucha“TBitmapLink”,youwillgetthefollowingview.Thereferencestothestylebitmap,youwillfindunder“SourceRect”:

Bytheway,youcanalsofindfortheTSpeedButtona“FocusedLink”,butithasthesamesource-positionasthe“NormalLink”,becausethestate“Focused”doesnotexistfortheTSpeedButton.

Page 74: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Asmentionedearlier,inthestylesforXE2ithasnobitmap-links.ItstartswithXE3.Thismakesitpossibletodrawtherepresentationofthecomponentsmorequicklybecauseitiseasiertouseareadybitmapforthedrawing,astodrawacompicateappeareanceatruntime.

Youcaneasilycreateyourownbitmapstylebysavingthe“Windows7Style”bitmap(orthe“Windows8desktopstyle.png”asafile,changethecolorbalanceinagraphicseditorandthenuploadthemodifiedfilebackwiththebitmapdialog.

Youwillgetaccesstothebitmapovertheproperty“MultiResBitmap”.HereintheObjectinspector,clickonthebuttonwiththe3points.

Thefollowingdialogappears:

Clickonceonthebitmapthatisshowninthedialogabove.Hereyouhavethenagainaproperty“Bitmap”intheObjectinspector.Clickalsohereonthebuttonwiththethreepoints,the“BitmapEditor”willbeshown,whereyoucanloadandsavetheimage:

Page 75: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

OnYouTubeyouwillfindalsoashortvideoforit(Germanlanguage):https://www.youtube.com/watch?v=gcMPZQiVR-w

HereIhavedonethisoncewithmyprogram“PixPowerPhoto&Draw6.x”(command“Specialcolors”):

ThetrickhereistosavethebitmapasaPNGfileandthenloaditgainasaPNGfileintothe“BitmapEditor”dialogofDelphi,otherwiseitwillnotwork.Withtheeditedbitmaphere,buttonsareunderWindowsthene.g.displayedinalightblue,andselectedorfocusedwithaslightorange(youmayneedtoclosetheformandreopenitagainforthechangestobeapplied).

Page 76: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Knowledgeofthestandardstylesisimportantifyouwanttocreateacustomstyleforacomponentforexample,aTButton.

ThestructureofabuttonstyleisstilldifferentifyouareusingthesuppliedFireMonkeystyles.Ifyou,forexample,loadthe“DarkStyle”intoastylebook,yougetfortheTButton

thefollowingstructurepresentedtheinthetreeview:

HereconsiststhebackgroundsimplyofaTRectanglethatcontainstwoTColorAnimationsandaTGlowEffect.Thefilecontainsnostylebitmap.Soyoucansee,thatthereareultimatelyseveralwaystodefinetheappearanceofacomponent.Ingeneral,itisworthtolookonceatthebasicstylesoftheindividualcomponentsinthestyleeditor,thatwillincreasesourunderstandingoftheuseofFireMonkeycomponents.

Anothernoteaboutthe“MetroplisXXX.Styles”.TheMetropolis-stylefilesalsocontainastylebitmap.However,thisiswithapproximately935pixelsx907pixelssignificantlylargerthanthebitmapWindows7Style(400x400pixels).FortheBlue-styleitlookslikethis:

Page 77: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

c)ConvertVCLStylestoFireMonkeyStyles

Veryuseful,thatyoucanconvertVCLStylesinFireMonkeystyles,anduseitinFireMonkeyapplications.

Proceedasfollows:InDelphi,youcallinthe“Tools”menuthecommand“BitmapStyleDesigner”.Thenopene.g.under

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\Redist\styles\vcl

Luna-Style(Luna.vsf).

Inthe“File”menu,thencallthecommand“SaveAs”.Inthedialogthatappears,thenselectthefiletype“FireMonkeyStyle”:

Savethefiletoafolderofyourchoice(preferablyinonethatisnotdeletedwhenyouuninstallDelphi).

InaFireMonkeyproject,youcanthenloadandusethisstylefileinastylebook.Itwilllooklikethis:

d)UsingFireMonkeyStyles

Page 78: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Howdoesyourapplicationnowcometothestyleyouwant?Thereareseveralpossibilities.Eitheryouloadoneofthesuppliedstylefilesinastylebookcomponentthatyouputonyourform(donotforgettoassigntheformproperty“StyleBook”withthenameofyourstylebookcomponent).

OryouprovideoneormorestylefileswithyourapplicationandthenloadthewantedatruntimeintotheStyleBook.Thus,e.g.theusercanselectastylethathelikes.

Youcandothis,forexample,likethis(thepathmustofcoursebeadaptedtoyourprogramenvironment):

StyleBook1.Resource.LoadFromFile(‘D:\LunaStyle.style’);

Ifyouwanttoassignthestyletotheentireapplication,sothatmultipleformsthataregeneratedatruntimelaterhasaconsistentstyle,usingforthispurposetheTStyleManager,egatthecreateeventofthemainform:

TStyleManager.SetStyleFromFile(‘D:\LunaStyle.style’);

Forgettingthistowork,youmustincludetheunit“FMX.Styles”inyourunitslist.

Page 79: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section5:ConvertVCLprogramsintoFireMonkeyprograms

IfyouhavedevelopedaWindowsVCLprogramwithperhapsmorethan100,000linesofcodethathasevenoverseveraldozenforms,thequestionariseshowtochangeallthistotheFireMonkeyplatform.

Onepossibilitywouldbetostartfromscratchagain,sodesigningnewforms,usecopyandpasteandcodeaslongasit’sgoingtotake.Itellyou,forgetaboutthis.Withasmallapplication,onecoulddoitthisway.Butwhatreallyneedstime,istodesigningforms,entertextandgraphics,dotheassignmentsofeventhandlers,andsoon.Aprogramthatyouhavedevelopedovertheyears,youdonotwanttodevelopagain,evenifitmighttakeayear“only”.

SoyouneedtoworkwithsolutionsthatassistyouinconvertingaVCLprogramintoaFireMonkeyprogram.

a)WorkingwiththeMidaBasicEdition

OnacquisitionofDelphiXE7youcandownloadfromtheEmbarcaderoDeveloperNetworkMidatheconverter.

Afterrunningthesetup-program,intheintheDelphimenu“Tools”youwillfindthenewcommand“Mida-VCLtoFireMonkey”.

Page 80: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Theworkwithitisverysimple:

With“SourceDirectory”,youselectyourVCL-projectdirectoryandwith“Destinationdirectory”theplacewheretheprogramwillbestoredasFireMonkeyversion.Afterhat,clickon“ConvertProject”.

TheRegister“CustomComponent”isintheBasicversionwithoutfunction,whatit’sallabout,IwillreportlaterinmyremarkstothePro/Studioversion.Thesameappliestothetab“Options”,whereyoucandisableorenableonlytheuseofLiveBindingsBasic.

ThebluebarindicateshowmuchVCLcomponentscanbeidentifybytheprogram.Soifyouclickonthebutton“ConvertProject”,aredprogress-barappearsduringtheconversionprocessinadditiontothebluebar.ThisreflectshowmuchVCLcomponentscouldbeconvertedintoFireMonkeycomponents.

YoucannowgotoDelphitothedestinationdirectoryandopentheFMX-projectfile.Foramoreextensiveprojectnormallyavarietyofmessageswillappearstatingthatcertainpropertiesofcomponentsaremissing.

Youneedtoclick“ignore”italways.

Theprojectisthennormallynotdirectlycompileableandexecutable.Hereisasmallexample:

Page 81: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

SoherewehaveaTButton,aTBitBtn,aTSpeedButton.Thefirstthreebuttonsareassociatedwithaneventhandlerthatshowsintheonclick-event,whichclassthebuttonhas.

ThelastbuttonisassociatedwithaSchowMessageprocedure.

Besides,thereisaTImage,whichcontainsaTBitmap.

Thesourcecodeforthisisasfollows:

procedureTForm5.BitBtn1Click(Sender:TObject);

begin

MessageDlg(‘Clicked:‘+Sender.ClassName,mtInformation,[mbOK],0);

end;

procedureTForm5.Button2Click(Sender:TObject);

begin

ShowMessage(‘ThisisaTest.’);

end;

Afterconversionofthedialog,itlookslikebelow:

·ThegraphicsinTSpeedButtonismissing.OK,inFireMonkeytheTSpeedButtonhasindeednographics.

·TheTBitBtnmissinggraphicsandtext.OK,therearenoTBitBtninFireMonkey,sothat’sthereasonwhyitwasconvertedtoaTButton.

·TheTImagehasnobitmap.

Page 82: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IfwewanttocompiletheFireMonkeyproject,wegetthefollowingmessage:

Thesearetypicalcaseswherethetypequalifiersarerequired,whichIhadearlierbeenaddressed.Ifweadjustitasfollows,itruns:

procedureTForm5.BitBtn1Click(Sender:TObject);

begin

MessageDlg(‘Geklickt:‘+Sender.ClassName,

TMsgDlgType.mtInformation,[TMsgDlgBtn.mbOK],0);

end;

Verygood,itrunsonWindowsnow.ButwewanttouseFireMonkeytodevelopmulti-platformprojects.

However,wecanaddontherightsideoftheProjectwindowonlyMACOSasthetarget(byright-clickingtargetplatforms).

Thenyoucandothefollowing:Letdisplaythesourcecodeoftheprogram(Projectmenu)andcopyallthetexttotheclipboard.Thenclosetheproject.Afterthat,createanewFireMonkeyprojectunderthe“File”menu,chooseherethecommand“New”,“MultiDeviceApplication”.Whenthenewprojectwillbeshown,removedirectlythedefaultmainformwithnosavingandthensavetheprojectunderthenamethatyouhadconvertedbefore,inotherwords,overwriteit.Thengetbacktowith“Project,ViewSource”tothe

Page 83: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

programsourcecodeandpastethetextfromtheclipboard.

Nowwhenyouaddeverythingandsaveaspreviouslydescribedabove,theMacOSXplatform,worksasdesired.

HereistheprogramrunningontheMac:

Bytheway,therearestillmanyotheraspectsofshiftingnotes,ifyouworkprimarilywithareal,comprehensiveproject.AllthisIwilldescribehereinthesamesectionlaterinc),firstI’mstillontheMidaPro/Studioversion,whichcanbepurchasedasanupgrade.

b)WorkingwiththeMidaPro/StudioVersion

IfyouhavepurchasedtheProorStudioversionandenteryourdatain“License”-Field,theprogramisfullyavailable.

Butperhapsafewwordsonhowtoinstalltheprogram.Ithasnoseparatesetupprocedure,youwillreceiveazipfilethatyoumustunzipitintoadirectoryofyourchoice:

Page 84: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Mida.exeistheactualprogramfile.

Incontrasttothebasicversionitrunsnon-modal,soyoucanthedialogleaveopen,whileyouarestillmakingadjustmentsorchangeswithDelphi.

WhatmakesMida_FM_addon.exe,Iamnotentirelyclear.

ToinstalltheMidaImageButtonsandMidaSpeedbuttonsIhaveaprojectinDCU_Win_32bitopened,compiledandinstalledthecomponents.TrieswiththesameprojectinDCU_MAC,didnotwork,itappearsas“.dlyb”andtheinstallentryintheProjectmenuismissing.Butisapparentlynotrequiredtoworkatall.However,youmustsetbothintheFireMonkeyandWindowsplatformaswellthesearchpathstothesedirectories,soeachonDCU_Win_32bitandDCU_MAC_32Bit.

WiththePro/Studioversionyou’llhaveaccessto“Options”andsomoreopportunitiestoinfluencetheconversionprocess:

Page 85: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Here,especiallylooktattheoptions“UpdateSourcenotcompatiblewithFireMonkey”and“ConvertTImage”.

Sowhenwecompilethesameprojectasabove(andearlierdonothavetheMidapackcomponentsinstalled),theresultisasfollows:

Asyoucansee,the“TSpeedButton”hasnowanimage-thatisbecauseitwasconvertedtothe“TImageButton”,aMidacomponent.

AlsothebitmapisnowavailableintheTImagecomponent.

Page 86: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifourbuttonswouldhavebeenbold,anappropriatestylewouldhavebeencreatedinthisstylebook.

Inthesourcecodeitselfhasmoredone,incomparisontotheMidaBasicconversion:

procedureTForm5.BitBtn1Click(Sender:TObject);

begin

MessageDlg(‘Geklickt:‘+Sender.ClassName,TMsgDlgType.mtInformation,

[TMsgDlgBtn.mbOk],0);

end;

Here,the“TMsgDlgBtn”before“mbOK”and“TMsgDlgType”before“mtInformation”wasinsertedbytheconverter.

AnotherimportantsupportfortheconversioninthePro/Studioversioncanbefoundunderthe“CustomComponent”.Hereyouhavethepossibilitytomakeacustomconversionwithowncomponentsorthoseofthirdpartynotsupportedyet(thescreenshotisslightlymodifiedinordertosavespace):

YoucanenterthenameoftheVCLcomponentintheupperwindowandthenameoftheFireMonkeycomponentwhichistobeusedfortheconversion.

Inthelowerwindow,youcanspecifyagaintheVCLcomponentandthenthenameoftheVCLpropertyandthenameoftheFireMonkeyproperty.

Conclusion:Eventhebasicversionisabighelp.Withtheirhelp,ImanagedtoconvertasimplecalculatorprojectwithinafewhoursintoaFireMonkeyproject,afewdayslater,theprogramwasalreadyavailableintheMacAppStore!

TheProandStudioversionofferevenmuchmorethanthebasicversion.

Page 87: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Inparticular,theacquisitionofimages,andtheadaptationofthesourcecodeareanotheressentialassistanceifyouneedtoconvertlargerprojects.Themanyhoursoftimesavedjustifyinanycases,theinvestmentintheProortheStudioversion.ThestudioversionoffersbesidestheconversionofreportsalsotheMidaComponentPack(currentlyMidaImageButtonandMidaSpeedbutton).

Infact,theprogramisessentialforthemigrationoflargerVCLprogramprojectsintoaFireMonkeyCrossCompileproject.

c)StrategicapproachtoworkingwiththeMidaConverter

Inlargeprojects,youmustfirstmakeaseriesofpreparatorywork,beforeyoustarttheconversion.Asanexample:makeacopyofyourproject,performaconversionwiththeMida-Converterandthenopentheconvertedproject.Thereareprobablyalotofmessagesaboutmissingfeaturesandcomponents.

Example:

TheslightlyolderTNoteBookcomponentisnotsupportedbytheconverter.Sobeforeyoustarttheconversion,youmusttransfermanuallyinyourVCLprogramthecontentsfromtheTNoteBookintoaTPageControl.

Youcanthenviewtheindividualformsonceandcheckoutwhatismissingorwhatnot.

SoyouneedtomodifyinmanycasesyourexistingVCLprojectpreviouslyoftheconversionoftheVCLprogram.HeretheVCLform:

Page 88: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AndheretheconvertedFireMonkeyForm:

Currently-orratherstill,ayearagoitwasalreadyso-TTreeViewcomponentswillonlybeconvertedwithouttextcontent.

WhentheTTreeViewconsistedofonlyonelevel,youcanreplaceitintheVCLprogramthroughaTListBoxcomponentandprovidethosewiththerequiredtextentries.TheTNoteBookyoucanreplacewithaTPageControl.YoucangivetheTabItemsoftheTPageControlswithoutproblemsthesamenameastheTabsoftheTNoteBook.Soitsupportsthenfurthermoretheprogramlogic.TheMidaConverterprogramconvertstheTPageControlthenintoaTTabControl.YoucaninTTabControlsettheproperty“TabPosition”to“TpNone”tohidethenamesoftheregistersandsotheTTabControlworksliketheTNoteBook(onlymorecomfortable).

Bytheway,againthenote:Thecolordesignofthelabeltexts(bluishshownhere)isadoptedusingthestylebookcomponentonlyfromMidaConverterProversion.IntheBasicversionwouldallthesetextsbeinblack.

Forprocessingindetail:

Page 89: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

·OnlyFormsandunitsthatarelocatedintheprojectdirectorywillbecoveredbytheconverter.Soifyouhaveso-called“standardforms”thatyouuseinmultipleprojectsandthesearelocatedinaseparatedirectory,youmustcopythemintotheprojectdirectory.ItisbestwaythatyouclickintheProjectGroupWindowtosuchastandardformwiththerightmousebuttonandchoosing“saveas”.Thatleavesyouroriginalformattheoriginalplace,butmakesacopytotheprojectdirectoryandplaceavalidlinkintheProjectManagertothecorrectlocation.

·OftenVCLTPanelsareusedtodisplayatextwiththecaptionpropertyinarectangle.ButinFireMonkeytheTPanelhasneitheracaption,noratextproperty,thetextcontentthereforeislostwiththeconversion(!).Therefore,youshouldpreviouslyinsertaTLabelcomponentintheVCLprogramintotheTPanelcomponentandapplythetextoftheTPanelcaptionpropertytothecaptionpropertyoftheTLabel.

·Unfortunately,theMidaConverterconvertsalwaysentireprojects.So,ifyouconvertedtheprojectagainandhavealreadyworkedwiththepreviouslyconvertedforms,itwouldoverwritethisformwitharenewedconversionandyourpreviouschangeswouldbelost.Eitherthereforeconverteachtimeinadifferentdestinationdirectoryandcopyneededformsinyourprojectdirectory.Orconvertanytimeintothesametargetdirectory,butfirstsavethealreadyconvertedformsinan“OK”directory(withthecommand“SaveAs)andleaveitthereandcontinuetoworkwiththis(soIdoit).Butdonotforgettospecifythe“.dpr”or“.dproj”filesbecausetheycontainotherimportantsettingsthatyoudonotwanttodoediteachtime.YoushouldcopyittotheOK-directoyalsoanduseitfromthisplace.

·Starttheconversionwithunitsorformsthatdonotrequireadditionalunitsorotherforms.Forexample,an“Infoaboutdialog”ora“Registration”dialog.SoifyouhavecompletedallthepreparatoryworkontheVCLproject,goaheadandmakethefirstconversion.Afterthat,removefromtheFireMonkeyprojectallforms.Youcanuse“RemovefromProject”underthe“Project”menu,whereyoucanselectallforms.Thenjustaddaformandworkonit,untiltheprogramiscompiledandexecutedwiththisform(eg,the“About”dialog).Thenaddanotherformtoyourproject,setitasthemainformandworkonit,untiltheformcanbecompiledandtheprogramisexecuted.

·Evenatthisearlystage,youshouldrelativelyquicklyaddaMACOSXplatformandlettheprogramrunontimesevenontheMAC.Soyouseequickly,wherespecificadjustmentsfortheMacmustbemadeandyoucanreactintime.Otherwise,itmayhappenthatyourprogramrunsunderWindowsfine,butundertheMACplatformithailserrormessageswithoutend.

·TakeintoaccounttheMACpeculiarities,whendesigningyourdialogs.Forexample,buttonsthatarelocatedatthebottomofthewindow,theOKbuttonisdisplayedontherightsideinMACdialogs,butinWindowsdialogsattheleft.Sothebestwouldbe,youareusingaspecificMAC-Viewforthis.

·Backup,backup!!Veryfastanyproblemsoccurred,e.g.aformwillbedestroyedandisnolongerusable,whatever.Therefore,youshouldmakeadequate

Page 90: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

backups,soyouhaveaccesstopreviousversionsandyoucancontinueyourworkfromthat.

·DependingonhoweasyordifficultityoursourcecodecanbeputintoFireMonkeylogic,itcanbeusefultoenableordisableanumberoffunctionsoreventhandlerswithIFDEFdeclarations.Youwillthenhavethewholesourcecodeinyourformandprocedurebyprocedureyoucanthenworkthroughandmakethenecessaryadjustments.Advantageishere,thattheprogramiscompilingandyouhaveabase,youcanaddthingsonebyone.Afterall,youwillhaveevenmorefuntovisuallyseehowtheconversionprogressgoesonwitharunningprogram.AndsoyoucanhaveanearlylookofyourprogramattheMacplatform.

·IfyouhavealsotheTMSFMXGrid-componentavailable,youshouldconsidertolettheconverterconvertyourVCL-GridintoaTMSFMXGridandnotintoaFireMonkeyTStringGrid(seetheappropriatesettingunder“Options”).ThisisbecausetheTMSGridistheVCLStringGridinmanyfunctionsmoresimilarlythantheFireMonkeyTStringGridandalsooffersmanyotherskills.Tip:YoumayneedtospecifytheconversionofTStringGridtoTTMSFMXGridundertheregistercustomcomponentexplicitlyinMidaconverter,onlyactivatingthecheckbox“TMSTTMSFMXGrid”onthe“Options”pagehashadintheMidaversionavailabletome,noeffect.

·TShapesarenotok,accordingtomyexperience,soyoushouldreplaceitwithaTPanelbeforeconversion.

·IfupdatesoftheMidaConverterwillbeavailable,readexactlywhathaschanged.Possiblythenextversionresolvesanexistingproblemorhasabilitiesthatreducethenecessarypreparatorywork.

Ifyoufollowtheseaspects,youwillmakeitsafetoconvertstepbystepyourVCLprogramintoaFireMonkeyprogramandbeabletoofferyourprogramfortheMACOSXplatformsimultaneously.

Meanwhile,Ihaveconvertedamedium-sizedproject(CopyBackupwithnofewerthan50,000linesofcode:http://www.hastasoft.de/CopyBack-info.htm)fromVCLtoFireMonkey:WithintwoweeksitwasfinishedandaweeklatertheMACversionwasready(whichrequiresalittlemoretimebecauseofsomespecialfeaturesoftheMAC-filesystem).

Thesecond,alargerproject(PC-Rechnung:http://www.pc-rechnung.de)withover100,000linesthenwentagainmucheasier.Ifyouhaveoncemakeyourexperiences,thanyouknowwhattolookfor,andyoucanrelativelyquicklygoaheadwiththeconversion.

Page 91: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter2:TipsandtricksforCross-PlatformDevelopment

Section1:startingotherprograms

DependingonwhetheryouwanttostartanotherprogramonWindowsorMac(orwanttoopenafilewiththedefaultviewer)foreachsystemsotherroutinesareneeded.ThisisachievedwiththeuseofdifferentunitsandtheuseofIFDEFdirectives.

IntheUsesclause,usethefollowing:

{$IFDEFMACOS}

POSIX.Stdlib,

$ENDIF}

{$IFDEFMSWINDOWS}

ShellApi,

{$ENDIF}

Intheimplementationsectionitlooksasfollows:

procedureRunProg(prog:string);

begin

{$IFDEFMSWINDOWS}

ShellExecute(0,‘open’,Pchar(prog),nil,nil,0);

{$ELSE}

_system(PAnsiChar(‘open‘+AnsiString(prog)));

{$ENDIF}

end;

Ifyouneedtofindout,werefunctionsandproceduresfortheMacarelocated,lookintothecorrespondingfilesinthefollowingdirectories:

Page 92: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\source\rtl\osx

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\source\rtl\posix

Page 93: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section2:Gettheprogramdirectoryandprogramdatadirectory

TheprogramdirectoryoftheexecutablefileyoucanfindoutbothunderWindowsandtheMacusingthecommand“ParamStr(0)”.Infact,thewholenameoftheexecutablefileisstoredhere,butsoit’seasytoidentifytheprogramdirectory.

Itisbesttouseaunit,inwhichyousetupthecorrespondingvariablesintheinitializationsection.Here’sanexample:

unitMyData;

interface

uses

{$IFDEFMACOS}

POSIX.Stdlib,

{$ENDIF}

{$IFDEFMSWINDOWS}

ShellApi,

{$ENDIF}

FMX.Forms;

var

AppPath:String;

AppName:String;

AppExeName:string;

AppIniName:String;

ProgDataPath:String;

Implementation

begin

AppExeName:=paramstr(0);

Page 94: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AppPath:=ExtractFileDir(paramstr(0));

AppName:=ChangeFileExt(ExtractFileName(paramstr(0)),”);//withoutext.

{$IFDEFMACOS}

ProgDataPath:=IncludeTrailingPathDelimiter(GetHomePath)+

‘.config/’+AppName;

AppIniName:=ProgDataPath+PathDelim+AppName+‘.cfg’;

{$ENDIF}

{$IFDEFMSWINDOWS}

ProgDataPath:=IncludeTrailingPathDelimiter(GetHomePath)+‘hastasoft’+

PathDelim+AppName;

AppIniName:=IncludeTrailingPathDelimiter(GetHomePath)+‘hastasoft’+

PathDelim+AppName+PathDelim+AppName+‘.ini’;

{$ENDIF}

ifNotDirectoryExists(ProgDataPath)thenbegin

ForceDirectories(ProgDataPath);

end;

end;

Herepleasereplacekindly“Hastasoft”withyourowncompanynameorleavethispartcompletelyfree.Thissupplementisespeciallyrecommendedifyouhavedevelopedmanyprogramsandcustomersuseseveralofyourprograms.The“Config”folderisafolderontheMACwhereprogramscanstoretheirconfigurationfiles.ThisfolderisnormallyinvisibleintheFinder.Youcanofcourseuseanalternativefilemanagerthatcan(egFileIOforMAC)showthesefoldersanyway.

YoucanturnonandoffthevisibilityofthenormallyhiddenfoldersintheFinder,with:

defaultswritecom.apple.finderAppleShowAllFilesYES//unvisiblewithNO

Page 95: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section3:Catchtotheprogrampassedstart-upparameters

WhatunderWindowscouldbedoneveryeasywith“StartParam=ParamStr(1)”,willbeconductedinMACOSXconsiderablymoredifficult,asthereitworksquitedifferently.Ifyou,forexample,intheFinderclickwiththerightmousebuttononafileandfromthemenuchoose“Openwith”,thesystemstartstheprogramandthensendsamessagetotheprogramthatitshouldopentheselectedfile.

Soyouhavetosetupamechanismtoensurethatmessagescanbereceivedfromyourprogram.

InMACAPI.AppKitisaNSApplicationDelegateavailable,whichbasicallyhandledunderMACOSX,themessage“OpenFile”.Unfortunately,thisfeaturehasnotyetbeenintegratedintotheDelphiFireMonkeyimplementation.

Sothereiscurrentlynochoice,astomakeitbyyourself.Thefollowingisthesourcecodeoftheunitthatdoestheimplementation.InthemainprogramthenanOpeneventproceduremustbeimplementedandbepassedongenerationofowndelegates.Itlookslikeso:

––––––––––––-uniths_NSApplicationDelegate;

//WillimplementanownNSApplicationdelegate;bythis

//application:openFile:messagesfromMAC-OS-Systemcanbehandled.

interface

uses

Macapi.ObjectiveC,Macapi.CoreFoundation,Macapi.AppKit,Macapi.Foundation,Macapi.CocoaTypes;

type

//AlthoughweonlyneedtheOpenFilefunctionhere,wemustalso

//stillimplementDidFinischLaunchingandWilltTerminate,without

//ican’tcompile

Page 96: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

//fromMacapi.AppKit

NSApplicationDelegateExtended=interface(NSApplicationDelegate)

//hierineigenemProgrammmitStrg+Umsch+GeineneigenenGUIDerzeugen//verwendenSieNICHTdenuntenstehenden

[‘{2F5BD639-88DE-46F7-950A-D4469A125229}’]

functionapplication(theApplication:Pointer;openFile:CFStringRef):Boolean;cdecl;

end;

TOpenFileEvent=referencetoprocedure(constAFileName:string);

TNSApplicationDelegateExtended=class(TOCLocal,NSApplicationDelegateExtended)

private

FOnOpenFile:TOpenFileEvent;

public

constructorCreate(constAOnOpenFile:TOpenFileEvent);

functionapplication(theApplication:Pointer;openFile:CFStringRef):Boolean;cdecl;

functionapplicationShouldTerminate(Notification:NSNotification):NSInteger;cdecl;

procedureapplicationWillTerminate(Notification:NSNotification);cdecl;

procedureapplicationDidFinishLaunching(Notification:NSNotification);cdecl;

functionapplicationDockMenu(sender:NSApplication):NSMenu;cdecl;

end;

procedureStartExtendedApplicationDelegate(constAOnOpenFile:TOpenFileEvent);

var

ExtendedDelegate:NSApplicationDelegateExtended;

implementation

uses

FMX.Forms;

constructorTNSApplicationDelegateExtended.Create(constAOnOpenFile:TOpenFileEvent);

begin

inheritedCreate;

FOnOpenFile:=AOnOpenFile;

end;

Page 97: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedureTNSApplicationDelegateExtended.applicationDidFinishLaunching(

Notification:NSNotification);

begin

//Dummy

end;

functionTNSApplicationDelegateExtended.applicationDockMenu(

sender:NSApplication):NSMenu;

begin

//dummy

end;

functionTNSApplicationDelegateExtended.applicationShouldTerminate(

Notification:NSNotification):NSInteger;

begin

inherited;

//dummy

end;

procedureTNSApplicationDelegateExtended.applicationWillTerminate(Notification:NSNotification);

begin

//NichtFreeAndNil,verwenden,sonstgibtesFehler!!

FMX.Forms.Application.Free;

FMX.Forms.Application:=NIL;

end;

functionTNSApplicationDelegateExtended.application(theApplication:Pointer;openFile:CFStringRef):Boolean;

var

Range:CFRange;S:string;

begin

Result:=True;

Range.location:=0;

Range.length:=CFStringGetLength(openFile);

SetLength(S,Range.length);

CFStringGetCharacters(openFile,Range,PChar(S));

TRY

FOnOpenFile(S);

Page 98: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

EXCEPT

FMX.Forms.Application.HandleException(ExceptObject);

Result:=False;

END;

end;

procedureStartExtendedApplicationDelegate(constAOnOpenFile:TOpenFileEvent);

var

NSApp:NSApplication;

begin

Assert(ExtendedDelegate=nil);

NSApp:=TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);

ifAssigned(NSApp)thenbegin

ExtendedDelegate:=TNSApplicationDelegateExtended.Create(AOnOpenFile);

NSApp.setDelegate(ExtendedDelegate);

end;

end;

end.

–––––––––—

Inthemainform,thenthefollowingmusthappen:

procedureTF_Main.FormCreate(Sender:TObject);

begin

{$IFDEFMACOS}

StartExtendedApplicationDelegate(OnOpenParaFile);

{$ENDIF}

end;

Intheform-declaration,intheprivatesection:

private

{Private-Deklarationen}

procedureOnOpenParaFile(constS:String);

Page 99: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Intheimplementation-section:

procedureTF_Main.OnOpenParaFile(constS:String);

begin

if(s<>”)andfileExists(s)thenbegin

memo.lines.LoadFromFile(fn);

end;

end;

Unfortunatelyabitcomplicated,butitworks.

Itshouldalsobenotedthatitisalsonecessarytoenterintheinfo.plisttheinformation,whichtypesoffilesyourprogramwillbeabletoopen.

Hereanexampleofanadditiontotheinfo.plistfile,givingtheMAC-OStheinformation,thatyourprogramcanopentextfilesand.xml,andalsosourcecodefiles:

<key>CFBundleDocumentTypes</key>

<array>

<dict>

<key>CFBundleTypeRole</key>

<string>Editor</string>

<key>LSItemContentTypes</key>

<array>

<string>public.plain-text</string>

<string>public.source-code</string>

<string>public.xml</string>

</array>

</dict>

</array>

Withoutthis,theFinderdoesnotprovideforyourprogramnameanentryinthe“OpenWithmenu”.ButthatdoesnotpreventotherprogramsastheFindertotransmitparameterstotheprogramforopeningfiles,socanmyFileManager“FileIOforMAC”starteveryprogramandgiveatthesametimeastartupparametertotheprogram(thisismanagedbytheMACsystemmanagedinthebackground).

Page 100: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section4:“HelloWorld”-Multilingualprogramsandnewmarkets

TheAppleAppStoreisidealtosellyourprogramsinternationallyanditcanthusopenupentirelynewmarkets.Forthispurpose,however,youshouldnotonlyofferyourprograminyourownlanguage(inmycaseGerman),butalsoofferinganEnglishlanguageversion.

ForthisintentionhelpsusFireMonkeyinaverysimplewaywiththeTLangcomponent,ofcourse,inacross-platformway.Ifyouhavedevelopedyourapplication,addtothemainformaTLang-component.

Example:

DoubleclickingonthisTLangcomponent,itopensthefollowingdialog:

Page 101: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Youmightbesurprisedthateventheentry“ÖffnemichMac”isoffered.Thissourceisfromtheview“OSXDesktop”.Butitwillonlyshowup,whenIhavehereagainclickedonthebutton”Scanforstrings”.Thatway,youmustalwaysdo,whenyouaddnewcontrolstotheformandwanttoeditthetextsinthelanguagedesigner.

Inthefield“Two-letterlanguagecode”enter“en”andclickonthe“Add”button.

Thedialogthenchangesitsappearanceandbehindtherecognizedtextisnowforeachentryaninputfieldavailable,whereyoucanentertheEnglishequivalents:

Nowclosethedialogsimply,thechangesareapplieddirectly.

ToswitchnowfromthestandardlanguagetoEnglish,youhavetodothisviaasoftwarecommand.

Auserwouldnaturallychooseonamenuentryhislanguage.Hischoiceyoucansaveintheprogrambyanentryintheini-fileandrestoreitthenextlaunch.

Forthisdemoherewedothisdirectlyattheprogramstart,intheFormCreateevent:

procedureTForm13.FormCreate(Sender:TObject);

begin

Lang1.Lang:=‘EN’;

end;

Page 102: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

WARNING:Ifyouwrite“en”inlowercase,itdoesnotwork,youmustenterthelanguagecodehereinuppercase,asshownabove.

Theformlooksafterprogramstartlikethis:

Whatyoucanseehere,isthatthetextoftheform(“caption”)isnotcompiledfromtheTLangcomponent.Notevenwhenyouusethe“Add”buttonontherightsideoftheLanguageDesignerdialogtoaddanentrywithatranslationfor“Form13”manually.

Youmustthereforemakethechangesinthesourcecodebyyourself,suchas:

procedureTForm13.FormCreate(Sender:TObject);

begin

//Sprachevorgeben

Lang1.Lang:=‘EN’;

//JenachSprache:

ifLang1.Lang=‘EN’thenbegin

Caption:=‘Title’;

end;

ifLang1.Lang=‘DE’thenbegin

Caption:=‘Überschrift’;

end;

end;

Evenmenutextsarenottranslated.ThemainmenuentriesareshownintheLanguageDesignerandtheyareeditable,buttherearenottranslatedatruntime.

Page 103: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Youmust-aslongasthisbugisnotresolvedinDelphi-makeaseparateprocedure,whereyoucanassigneachmenuitemwiththeneededtext(i.e.“mnu_Optionen.text=‘Options’,etc.).Itistobehopedthatthemenuitemsarecoveredbythiscomponentinasubsequentversion.

Andthinkonit,thatyouhavealsotomakeadifferenceindialogs,whenyouprogramrunsinEnglishorotherlanguagemode.

Ifacomponentshouldnotbetranslated,youcandisablethefeature“AutoTranslate”intheObjectinspector.

Doyouhavemultipleformsintheproject,thesearesearchedforstrings,butpossiblyonlyafteryouhaveclickedonthebutton“ScanforStrings”.Thisbuttonmustalsobepressedagain,whenyouaddadditionalformstoyourproject.YouneedonlyoneTlangcomponentforyourwholeproject,becauseeverysecondTLangcomponentwouldagainsearchtheentireprojectforstringsandwouldaddthemtoyourproject.

Butinanyatruntimenewlycreatedforms,youmustusetheformcreateeventtotelltheTLangcomponentwhichlanguageitshoulduse.

Itoffersitselfheretocreateaseparateproceduresothatyoucanswitchatruntimebetweendifferentlanguages.Butyoucanonlychangefromtheoriginallanguagetootherlanguages.Totheoriginallanguageyoucanonlycomebackwhenyourestarttheprogramandusetheoriginallanguageasdefault.ORyouspecifyanewlanguageinadditiontotheoriginallanguage,ie“AddLanguage”herewiththeswitch“de”(whenGermanisthedefaultlanguage).Sinceitobviouslymakesnosenseforittoprovideatranslation,itsimplyrestoredtheoriginalentries.Inthiscase,youcanalsoswitchbacksoatruntimetotheoriginallanguage.

ThedataoftheTLang-componentwillbestoredbydefaultinthetheforminanunreadableencodedformat.Alternatively,youcansavethetextsoutsideofthefile.

WARNING:Ifyouhavealreadytranslatedtextsandthenuncheck“StoreInForm”intheObjectinspector:

Page 104: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Youlostyourpreviouswork;thereisnoconfirmationprompt.So,beforeyouuncheckit,use“SaveFile”intheLanguageDesignerdialogboxtosaveyourlanguagefile.Thisfilecontainsallpreviouslyappliedlanguages,itautomaticallyreceivesthefileextension“.lng”.Atruntime,youcanthenloadthefilewith“Lang.LoadfromFile(filename)”intothecomponent.

Hereatthedemoeverythingworksthewayitshould.InalargerapplicationthatIhaveprovidedherewiththeTLangcomponent,thecomponentdoesnotkeeptrackofalltranslations.ThereforeIhavesavedtranslationsasatextfile(withthebutton“Createtxt-filetemplate”)andthenreloadedagainandagainforrevisions.YouloadthisfilebacktotheDesigner,whenyouaddalanguagebyusingthebutton“Fromtxtfile”.

Anyway,everythinghasworkedsatisfactorilyattheend.

Page 105: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section5:ApplysandboxingandEntitlementsproperly

IfyouwanttobringyourapplicationintotheAppStore,itmustsupportthesandboxingmodel.FromJuly01,2012on,thisistheduty.Therefore,firstafewwordsaboutthesandboxingmodel.Tounderstandit,itisbeshownhowyourapplicationworkswithandwithoutsandboxing:

Withoutthesandboxyourapplicationhasfullaccesstoallthefilesandfoldersoftheoperatingsystem(itmightbe,thatforsomeactionsyourprogrammustberunwithadministratorrights).Youmayobtainaccesstothedocumentsfolderortheimagesormusicfoldersoatanytime.Also,yourapplicationcouldwritetotheApplicationBundlesofotherapplications,whichsofarisatargetforthesecurityoftheoperatingsystemhere.

Ifyourapplicationonlyplays“inthesandbox”,itdoesnotrealizewhatelserunaroundit,ordoesnothaveaccesstodatathatareoutsidethesandbox.Theremaybeapplications

Page 106: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

whereitisenoughtoplayinthesandbox.Butoftenitisso,thatyouwantgivetheworkingresultsofyourapplicationtootherapplicationsorewantgetaccesstodata-outputfromotherapplications.

Here,the“Entitlements”comeintoplay.So,ifyourapplicationwouldalsoliketoplayoutsideofthesandbox,youneedtorequesttheappropriaterights.

ThefundamentalrightscanbesetwithDelphiunderProject,Options,“EntitlementList”(hereagaintonotethatthisinformationisonlydisplayedifyouhaveMACOSXsetasthetargetplatform):

Whatmostapplicationswillprobablyneedistherighttoreadandsavefiles,overwhichonecantakeaccesswiththedialog“Open”and“Save”.ThisisalsoasettingwhereAppleitletsyougothroughifyounotdescribe,whyitisneeded,whenregisteringtheapplicationintheAppStore.

Incontrast,ifyouneeddirectreadandwriteaccesstotheothermentionedfolders(pictures,music,etc.),youmustitspecifyexactlyiniTunesConnect,whyyouneedtheserights.Ifyoudon’tdothis,yourwillhaveagoodchance,thatyourapplicationwillberejected(alreadyhappenedtome).

WhenyouclickiniTunesConnectonthepageofyourapplicationonthe“ViewDetails”,button,youcanedittheso-calledmeta-dataoftheapplication.Thisisthedescriptionofwhatyourapplicationdoesandyoucanaddafewscreenshotsthatshowsyourapplication.

Underthesection“AppReviewInformation”thereisabutton“AddEntitlement”:

Page 107: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Herejustclickonit,selecttherequirerightandthenbrieflydescribe(inEnglishofcourse)whyyourapplicationneedstheright.Itshouldalsobereallynecessaryoratleastbecomprehensible.

Onethingisimportanttoknow:thatyoucanrequestmorerightsthanyoucanselectintheDelphipermissionlist.

Indeed,itispossibletorequestarightthatyourapplicationcanreadorwritetoaspecificfolder,forexample,intothedesktop-folder.

However,youmustmanuallyedittheEntitlementslist.Itisbesttogoaheadsothatyouareeditingthislistrightintheapplicationbundle.ButyouhavetodisableinDelphiintheDeploymentthetransmittingoftheEntitlementslisttotheMACcomputersinceDelphiwouldotherwiseoverwriteyourmanualentriesagain.

However,itissothatanalreadyonthetargetexistingfileisdeletedifitisnottobetransferred.Sowehaveto“outsmart”thedeploymentmanagerhere.I’vesolveditsothatIhavecreatedaseparateEntitlementsfileanditsownInfo.plistfile.ThesearethentransmittedinsteadofthefilesthatDelphimanaged.Youhavetomaintainthefiles

Page 108: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

yourselfmanually,butthisisnotaproblemtodoso.Thisworkflowisalsorequiredinsomeothercases,whenyouhavetoentermultilineentries(<ARRAY>)intotheInfo.plistfile(whichDelphican’tmanage).Thefollowingscreenshotshowsitonce.Theyellow,byDelphicreatedfilesaredisabledandmyfilesmarkedingreen,aretransmitted:

Hereisaconcreteexampleofanextensionofthelist:

<?xmlversion=“1.0”encoding=“UTF-8”?>

<!DOCTYPEplistPUBLIC“-//Apple//DTDPLIST1.0//EN”“http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

<plistversion=“1.0”>

<dict>

<key>com.apple.security.app-sandbox</key>

<true/>

<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>

<array>

<string>/Desktop/</string>

</array>

</dict>

</plist>

Therelevantentryisinthiscasethekey:

„ com.apple.security.temporary-exception.files.home-relative-path.read-write”

Hereyoucanenterinanarraylist,forwhichfolders,relativetothehomedirectoryofyourapplication,adirectreadandwriterightwillbeneeded.

Page 109: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thedirectorymustalwaysbeginwitha“/”andendwitha“/”.

Ageneraldescriptionoftheuseofentitlements,seetheAppleonlinedocumentation,here:

http://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AboutEntitlements.html

Whereinasandbox-appthedataarethenactuallyreally?

Mymulti-applicationscreenshotshowsasavedimagecopywiththefollowingpath:

„/Users/harrystahl/Library/Containers/com.hastasoft.multiscreenshot/Data/Desktop/Bildkopie1.jpg“.

Asyoucansee,hereisjustasymlink,soanaliasthatisareferencetotheactuallocationofthedesktop:

Howtorequestfurtherrightsfordirectaccesstospecificfolders,isdescribedhere:

http://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html#//apple_ref/doc/uid/TP40011195-CH5-SW1

Thereforeitwillevenbepossibleaccessingfolderswithabsolutedirectoryinformation:

<?xmlversion=“1.0”encoding=“UTF-8”?>

<!DOCTYPEplistPUBLIC“-//Apple//DTDPLIST1.0//EN”“http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

<plistversion=“1.0”>

<dict>

Page 110: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

<key>com.apple.security.app-sandbox</key>

<true/><key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>

<array>

<string>/Volumes/</string>

</array>

</dict>

</plist>

Withthatyoucangetdirectlyaccessthefolder“Volumes”andthusonmounteddrives.

Andindeed,forthislocationshowsmyScreenShotprogramasstoragelocationthen

“/Volumes/D/Bildkopie1.jpg”.

Sothismeansthattheabsolutereadandwriteaccesses,isatthereallocationsandnotonlyvirtualviathedatacontainer.

Bytheway,therewillalwaysbeaninterestingquestionwhetheryoucanactuallyconvincetheApplereviewers,thatyourapplicationabsolutelyrequirestheserights.Anapplicationshouldatleast,accordingtothespecificationsofApple,requestonlyasmuchrightsasyouneedtomeetyourrequirements.

Youshouldthereforegivethedescriptionofwhyyourapplicationrequirestheserightsreallyhardandnevermakeacompletelymeaninglessstatement.Formymulti-screen-shotprogramIhadnosuccesswithit,soIhavethereforechangedthestrategyandthestoragelocationsfortheprogram.

WhentalkingaboutsandboxingIwanttellyou,thatthereisuntilnowanotherunsolvedproblem:theOpenandSavedialogsunfortunatelydonotworkonMACOSXLion.Theapplicationfreezesonlybriefly,nothinghappens,thatwasit.

ForMacSnowLeopardasandboxedapplicationloadedfromtheAppleStoreworksproperly,butnotsurprising,becauseSnowLeoparddoesnotsupportsandboxingatall.

Furthermore,IhavetheimpressionthatperhapstheApplerevieweronlyormainlyalwaysconducttheirtestswiththelatestAppleoperatingsystem,sountilrecentlywithMACOSXMountainLionandnowwiththenewMavericks(MACOSX10.9)andYosemite(MACOSX10.10).ButfrommyownexperienceIknowthatapplicationscanstillcome

Page 111: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

intothestore,althoughtheOpenandSavedialogsinLionnotwork.

Asadeveloper,youcanactuallynotbeveryenthusiasticaboutthesandboxing,becauseitisverydifficulttouseanditisnoteasytoaddusefulfunctionalitiestoyourprogram.

ItmaythereforebetherightdecisiontodeveloptheapplicationwithoutsandboxingandthensellitjustoutsidetheAppStore.Whichofcoursehascertaindisadvantages,becausethemarketpowerthatApplehasnowwithhisstore,youcannormallynotconcurwith.Unlessyouarerepresentingyourselfasalargerormultinationalcompany.

Page 112: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section6:SandboxingandpersistentrequeststoBookmarks

Theoptionsetoutinsection5isuseful,ifyouwanttohavefromthebeginningonadirectaccesstogivendirectories.

Ifitwillbeclear,thattheuserneedspersistentaccesstofoldersandfilesoutsidethesandbox,butnotclear,whichfolders,youcanuseherebookmarksinconnectionwithcertainentitlement-keys.

Therearetwotypesofbookmarks,youcanusehere:

App-ScopedBookmarks

com.apple.security.files.bookmarks.app-scope

Thisgetsyourapplicationaccesstothefoldersandtheircontents,selectedbytheuserifthebookmarkwascreatedforafolder,ortoasinglefile,whenthebookmarkwascreatedforafile.

Document-ScopedBookmarks

com.apple.security.files.bookmarks.document-scope

Allowsyoutocreateabookmarkforonefile.Whileonlyyourownapplicationhasaccesstotheresourcewiththeapp-scopedbookmark,withtheDocument-ScopedBookmarkanyapplicationgetsaccesstothefilewhentheyhaveaccesstothebookmark(andthefile).ArequirementforDocument-Scopedbookmarkisstill,thatthefiletowhichthebookmarkreferences,isnotinafolderthatisonlyusedbythesystem,suchas“private”or“Library”.

Heretheprocessisdescribed,howyouwillgetapermanentaccessviaapp-scopedbookmarkstoafolder(anditscontents)thattheuserhasselectedandhowyoucanaccessthemagain:

Step1

Page 113: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Theuserselectsafolderwiththe“MACSelectDirectory”functiondescribedinAnnex2.Inthismomentafunctionwillbecalled,thatAppledescribesasthePowerBoxmechanism.Indeed,iftheoriginalMACOpenandSavedialogsused-andonlythen-thePowerBoxfunctionmakesthattheprogramduringitsruntimewouldcontinuetohaveaccesstotheselectedresource(i.e.inthisexamplethefolderanditscontents).

Step2Ifwewant,thattheprogram-evenafterrestarting-hasagainaccesstotheselectedfolder,withoutre-usingtheopendialog,wehavetouse“SecurityScoped”bookmarkshere.

Whatisextremelyimportanthere(withoutitwillnotwork):Youhavetocreatethisbookmarkatacertainmoment.AndthismomentisaftertheuserhasselectedthefolderwiththeOpendialog(aNSPanelobject)andbeforethepanelisreleased.TheoperatingsystemprovidestheabilitytocreateaSecurityScopedBookmarkonlyinthisbriefmomenttoyourapplication.

Therefore,wecannotusetheOpenandSavedialogcomponents,thatcomeswithDelphi.Iftheexecute-functionoftheopendilaogreturns,theNSOpenPanelisreleased.AlthoughthePowerBoxgrantedfurthermoreaccessatthedurationoftheruntimeoftheprogram,thereisnowaytocreateaSecurityScopedBookmarkafterclosingthedialog.

Ihavethereforethefunction,describedinAnnex2,hereforthesandboxingadjusted(simplifiedillustration):

{$IFDEFMACOS}

functionMACSelectDirectory(constATitle:string;varADir:string;CreateBookMark:Boolean):Boolean;

var

LOpenDir:NSOpenPanel;

LInitialDir:NSURL;

LDlgResult:NSInteger;

Data:NSData;

begin

Result:=False;

LOpenDir:=TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel);

LOpenDir.setAllowsMultipleSelection(False);

LOpenDir.setCanChooseFiles(False);

LOpenDir.setCanChooseDirectories(True);

ifADir<>”then

begin

Page 114: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

LInitialDir:=TNSURL.Create;

LInitialDir.initFileURLWithPath(NSSTR(ADir));

LOpenDir.setDirectoryURL(LInitialDir);

end;

ifATitle<>”then

LOpenDir.setTitle(NSSTR(ATitle));

LOpenDir.retain;

try

LDlgResult:=LOpenDir.runModal;

ifLDlgResult=NSOKButtonthen

begin

ADir:=string(TNSUrl.Wrap(LOpenDir.URLs.objectAtIndex(0)).relativePath.UTF8String);

Result:=True;

{$IFDEFUseSandbox}

if(AppScopedBookMarksEnabled)and(CreateBookMark)thenbegin

CreateAppScopedBookMark(Data,LOpenDir.URL);

end;

{$ENDIF}

end;

finally

LOpenDir.release;

end;

end;

{$ENDIF}

Toensure,thatthedialogdoesnotpermanentlycreatebookmarks,wheninvoked,youcancallthefunctionwithapassedvariable,thatwillhandlethis(Booleanvariable“CreateBookmark”)and,secondly,whetherthesandboxfunctionalityshouldgenerallybesupportedbytheapplication(compilerdirective“UseSandbox”).Thecompilerdirectiveallowsyoutocompiletheapplication,ifrequired,withoutsandboxing.Soyouhaveaneasyoption,tosellyourprogramalsooutsideoftheAppStore,ifyouwantthat.

Furthermore,itischeckedwhetherAppScopedbookmarksaresupportedatall,thatisonlyfromMACOSX10.7.3onornewerthecase(checkedwiththe“AppScopedBookmarksEnabled”,whichyoucanreadintheappendix).

Theyellowmarkedtextrepresentsthetime,atwhichthebookmarkshouldbecreated.

Page 115: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Here,beforetheNSOpenPanelisreleased.

IntheCreateAppScopedBookMarkfunctionIhavedonetheDelphiimplementationoftheNSURLfunction“bookmarkDataWithOptions”(definedinMACApi.Foundation.pas),whichgeneratesthebookmark:

functionCreateAppScopedBookMark(vardata:NSDATA;URL:MacApi.Foundation.NSURL):Boolean;

var

err2:NSError;

includingResourceValuesForKeys:NSArray;

relativeToURL:MacApi.Foundation.NSURL;

begin

Result:=False;

//Checkwhetherthisalreadycontainsanentryexists

//ReturnbutexistingDataObject

//Forsimplicityhereaway

//…

//Bookmarkdoesnotexist,thereforecreate

err2:=TNSError.Create;

err2:=NIL;

includingResourceValuesForKeys:=NIL;

relativeToURL:=NIL;

Data:=URL.bookmarkDataWithOptions(

NSURLBookmarkCreationWithSecurityScope,

includingResourceValuesForKeys,

relativeToURL,//NIL=App-Scope

@Err2);

try

ifnotAssigned(err2)thenbegin

Result:=True;

ifData<>NILthenbegin

//BookmarkindasBookmarkverzeichnisspeichern

//z.B.Data.writeToFile(NSSTr([Dateiname]),true);

endelsebegin

Page 116: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Result:=false;

//ShowMessage(‘DataisNIL’);

end;

endelsebegin

ShowMessage(String(err2.localizedDescription));

end;

except

ShowMessage(‘Problemwitherr2inCreateAppscopeBookmark’);

end;

end;

Step3

Ifyou(afterrestartingtheprogram)wanttoaccessthefolderlater,youmustloadthepreviouslysavedbookmarkandresolveit,byusingthe“ URLByResolvingBookmarkData “,function,whichisalsoafunctionoftheNSURLinterface.

functionGetResolvedAppScopedBookMark(data:NSData;varNEWURL:NSURL;varADir:String):Boolean;

var

Err:NSError;

relativeToURL:MACAPI.Foundation.NSURL;

begin

Result:=False;

err:=NIL;

RelativeToURL:=NIL;

NewUrl:=TNSURL.Wrap(TNSURL.OCClass.URLByResolvingBookmarkData(

Data,

NSURLBookmarkResolutionWithSecurityScope,

RelativeToURL,

0,

@Err));

if(NewUrl<>NIL)and(notAssigned(err))thenbegin

Result:=True;

end;

end;

Page 117: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Step4

Ifthebookmarkwassuccessfullyresolved,youhaveaNSURLobject,withthatyoucangetaccesstothefolderthen.

However,youmustusethereforethefunction

„URL.startAccessingSecurityScopedResource“

IfthisreturnsthevalueTrue,youcantakeaccesstothefolderorthefilestherein.

Step5

Thenyouterminateaccesstotheresourcewith

URL.stopAccessingSecurityScopedResource

Itisimportantthatthecallsto“start”and“stop”functionsarealwaysbalanced.Youcanmakeacoupleofcallswith“start”insucsession,butyouhavemakeallthe“stop”callsagaininreverseorderwiththerespectiveURLs.Ifyoucomehereoutofbalance,youcannotcallanymoreresourcesduringtheexecutionoftheprogram(sothenonlyafteryourestarttheprogram).

Thementioned“start…”and“stop…”functionsarenotimplementedinDelphiXE3-XE7inthe“MACApi.Foundation.pas”fileintheNSURLinterface.IhavealreadyleftthisatEmbarcaderobyQualityCentralaswish,thattheywillimplementdirectlytheseimportantfunctions.Butuntilnow,itonlyremainstomakethemissingfeaturesinaseparateinterfaceimplementationinanaccessiblelocation.Thismeans,unfortunatelyanunnecessarycomplicationoftheprogramlogic.

Tomakethewholethingalittleeasier,Ihaveincludedattheendofthebookasanattachmentmycurrentunit“HSW.FMXSandbox.pas”.YouwillalsofindmissingconstantvaluesthatyouneedtousetheMACfunctions.Befreetousetheunit,butatyourownrisk.ThereisnoguaranteethatIhaveeverythingproperlyimplemented.Evenifthethingnowseemstoworksuccessfullyinmyprograms,youshouldstilltesttheuseindetailinyourprograms.Ifyoufindanyerrorsorifyounoticeinconsistencies,Iamgratefulforahint.

IntheunitthatIhavegeneratedarealreadyintegratedthefunctionstostoreandmanagebookmarks,thatwillsignificantlysimplifiesaccesstotheresources.Thislooksthanlike

Page 118: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

this:

FunctionLoadLastFile(FileName:string):boolean;

Var

{$IFDEFMACOS}

{$IFDEFUseSandbox}

URL:HSW.FMXSandbox.NSURL;

HasAccess:Boolean;

{$ENDIF}

{$ENDIF}

Begin

Result:=false;

{$IFDEFMACOS}

{$IFDEFUseSandbox}

ifAppScopedBookMarksEnabledthenbegin

//Resourceanfordern

ifGetAppScopedAccessToResource(Filename,url)thenbegin

HasAccess:=True;

endelsebegin

ShowMessage(‘Can’tgetaccessto‘+Filename);

Exit;

end;

end;

{$ENDIF}

{$ENDIF}

//here:openfile…

//Result=Trueorfalse

{$IFDEFMACOS}

{$IFDEFUseSandbox}

ifAppScopedBookMarksEnabledthenbegin

ifHasAccess=Truethenbegin

ifnotCanStopAccessingSecurityScopedResource(Url)thenbegin

//giveanerrormessage

end;

end;

Page 119: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

end;

{$ENDIF}

{$ENDIF}

End;

Andsothedatastructurewouldthenbecreatedinyourapplication:

Inthecontainer,inAppSupportPaththeindividualbookmarksaresavedinthe“AppScopeBookmarks.dat”file(asimpleTStringList);

Thelistentriesconsistofthenameofthefolder(orfiles),whichhasassignedabookmarkname.Togrant,thatthebookmarknamesareunique,IuseGUIDnamestherefore.ThebookmarksthemselvesarestoredunderthenameoftheGUIDidentifierinthefolder“Bookmarks”.

Atleastitisasolutionthatworks.Eachbookmarkfilesconsistofalettersandnumbers,probablywithbinarycontent.

Specialcase“savenewlycreatedfilesoutsidethesandbox”

Ifyouwanttocreateanewfileoutsideofthesandbox,thereare2options.

Option1:Youfirstlettheuserselectafoldertostorefilesandtherebycreatedabookmark.Thentheyhaveduringruntimeaccesstothefolderandcancreatefilesandhavealsoafterrestartingtheprogramaccesstothem.

Option2:Moreoften,however,probablytheotherwaywouldbeused:Theuserofyourprogramhasanewtextdocumentoragraphicorwhatevercreated,andthecontentshouldnowbesavedtoafile.Aslongasyousavethecontentsinthesandboxenvironment-noproblem,thisyoucandoofcoursealways.

Buttheusermaywanttoplacethefileinthefolder“Documents”or“MyPictures”or

Page 120: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

“Desktop”.Ofcourseyoudonotwanttoasktheuserineachcaseinafirststeptoselectafolderandinasecondstep,thefilenameforit.

Thereforeitisobviousthatyouwanttousethe“SaveAs”dialog.Again,youcannotusetheTSaveDialogofDelphi,becausethesavingofabookmarkcanbeappliedonlyduringthelifetimeoftheNSSavePanel.

NowitissothataBookmarkonlyforanexistingfolderoranexistingfilecanbecreated.Butyourfiledoesnotyetexist,youcancreateitfirst,aftertheuserhasgivenanameforit.

Thetrickthatwewillusehere,isthattheextendedNSSavePaneldialogwilldirectly-afterselectingthefilename-createadummyfilewiththeselectednameandthenitdirectlygeneratesthebookmark.Thenthedialogwillbereleasedandyouhaveafile,intothatyoucanwritethecontentyouneed.Withthebookmarkyoucanalsogetaccesstothefileafterrestartingtheprogram,e.g.ifthefilewillbeloadedautomaticallyas“Openlastfile”afteryourprogramlogic.

Withthissecondwaythereisasmallcaveat:Youcan’tchangethenameafterselectingthefilenamebytheuser,becausethebookmarkwascreatedalreadyforthenameselectedbytheuser.Iftheuserthereforeindicatesanunusualextension,theprogramcan’tchangeitanymore.

Soifyouneedthataspecificfileextensionismandatory,youmustmodifythefunction,whereIhaveimplementedtheNSSavePaneldialog.Youthanhavetoensure,thatthefilenamewillbeadjusted,beforethebookmarkiscreated.

Conclusion:Theissueofsandboxingisnotaverysimpleissue.That’swhyIhopeevenmore,thatthisinformationwillhelpyoutomakeyourappasdesiredsandbox-enabled.

Page 121: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section7:UseMACAPIs(POSIX,COREandCocoa)inDelphi

TheMACOSXoperatingsystemessentiallyworkswith3-layersystems:

POSIXCOREAPICOCOAFramework

WhilethefirsttwolayersareaddressedoveraconventionalC-interface,theCOCOAlayerisaccessibleviaaspecialObjective-Cinterface.Asetoffunctionsisultimatelyinallorseverallayers.Forexample,youcanquerythecomputernamewithaPOSIXfunction(gethostname)ortheCOCOAinterfaceNSHost(Host.Name).

Inthefollowingwefocusontheindividuallayers:

POSIX

ThePOSIXinterfaceofferstypicallow-leveloperatingsystemfunctions,whichcanalsobefoundinotherUnixorLinuxsystems.

Soyoucan,forexample,askforthenameofthecomputeronwhichyourprogramisrunning,withthePOSIXfunction“gethostname”.Thisfunctionisdefinedinthe“Posix.Unistd.pas”.Youcouldhereinterprettheabbreviation“UniStd”perhapsas“Unixstandard”becausetherearejusttypicalforUnixstandardfeaturestofind.

Strictlyspeaking,thefunctionisinthe“UniStdAPI.inc”filetofind.It’sworthittosayhere2-3wordsonthestructure,withthatEmbarcaderohasimplementedtheAPIfunctions.

Under

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\source\rtl\posix

youcanfindthePOSIXfolder.Hehasasubdirectorycalled“OSX”.Theconcretimplementationsarefoundinthe“.INC”-files(.INCstandsfor“include”).Ifyoulookat

Page 122: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

theindividualunitsofthePOSIXfolder,forexample,inthe“Posix.Stdlib.pas”youwillfindIFDEFdeclarationsinthefollowingway:

{$IFDEFMACOS}

{$Iosx/StdlibTypes.inc}

{$ENDIFMACOS}

{$IFDEFLINUX}

{$Ilinux/StdlibTypes.inc}

{$ENDIFLINUX}

TheLinuxfolderdoesnotexistyet,butwemaysafelyconcludethatEmbarcaderoisworkingonaLinuximplementation.

SothefunctionintheUniStdApi.incisimplemented:

functiongethostname(name:MarshaledAString;namelen:size_t):Integer;cdecl;

externallibcname_PU+‘gethostname’;

{$EXTERNALSYMgethostname}

TomakethemsuitableforDelphi,wecandothisasfollows:

Uses

Posix.unistd.pas,

functionmac_GetComputerName:string;

Implemtation

functionmac_GetComputerName:string;

var

buf:Array[0..255]ofAnsiChar;

begin

ifgethostname(buf,sizeOf(Buf))<>-1thenbegin

Result:=UTF8ToUnicodeString(buf);

ifpos(‘.local’,Result)<>0thenbegin

Result:=copy(Result,1,pos(‘.local’,Result)-1);

Page 123: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

end;

end;

end;

ProbablythecomputernameonUnixmaybesignificantlylesstimethanthe256charactersthatIreservehere,butsinceIdonotknow,I’llgoonthesafeside.

ForMacOSX,thereturnnameisnormallysupplementedwitha“.local”,bywhichhecanbeaddressedoverallinthenetwork.Forourpurposes,however,weonlyneedthenameasitwillusuallyappearinthesystem.

AsimilarlyusefulfeaturethatyoucouldstillimplementfromthePosix.unistd,wouldbethe“getLogin”functionwithwhichyoucanquerytheusername.Sinceweneedherenobufferinwhichthenamemustbestored,wecanusethisfunctiondirectlyas:

„strUsername:=UTF8ToUnicodeString(GetLogin)“.

COREAPI

MostofthecoreApisyouwillfindintheunit“Macapi.CoreFoundation.pas”.Again,takealookattheDelphifolderstructure.TheMacApi.Corefoundation.pascanbefoundat:

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\source\rtl\osx

Alsolookonceintotheunit,it’sashortunitthatintegratesanumberofincludefiles,suchastheCFString.incfilethatimplementssomeCFStringfunctionsinDelphi,whichweneedtoworkwithCFStringobjects.

AlsotheCoreAPIisaccessedviaaCcallsystematic.ThemaindifferencewiththePOSIXfunctionsisthatbehindtheso-calledCoreAPIare“Referencecountedobjects”.Thatmeans,thatbehindfunctionsordatastructures,areintruthobjects,sometimesevenCOCOAobjects.

Soifyouwanttousestringsaspassingparametershere,thiscan’tbeDelphistrings,butitmustbeCFStrings,soreferencecountedstringobjects.

Page 124: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

HereisanexamplethatdemonstratestheuseoftheCFStrings:

proceduremac_ShowMessageNative(aHead,AMsg:string);

var

CFHead,CFMsg:CFStringRef;

AResult:CFOptionFlags;

begin

CFHead:=CFStringCreateWithCharactersNoCopy

(NIL,PChar(AHead),Length(aHead),kcfAllocatorNull);

CFMsg:=CFStringCreateWithCharactersNoCopy

(NIL,PChar(AMsg),Length(aMsg),kcfAllocatorNull);

try

CFUserNotificationDisplayAlert

(0,1,NIL,NIL,NIL,CFHead,CFMsg,NIL,NIL,NIL,AResult);

finally

CFRelease(CFHead);

CFRelease(CFMsg);

end;

end;

HeretheCoreFoundationfunction“CFUserNotifiationDisplayAlert”isimplemented.Weusehereonlyaverysimpleimplementation.Ifrequired,thealertfunctioncouldevenbeenshownwithatime-outtime,withafurtherbuttonanduser-definedtextforthebutton.TheexactskillsofthefunctionyoucanseeintheMacDeveloperLibraryonthefollowingpage:

http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFUserNotificationRef/Reference/reference.html

TheCFStringCreateWithCharactersNoCopyfunctioncomesfromtheMacAPI.CoreFoundation.pas(orCFString.inc).ItcreatestheStringobject.

Allfunctionswhosenamescontainsa“Create”or“Copy”,cause,whentheyarecalled,thatthereferencecounttotheobjectisincreasedbythevalueof“1”.Afterusingtheobjectsyoumustthereforereleasethemwiththe“CFRelease”sothatthereferencecountcanbereducedbythevalueof“1”again.Ifthereferencecountisresettozero,theobjectistotalreleased.Ifyoudonot,youretainresidualobjectsinmemorythatwillremainaftercompletionofyourprogram.IdonotknowhowtheprogramsarecheckedforMAC

Page 125: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Appstoreforsuchshortcomings,Iwouldadvisetoworkcarefullywithsuchobjects.

Animportantadditionistomentioninthiscontextforfunctionsthathavea“Get”inthename.Thereobjectsarenotcopiedornewcreated,youjustusetheoriginal.Directlyafterusingthe“Getxxx”function,youhavetocallthefunction“CFRetain”beforeyoucontinuewiththeStringobjects.CFRetainthenalsoperformsanincreaseofthereferencecounterandassuresyouthefurtheruseoftheobject.Aftercompletionoftheworkwiththeobjectyougiveitfreewith“CFRelease”,whatthereferencecountdecrementby“1”.

COCOAAPI

TheAPI’sfromtheCOCOAFrameworkarespecificallytailoredforusewithObjective-C.Manyobjectsandfunctions,youwillfindinthe“Macapi.Foundation.pas”implemented,forexample,theentireURLfunctionsIuseintheHSW.FMXSandbox.pasunit.LookonceinthisMacApifile,youfinditinDelphiiXE7alsointhefollowingfolder:

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\source\rtl\osx

TheCOCOA“objects”(Objetive-Cclasses,metaclassesandprotocols)areusuallyimplementedasinterfaces.Therefore,fortheNSStringobject/classyouwillfindtwointerfaceimplementations,onceas

NSString=interface(NSObject)

andalsoas

NSStringClass=interface(NSObjectClass).

Thesameapplies,forexample,forNSURLandNSURLCLASS.Itisthereforeimportanttoknow,becauseyouwillsometimesneedfunctionsoftheoneandoftheotherinterface.Bytheway,hereisimplementedmuch,butnotall,nowandthentherewillbetimeswhenyouneedtoupgradeindividualfunctionsthroughare-implementationitself,likeIhavemadeitforexampleintheHSW.FMXSandbox.pasunit.

Butagain,let’slookatanexampleofhowCOCOAobjectsaretobeused,hereweuseaNSWorkspaceobject(theunitMacApi.Appkit.pasmustbeincluded).However,Iwillshowyoufirsthowitdoesnotwork,becausethatiswhatyouwouldnormallytry(andoftenseesinforumswherethenaskswhythissodoesnotwork):

Page 126: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

var

URL:NSURL;

Workspace:NSWorkspace;

begin

URL:=TNSURL.Create;

URL.initWithString(NSSTR(’http://www.hastasoft.de’));

Workspace:=TNSWorkspace.Create;

Workspace.openURL(URL);

URL.release;

Workspace.release;

Itwillthereforenotwork,becauseasaresultoftheDelphiObjective-Cbridgejusta“Raw”objectissuppliedbackthatissonotusable.MoreoverappliestotheWorkspaceobjectthatforeachprogramonlyonesharedworkspaceobjectisavailable,whichmustbeaccessedviathe“sharedWorkspace”.

Detailstothisextremelyusefulobjectcanbefoundhere:

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/Reference/Reference.html

Properlythereforetheuseofitlookslikethis:

var

URL:NSURL;

Workspace:NSWorkspace;

begin

url:=TNSURL.Wrap(TNSURL.OCClass.URLWithString(NSSTR(’http://www.hastasoft.de’)));

WorkSpace:=TNSWorkspace.Wrap(TNSWorkspace.OCClass.sharedWorkspace);

Workspace.openURL(URL);

Thereisthenalsononeedtoreleaseanything,becausenothingiscreated,onlyvariables(objects)weresetwithcontent.

ThemostCOCOAobjectsarereferencecounted,butthisusuallyworksautomatically,in

Page 127: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

theexamplecase,therefore,neithera“retain”nora“release”aftertheuseoftheobjectisrequired.

InCOCOAobjectsitisonlyinexceptionalcasesrequiredtoworkwith“Release”functions,thissimplifiesworkingwiththeseobjectsverymuch.

Page 128: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter3:RequirementsforCross-PlatformDevelopment

Section1:SettingupWindowsPCandMACPC

YoumusthaveaWindowsPCandaMAC,whichareconnectedviaanetwork(wirelessorwirednetwork).Alternatively,youcanalsosetWindowsinavirtualmachineontheMAC.Ifindthelattersolutionnotsogood,becauseI’verunonmyMacdifferentpartitionswithdifferentMACOSXversions,thatIrunasneeded.Andthenit’sanadvantagetohaveyourownWindowsPC,withDelphithereinstalled.

Preparation

OnyourWindowsPC,refertothefollowingdirectory

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\PAServer

tothefile“PAServer15.0.pkg”.CopythisfiletotheMAC(e.g.tothedesktop).ThealsointheWindowsdirectoryexistingfile“Setup_paserver.exe”-isnotneeded(itisused,ifyouwanttoperformonanotherWindowsmachinearemotedebugging-andthanyoumustinstalleditontheotherWindowsmachine).

Smalldigression:HowtosetupadriveconnectingfromyourMactoyourPC:OpentheFinderandchoosefromthemenu“Goto”the“ConnecttoServer”command:

ClickConnect.Ifyoudotheconnectionforthefirsttime,thisdialogwillappear:

Page 129: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

UnderName,entertheusernameoftheWindowsPC’sandalsothelocalpassword(notthepasswordoftheMAC-PC).

Iftheconnectionworks,youhaveontheMAC,anewvolume(drive)available.Withthisdriveyoucanshareyourfiles.

ThenclickontheMAConthe.PKGfile,itisautomaticallyextracted.Thendouble-clicktheunpackedfile“Setup_paserver”.Thefollowingsetupprogramstarts,whichinstallsthePAServerontheMAC.

ThePCAServerprogramisaninterfaceprogramthatDelphineedstotransmittfilesoveraTCP-IPconnectionfromyourWindowsPCtotheMACandthenstartthemthere.

Page 130: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ThePAServerisfoundafterinstallationontheMACintheprogramfolder:

/Applications/PAServer15.0.app

AttheInternetitisalsodescribedinadocwikihowtheservershouldbeinstalledandrunning:

http://docwiki.embarcadero.com/RADStudio/XE7/en/Installing_the_Platform_Assistant_on_a_Mac

Tostarttheserver,gototheApplicationsfolderandlaunchtheapplication“PAServer15.0”

Aconsolewindowwillbeopenthen,whereyoujustconfirmthestartwithreturn,ifyoudon’twanttoassignapassword(inmyopinionisthatneverneeded).

ThenApplewillpromptyoutoenteryouradminpassword.Ifyouhavedonethis,theserverprogramisreadyandwaitingforaconnection.

DelphitransmitthentheontheWindowsPCproducedMACapplication,usingthePAServer,totheMACintotheso-called“ScratchDir”.Thiscanusuallybefoundhere:

/Users/YourUserName/PAServer/Scratch-Dir.

HereI’vecreatedalinkinmyMACOSFilemanagerdirectytothisfolder:

Page 131: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission
Page 132: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section2:EnablingMACOSXPlatform

Bydefault,inthe“MultiDeviceApplication”theMACPlatformisautomaticallyasatargetintheProjectManager.Ifyouhavethisdeletedonceordonotfindinaninheritedproject,addyourFireMonkeyprojectbyusingtherightmousebuttononthe“TargetPlatforms”buttonintheProjectManagerandselectfromthepopupmenu“AddPlatform”command,

Ifyoudothisforthefirsttime,theplatformmustfirstbeestablished.

YoumayneedalsotomakesettingsfortheSDK.Forthispurpose,thePAServerontheMACmustalreadyberunning.Clickwiththerightmousebuttonontheplatformnameandselect“EditSDK”command:

BeforeIgointothisdialog:Itcouldbe,thatbeforethisdialogappears,youhavetoinputaprofilename.Andnowtothedialog:

Page 133: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ForHostName,IrecommendinsteadspecifythenameoftheMACPC,totaketheIP-addressfromtheMACinthenetwork(youwillfindtheIPaddressoftheMACthereunder“ControlPanel,Network”).Theconnectionworksfasterinmixedwiredandwirelessnetworks,andsometimesitworksonlywiththeIPaddress(TIP:IftheIPaddressisdynamicallyassignedbyyourrouter,theIPaddresswillchangeatthenextday,whenyouworkagainwithyourconection.SoifsubmissiontotheMACdoesnotwork(itthenonlygivesthemessage“Error”,withoutfurtherexplanation),thisshouldbethefirstthingtocheck.YoucanalsoadjustthesystemsettingsoftheMAC’s,sothatherealwayswillbeusedaspecificIPaddress,thenyouwillneverneedtochangeanythinghere(Ihavedoneitlikethat,allworksgreat!).

Leavetheportnumberhereasspecified,underpasswordleaveitblank,orenterapasswordforthePAServerifyouhavesetupone(noneedusuallythereforanditcomplicatesmattersevenunnecessary).

Butnowbacktothe“EditSDK”dialog.HereyoucanselectasuitableSDK.Thereareherenormallyavailableoneorseveraltochoosefrom.Normallyselectthenewest.Orselectonolderone,ifthereareproblemswiththelatestSDK.SDKversionsaredirectlyrelatedtotherespectiveOSversions.

IfyouhaveaddedaplatformthanitcouldlooklikeintheProjectwindowlikethis:

Page 134: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ImportantNote:DependingonwhetheryouselectthetargetplatformWindowsorMACOSX,alsothepresentationoftheProjectOptionsdialogchanges.Specialattentionishereaboutthe“VersionInfo”.Becausewiththatitislatermadetheinfo.plistfilethatmustaccompanyeachMACprogram.

AlsoofimportanceintheProjectOptionsisthe“EntitlementList”,whereyoucanspecifywhichrightsareavailabletoyourprogram.Inparticular,ifyouwanttodistributeyourprogramsontheAPPLEAppStore,youshouldchoosecarefullytheinformationhere.

FromtheEntitlementListDelphigeneratesthe“.Entitlements”filethatisdistributedwiththeprogram(whichisespeciallyforthesandboxingmodelofrelevance).

TheEntitlementList:

TheVersionInfo:

Page 135: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifneeded,youcanaddanewkeyhere.Thisisbyclickingtherightmousebuttononthetableheader“Key”(seeinyellow):

Thebelowdialogwillthenappearwhereyoucanenterthenewkeyname:

Unfortunately,youcanonlyentersinglevaluesinthegridlist.Ifyouaddanarraystructure,thislooksatfirstsightgood:

However,theeditorinsertsanadditional<String>entrysothatthekeygroupultimatelycan’tbeutilized.Therefore(andaslongitisnotfixedinDelphi),youmustedittheinfo.plistfilebyyourselfinatexteditor,sothattheentriesarevalidhere.

Page 136: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Section3:Provisioninganddeployment

Undermenu“Project”,youcallthecommand“Deployment”andtheregister“Deployment”willbeshown.Hereyoucanaddmorefilestoyourproject.Thatcan,forexample,beHTMLHelpfilesorplaintextfilesorgraphicsthatarerequiredbyyourprogram.Thisisareallyhandything:

The.rsmfileisafile,whichisrequiredonlyforthedebugger.Ifyoulatercreatethefoldermanuallyfroma.dmgfile(DiskImage)(i.e.fordistributionoutsidetheappstore),youmustdeletethefileinthescratch-directoryfromtheMacOSfolderbefore.Howitworksandhowtocreatethe.dmgfile,seebelow.The.rsmfileisalsonotrequiredfordistributionintheMACAppstore.Therefore,forallcompletedprojects,deletethisfilefromtheapplicationbundle,asfarasDelphihasnotalreadydonethisforyou.

IfDelphihascreatedtheprogram,DelphitransmitsittotheMACintotheScratch-Dirdirectorythatyoucanfindnormallyunder

“/Users/YourUserName/PAServer/Scratch-Dir”.

Theexecutablefileisusuallylocatedinthe“MacOS”folder.Under“Contents”,youwillfind“info.plist”andthe“Entitlements.plist”.Thelybcgunwind.1.0.dlybfile,youneedinthedeliveryversionoftheprogram,otherwiseitwillnotrun.

Page 137: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

1.SubmissiontotheAPPLEAppStore

ForthisyouhaveunderthetargetplatformMACOSentrytoswitchfrom“Normal”to“ApplicationStore”:

Underthemenu“Project,Options,Provisioning”,checkthatthereisselectedasabuildtype“OSXApplicationStore”.Andofcourseyouusethe“Releaseconfiguration”.Inthetwoinputlinesyoumakeentriesaslistedbelow:

Theinstallationprofile“3rdpartyMacDeveloperInstaller”isacertificatethatisusedtosigntheinstallerfile.

FirstcheckonyourMacinthe“KeychainAccess”ifyouhavealreadyinstalledtherequiredcertificatesonyourMAC:

Page 138: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifyoudonotalreadyhavesuchacertificate,youcangetonefromApple,butyoudefinitelyneedanAppleDeveloperIDforit(seebelowunder3a).

Ifyouhavecalledthecommand“Deploy<Projectname>”intheDelphiProjectmenu,DelphitransferstherequiredfilestoyourMacandcallsthecodesigningtoolthatinitiallysignedtheexecutable(youwillbepromptedtoallowthis).Rightafterthat,Delphicallsthe“ProductBuildTool”thatproducesaso-called“Package”,afilewiththeextension“.pkg”willbecreated.This“package”isthenalsotheinstallationfile,andthatiswhyitisthenalsowiththecodesigningtoolsignedwiththeInstallationCertificate(youmustalsoallowthis,unlessyoualwaysallowthis).

ThiscompletedPackage,youcanthenuploadtoApplewiththeAppleprogram“ApplicationLoader”.First,however,youmustcreateadataentryforyourprogramthroughiTunesConnectandcompleteyourinputwith“Readytouploadbinary”.Aftertwomoreconfirmationsfordatasecurity,youcanthenuploadyourapplication(thepackage)withtheApplicationLoader:

IfyourprogramisattheAppleemployeesforreview,itusuallytakes3-7daysuntilactuallyanassessmentiscarriedout.

Tostayinformedabouttheprogress,youcanuseafreeappfromApple(ITC-Mobile),ImadebelowascreenshotofmyiPhone.

Thisallowsyoutomanagetheappstoacertainextentandexamineyoursales.

Page 139: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Theprogramswiththegreendotsarealreadyinthestore.Thesewithorangedotsareeitherwaitingforarevieworarejustinreview.Inthegrayboxyoucanseethe“OSX”or“iOS”label.Thatwillindicate,ifitisaprogramfortheMACorforiPhone/IPad.Under“Sales/Trends”youcancheckforadayorforaweek,howmanyproductshavebeensold.Alsoyoucanseethecountriesinwhichyouhavesoldyourprograms.Surprisingly,IwasabletofindevenwithmyonlyGerman-languageprogramsbuyersintheUS,Russia,Thailand,Japan,Italy,MexicoandSlovakia.

AfteramonthyouwillgetfromAppleoneormore“FinancialReports”viae-mail,youcanviewitoverthewebiniTunesConnect.Thereyoucanseehowmanyunitshaveyousoldinthecountriesandwhatamountofmoneyisowedtoyou.Andyouwillseewhenthenextpaymentdateis,whenApplewilltransferyourshare.Butmoneywillonlybepaidifyoutakemorethantheequivalentof$150.Thefirstregularpaymentdateisbetween1-2months,dependingonthetimeatwhichyouhaveentered.

Atip:BeforeyouloadaprogramintotheApplestore,lookatApple’s“AppStoreReviewGuidelines”on.Hereisthelinkto:

https://developer.apple.com/app-store/review/guidelines

Page 140: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

2.Createa.dmgfilefordistributionoutsidetheAppleAppStore

IsellmyprogramsevenwithouttheAppStore.Thiscanyoudoalsoasfollows:AfteryouhavecreatedwithDelphiaMACOSXreleaseversion(withtheprojectsetting“Normal”andnot“AppStore”),runontheMacthe“DiskUtility”(Applicationsfolder,“Utilities).Selectthe“File”menuandselect“New”,“DiskImagefromFolder”:

TheFinderdialogisthandisplayed,soyoucannavigatetothedirectorywhereyourprogramis:

Selecttheprogramfileandclickon“Image”.Thefollowingdialogisdisplayed:

Page 141: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Irecommendtoremovetheextension“.app”andchoosethelocationofthedesk.TheinthiscasecreatedTEditor.dmgfile,youcannowdistributeitovertheInternettoyourcustomers.

Afterdownloading,thecustomerclicksdoubleonthe.dmg-fileandfromthewindowthatappears,dragsthefileintotheprogramfolderandtheprogramisthaninstalled.

Page 142: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

3.CreateyourownsetuppackagewithApplicationDeveloperID/Installer

Anotherpossibilitywouldbetosigntheprogramwiththe“DeveloperApplicationID”certificate,andthencreateyourownsetuppackageandsignthiswiththe“DeveloperIDInstaller”certificate.

Whatarethebenefits?

Well,sinceMACOS10.7.5Appleusestheso-called“Gatekeeper”functionthatcanbeenabledinthesystemsettingsunder“Security”,“General”tab:

Evenifthereiswritten“AllowDownload”-itisprobablymeant“Run”.Becauseyoucandownloadaprogram,whichislocatedina.dmgfilefromtheInternetandeventhendragtheapplicationintotheApplicationsfolder.

Iftheuserhasthesettingsshownasaboveactivated,andisnowtryingtorunyourprogramthatyouhavesoldasdescribedaboveundernumber2,itwillbeshownadialogasfollows:

Soifyouwanttoplayitsafe,youneedtohaveyourprogramwiththecertificatesdescribedabove.InyourKeychainAccess,youmusthavethefollowing(colored)certificates:

Page 143: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifyoualreadyhavethesecertificates,youcanskipthenextsubsectionandreadmoreunder3b)“WorkingwithCodeSigntoolandPackageMaker”.

a)RequestaDeveloperIDcertificateandanApplicationDeveloperInstallerID

Ifyoudonotalreadyhavesuchcertificates,loginunderhttps://developer.apple.comandclickatthetoprightonto“MemberCenter”.

Thenclickonthelinkbelowisshown,thenyouwillbeforwardedintotheareawhereyoucanmanageyourcertificates:

Thenclickonthetable:“MACApps,Certificates”.ThistakesyoutothepagewherethemanagementofMACcertificatestakesplace.Clickrightthereontopontheplusbutton,thenyouwillgetthepagewhereyoucanchoosethecertificateaccordingtoyourneeds.

Page 144: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ultimatelyyouneedallcertificatesthatareofferedhere(ifyoualsowanttousetheAppStore).Forourpurposesitisatthemomentsufficient,whenyouaskforthethelowercertificates(“DeveloperID”,notvisibleinthescreenshotabove).DownloadittoyourMAC,doubleclickonthefile,soitwillbeinstalledintoyourKeychainAccess.

Idonotwanttotakeallthestepshere,butmaybetwotipsonthis:

Tip1:Beforeyoucaninstallyourcertificates,youneedthe“WWDRIntermediateCertificate”andthe“DeveloperIDIntermediateCertificate”.Thisnoticeisalsodisplayedonthepageshownabove,ifyouscrolldown.

Tip2:Tobeabletocreateyourcertificatesingeneral,youneeda“CertifacteSigningRequest”file.

Wheredoyougetthemfrom?

UsingtheKeychainAccess.Hereyougoto“KeychainAccess”,“CertificateWizard,”“Requestacertificatefromacertificateauthority”:

Page 145: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thenthefollowingdialogwillbedisplayed:

Onceyouhavefinishedthisdialog,youwillreceivetherequestedfile.InmycaseIhadtocreatethisfilebythewayseveraltimes,becauseofthedifferentcertificatesanddifferentrequestfileswereneeded.

Alsoanimportanthint:afterIgotmyDeveloperID’sandthiswastransferredtotheKeychainAccess,firstitwasdisplayed,thattheywereinvalidbecauseitweresignedbya“UnknownCertificateAuthority”.Ithashelpedtowait:24hourslater,Ihavedownloadedthecertificatesagainfromthecertificatesareaandre-installedit.Thanallwasperfect.

b)WorkingwiththecodesigningtoolandPackageMaker

IfyouhaveDelphirunningwithyourMacOSXprofileandcreatedyourMACprogram,youmustsignitthen.

SincetheprogramisnotfortheAppStore,youselectas‘Build-type”intheprojectoptions“OSX-Normal“.

Page 146: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AfterrunningtheprogramandthetransfertotheMAC,youmustusethecodesigningtoolmanually,tosignyourpackage.Youcanuseitbyinvokingitfromthecommandline.Todothis,openanotherterminalwindowandchangetothedirectorywhereyourapplicationresides.

Thentypeintheterminalwindow:

codesign-s“DeveloperIDApplication”TEditor.App

Whichthenofcoursereplace“TEditor.App”withthenameofyourapplication.

You’llagainbepromptedtoallowthesign:

So,nowyouhavesignedyourprogram,buthowdoyoucreatethesetuppackage?

Youcandothisusingthe“PackageMaker“,whichyouwillfindbydefaultnolongeronnewerMACOSversions.SoyoumustdownloaditfromApple.Thisisdonethereinthe

Page 147: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

downloadarea(https://developer.apple.com/downloads/index.action?name=PackageMaker).Ifindoubt,searchfor“AuxiliaryToolsforX-Code”.

Then,installthedownloadedprogrampackage,openitandstartthePackageMakerprogram.

ForMacOSXMaverickorlatertheprogramcan’tbeused(apparently)becauseitkeepscrashing.I’vesimplyinstalleditonanolderMacOSXversion(MountainLion)anduseditthere.Hereyoucansee,thatitcouldsometimesbeusefultohavealsoolderMACOSSystemsinaccess(IhavethisonseveralofpartitionsonmyMac).Ifthat’stoomuchtrouble,youmustuseoneofthecommercialprogramswithwhichyoucancreateinstallationpackagesfortheMAC.IfyoucanusethePackageMaker,proceedasfollows:

At“Certificate”,youclickthearrow,andthenenteryour“DeveloperIDInstaller”certificate.Alsoyoucanmakebasicsettings,e.g.asthetitleofthesetup,wheretheprogrammaybeinstalled,andsoon.

Nextimage:justdragyourprogramfromtheFinderintotheleftsideofthewindow,orclickbesidetotheline“Install”onthebuttonandgotoyourfolderwherethecompiledandalreadysignedprogramis:

Page 148: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Soyoucaneasilyusethisdialogtomakethenecessarysettingsforyoursetuppackage.

Ifyouclickon“EditInterface”onthetopright,adialogappearswhereyoucanselecttheindividualinstallationstepsindetail:

Hereyoucandirectlyinsertyourcontractortextsorrefertoafile.Thelicenseinformationmustbeacceptedbytheuser,otherwisetheprogramcan’tbeinstalled.

Thenclickthe“Build”or“BuildandRun”,thenyoursetuppackageiscreated.Youwillbepromptedagaintoallowthesigningandthenyoursetuppackageisready.

Anditworkswellwiththegatekeeperiftheusershouldhavesettheinstallationrestrictionsdescribedatthebeginningofthissection.Forme,thisiscertainlynowthepreferreddistributionmethod(IuseditalsoformypreviouslywithLazaruscreatedMACprograms).

Page 149: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Note:Whenrunningthesetup-programonmyMac,thePackageMaker-Setupinstalledagainandagaintheprogramintothedirectorywheretheprogramwasdeveloped.Icouldnotstopthat,butultimatelyithasnonegativeimpacttootherMACPC’s,thereitworks,asexpected.

Page 150: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter4:WorkingwithGraphicsinFireMonkey1.FireMonkeyTBitmapversusWindowsTBitmap

TheWindowsbitmapandFireMonkeybitmaparedifferent.Thisparticularlyconcernsthepixelformats.WhiletheWindowsbitmaphasbesidethe24-bitmapformatotherbitmapformatsavailable,themostwithFireMonkeylackthereofintheoutputformat.Inparticular,for1-bit,4-bit,8-bit,16-bitand24-bitoutputformatisnotavailableifyouwanttosavethebitmapwiththeextension“.bmp”.

WhileyoucanreadandwriteinWindowsTBitmaptheproperty“PixelFormat”,itisinFireMonkeyjustasareadingpropertyavailable.Thereisaprivate“SetPixelFormat”procedureintheTBitmapclass.Youcouldperhapsmakethisavailablewithaclasshelperfunction,butprobablyitwillnotmakemuchsense,sinceinternallyFireMonkeyalwaysoperateswitha32-bitbitmap.

However,whenusingtheformats,thattypicallyincludeanalphachannel,e.g.theformat“PNG”or“TIF”,theserelevantinformationisalsowrittentotheimagefile.

Whenloadingan8-bitbitmapfileinBMPformatandstoresagain,thecolorsaretakenovercorrectlyintheFireMonkeybitmap,butaftersavingthebitmapfile,itisa32-bitbitmapfile.

Andunfortunatelyinformationislost,ifoneloadsaWindows32-bitmapfilethathasanalphachannelintoaFireMonkeybitmap.Thevaluesofthealphachannelwillnotbetakeintoaccount,thisallhaveallthevalueof255(thatiscompletelyvisible).Iamnotquiteclearwhetherthisisabug.

2.TBitmapDatainsteadScanLineforbitmapmanipulation

WhileyoucanintheVCLprocessbitmapswiththe“ScanLine”function,itwillbereplacedwithFireMonkeysinceDelphiXE3bytheTBitmapDatarecord.

Thisrecordisdefinedasfollows:

Page 151: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TBitmapData=record

private

FPixelFormat:TPixelFormat;

public

Data:Pointer;

Pitch:Integer;

propertyPixelFormat:TPixelFormatreadFPixelFormat;

functionGetPixel(constX,Y:Integer):TAlphaColor;

procedureSetPixel(constX,Y:Integer;constAColor:TAlphaColor);

end;

Beforeyoucanaccessthepixels,youmustwith“MAP”askfortheaccesstothebitmap.Sowiththat,dependingonthetypeofaccess,thiswillbethandisabledforotherprocesses.Thiscontributestothethreadsafetyofbitmapediting.Ifyouhavefinishededitingthebitmap,youreleasetheaccesswith“UNMAP”.

TheaccesstypeisdeterminedbyTMapAccess,whichisdefinedasfollows:

TMapAccess=(maRead,maWrite,maReadWrite);

Forexample,tomanipulateaparticularpixelinabitmap,thatlooksinawholeasfollows(assumingmyBitmapisaglobalbitmapvariable):

procedureTF_Main.Image1MouseMove(Sender:TObject;Shift:TShiftState;X,

Y:Single);

var

vBitMapData:TBitmapData;

vPixelColor:TAlphaColor;

begin

ifMyBitmap.Map(TMapAccess.maWrite,vBitMapData)thenbegin

vBitmapData.SetPixel(Round(x),Round(y),TAlphaColors.Red);

MxBitmap.Unmap(vBitMapData);

end;

end;

Ifyoualsoneedareadingaccess,youmustuse“maReadWrite”.Ifyouneedonlyreadaccess,use“maRead”.

Page 152: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Theexampleissimple,andsoeasiertounderstand,butinyourownprojects,youshouldofcourseworkwithTRY…FINALLYconstructs,toensurethattheblockingofthebitmapwillbecanceledintheeventofafault.

3.ChangethealphachannelofaTBitmap

Ifyouwanttochangeonlythealphavalueofapixel,youneedtousealittletrick.UseheretheTAlphaColorRectogetdirectlyaccesstothebyte,whichisresponsibleforthevalueofthealphachannel.

Thisworksasfollows:

procedureTF_Main.SetAlpha(X,Y:Integer;AVal:Byte);

var

vBitMapData:TBitmapData;

vPixelColor:TAlphaColor;

begin

ifMyBitmap.Map(TMapAccess.maReadWrite,vBitMapData)thenbegin

vPixelColor:=vBitmapData.GetPixel(x,y);

TAlphaColorRec(vPixelColor).A:=AVal;

vBitmapData.SetPixel(x,y,vPixelColor);

MxBitmap.Unmap(vBitMapData);

end;

end;

4.Drawonthecanvasofabitmap

AsisknownfromtheWindowsbitmap,itisalsopossibletodrawonacanvasfortheFireMonkeybitmap.Youcanusethisas“Bitmap.canvas.fillrect”,“Bitmap.canvas.Fillelipse”etc.TheunderWindowswellknown“canvas.textout”functionisherenotavailable,butinsteaduse“canvas.Filltext”.

Finally,aspecialnote:Youmustrunbeforeallthedrawingactionsonthecanvas“Canvas.BeginScene”andaftercompletion“Canvas.EndScene”.

Sothiswouldlooklike,forexample,asfollows:

Page 153: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IfBitmap.canvas.beginscenethenbegin

try

Bitmap.canvas.Filltext(…);

finally

Bitmap.canvas.EndScene;

End;

End;

5.Turngraphics,flip,invertorcolortogray

AseriesofgraphicsprocessingfunctionsisalreadyavailableinFireMonkeybydefault.

Rotateaimageleftorright?Nothingeasierthanthat:

Bitmap.rotate(270);//Turnbitmapleft

Bitmap.Rotate(90);//Turnbitmapright

Agraphichorizontallyorverticallyreflect:

Bitmap.Fliphorizontal;//mirroringthepicturehorizontal

Bitmap.FlipVertical;//mirroringthepicturevertical

ToinvertanimageortocolorgrayoneusesoneofthemostextensiveinFireMonkeysuppliedfilterfunctions.

AmongtheFireMonkeydemosisafineexamplethatdemonstrateswhatfiltersareavailableinFireMonkey,youwillfinditintheexamplesfolderinthesubfolder“shaderfilter”.

Althoughthedemocandemonstratealot,unfortunately,itiswrittenso,thatmuchisgeneratedatruntimeordynamically.Ifwelookintothesourcecode,itisthanunfortunatelynotveryhelpful.

Ihavethereforecreatedasimplefunction,whichillustratestheuseoffilters.

Page 154: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Forexample,toinvertanexistingbitmap,itissufficienttocallthefunctionasfollows:

MyBitmap.Assign(ImgByFilter(MyBitmap,‘Invert’));

Andsothefunctionlooks(theunit“FMX.Filter”isrequired):

functionImgByFilter(bm:TBitmap;FilterName:string):TBitmap;

var

bmold:TBitmap;

Filter:FMX.Filter.TFilter;

begin

Filter:=TFilterManager.FilterByName(FilterName);

bmold:=TBitmap.Create(0,0);

bmOld.Assign(bm);

ifFilter<>nilthen

begin

//setinput

Filter.ValuesAsBitmap[‘Input’]:=bmOld;

//setTargetonlyfortransition

Filter.ValuesAsBitmap[‘Target’]:=bm;

//applyandgetintoresult

Result:=TBitmap(Filter.ValuesAsBitmap[‘output’]);

Filter.Free;

end;

bmOld.Free;

end;

Tocolorabitmaptogray,callthefilterfunctionasfollows:

Myitmap.Assign(ImgByFilter(MyBitmap,‘Monochrome’));

Ofcoursewiththisfunction,onlythefiltersareappliedthatworkwithoutadditionalsettings.

Page 155: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IntheFireMonkeydemomentionedabove,theuseoffilterswithsettingshasbeensolvedso,thatdynamicallyatruntimeafilterattributerecordwiththepossibleattributenamesandsettingvaluesofthefilterisfilled.ThisinformationisthenusedtodynamicallygenerateTTrackbarsthataregeneratedwiththeminimumandmaximumvaluesofthefilterattributes.ThisTTrackbarsalsobeassociatedwithaneventhandlertorespondtochangesinTTrackbarsandthenapplythefilteraccordingtothebitmaps.

Thisisalsothereasonwhythedemoisnotquitesoeasytounderstandwhenyoulookatthesourcecodeofthedemo.

Soyoucouldextendthe“ImgByFilter”function,byexampletointegratethefollowingsettings:

Filter.ValuesAsPoint

Filter.ValuesAsColor

Filter.ValuesAsFloat

Filter.ValuesAsTexture

Forexample,applyingthesepiafilterwithaspecificvalueintheabovefunction,youwould-beforecallingtheValuesAsBitmapwiththe“output”option-usethefollowinglinebefore:

Filter.ValuesAsFloat[‘Amount’]:=0.2;

Hereyouwouldgeta20%sepiacoloringofthebitmap.

Itshouldbenoted,however,thatnotallsettingsareusedwith“Amount”.Someuseforexample,“Levels”,“Length”,“Opacity”andthesettingsarenotalwaysbetween0and1,theycanhavealsootherminimumandmaximumvalues.

Forthatthementionedshaderfilterdemohelpsyou.Thereyoucansimplyclickonthefilternameandyouwillgettheindividualsettingsnameandthevaluerangeswillbeshown.Hereisanexampleofthe“sharpening”function:

Page 156: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Andhereisanexampleofthe“Emboss”function,whichusestwosettingattributes:

Overall,IfindthegraphicscapabilitiesofFireMonkeyquiteimpressive.

6.Drawingabitmapscaled

FromtheVCLyouknow,forexample,the“StretchDraw”function,whichallowsyoutodrawscaledgraphics.InFireMonkeyyouusethefunction“DrawBitmap”.IusethisforexamplealsoinmyAppStoreprogram“MultiScreenCopy”:

Page 157: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

SojustassumedyouhaveabitmapintheTImagecomponent“Bild”insize1680x1050pixels.Itcanbescaledforexample,asshownhere,scaleddownto1024x640pixels(proportional).

ifShowModal=mrOKthenbegin

bm:=TBitmap.Create(StrToInt(ceNewWidth.text),StrToInt(ceNewHeight.text));

bm.Canvas.BeginScene;

bm.canvas.DrawBitmap(Bild.Bitmap,RectF(0,0,Bild.Bitmap.Width,Bild.Bitmap.Height),RectF(0,0,StrToInt(ceNewWidth.text),StrToInt(ceNewHeight.text)),1,False);

bm.Canvas.EndScene;

End;

Soyoufirstcreatethebitmapinthedesirednewsize,andthenpaintonthecanvaswith“DrawBitmap”.Asaparameteryouusetheoriginalbitmap,whosesizeandthenewdesiredoutputsize.Thetransparencyyouleaveto“1”forfullyvisible,theinterpolation-modeleavewith(“HighSpeed”=)“False”.

Page 158: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter5:UsefulthirdpartycomponentsforFireMonkey

1.TMS-Components

SeveraltimesinthisbooktheTMScomponentshavealreadybeenmentioned.ThemostusefulTMSFMXBitmapcontainercomponenthasalreadybeenmentioned,becauseitispracticallya(better)replacementfortheTImageListfromtheVCLworld.ButalsoprovidestheTTMSFMXGridanumberofusefulfeatures,e.g.incombinationwiththepossibilitytoexportthecontentofthegridasExcel,RTForPDFfile(TTMSFMXGridExcelIO,TTMSFMXGridRTFIO,TTMSFMXGridPDFIO).

AlsobrieflymentionedwastheTTMSFMXRichEditor,whichisaworthyreplacementfortheVCLRichEditcomponent.WiththeTTMSFMXRichEditorFormatToolbarcomponentandtheTTMSFMXRichEditorEditToolbartworeadytouseToolBarcomponentsaredelivered,thatyoucanassociatewiththeeditor.

TheTMS-RichEditorcansave,ifnecessary,histextasRTForHTMLfile.

FortheRichEditorIhaveplacedashortvideoonYouTube,justhavealookhere:

https://www.youtube.com/watch?v=_BjlRX_CjX4

Thisisgoodnews:Asofversion2.9.0.0ofTMSPackforFireMonkey,onecanusetheRichEditorevenwithacompletespellcheck.Thedictionariesareincluded,interalia,inGerman,English,French,SpanishandItalian.

HereisthelinktotheTMSPackforFireMonkey:

http://www.tmssoftware.com/site/tmsfmxpack.asp

Finally,wemustmentiontheTMScloudPackforFireMonkey:WiththatyouwillgetaccessunderWindows,Mac,iOSandAndroidtothevariouscloudservices,whichareofferedforthoseplatforms.Soforinstance,DropBox,GoogleDrive,WindowsOneDriveBOXandservicesoniOS.

Page 159: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

HereisthelinktotheTMSCloudPackforFireMonkey:

http://www.tmssoftware.com/site/tmsfmxcloudpack.asp

EvenifyouhaveorwanttousecertainnativecomponentsforMAC(oriOS),TMShelpsyouwiththemCLcomponents(oriCLoniOS).

Inacrosscompileproject,however,youhavewiththeuseofthiscomponentsalittlemoreeffort,becauseofcoursefortheWindowsdesktopthisnativeMACOScomponentswillnotwork.Butsometimesit’stheonlywaytorealizeaprojectforMACatall.

Forexample,todisplayPDFfilesinmyinvoiceprogramontheMacinaseparateform,IusetheTMSFMXNativeNSViewcomponentfromTMS(whileIuseunderWindowsawithaHydra-moduleintegratedcomponentofGnostice).

ThedirectgenerationofPDFinvoicefileI’lldoonMACwiththeTMSFMXNativeMacPDFLibcomponent.

HereisthelinktotheTMSmCLcomponents:

http://www.tmssoftware.com/site/tmsmcl.asp

However,TMShasmoreFireMonkeycomponentstooffer.AcompleteoverviewoftheTMSComponentsforFireMonkeycanbefoundhere:

http://www.tmssoftware.com/site/products.asp?t=fm

2.ReportgeneratorFastReportFMX

WithFastReportsFMX,youcancreatereportslikeyou’reusedtodoitundertheWindowsVCL.InDelphiXE7althoughastandardversionofFastReportsFMXisincluded,however,itcontainsnoredistributablereportdesigner.ThisisobtainedwhenoneacquiresthecommercialversionofFastReports.

HeretheFastReportdesigneratdesigntime:

Page 160: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Together,thesecomponentsprovidealargeamountofoptionsforcreatingreports(incl.PDFoutput).

Hereisthelink:

https://www.fast-report.com/en/product/fast-report-fmx

3.RemObjects-ApplicationFramework(Hydra)

Thesearenotcomponents,butaframeworkthatallowsyoutomixVCLandFMXcomponentsinaform.ForexampleyoucaninaVCLFormsdirectlyintegrateFMXcomponents(ortheotherwayaround).

ThisissurelyawaythatshouldnotbethefocusofyourworkwithFireMonkey,butitoffersadditionalwaysandopportunitiestotopickallpossibilitiesfromtheVCLandFMXworldsout.

Hereisthedirectlink:

http://www.hydra4.com/hydra/default.aspx

Page 161: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Here,too,IdepositedashortvideoinYouTube,whichyouarewelcomedtoview,ifwanted:

https://www.youtube.com/watch?v=0K8mEzDmlaM

4.Othercomponents

OthercomponentsmanufacturershaveannouncedsupportforFireMonkey(e.g.Gnostice)orwaitingtomakeadecisionforit(DevExpress,ImageEn,TRichView).ButtherearealsootherdevelopersandFMXsupporters,whohavedevelopedasetofcomponentsandprovidethempredominantlyfreeofchargeforyou.

HereIrecommendyoutotakealookoverathttp://www.fmxexpress.comandtoexaminewhetherthereissomethingforyourneedshere(wheremostcomponentsratherrefertoiOSorAndroiddevelopment).

IhopeIcanthismeagerlistheresoonextendalittlebit…

DoyouknowgoodFMXcomponentsthatIshouldmentionhere?Ifyouwant,sendmeyoursuggestionwithashorte-mailto([email protected]).

Page 162: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter6:Howto-tips&tricksforFMX

Hereyouwillfindanumberofdifferentquestionsandanswers.Asatributetomybeloved“cookbook”-DelphiseriesbyWalterDoberenzandThomasKowaslkiIleantotheR-numberingfromthesebooks,whichstandsfor“recipes”(inGermanitmeansakindofwrittendescriptiontohandlesomething).

R1…Getthedisplayresolution?

Forthispurpose,weusedaplatformservice.

Example:

procedureTfrm_Main.FormCreate(Sender:TObject);

var

ScreenSvc:IFMXScreenService;

Size:TPointF;

begin

ifTPlatformServices.Current.SupportsPlatformService(IFMXScreenService,IInterface(ScreenSvc))

thenbegin

Size:=ScreenSvc.GetScreenSize;

end;

end;

Size.xgivethewidthandtheheightisinSize.y.

R2…CheckiftheEscape,CtrlorAltkeyispressed

Sometimesyouneedforanongoingprocessanoffertointerruptorcancelit.UnderWindows,intheVCLitworkslikethis:

if(Getkeystate(VK_CONTROL)<0)thenbegin//IstheShift-keypressed?

Page 163: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

//yes—>

exit;

end;

AndsodoyoudoitunderFireMonkey:

{$IFDEFMACOS}

Uses

MacApi.AppKit,MacApi.Foundation,Macapi.CocoaTypes;

{$ENDIF}

functionIsControlKeyPressed:Boolean;

begin

Result:=NSControlKeyMaskandTNSEvent.OCClass.modifierFlags=

NSControlKeyMask;

end;

InaCross-platformwayyouhandleitbestlikethis(whichIunfortunatelystilldon’tknowisthesolutiontoquerytheESCkeyonMAC(doesanyoneknowthesolution?):

functionIsControlKeyPressed:Boolean;

begin

{$IFDEFMSWINDOWS}

Result:=GetKeyState(VK_CONTROL)<0;

{$ELSE}

Result:=NSControlKeyMaskandTNSEvent.OCClass.modifierFlags=NSControlKeyMask;

{$ENDIF}

end;

functionIsShiftKeyPressed:Boolean;

begin

{$IFDEFMSWINDOWS}

Result:=GetKeyState(VK_SHIFT)<0;

{$ELSE}

Result:=NSShiftKeyMaskandTNSEvent.OCClass.modifierFlags=NSShiftKeyMask;

{$ENDIF}

end;

Page 164: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

functionIsESCKeyPressed:Boolean;

begin

{$IFDEFMSWINDOWS}

Result:=GetKeyState(VK_Escape)<0;

{$ELSE}

//Result:=NSEscapeKeyMaskandTNSEvent.OCClass.modifierFlags=//NSEscapeKeyMask;(soitdoesnotwork)

{$ENDIF}

end;

HereIshouldmention,thatIhavestoredthisfunctionsina“shared.plattform.pas”unit,whichiscurrentlyonlyavailableforWindowsandMAC.Butitwouldbebetter,onewouldmaketheIFDEF’swith“MSWINDOWS”and“MACOS”,thenitwouldbe,forexample,easiertoextendthefunctionslatertousewithLinux.

R3…UsefoldernamesunderWindowsandMACproperly

OnWindows,youusethe“\”charactertospecifydirectoriesandfilesinafilepath,e.g.,

“D:\Data\Forms\File.doc”.

UnderMAC,itisthe“/”characterwhichistobeused.Example:

“/Users/harrystahl/Documents/Datei.doc”.

Tobeshure,thatthatyoualwaysusetherightdelimiter,usethedefinedconstant“Pathdelim”.DependingonwhetheryoucompileonWindowsorMac,thecorrectversionisused.Thebelowexcerptfromtheunit“System.SysUtils”shows,thatalsotheconstants“DriveDelim”and“PathSep”areavailable:

const

PathDelim={$IFDEFMSWINDOWS}‘';{$ELSE}‘/’;{$ENDIF}

DriveDelim={$IFDEFMSWINDOWS}‘:’;{$ELSE}”;{$ENDIF}

PathSep={$IFDEFMSWINDOWS}‘;’;{$ELSE}‘:’;{$ENDIF}

Thus,therootdirectoryalwaysstartswith“/”undertheMAC.Ifyouwanttofindonthe

Page 165: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

MACassociateddrives,youmustquerytheentriesofthefirst-leveldirectoryunder

“/Volumes”.

Thefollowingsourcecodereadstheexistingdrives(“volumes”)onmyMac(underWindowsitworkslikethis,ofcoursenot):

//UnitsSystem.IOUtilsundSystem.Typeswillbeneeded

procedureTForm9.FormCreate(Sender:TObject);

var

sdaDrives:TStringDynArray;

sDrive:string;

begin

sdaDrives:=TDirectory.GetDirectories(‘/Volumes’);

forsDriveinsdaDrivesdobegin

Listbox1.Items.Add(sDrive);

end;

end;

Herearetheresults(with“Add(copy(sDrives,10,255))youwouldgetonlythedrivename):

R4…Usesearchmaskfor“allfiles”inWindowsandMACproperly

IfyouwanttoviewinfilesearchesonWindows“allfiles”usethemask“*.*”.UnderMACitseemsalsotoworkwell.However,“*”istherightmask.The“*.*”woulde.g.notdisplayfiles,thatarewithoutafileextension.

Page 166: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ithereforeusethefollowingsolutionwithaconstant,whichalwayshastherightcontentintheusedcontext:

{$IFDEFMSWINDOWS}

const

AllMask=‘*.*’;

{$ENDIF}

{$IFDEFMACOS}

const

AllMask=‘*’;

{$ENDIF}

R5…Avoidloopingsymlinkfolders(Alias)

OntheMac,youcancreatean“alias”forfoldersandfiles.Analiasfolderisultimatelyonlyareferencetothefolderthatisontheharddriveonanotherlocation.Ifyouareinafolderandallsubfolderssearchesforfilesinarecursivesearch,herecanpossiblyariseaclosedloopsituation.Ifanaliasinafolder“A”pointstoafolder“C”andthisfolderisfoundareferencebacktothefolder“A”,thesearchcontinuesendlessly.

Therefore,inarecursivefilesearchtheattribute“faSymlink”hastobefilteredout.

Hereisanexamplethatsearchesforallthe“.pas”filesinthefolder“D:\Delphi”andstorestheresultinaTStringList:

//Findsallfilesthatmatchthespecifiedcriteria

procedureFindThisFiles(pa:String;subDirs:Boolean;sl:TSTringList);

var

Search:TSearchRec;

begin

ifFindFirst(Pa,faAnyFile-faDirectory,Search)=0thenrepeat

sl.add(ExtractFilepath(pa)+Search.name);

untilFindNext(Search)<>0;

FindClose(Search);

Page 167: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ifSubDirsthenbegin

ifFindFirst(ExtractFilePath(pa)+‘*’,faDirectory-faSymLink,Search)=0

thenbegin

Repeat

if((search.attrandfaDirectory)=faDirectory)

and(search.name[1]<>‘.’)

thenbegin

FindThisFiles(ExtractFilePath(pa)+Search.Name+PathDelim+

ExtractFileName(pa),SubDirs,sl);

end;

untilFindNext(Search)<>0;

end;

FindClose(Search);

end;

end;

procedureTForm11.Button1Click(Sender:TObject);

var

sl:TSTringList;

begin

sl:=TStringList.Create;

FindThisfiles(‘D:\Delphi\*.pas’,true,sl);

end;

R6…Inwhichsituationsfilesymlinksfunctionsplayaroleotherwise

Ifyouwanttogettheattributesfromafileyouuse“TFile.GetAttributes”

Attributes:=TFile.GetAttributes(‘MyFileName’);

Butitmaybe,thatthefileisanalias.Bydefault,youwillreceivenottheattributesofthealiasfile,buttheattributesofthefiletowhichthealiasfilepoints(targetfile).

Youcanuse“TFile.GetAttributes”thereforebyaddinganotherparameter(which,ifnotspecified,isjusttrue)inordertoavoidthepointingtothetargetfile:

Page 168: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Attributes:=TFile.GetAttributes(‘MyFileName’,false);

Thefunctionisdeclaredin“System.ioutils”asfollows:

classfunctionGetAttributes(constPath:string;FollowLink:Boolean=true):TFileAttributes;inline;static;

TheFollowLinkparametersalsoexistinanumberofotherfilefunctionssuch“TFile.exists”,“TDirectory.Exists”,etc.

Whenusingfilefunctions,soyoushouldletdisplayalwaystheparametersthatyoucanusethere,becausepossiblythereareevenmorethanyouwouldexpect.

Uncheckedsymlinkpropertiescanleadtounwantedresultsnowandthen.Let’ssayyouwanttocopyafile.Ifitisanalias,sodonotcopytheperhapsonly30byteswidealiasfile,buttheTargetfilethatispossiblyseveralgigabytesinsize.Thiscaneverleadtosurpriseswhenyou,forexample,performabackupoffilesinadirectory.Youshouldthereforealwayscheckfilestosee,ifthereisanaliasfileandthenreacttoitasneeded.

Normallyitshouldbesufficienttoexaminetheattribute“faSymlink”inthefileattributes.However,I’vefoundundertheMACthathere(forwhateverreason)somefileshavetheattribute,althoughtherewereobviouslynoaliasfiles.

Justtobeonthesafeside,youcouldusethefollowingexampletocheckthis:

FunctionIsASymlinkfile(Filename:string):Boolean;

Var

SymlinkRec:TSymLinkRec;

attr:TFileAttributes;

begin

Result:=False;

TFile.GetAttributes(Filename,false);

ifTFileAttribute.faSymLinkinAttrthenbegin

TFile.GetSymLinkTarget(Filename,SymlinkRec);

ifSymlinkRec.TargetName<>”thenbegin

Result:=True;

end;

end;

Page 169: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

end;

R7…Determinethecontrolunderthemouseposition

Ifyouwanttofindoutwhichcontroliscurrentlylocatedatthecurrentmouseposition,youcandosowiththe“ObjectAtPoint”.

Hereisanexample,togettheclassnameoftheobjectoverwhichthemousepointerisjust:procedureTForm9.Timer1Timer(Sender:TObject);

var

obj:IControl;

begin

obj:=ObjectAtPoint(Screen.MousePos);

ifobj<>NILthenbegin

Label2.Text:=TControl(obj).ClassName;

end;

end;

R8…findoutonwhichMACOSXoperatingsystemtheprogramisrunning

Intheunit“System.SysUtils”therecord“TOSVersion”isavailable,thatallowsyoutoquerytheoperatingsystembothunderWindowsandMACOSX.

With“TOSVersion.ToString”yougetseveralrelevantparameterssummarizedtogether.UnderWindows7,theexamplelookshereasfollows:

UnderMacOSX,thenso:

Page 170: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Ifyoulookatthestructureoftherecordonce,youseewhatfeaturesanddataareavailableintotal:

TOSVersion=record

publictype

TArchitecture=(arIntelX86,arIntelX64);

TPlatform=(pfWindows,pfMacOS);

private

classvarFArchitecture:TArchitecture;

classvarFBuild:Integer;

classvarFMajor:Integer;

classvarFMinor:Integer;

classvarFName:string;

classvarFPlatform:TPlatform;

classvarFServicePackMajor:Integer;

classvarFServicePackMinor:Integer;

classconstructorCreate;

public

classfunctionCheck(AMajor:Integer):Boolean;overload;static;inline;

classfunctionCheck(AMajor,AMinor:Integer):Boolean;overload;static;inline;

classfunctionCheck(AMajor,AMinor,AServicePackMajor:Integer):Boolean;overload;static;inline;

classfunctionToString:string;static;

classpropertyArchitecture:TArchitecturereadFArchitecture;

classpropertyBuild:IntegerreadFBuild;

classpropertyMajor:IntegerreadFMajor;

classpropertyMinor:IntegerreadFMinor;

classpropertyName:stringreadFName;

classpropertyPlatform:TPlatformreadFPlatform;

classpropertyServicePackMajor:IntegerreadFServicePackMajor;

classpropertyServicePackMinor:IntegerreadFServicePackMinor;

end;

Page 171: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

R9…determinethecurrentusernameinMacOSX/Windows

Yousimplytakethe2ndentryfromthedirectory“GetHomepath”command:

{$IFDEFMACOS}

functionmac_GetComputerUserName:string;

begin

result:=GetfieldStr(PathDelim,GetHomePath,3);

end;

{$ENDIF}

IfyoudonothaveacomparableGetFieldStrfunction,youmakeitso:

{$IFDEFMACOS}

functionmac_GetComputerUserName:string;

var

sl:TStringList;

begin

sl:=TStringList.Create;

sl.Text:=StringReplace(GetHomePath,PathDelim,#13#10,[rfReplaceAll]);

result:=sl[2];

sl.Free;

end;

{$ENDIF}

Bearinmind,onWindowsitgoeslikethis(theWindowsunitisrequired):

{$IFDEFMSWINDOWS}

functionWin_GetComputerUserName:String;

var

P:PChar;

dw:dword;

ms:String;

begin

dw:=255;

P:=StrAlloc(256);

Page 172: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

GetUserName(p,dw);

ifdw>0thenbegin

ms:=String(P);

end;

Result:=ms;

end;

{$ENDIF}

OnWindows,theresultlookslikethis:

AndthenontheMACas:

R10…Sendfilesasanattachmentofane-mailwiththesystemmailprogram

Afrequentlyusedfunctionisthesendingoffilesthatwascreatedinyourownprogram.Thesimplestsolutionistotransferthefilestothee-mailprogram,thatisusedbytheoperatingsystem.

OnWindows,youcanusetheMicrosoftMAPI.I’massumingthatyouprobablyalready

Page 173: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

knowhowtodothatinWindowsusingtheMAPIinterface.Ifnot,youcandownloadfrommydevpagewebsitemyunit“uSendMail.pas”containingthehereused“SendFiles”function:

http://www.devpage.de/download/fmbook/uSendMail.pas

Thecross-platformsolutionforWindowsandMACisthenasfollows(usingtheexampleofaformwithalistbox,inwhichyouhaveselectedoneormorefiles,andthenclickabutton“sendmail”):

…Uses

{$IFDEFMACOS}

POSIX.Stdlib,

{$ENDIF}

{$IFDEFMACOS}

uSendMail.pas,

{$ENDIF}

procedureTf_Main.SendMailClick(Sender:TObject);

var

L:Integer;

app,s:String;

sl:TSTringList;

begin

sl:=TStringList.create;

{$IFDEFMSWINDOWS}

forL:=0tolbBilder.count-1dobegin

iflbBilder.listitems[L].isSelectedthenbegin

sl.add(lbBilder.Items[L]);

end;

end;

//E-mailthisherewiththeMAPIfiles

SendFiles(sl);

Page 174: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

{$ENDIF}

{$IFDEFMACOS}

forL:=0tolbBilder.count-1dobegin

iflbBilder.listitems[L].isSelectedthenbegin

sl.add(‘”’+lbBilder.Items[L]+‘”’);

end;

end;

s:=StringReplace(Trim(sl.text),#10,”,[rfReplaceAll]);

app:=‘/Applications/Mail.app’;

_system(PAnsiChar(‘open-a’+AnsiString(app+‘‘+s)));

{$ENDIF}

sl.free;

end;

IntheMACOSXsolutionastringismadeofthefilestobesentthatholdsthefilenameinquotesandseparatedbyaspace.AsamailprogramheretheAppleMailprogramisused.

Theparameters‘open-a’simplymeansthatthefunction“_system”shouldstartanapplication,andthenpassoverthefilestobesentseparatedbyaspace.

Note:Ifyouwanttogivetheusertheoptiontouseanothermailprogram,youcouldofferappropriateoptionsinasettingdialog.HewouldthensimplyselectthemailprograminAppleApplicationsfolder,whichheused.

Insteadof

app:=‘/Applications/Mail.app’;

youwoulduse

app:=‘/Applications/UserMailprog.app’;

Page 175: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

where“UserMailprog”theselectedusermailprogramwouldbe.Onerequirementwouldbe,ofcourse,thatthise-mailprogramwouldalsohavetosupportthetransferoffilesasparameters.

R11…providetheuserwithhelpfilesunderWin&MAC

OnWindows,youwilleitherhavebeentheMicrosoftHTMLHelpWorkshopusedtocreatea“.chm”helpfileoranotherprofessionalprogramwhichgeneratesthesefiles.

TheHelpWorkshopusedassourceHTMLfiles.OtherprofessionalprogramsworkeitherwithHTMLfilesorcanoutputthehelptext,atleastinsuchaformat.

Andthisisalsothesolution:useunderbothWindowsandMACOSXHTMLfilesthatallowyoutocallandviewhelpfromyourprogram.

Thefilesarethendisplayedinthebrowser.

InDelphi,youcanincludetherequiredHTMLfilesinyourapplicationbundlebyusingtheDeploymentfeature,thattransferthefilestotheMACOSfolder.

Hereyoucanseeanexampleofthe“index-en.htm”,whichcontainsthehelptextfortheEnglishlanguageversionandthe“index.htm”fortheGermanlanguageversion.FormoreextensiveprogramsyoucanalsocreatemultipleHTMLhelptextsandincludetheminyourprogram.

Inyourprogram,thencallasneededtheHTMLfiles(“AktLang”ishereaglobalvariable,managedbytheprogram.Itkeepstheinformationaboutthecurrentlyusedlanguage):

procedureTf_Main.mnu_ContentClick(Sender:TObject);

var

Page 176: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

fn:string;

begin

ifAktLang=‘DE’thenbegin

fn:=IncludeTrailingPathDelimiter(AppPath)+‘index.htm’;

end;

ifAktLang=‘EN’thenbegin

fn:=IncludeTrailingPathDelimiter(AppPath)+‘index-en.htm’;

end;

pf_ShowHelp(fn);

end;

Wherebytheprocedure“pf_ShowHelp”isdefinedasfollows:

Uses

{$IFDEFMSWindows}

uses

Windows,

ShellApi,

Classes;

{$ENDIF}

{$IFDEFMACOS}

Uses

System.Classes,

POSIX.Stdlib;

{$ENDIF}

procedurepf_ShowHelp(HTMLFile:string);

begin

{$IFDEFMSWINDOWS}

Page 177: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ShellExecute(0,‘open’,Pchar(HTMLFile),nil,nil,0);

{$ELSE}

_system(PAnsiChar(‘open‘+AnsiString(HTMLFile)));

{$ENDIF}

end;

Bytheway,Irecommendthatyoudonotdirectlycallawindowsfunctionfromaunit,whereyourprogramlogicisin.Itisbettertoplacethisinextra-units,e.g.a“WinOnly.pas”anda“Shared.plattform.pas”.In“WinOnly.pas”youshipfeaturesthatonlyexistunderWindowsandin“Shared.plattform.pas”thefunctionsthatareavailableforseveralplatforms.

ThisapproachalsohastheadvantagethatyoudonothavetoconstantlyworkwithIFDEF’sinyourprogramlogic.Thenitislateralsomucheasiertoexpandyourprogramforanotherplatform(e.g.Linux).

R12…AfteruploadingtoAppStore:Invalidbinary-causesandremedies

Whathasjustcostmehalfanight:AftercreatingtheapplicationIhavemadeanentryiniTunesConnectandthenuploadedthebinary(i.e.thepackage).Thisinsofarworks,but2minuteslater,thefilehasbeenfeaturediniTunesConnectas“Invalidbinary”.

Thefirstmistakewas,thatIdidnotlookinmye-mails.TherewasnoexplanationsiniTunesConnect,butApplehadsentmeinstructionsviaemail.

Theexplanationinthemailwas:

FilesOnlyReadableByTheRootUser-Theinstallerpackageincludesfilesthatareonlyreadablebytherootuser.Thiswillpreventverificationoftheapplication’scodesignaturewhenyourappisrun.Ensurethatnon-rootuserscanreadthefilesinyourapp.

Howcouldthatbe?“Filesonlyreadablebytherootuser”?

Thiswasonmyseconderror(historically,thefirstmistake):

InbetweenIhadinstalledthesetuppackagefortestingonthedevelopmentsystem.ButstrangelytheinstallationwasexactlydonetotheplacewhereDelphistorestheapplicationprogram.BecausetheSetuppackagewasinstalledwithadminrights(itwasdonea

Page 178: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

passwordprompt)theexistingfilesareoverwrittenwithcorrespondingattributes.

LaterIhadcompilemyapplicationagainwithDelphi,butviatransfertothemac,notallfileswereoverwrittenatthedestination,becauseIhadexceptsomefilesinthedeploymentlist.Sothat’ssomeofthefilesweremarkedsothatonlytheadminhasreadaccessontheapplicationbundle.

ThesolutionoftheproblemwasthentoshipthewholeapplicationbundletothetrashandletitcreateDelphiagainfromscratch.

Andtheneverythingworksagainasdesired.

R13…Applicationrejected:Somereasonsforrefusal,whichyoucanavoid

MissingCommand-QBefehl

TheuserinterfaceisnotconsistentwiththeOSXHumanInterfaceGuidelines

WehavefoundthatwhentheuserpressesCommand-Q,theappdoesnotquit.

SoInsertintothemenu,whichbearsthenameofyourprogram,evenacommandwiththetext“Quit[YourProgramname]”andassigntheshortcut“CommandQ”tothatcommand,youcanselectitattheObjectinspector.

DifferentnameoftheapplicationintheSystemMenuandintheProgramsfolder

TheappnametobedisplayedontheAppStoredoesnotsufficientlymatchthenameoftheappwheninstalledonMacOSX.

iTunesConnectName:MultiScreenShot.AppNamewhenInstalled:MScrShot.

SothenamethatappearsrightnexttotheAppleiconinthetoolbar,hastomatchwiththenameiniTunesConnectandintheApplicationsfolder.IdidindeedmanagetoletitdisplayinthemenubarasdesiredwithachangedentryinthepInfolist(bundlenameandbundledisplayname)name.ButthatithadnoeffectforthenameoftheApplicationsfolder.HereIwouldalsohavetochangetheexecutablename,butDelphiallowsnoprojectnamewithaspaceinit.SoIhadtochangetheprogramnamein“MultiScreenShot”,justwithnospaces.SonowistheexecutablefileandtheentryiniTunesConnect.

Page 179: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Thepurposesrequiredrights(entitlements)hasnofurtherexplanation

Inordertocontinuereviewingthisapp,werequireadditionalinformation.

Thisappusesoneormoreentitlementswhichdonotappeartohavematchingfunctionalitywithintheapp.PleasedescribehowandwheretheappusesthefollowingentitlementsbyaddingyourcommentstotheResolutionCenter.

IdemandedintheEntitlementsfile(fortheApplesandboxmodelrelevant)morerightsthanareactuallywasneeded.Forexample,Ihadrequestedadirectreadaccesstotheglobalimagesfolderofmyapplication.Actually,thisoptionwouldhavebeenenough:

Normally,youshouldthereforeonly“ReadandwriteaccesstofilesselectedwiththeOpenorSavedialog”tickhere.Ifmorerightsareneeded,youmustdescribeitinmoredetailduringtheupload.Anyway,withoutdescription,theapplicationisotherwiserejected.

Again,youselectthisrightsinDelphiundertheProjectmenu,Options,“EntitlementList”.

R14…UsingActiveControl

Ifyouhaveplacedinaformvariouscontrolsandmakeaqueryonthevariable“ActiveControl”,thisis-unlikeundertheVCL-alwaysNIL.Whetherthisisintentionalorabug,itisnotclear.Anyway,whiletheprogramisrunning,itwillsometimesbeusefulltoknow,whatisjusttheactivecontrol(i.e.theonethathasthefocus).

Youcandirectlyusethepropertyoftheform“Focused”here.Thisisnamelythecontrol,whichhasthefocus.

SoifyouwantsettheActiveControlvariable,youcandosointheevent“OnFocusChanged”oftheform:

procedureTForm9.FormFocusChanged(Sender:TObject);

Page 180: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

begin

ActiveControl:=TControl(Focused.GetObject);

//ifActiveControl<>NILthenbegin

//Label1.Text:=‘AktivesControl:‘+ActiveControl.ClassName+‘(‘+ActiveControl.Name+‘)’;

//end;

end;

Youcanactivateherethedisabledlinesintheabovesource-codeexampleandseewhatwillbeshownwhenyouchangethefocustoanindividualcontrol(and,forexampleinagridwithF2togetintoeditmode).

R15…ReplaceOnDrawItemeventoftheListBoxfromVCLwiththeOnPaintingeventoftheTListBoxItems

IndeedtheListBoxhasno“OnDrawItem”eventastheVCLlistbox,buttheListBoxItemhasan“OnPaint”or“OnPainting”event.

Hereyoucan,justlikeintheoldVCL-way,dodrawingsasyouwant.Thatis,forexample,usefulifyouhavelotsofdatastoredininternalobjectsthathavebeenconnectedtotheListBoxItems(orotherwiseholdssomewhereinalistordatabase).ForthebelowdemoIhavekeptitsimpleanddemonstrateitwithnoassociateddataobjects.TheListBoxItemsdoescontainnotext(andtheyshouldnot,becauseitwillbedrawedbydefaultbyFireMonkey).ThetextIgetherefromthenameoftheListBoxItems.Soonlythedrawingprocessisdemonstratedhere:

procedureTForm22.ListBoxItem1Painting(Sender:TObject;Canvas:TCanvas;

constARect:TRectF);

Page 181: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

varFlags:TFillTextFlags;beginWithTListBoxItem(sender)dobegincanvas.BeginScene;

canvas.Fill.Kind:=TBrushKind.bkSolid;

Flags:=[TFillTextFlag.ftRightToLeft];

ifName=‘ListBoxItem3’thenbeginifListBox1.ListItems[ListBox1.ItemIndex]<>TListBoxItem(sender)thenbeginCanvas.Clearrect(Arect,TAlphaColorRec.Yellow);end;end;

ifName=‘ListBoxItem2’thenCanvas.Fill.Color:=TAlphaColorRec.redelseCanvas.Fill.Color:=TAlphaColorRec.black;

Canvas.FillText(ARect,name,true,1,flags,TTextAlign.taTrailing,TTextAlign.taCenter);

canvas.EndScene;end;end;

Noteagain:Thetextproperty“Text”oftheTListboxItemshavenocontentitself,ofcourse,becausethiswouldresultinduplicatedrawings(textoverlays).Youcanuse“Tagstring”insteadofthe“Text”propertyofaListboxItem,ifyouwanttokeepdatainaListbox-Item(butbestwouldbe,youuseitonlyfordrawing).

Sothatthenitlooksintheresult:

R16…LoadBitmapfromresourcefile(forretinadisplay)

Page 182: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

SinceDelphiXE5youcaneasilyaddresourcestoyourprogramthatcanlaterbeloadedintoacomponent.Todistinguish:herewetalkaboutaprogramresourceandnotabouttheMultiResBitmapintowhichyoucanloadmultiplebitmapsatdesigntime(alsowithdifferentresolutions-insofarthistiphereisanalternativesolution).

WhenyouruntheprogramonMACOSX,itmaybeso,thattheuserusesascreenwithtwicetheresolution,theso-called.Retinadisplay.Ifitisimportantforyourprogramthatyouareusingcertainbitmapsthatyoucanalsodisplaywithtwicetheresolution,youcancreateabitmapwithanormalresolution,andsaveonewithtwicetheresolutionintheprogramresource.

Atruntime,examinethepresentresolution,andthenloadtheappropriatebitmapinyourimagecomponent.

First,howdoyougetthebitmapsintheprogramresource?Hereyoucanuseunderthe“Projects”menuthecommand“ResourcesandImages”.

Addanormalsizedimageandyouprovidethefilenameattheendwitha“1”.Imageswithtwicetheresolutionyouwillprovidewitha“2”attheend.Renamealsotheidentifierto“Dia1”.Warning:Upperandlowercaseisnecessary!Soifyouenterhere“Dia1”anduseinsourcecode“dia1”,theresourcewillnotbefound.

Itisalsoimportantthatyouchangetheresourcetypeof“BITMAP”to“RCDATA”,otherwiseitwillnotwork.

Atruntim,forexample,intheOnCreateevent,youcandoitlikethis:

//UnitFMX.Platformisrequired

Page 183: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedureTForm1.FormCreate(Sender:TObject);

var

RS:TResourceStream;

ScreenSrv:IFMXScreenService;

scale:single;

begin

ifTPlatformServices.Current.SupportsPlatformService(IFMXScreenService,IInterface(ScreenSrv))then

Scale:=ScreenSrv.GetScreenScale

else

Scale:=1.0;

ifScale<2.0thenbegin

RS:=TResourceStream.Create(HInstance,‘dia1’,RT_RCDATA);

Image1.MultiResBitmap.LoadItemFromStream(RS,1.0);

endelsebegin

RS:=TResourceStream.Create(HInstance,‘dia2’,RT_RCDATA);

Image1.MultiResBitmap.LoadItemFromStream(RS,2.0);

end;

FreeAndNil(RS);

end;

SocheckfirstwiththeScreenService,whichscreenresolutionispresent.“1.0”wouldbenormal,everythingelsehasahigherresolution.Thenyoucreatearesourcestream,loadthebitmapintoitandthenloadthebitmapitfromthestreamintotheimagecomponent.Thedetourviatheresourcestreamisunfortunatelynecessarybecausetheimagecomponentcan’tloaddirectlytheimagefromaprogramresource.

R17…Swapitemsinalistbox

FromtheVCLyouknowthefunction

ListBox1.Items.Exchange();

Toswaptwoitems,forexample,youcouldusethefollowingsourcecode(assumedinthelistboxwouldbe10entries):

Page 184: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedureTForm38.Button1Click(Sender:TObject);

begin

Listbox1.Items.BeginUpdate;

Listbox1.Items.Exchange(2,1);

Listbox1.Items.EndUpdate;

end;

UnderFireMonkeyyouhavetodothis:

procedureTForm4.btExchangeClick(Sender:TObject);begin

lb.ItemsExchange(lb.ListItems[2],lb.ListItems[1]);end;

UnlikeundertheVCL,soyoumustleavetheBeginUpdateResourceandEndUpdate.

Explanationofthis:Internallythefunction“Items.Exchange”usedbyitselfa“Listbox.BeginUpdate”anda“Listbox.Endupdate”.Ifyouuseyourself“BeginUpdate”before,theinternalroutineassumesthatthelistboxisbeingupdatedanddoesnotperformthechange.

Unfortunately,thisisnotdocumentedanywhere,butifyouevenknowOK.

R18…SwapitemsinaListboxviaDrag&Drop

Thelistboxproperty“Allowdrag”mustsetto“True”.Inthe“OnDragDrop”eventyoumustrespondtothedrop:

procedureTForm1.ListBox1DragDrop(Sender:TObject;constData:TDragObject;constPoint:TPointF);varLI:TListBoxItem;beginifData.SourceisTListboxItemthenbeginLI:=ListBox1.ItemByPoint(Point.X,Point.Y);Listbox1.ItemsExchange(LI,TListboxItem(Data.Source));end;end;

Page 185: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

R19…UsingFMXfunctionsinaVCLapplicationviaDLL

ConvertinganexistingVCLapplicationtoaFireMonkeyapplicationcanbedoneinaradicalapproach.Soconverteverythinginonego.Thedisadvantageis,thatthiscantakealongtimeonalargerVCLprojectandinthemeantimeyoucan’tchangemuchinthecurrentapplication.

Thealternativecouldbeasmoothtransition.Byexample,outsourcestepbystepdialoguesandrelatedfunctionsintoaFireMonkeyDLL.Hereyoucanalsousetheextendedcapabilities(graphics,GPS-functions,etc.),sothatthecurrentapplicationcandirectlybenefitfromit.

PerhapsyoumayingeneralnotwanttoconverttheprojecttoFireMonkey,butforcertainfunctionalitiesyouwouldliketouseFireMonkey.Inbothvariants,itmakessensetoprovidethisfunctionacrossaFireMonkeyDLL.Thisisnotthatdifficult,itworksmuchlikeundertheVCL.

HereIshowyouanexampleofhowIhaveaddedtotheVCL-imageeditingprogram“PixPowerPhoto&Draw”anewfiltereffectoveraFireMonkeyDLL.AlthoughtheDLLhasgeneratedasizeofabout4MB,itaffectsmyinstallationpackageonlywithavalueof1.3MB.

SointheVCLapplicationIhaveabitmapthatIsaveasabitmapstreamandpassittotheFMX-DLL.ThebitmapIcan’tdirectlypassedas“TBitmap”totheDLLunfortunately,becauseVCLandFireMonkeybitmapsareincompatiblewitheachother.

IntheDLL,thebitmapisdisplayedinadialoginthe”ImageViewer”component,whichI’veaddeda“PaperSketch”effect.Theintensityisadjustedviaatrackable.

Iftheuserthenconfirmedtheresultwith“OK”,theeffectisactuallyappliedtothebitmapandwritethebitmapbackintothestream.Here,alittletrickisused,becausebydefaultFireMonkeywritesabitmapasaPNGstream.Therefore,aseparateclass“TMyBitmap”derivedfromTBitmapisusedandoverwritethesavestreamprocedureandadaptedsothatthestreamcanbesavedasbitmapstream.

That’sthewayhowtodoit:Createonthemenu“File”,command“New”aDynamic-linklibrary:

Page 186: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

libraryFMXFilters;

uses

FMX.Forms,

System.SysUtils,

System.Classes,

FrmFilterin‘FrmFilter.pas’{F_Filters};

{R*.res}

exports

ShowBitmapFromStream;

begin

end.

Ifyouhavecreatedthelibrary,theelementsmarkedhereinboldarenotavailableyet.

YouhavetoaddmanuallytheUnitFMX.Forms,sothatitisclearthatthereshouldbeaFireMonkeyDLL.DependingonwhetheryouarecreatingthelibraryinanalreadyopenVCLprojectorseparately,itmaybethatDelphiindicatingthattheDLLhereishandledasFireMonkeyprojectandthereforeanappropriatemarkingshouldbemade.Thisqueryyoucanpositivelyconfirm.

TheUnitFrmFilterisaformunitthatIhavecreatedunder“File”,“New”,“FireMonkeyForm”:

Note:ThiscommandisonlydisplayedwhenyouviewtheDLLprojectintheProject

Page 187: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Explorer:

Theformlookslikethis:

Inthestructureviewitlookslikethis:

InthesourcecodeIhavedefinedthefollowingfunctionbeforethe“Implementation”:

FunctionShowBitmapFromStream(ms:TMemoryStream):Boolean;export;

Thisisthefunctionthatisprovidedasexternallycallablefunctionavailablethroughthe“exports”statementinthelibraryfile.

Page 188: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Note1:IfyouwanttopassastringinsteadabitmaptotheDLL,youshoulduseeitheraShortString,PCharorWideString.Soyoudon’tneedtotaketheShareMemunitintotheunitusesandyoudon’tneedtodelivertheBORLNDMM.DLLwithyourapplication.

Note2:IfyouwanttoensurethatthegeneratedDLLcanbecallednotonlyfromDelphiprograms,butalsoprogramsthatwerecreatedbyotherdevelopmentenvironments,youshouldusean“IStream”ratherthanamemorystream.

Hereistheimplementationofthisfunctionintheformfile(underusestheunitsFMX.Filter,FMX.Effects,FMX.Filter.EffectsandFMX.Surfacesarerequired):

functionShowBitmapFromStream(ms:TMemoryStream):Boolean;

var

Filter:FMX.Filter.TFilter;

begin

Filter:=TFilterManager.FilterByName(‘PaperSketch’);

try

F_Filters:=TF_Filters.Create(Application);

F_Filters.ImageViewer1.bitmap.LoadFromStream(ms);

ifF_Filters.ShowModal=mrOKthenbegin

Filter.ValuesAsBitmap[‘Input’]:=F_Filters.ImageViewer1.bitmap;

Filter.ValuesAsFloat[‘BrushSize’]:=F_Filters.TrackBar1.Value;

F_Filters.ImageViewer1.bitmap:=TBitmap(Filter.ValuesAsBitmap[‘Output’]);

TMyBitmap(F_Filters.ImageViewer1.bitmap).SaveToStream(ms);

Result:=True;

endelsebegin

Result:=False;

end;

finally

F_Filters.Free;

end;

end;

Page 189: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Herearetherequiredadjustmenttostorethebitmapstreams:

Type

TMyBitmap=class(TBitmap)

procedureSaveToStream(Stream:TStream);

end;

Implementation

procedureTMyBitmap.SaveToStream(Stream:TStream);

var

Surf:TBitmapSurface;

begin

Surf:=TBitmapSurface.Create;

try

Surf.Assign(Self);

TBitmapCodecManager.SaveToStream(Stream,Surf,‘.bmp’);

finally

Surf.Free;

end;

end;

WiththeFilterManagerandthenameofthefilterfunctionthewantedeffect“PaperSketch”isselected.

ThentheFMXdialogiscreated,thebitmapstreamisloadedintothebitmapoftheImageViewer.

Iftheuserhassetthedesiredintensityoftheeffectwiththetrackbarandthanheconfirmsthiswith“OK”,thesettingofthetrackbar-valuewillbeapplied.

Thenthemodifiedbitmapwiththederivedclassisstoredas“BMP’bitmapstream(i.e.,abitmapinRGBformat).

InthefollowingVCLapplicationunitisnowadded:unituFMXLink;

interface

uses

Windows,Dialogs,Classes;

type

TShowBitmapFromStream=function(ms:TMemoryStream):Boolean;

Page 190: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

var

ShowBitmapFromStream:TShowBitmapFromStream=nil;

DllHandle:THandle;

implementation

initialization

ifDllHandle=0thenbegin

DllHandle:=LoadLibrary(‘FMXFilters.dll’);

ifDllHandle>0thenbegin

@ShowBitmapFromStream:=GetProcAddress(DllHandle,‘ShowBitmapFromStream’);

endelsebegin

MessageDlg(‘Thefunction„ShowBitmapFromStream“/theDLL-file„FMFilters.dll“istnotavailable’,mtInformation,[mbOK],0);

end;

end;

finalization

ifDLLHandle<>0then

FreeLibrary(DLLHandle);

end.

Under“Type”,afunctionisdefinedwhichcorrespondstotheexportfunctionoftheDLL.

UnderVaris“ShowBitMapFromStream”thenintroducedasprocedurevariable.

Intheinitializationsection,theDLLisloadedandourpreviouslydeclaredprocedurewillthenbeassignedtothememory-adressofthefunctionintheDLL.

IfyouincludethisVCL-unitinyourVCLapplicationyoucanthencallfromtherethefunction“ShowBitmapFromStream”.

So,forexample:Var

MemStream:TMemorySteam;

TempFileName:String;

Begin

TempFileName:=…//imposetemporaryfilename

ABitmap.saveToStream(MemStream);//SavethebitmapasaMemoryStream

MemStream.position:=0;

Page 191: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IfShowBitmapFromStream(MemStream)thenbegin

MemStream.Position:=0;

ABitmap.LoadFromStream(ms)//DateiwiederinBitmapladen

end;

End;

NOTE:TogetthistoworkyouhavetoincludeinthemainformofyourVCLapplicationtheunit“Winapi.GDIPOBJ”directlyintotheUSESsectionoftheinterface-section(notinausesclauseintheimplementationsection,thatwouldbenotenough).

ThisunitisrequiredsothattheGDIfunctioncanbeinitializedalsofortheVCLapplication.Thiscanbedoneonlythroughthemainprogram,itnotbelongsintotheFireMonkeyunit.

Ifyouareinterested,youcanlookatthefunctionalityintheprogramoncehere(www.Pixpower.info)orsimplyinaYouTubevideoinmyPixPowerchannel,whereIhavethisfilter:http://youtu.be/W21uxyPsJvc.

R20…DrawtextinTGridright,orcentered

SinceXE6,theTGridcontainsthepossibility,under“TextSettings”choosewith“HorzAlign”ifthetextshownisintendedtobeleft-justified,centeredorright-justified.

However,thissettingappliestoallcolumnsthataredisplayingtext.TheTColumsorTStringColumsyouhaveplacedintotheTGridhavenopropertyliketheTGrid.Butthatcouldbenecessary,ifthetextinonecolumnsouldbedisplayedjustifiedontheleftandinanothercolumntotheright(e.g.monetaryamounts).

HereitisusefulinitiallytosettheTag-valueoftheTStringColumnsthatshouldbealignedtotherightwiththevalueof“1”.Forallcolumnsthathavethevalue“1”,thenwedeliverinGrid.GetValueanemptyvaluebacksothatthegriditselfdoesnotcarryoutadrawingactionhere:

procedureTForm9.Grid1GetValue(Sender:TObject;constCol,Row:Integer;

varValue:TValue);

begin

ifTGrid(sender).ColumnByIndex(col).Tag=1thenbegin

exit;

end;

….

end;

Page 192: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

IntheeventoftheOnDrawColumnCelloftheTGridwecallforallcolumnstheDrawCellRightthefunction:

procedureTForm9.Grid1DrawColumnCell(Sender:TObject;constCanvas:TCanvas;

constColumn:TColumn;constBounds:TRectF;constRow:Integer;

constValue:TValue;constState:TGridDrawStates);

begin

DrawCellRight(Sender,Column,canvas,bounds,Row,Value);

end;

Here,theuser-definedfunction“DrawCellRight”iscalled.WealsousetheOnGetValueeventoftheTGridtogetthevalueofthecell.TemporarywesettheTagvalueoftheTColumnto“0”sothatthevalueisreturnedtous(remember:WehaveaboveasupplementinstalledsothatthevalueisonlyreturnediftheTagvalueofthecolumnhasthevalue“0”.

Itwilllooklikethis:

procedureDrawCellRight(Sender:TObject;Column:TColumn;canvas:TCanvas;bounds:TRectF;Row:Integer;Value:TValue);

var

B:TRectF;

V:TValue;

begin

ifColumn.Tag=1thenbegin

Column.Tag:=0;

V:=Value;

TGrid(Sender).OnGetValue(Sender,column.Index,Row,V);

B:=Bounds;

B.Right:=B.Right-1;

DrawTextEx(canvas,B,TAlphaColorRec.black,V.tostring,TTextAlign.Trailing);

Column.Tag:=1;

end;

end;

Andhereisthehelpfunction,whichthendrawsforusthetext:

Page 193: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedureDrawTextEx(Z:TCanvas;aRec:TRectF;ATextColor:TAlphaColor;S:String;a:TTextalign);

var

r:TRectF;

tf:tfilltextflags;

h:TTextalign;

begin

h:=TTextAlign.taCenter;

Z.Fill.Color:=ATextColor;

Z.BeginScene;

Z.FillText(arec,S,false,1,tf,a,h);

Z.EndScene;

end;

Theresultisthatallcolumnswhosetag-valueis“0”,thedrawingstartsatheleftmargin(donebytheTGriditself),allwhosetag-valueis“1”,thetextisrightjustified(donebyourdrawingfunction):

R21…DrawtextinTStringGridright,orcentered

AlsoinTStringGridyoucansetthetextoutputforthecolumnsonlyforallthesame.Soalsoherewehavetodrawthetextbyourselfinthe“OnDrawColumnCell”-event.Thissolutionassumesthatthestringgriddoesnotholdthedata,itonlydisplaytherelevantcontent(asitshouldbe).So,leavee.g.theleft-alignedtextoutputasdefaultandsettheTagvalueofthecolumnthatyouwanttoberight-justifiedto“1”andtobeoutputcenteredto“2”.Sothenitlooksinthedraw-event:procedureTForm9.StringGrid1DrawColumnCell(Sender:TObject;

constCanvas:TCanvas;constColumn:TColumn;constBounds:TRectF;

constRow:Integer;constValue:TValue;constState:TGridDrawStates);

var

Flags:TFillTextFlags;

ar:TRectF;

S:string;

begin

Page 194: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Flags:=[TFillTextFlag.ftRightToLeft];

canvas.BeginScene;

ar:=bounds;

ar.Inflate(-1,-1);

canvas.ClearRect(ar);

canvas.Fill.Color:=TAlphaColorrec.Black;

S:=Row.ToString;

casecolumn.Tagof

0:canvas.FillText(bounds,S,True,1,flags,TTextAlign.taTrailing,TTextAlign.Center);

1:canvas.FillText(bounds,S,True,1,flags,TTextAlign.taLeading,TTextAlign.Center);

2:canvas.FillText(bounds,S,True,1,flags,TTextAlign.taCenter,TTextAlign.Center);

end;

canvas.EndScene;

end;

Heretheresult:

R22…Dealingwiththe“visible”propertyofcontrols

NewsinceXE7:

SinceXE7thereisnolongertheproperty“DesignVisible”thatwasbeforebesidetheproperty“Visible”.Whenyouputacontrolatdesigntimeto“Visible=False”,itisalsonolongervisibleatdesigntime.Thatmakesitalittledifficulttochoosethecontrole.g.forsettingstomakeintheObjectinspector.Useinthiscasethetreeviewwhereyoucaneasilyselectandactivatetheinvisiblecontrol.Soifyouupgradeaprojectfromaprevious

Page 195: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

versionofDelphi,andacontrolnolongerappearstobeavailable,checkifyoucanfinditinthestructureviewandifthe“Visible”propertyjuststoodto“False”.

R23…PreventunintendedshorteningofTLabeltext

SinceXE6isavailable,under“TextSettings,isfor“Trimming”thedefaultsetting“character”todisplaythelabeltext.AutoSizeisturnedoff.Thiscansometimesleadto,thatthetextisshortenedatruntimewith“…”whenthedisplaywidthisnotwideenough.Youshouldeitherset“AutoSizeto”Trueorturnoff“AutoSize”andthetrimmingandleavemorespaceforthedisplayofthetextinadvance.Thisisalsotobeconsideredbecause,forexample,underWindowsthedisplaywidthissufficientbutnotunderMACOS,becausethefontsjustyetsometimesareslightlydifferent.Itisthereforeadvisableunderallplatformstolookatthedialogsatruntime.

CurrentlyIsuggestrathertoturnoffAutoSize,becauseIhavefoundthatrelativelymanytimesthetextisnotdisplayedcorrectlyinthehight(e.g.“g”and“p”hasmissingpartsaboveandbelow),inparticularonMACOSX.YoushouldthenalsotheheightoftheLabelcomponentslightlyenlarge.

R24…UsehintsinFireMonkey:Howitgoes

IfyouarelookingintheObjectinspectorfortheproperty“Hint”forTButton,TSpeedButtonorTLabel,youwillnotfindanything.

Inreality,allthecomponentsmentionedhere,hastheHintproperty(alsoforothers,forexampleTListBox),butitisnotpublished.Ifyoucouldsetthepropertyatruntime(whichusuallyisnotpossible)thehintfeaturewouldalsonotbesupported.

Ihavethereforedevelopedaunit(HS_FMXHints.pas)thatyouneedtoincludeonlytotheforminwhichyouwanttousehintsinthecontrolsmentionedabove.Theunitusesaknown“hacktrick”.Thehintpropertyismadeavailableanditcanbesetatruntime.Inaddition,withthe“SetAHint”functionan“OnMouseEnter”andan“OnMouseLeave”eventisthenaddedtothecontrols.

Atrun-time,e.g.intheOnCreateeventoftheform,thensetthehintsasfollows:SetAHint(Button1‘ShowHelp’);

SetAHint(Label1‘Sumoverallquarters’);

Attention:Ifyouusealabel,youhavebyyourselfsetintheObjectinspectortheproperty“HitTest”totrue,otherwisetheOnMouseEntereventisnotpassed(setatruntimecuriouslyhasnoeffect).

Ifyourunyourprogramandmovethemousepointeroveracontrol,thenacorrespondinghintisdisplayed.Itlookse.g.likethis:

Page 196: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Dependingonwhetherthehintappearsattheleftorrightedge,theuppertriangleisdisplayedjusttotheleftorright.Ifatextisincluded,whichismorethan200pixelswide,thehintisdisplayedonseverallines.IftheHintdisplayedatthebottom,itmayappearoverthecontrolbecauseitcouldnolongerbedisplayedintheformotherwise.

Youcanalsomakeaninitialization,overwritingthedefaultpredefinedvalues:SetHintSetting(TimeBeforeShow,TimeToShow:Integer;DynamicShow:Boolean;TC:TAlphaColor)

Thevaluefor“TimeBeforeShow”indicateswhenthemousepointerisoverthecontrolis,howlongtowaituntilthehintwillbedisplayed.

Thevalue“TimeToShow”indicateshowlongthehintwillbedisplayed.

Ifyouset“DynamicShow”toTrue,thedisplaytimeisextendedbyacalculatedvalueforlongertext,averyusefuloption.With“TC”youcanspecifyadifferenthintcolor.

Restrictions:

Becausethecallof”SetAHint”overridesanyexistingownOnMouseEnterorOnMouseLeaveevents(whichyou’vesetupthemselvesinyourprogram),youcan’tusethisworkaroundinthiscase.However,ifrequiredyoucanexpandtheunitbycheckingwhensettingthehintstringifthecontrolhasaneventfunctionalreadyassigned,andmakethensomeaddaptions.

IhopethatmaybefromDelphiXE8on,thehintfeatureissupporteddirectly,thenwedonotneedsuchworkarounds.

Theunitcanbedownloadedhere:

http://www.devpage.de/download/HS_FMXHints.zip

Foryou,thereaderofthisbook,isexclusiveasmalltoolavailable,whichIhadwrittenformetoreadthehintsfromtheoldVCLformsandtomakethemsoveryquicklyforconvertedFMXprogramavailable.JustopenwiththeprogramsimplytheVCLform(button“SelectVCLForm”)andyougetinthememoallhintslisted,readytouseforthefunction“SetAHint”.Youcantheneasilycopythistexte.g.intotheOnCreateeventoftheFMXformandhavethanallthehintsthereagain.

Page 197: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Theprogram,whichyoumayusefreelyforyourneeds,youuseatyourownrisk(disclosuretothirdpartiesisthereforenotallowed).Youcandownloadithere:

http://www.devpage.de/download/GetHints.zip

Extractthecontained“.exe”andcopyitsomewhere,fromwhereyouwanttousetheprogram.

Ashortvideo,howtousethehint-unitandthetool,youcanviewonYouTube:

http://youtu.be/eWGbhOexrJk

R25…Determinethedocumentdirectory

Forallplatforms,youcanusefromtheunit“System.IOUtils”thatyouneedtoincludeinyourproject,therecord“TPath”,whichcontainsalotofinformationaboutdirectoriesthatcanbeaccessedwiththecorrespondingfunctions:

procedureTForm2.FormCreate(Sender:TObject);

var

DocPath:String;

begin

DocPath:=TPath.GetDocumentsPath;

end;

ResultforDocPathhereonmyMacorWindowscomputer:

underMACOSX:„/Users/harrystahl/Documents“

underWindows:„C:\Users\Harry-Dev\Documents“

Page 198: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Tip:ClickoncebyholdingdowntheCtrlkeyon“TPath”,DelphiwillthenshowyoutheTPathrecord.Exploretheindividualvariablesandfunctionsthatareavailablethere(inthepublicsector).Thatitisreallyworthit,someofityoucanuseforshureagainlater.Forexample,youcanalsousetheimagesdirectory(TPath.GetPicturesPath)orthevideodirectory(TPath.GetMoviesPath).

R26…Improvethefontquality(especiallyonWindows)

UnderWindows,thedisplayqualityofthefontsunderFireMonkeyisnotoptimal.Imanageitso,thatIturnofftheDirect2Dfunctionalityintheprojectfile,beforetheinitialization:beginFMX.Types.GlobalUseDirect2D:=False;Application.Initialize;Application.CreateForm(TF_Main,F_Main);Application.Run;end.

Hint:TheFMX.Typestheunitmustbeincluded.

R27…Selectafolderwithadialog

With“SelectDirectory”youcannowselectafolder:procedureTForm2.Button1Click(Sender:TObject);

var

dir,root:string;

begin

root:=”;

//root:=System.IOUtils.TPath.GetPicturesPath;

ifSelectDirectory(‘BittewählenSieeinVerzeichnis’,root,dir)thenbegin

ShowMessage(‘Siehaben‘+dir+‘gewählt’);

end;

end;

TheUnitFMX.Dialogsmustbeintegrated.Thefirstparameterisusedtospecifyadescriptionthatisdisplayedinthetitlebarofthedialog.Inthesecondparameter,youcanspecifyadirectorytowhichthedialogisdisplayed(defaultisthedocumentdirectory),thethirdisaVARparameterandreturnesbacktheselecteddirectoryname.

Note:Ifyouwanttousetheselectiondialogalongwithabookmarkfunctioninasandboxedapplication,youmustusethereplacementfunctionshowninAnnex2.

Page 199: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

R28…GetaccesstoacellcontrolofTGrids

WhilewecansetatruntimeinaTStringGridwith

Stringrid1.cells[0,1]:=‘Test’;

thecellswithvaluesorcanretrievevaluesfromthecells,thatgoesunfortunatelynotwiththeTGrid,evenifitcontainsaTStringColumn.TheTGrid,ortheTColumscontainonly“StyledControls”,whichcanthentaketheappropriatevalues.

Beforehereawayisshownhowonestillcomestothevalueandcanchangeit(ifnecessary),thefollowingexplanation:FireMonkeywasalwaysevolvingwitheachversion,intermsofthespeedofthedisplay.

WithTGriditisso,thatactuallyneededdisplayelements(cells=StyledControls)aregeneratedatruntime.So,forexample,whenagridhas1000rowsandtherearedisplayedonlythefirst20rows,thenonlythefirst20rowsandcellsaregeneratedatruntime.Therewillthanalsobeonlyforthefirst20rows“GetValue”queries.

Thisofcourseismemory-friendlyandgoodforspeed.Butyoumusttakenotethatyoucanthereforegiveonlysetorretrievevaluesforthegridinthecellswhenthecellshavebeengeneratedforitalready.Youcanassumethatacellallreadyexists,ifyouwanttomanipulatethevalueofacellisshown.

Wewillsubsequentlyuseaclasshelperfunctiontogetaccesstotheprivatefunction“CellControlByRow”.ThisfunctionisdefinedasfollowsinFMX.Grid:

functionTColumn.CellControlByRow(Row:Integer):TStyledControl;

begin

if(Grid<>nil)andGrid.IsSelected(Row)then

Result:=CellControl

else

Result:=nil;

end;

Soyoualreadyrecognizesthatareturnvalueisreturnedbythefunctiononlywhenjustthedesiredrowinthegrid-andthusthecell-isselected.Becauseonlyjustthisensures,thatthecellalreadyexists.

SowedeclareinourmainformthefollowingClassHelper:

Page 200: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

type

THelperColumn=classhelperforTColumn

procedureSetACell(aRow:Integer;AVAL:TValue);

functionGetACell(aRow:Integer):TStyledControl;

end;

Theimplementationslooksthenasfollows:

{THelperColumn}

functionTHelperColumn.GetACell(aRow:Integer):TStyledControl;

begin

result:=TStyledControl(CellControlByRow(aRow));

end;

procedureTHelperColumn.SetACell(aRow:Integer;AVAL:TValue);

var

sc:TStyledControl;

begin

ifselfisTStringColumnthenbegin

sc:=TStyledControl(CellControlByRow(aRow));

ifsc<>NILthenbegin

TTextCell(CellControlByRow(aRow)).Text:=AVAL.tostring;

end;

end;

ifselfisTImageColumnthenbegin

sc:=TStyledControl(CellControlByRow(aRow));

ifsc<>NILthenbegin

TImageCell(CellControlByRow(aRow)).Bitmap:=AVAL.AsType<TBitmap>;

end;

end;

end;

WecannowseteachTStringColumnandeveryTImageColumn,forexample,likethis:

imgInfo.SetACell(0,Image1.Bitmap);//BitmapinaTImageColumn

strSize.SetACell(0,‘Len:‘+intToStr(length(memo1.text)));//Text

Page 201: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

OrjustthewaytogodirectlytogetthewholeStyledControltosetseveralproperties:

TProgressbar(progressInfo.GetACell(0)).max:=length(memo1.text);

TProgressbar(progressInfo.GetACell(0)).value:=Memo1.PosToTextPos(Memo1.CaretPosition);

YoumaybewonderingfortheexampleofwhyboththeTImageColumnandtheTSTringColumncanusethehelperfunction“SetACell”althoughtheHelperclasswasintroducedfortheTColumn.Thisisjustthemagicofinheritance,becauseTColumnisboththeancestorofTStringColumnaswellasTImageColumnsothatbothsuccessorsinherittheenhancedcapabilitiesofthepreviousclass.

Itisreallybeenagreatthing,that.Theclasshelpershashelpedmeinmanycaseswhereotherwiseonlythecomponentdevelopercoulddeliverasolution,ifhewouldchangehiscomponent(whichunderstandablythemostdevelopersdon’twant).

Youwillneedsuchdirectaccesstoacellofagridratherrare,butifiteverbecomesnecessaryinspecialcases(e.g.ifyouwanttooutputcertaininformationaboutthecurrentlyselectedcell),thenyouknowhowyoucandoit.

R29…Showpop-upmenuataspecialposition

Maybeyouarefacedwiththesituationthattheusercanclickonaspecificitemandthenaboveorbelowapop-upmenushouldbedisplayed.Hereisanexamplewheretheuserclicksonapanelandthenthenapop-upmenuwillbedisplayedbelowit:

Youcandoitlikethis:procedureTfrm_Main.pnMahnungRangeMouseUp(Sender:TObject;Button:

TMouseButton;Shift:TShiftState;X,Y:Single);

begin

hs_ShowPopup(self,pnMahnungRange,popMahnung,unten);

end;

Page 202: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Wherethefunction“hs_ShowPopup”isdefinedasfollows:procedurehs_ShowPopUp(frm:TForm;bn:TControl;pop:TPopupMenu;ObenUnten:Integer);

var

FP:TPointF;

begin

FP.X:=0;

FP.Y:=0;

//Transposesthecoordinatesinthecontextoftheform.

FP:=bn.LocalToAbsolute(FP);

//Transposesthecoordinatesinthecontextofthescreen.

FP:=frm.ClientToScreen(FP);

//Displaythepopupmenuatthecalculatedcoordinates.

pop.Popup(FP.X,FP.Y+bn.height);

end;

Thisfeaturealsoworksonmulti-monitorsystems.

R30…Storeadditionalinformationinstandardobjects

FromtheVCLyoumightknowtheproperty“Tag”,whichhasalmostanyobjectandrepresentsanintegervalue.

InFireMonkeyyoucansetsuchaTagvaluealso,forexample,withtheObjectinspector.Butbeyondthatthereareexistingforanobjectoracontrol(TFMXObject)theproperties“TagString”,“TagFloat”and“TagObject”.Thisisextremelyusefulifyouwanttostoreadditionaldata,informationorobjectstoaspecificcontrol.Thesevalues,however,canbereadorwriteonlyprogrammatically(i.e.notviatheObjectinspector).Overall,averyusefulextensiononFMX.

R31…Draganddroptextfromexternalsource(egbrowser)toaTEditbox

Attherequestofacustomer,Ihaveintegratedafunctioninmyaccountingprogramwiththatonecandragaselectedtextfromthebrowseronaneditfieldoftheprogramandthetextisplacedthere.

Forthis,youonlyneedtocompletetherelevanteventsasfollows:procedureTf_Bill.Edit1DragOver(Sender:TObject;

constData:TDragObject;constPoint:TPointF;varOperation:TDragOperation);

begin

Operation:=TDragOperation.Copy;

end;

Page 203: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

procedureTf_Bill.Edit1DragDrop(Sender:TObject;constData:TDragObject;

constPoint:TPointF);

begin

if(Data.Data.TypeInfo<>NIL)and(Data.Data.TypeData<>NIL)thenbegin

TEdit(Sender).Text:=Data.Data.ToString;

end;

end;

ApartfromWindowsInternetExplorer,thisfunctionalityissupportedbymostbrowsersandindeedacrossplatforms(e.g.evenSafariontheMAC).Also,thedraganddropwithtextworkswithmanywordprocessingprograms.

R32…Acolumninastringgridshouldoccupytheremainingspace

Youhaveastringgridwithmultiplecolumnsandwantatchangesinsizeofthegridthatalwaysaparticularcolumnrespondstothechangesinsizeandoccupythefreespaceinthegrid.Itshouldbenotedthatthecalculationcanonlyworkproperly,ifthegridhasbeenshownonce,sotheOnShow-eventoftheformhasbeenrunthroughcompletelyonce.Forthispurpose,youmustuseatimerthatyousetenabledintheOnShoweventwiththeintervallof25ms.Atthefirsttimethetimereventistriggered,youdisablethetimerandmakethedesiredcalculation(lateryoudothecalculationsontheOnResizeeventoftheformorthegrid).

Itcouldlookawholeas:var

Form9:TForm9;

VarCol:Integer;

implementation

{$R*.fmx}

procedureTForm9.FormCreate(Sender:TObject);

begin

VarCol:=0;//fürdieErste

//VarCol:=StringGrid1.ColumnCount-1;//z.B.fürdieletzteSpalte

end;

functionAColWidth(Grid:TStringGrid;VarCol:Integer):Extended;

vari:

Page 204: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

integer;

aWidth:Extended;

begin

aWidth:=0;

fori:=0toGrid.ColumnCount-1do

ifi<>VarColthenaWidth:=aWidth+Grid.Columns[i].Width+1;

Result:=Grid.ClientWidth-aWidth;

end;

procedureTForm9.FormResize(Sender:TObject);

begin

TStringColumn(StringGrid1.ColumnByIndex(VarCol)).width:=AColWidth(StringGrid1,VarCol);

end;

procedureTForm9.FormShow(Sender:TObject);

begin

Timer1.Enabled:=True;

end;

procedureTForm9.Timer1Timer(Sender:TObject);

begin

Timer1.Enabled:=false;

TStringColumn(StringGrid1.ColumnByIndex(VarCol)).width:=AColWidth(StringGrid1,VarCol);

end;

Page 205: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter7:UpgradingfromDelphiXE3-XE6toXE7

ForuserswhohavealreadyworkedwithDelphiXE3,Iwouldliketogivesomehintshere:

DelphiXE7andInstallationSinceDelphiXE5IworkwiththeEnterpriseversion,becausethenitiseasiertoinstalltheMobile-Pack,becausethepointisoffereddirectlyduringtheinstallationofDelphi(besidesofcoursethereareotheradvantagesintheEnterpriseversion).

DelphiXE4IhadpurchasedasaProfessionalversion.IntheProfessionalversion,youmustfirstinstallandactivateDelphiitself.Thenstartthesetupprogramagain,select“Upgrade”(herestillscreenshotsofXE4/5):

Clickonthe“Next-switch”andenteronthenextpagetheserialnumberthatyoureceivedwhenyoupurchasedthepackMobile:

ChecktheserialnumberidentifiesthesetupprogramnowthatyouwanttoinstalltheMobile-Packandproceedsaccordingly.

Itcouldbe,thatitischangedinthemeantimealsofortheProfessional-version.Someonetoldme,thatyoucanalsodothewholeinstallationdirectlywiththeserialfromtheMobile-Pack.

DelphiXE7andusableMACOSXversionsMountainLionandMaverickscanbeusedasdevelopmentplatforms.ButYosemitegoesalso.LiondoessupporttheAppStorenotperfectandyoucancertainthingsonthissystemnottest,soyoushouldatleastworkingwithMountainLionorMavericks,atleastifyouwanttodevelopMACOSXprogramsfortheAppStore.Allothersystemsshouldofcoursebeavailableandbeusedasatestsystem.IhaveaniMac,whereonthesystemdiskevenLeopardandSnowLeopardareinstalled.OnaconnectedFireWireharddriveIhaveinstalledondifferentpartitionsLion,MountainLion,MavericksandYosemite.

Inaddition,IhaveaMacAirnotebook,whereIcanuseMountainLionandMavericksas“Fresh”system(i.e.withoutanyinstalleddevelopmentenvironmentsthatcoulddistortanytestresults.Physicistsalwayssaythatthetestenvironmentitselfhasanimpactonthetestresult,that’sright).

Page 206: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Veryoften,ApplechangedanythingontheOSandsoitcansometimesbethatsomethingdoesnotworkanymoreinthedevelopmentprocess.EMBAstrivesalwaysherequicklytoprovidehotfixes.ExplorethereforefromtimetotimeinEMBAinthedevelopercommunity(EDNDeveloperNetwork).

TakeoverofprojectsXE3-XE6ForthetransferofyourprojectfromXE3-XE5toXE7youshouldfirstopenitagaininthepreviousversionofDelphi.Thereyoushouldthenclosealltheformsanddisplayonlytheprojectsourcecode.Thenyoucansavetheprojectandcloseit.ThisapproachisrecommendedbecauseotherwiseDelphimayagainusetheoldfolderifyoutakeovertheprojecttoadifferentfolder(Ialsorenametheolderfolder,becausesometimesDelphitriestoopenthereunitsagain).Thencopyallthefilestoanotherfolder,andopentheproject.

ThenjustadjustthepathsunderProject,Options,Directories!!

Whenyouloadtheforms,itcouldbe,thatyougetabadrepresentationofyourforms.Forexample,theregistersoftheTabControlcouldbemuchsmaller,inthememocomponentthecursorwillnotbedisplayed,ifnotextwasin,and,and,and…

SolutionwastoopentheStylescomponentandselect“RemoveAll”andreadthestyleagainfromtheharddisk.Obviously,changesintheStylesbeenmadewhichhaveaninfluenceonthefunctionofthecomponents.TheFMXstylescanbefoundontheharddriveunder:

C:\ProgramFiles(x86)\Embarcadero\Studio\15.0\Redist\styles\FMX

Afterthat,everythingwassoagain,asitshouldbe.

Butitshouldbenotedthatherethelossofcustomchangesthreatensthathadpossiblymadetothestyles.Insteadof“RemoveAll”youcouldtrytoselect“Add”possibly.ThecomponentslookafteragainOK,ifcustomsettingsareretained,youneedtotestitbyyourself,Ididnothaveanyinhere.

Otherobstacles:TLabelandTButton“unknown”AlreadyusingDelphiXE4therehasbeenare-orderingofthefunctionsandcomponentsintheindividualFireMonkeyunits.

Adescriptionofthedetailscanbefoundhere:

http://docwiki.embarcadero.com/RADStudio/XE4/en/Refactored_FireMonkey_Classes_in_XE4

ButtonandlabelsarenowlocatesintheunitFMX.StdCtrls,thisyoumustaddtothe“Uses”asaunit.Delphiisheresometimesalittleovereagerandthenautomaticallyaddsadditionalunitssometimestwice.Sodon’twonderifyouhavetheappropriateerrormessagesduringcompilation,butjustthenremovetheduplicateentries.

Inaddition,theprogramhasbitchedfortheWindowsplatformthat“Application.mainform.handle”isnotcompatiblewith“TWindowHandle”.Icouldcurrentlyonlydealwithawork-around,asIhaveheresimplyreplacedas“Application.mainform.handle”with“0”.Butthiscan’tbeapermanentsolution.

Tousethe“TFillTextFlags”inconnectionwiththeprintfunction,Ihadtoincludetheunit“FMX.Graphics”,alsoaconsequenceoftheabove-mentionedreorganization.Soif

Page 207: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

somethingisdeclaredas“unknown”,remberofthisreorderingandsearchthemissinguntisandadjustitaccordingly.

ProblemswiththemultiviewDesigner(Fire-UI)BeforeDelphiXE7,youaddaplatformintheProjectwindow.InXE7bycreatinga“MultiDeviceApplication”theotherplatformsareavailableastargetsautomatically:

InaprojecttakenfromDelphibeforeXE7,theprojectlistlookslikethis:

Sotheotherplatformsaremissing.

Anditdoesnothelp,ifyoutrytochooseanotherstyle(e.g.IOSorAndroid)fromView-dropdownlist.Thiswillendonlywithanerrormessage.

Thesolutionisagaintore-createtheproject.First,copythetextcontentoftheprojectfile(DPR)totheclipboardandthencreateanewprojectwiththesamenameagain.ThanreplacethenewtextintheDPRfilewiththeolderfromtheclipboard.Nowyouhaveavailableintheprojectwindowalsotheothertargets(Android,iOS)andyoucanexpandyourprojecttooneoftheplatformsifrequired.

Page 208: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Chapter8:Outlook

Othertopics

Thebookisstillintheexpansionphase,foraperiodoftimeothertopicswillbeadded.FornowI’amconvertingmorevcl-projectstofmx-projects.SoIwilladdmyexperienceherewhenIupdatethisbook(solooksometimesatamazonatthetimeanddateofthebook).

Perhapsthereisalsoaspecialtopic,whereyougetstuck.Ifitisapointthatmightfitwellhereinthisbook,donothesitatetosendmeane-mailwithadescriptionoftheproblem.IwillbehappytocheckwhetherIcantakeitasatopichere-withanappropriatesolution.

Ifyoushouldnoticedobviouserrorsoroutdatedinformationinthebook,Iwouldalsoappreciateanote.

Page 209: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Attachment1:UnitHSW.FMXSandbox.pas

unitHSW.FMXSandbox;

{**CopyrightbyHarryStahlSoftware,Bonn,www.hastasoft.de**}

{**Peoplewhobuyedmyebook”Cross-PlatformDevelopmentmitDelphiXE7}

{**&FireMonkeyfürWindows&MACOSX”arefreetousethisunit}

{**Othersmayaskme}

{**Useitatyourownrisk,theauthorwillnotberesponsibleforany}

{**damages}

{**DontforgettoDefine“UseSandbox”inyourcompilerconditions}

{**Andaddtheentitlementkey}

{**com.apple.security.files.bookmarks.app-scope}

{**toyourEntitlement-file}

interface

uses

System.SysUtils,System.Classes,FMX.Dialogs,

Macapi.CoreFoundation,Macapi.ObjectiveC,MACAPI.coreservices,

MacApi.AppKit,Macapi.CocoaTypes,MacApi.Foundation;

type

NSURL=interface(NSObject)

//[‘{BB3BDECA-2E3A-4326-BDD8-6C339A277E34}’]OriginalausMACApi.Foundation

//eingeeigeneImplementationistleidererforderlich,weildieseFunktionen

//dringendfürdieSandbox-Funktionalitätbenötigtwerden,inderMACApi-Unit

//aberleidervergessenwurden.

//FallsdasineinemdernächstenDelphi-Updatesnachgeholtwird,kannmandiese

//Implementierungwiederentfernen

[‘{4997B641-85B2-4BE9-A9A9-45F64CE34955}’]

functionstartAccessingSecurityScopedResource:Boolean;cdecl;

functionstopAccessingSecurityScopedResource:Boolean;cdecl;

end;

Page 210: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

TNSURL=class(TOCGenericImport<NSURLClass,HSW.FMXSandbox.NSURL>)end;

functionAppScopedBookMarksEnabled:boolean;

functionCreateAppScopedBookMark(vardata:NSDATA;URL:MacApi.Foundation.NSURL):Boolean;

functionGetResolvedAppScopedBookMark(data:NSData;varNEWURL:NSURL):Boolean;

functionCanStartAccessingSecurityScopedResource(url:NSURL):boolean;

functionCanStopAccessingSecurityScopedResource(url:NSURL):boolean;

functionGetAppScopedBookMarkFromList(ADir:String;vardata:NSData):Boolean;

functionExistsAppScopedBookmarkForRes(ADir:String):Boolean;

functionGetAppScopedAccessToRes(ADir:String;varurl:NSURL):Boolean;

functionGetBaseAppScopedAccessToRes(ADir:String;varurl:NSURL):Boolean;

const

//DieseKonstantenwerdenzumAufrufderBookmark-Funktionenbenötigt

//einweitererPunkt,womandieMACApi.Foundationerweiternmüsste

NSURLBookmarkCreationWithSecurityScope:NSUInteger=(1shl11);

NSURLBookmarkResolutionWithSecurityScope:NSUInteger=(1shl10);

NSURLBookmarkResolutionWithoutMounting:NSUInteger=(1shl9);

NSURLBookmarkResolutionWithoutUI:NSUInteger=(1shl8);

//SetzenSiedieseVariableaufTrue,wennSieimDebugmodus

//erweiterteInformationenerhaltenwollen,wannetwasfunktioniert

//undwannnicht.

ShowDebugInfos:Boolean=false;

var

//Liste,welchedieRessourcen(=OrdneroderDateien)unddiedamit

//verknüpftenBookmarkdateienenthält

slBookMarks:TStringList;

//VariablefürdenDateinnamenderBookmark-Liste

SandboxAppScopeBookmarksfile:string;

//OrdernamenfürOrterderBookmark-ListeunddieBookmark-Dateien

Page 211: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

SandboxAppSupportPath:string;

SandBoxBookmarksFolder:string;

{$IFDEFUseSandbox}

UseSandboxing:Boolean=True;

{$ELSE}

UseSandboxing:Boolean=false;

{$ENDIF}

implementation

//DieseFunktionmussaufgerufenwerden,bevormaneine

//RessourceaußerhalbderSandboxnutzenwill

//UrlenthältdabeidenNamendesOrdnersoderderDatei

functionCanStartAccessingSecurityScopedResource(url:NSURL):boolean;

begin

Result:=false;

ifUrl<>NILthenbegin

try

ifnotURL.startAccessingSecurityScopedResourcethenbegin

{$IFDEFDebug}

ifShowDebugInfosthenShowMessage(‘StartAccessingerfolglos’);

{$ENDIF}

endelsebegin

Result:=True;

end;

except

{$IFDEFDebug}

ifShowDebugInfosthenShowMessage(‘FehlerinStartAccessing’);

{$ENDIF}

end;

end;

end;

//DieseFunktionmussaufgerufenwerden,wennderZugriffaufeine

//RessourceaußerhalbderSandboxbeendetwerdensoll

//Achtung:DieAufrufederstartundstopfunktionenmüssenausbalanciertsein!

//IstdasnichtderFall,verliertdieAnwendungwährendderaktuellenLaufzeit

Page 212: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

//dieFähigkeitSecurityScopedBookmarksnutzenzukönnen

functionCanStopAccessingSecurityScopedResource(url:NSURL):boolean;

begin

Result:=false;

ifUrl<>NILthenbegin

try

ifnotURL.stopAccessingSecurityScopedResourcethenbegin

ShowMessage(‘Kannnichtstoppen’);

endelsebegin

Result:=True;

//ShowMessage(‘HasAccess’);

end;

except

ShowMessage(‘FehlerinstopAccessingSecurityScopedRessource’);

end;

end;

end;

//PrüftobdasbenutzteOSBetriebssystemüberhauptinderLageist,

//SecurityScopedBookmarkszuerzeugen

//DasisterstabLion,Version10.7.3möglich

functionAppScopedBookMarksEnabled:boolean;

begin

Result:=false;

ifTOSVersion.Major>10thenbegin

Result:=true;

end;

ifTOSVersion.Major>=10thenbegin

if(TOSVersion.Minor>=8)thenbegin

Result:=true;

end;

if(TOSVersion.Minor=7)thenbegin

if(TOSVersion.ServicePackMajor>=3)thenbegin

Result:=true;

end;

Page 213: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

end;

end;

end;

//LegteineApp-ScopedSecurityBookmarkan,Ressourcekanndabei

//einOrdnerodereineDateisein

functionCreateAppScopedBookMark(vardata:NSDATA;URL:MacApi.Foundation.NSURL):Boolean;

var

err2:NSError;

includingResourceValuesForKeys:NSArray;

relativeToURL,AURL:MacApi.Foundation.NSURL;

ag:System.TGuid;

aGuid,ADir:string;

begin

Result:=False;

ifURL=NILthenexit;

//Prüfen,obhierfürschoneinEintragbesteht,dannnichtnochmalanlegen

ADir:=URL.path.UTF8String;

ifGetAppScopedBookMarkFromList(ADir,data)thenbegin

Result:=True;

exit;

end;

//Bookmarkexistiertnochnicht,daheranlegen

err2:=TNSError.Create;

err2:=NIL;

includingResourceValuesForKeys:=NIL;

relativeToURL:=NIL;

Data:=URL.bookmarkDataWithOptions(

NSURLBookmarkCreationWithSecurityScope,

includingResourceValuesForKeys,

relativeToURL,//NIL=App-Scope

@Err2);

Page 214: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

try

ifnotAssigned(err2)thenbegin

Result:=True;

ifData<>NILthenbegin

CreateGuid(ag);

aGuid:=GUIDToString(ag);

slBookmarks.Add(URL.path.UTF8String+#1+aGuid);

aGuid:=IncludeTrailingPathDelimiter(SandBoxBookmarksFolder)+aGuid;

//BookmarkindasBookmarkverzeichnisspeichern

Data.writeToFile(NSSTr(aGuid),true);

//ListederBookmarksspeichern

slBookmarks.SaveToFile(SandboxAppScopeBookmarksfile);

endelsebegin

Result:=false;

{$IFDEFDEBUG}

ifShowDebugInfosthenShowMessage(‘DatainCreateBookmarkisNIL’);

{$ENDiF}

end;

endelsebegin

Result:=false;

{$IFDEFDEBUG}

ifShowDebugInfosthenShowMessage(‘ERRinCreateBookmarkis<>NIL’);

{$ENDIF}

end;

except

{$IFDEFDEBUG}

ifShowDebugInfosthenShowMessage(‘ProblemwithERRinCreateBookmark’);

{$ENDIF}

end;

end;

//DieseFunktionerhältalsInputdasData-Objekt,welchesdieBookmarkenthält

//DieResolveBookmark-FunktionliefertdanndieRessourcezurück,

Page 215: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

//diedannspätermitdemeinleitenden“StartAccessing”genutztwerdenkann

functionGetResolvedAppScopedBookMark(data:NSData;varNEWURL:NSURL):Boolean;

var

Err:NSError;

relativeToURL:MACAPI.Foundation.NSURL;

begin

Result:=False;

err:=TNSError.Create;

err:=NIL;

RelativeToURL:=NIL;

NewURL:=NIL;

NewUrl:=TNSURL.Wrap(TNSURL.OCClass.URLByResolvingBookmarkData(

Data,

NSURLBookmarkResolutionWithSecurityScope,

relativeToURL,

0,

@Err));

if(NewUrl<>NIL)and(notAssigned(err))thenbegin

Result:=True;

endelsebegin

{$IFDEFDEBUG}

ifShowDebugInfosthenshowMessage(‘ERR<>NILinResolvedBookmark’);

{$ENDIF}

end;

end;

//DieseHilfsfunktionprüft,obfürdieangeforderteRessourcezuvor

//schonmaleineBookmarkerzeugtwurdeundliefertindiesemFalldasentsprechende

//Data-Objekt(mitderBookmark)zurück

//Hinweis:ADirkanneinOrdnerodereineDateisein

functionGetAppScopedBookMarkFromList(ADir:String;vardata:NSData):Boolean;

var

P,L:Integer;

Dir,AMark:string;

begin

Page 216: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

Result:=false;

forL:=0toslBookmarks.Count-1dobegin

P:=Pos(#1,slBookMarks[L]);

ifP<>0thenbegin

Dir:=Copy(slBookMarks[L],1,P-1);

AMark:=Copy(slBookMarks[L],P+1,5000);

AMark:=IncludeTrailingPathDelimiter(SandBoxBookmarksFolder)+AMark;

end;

ifDir=ADirthenbegin

data:=TNSDATA.Wrap(TNSData.OCClass.dataWithContentsOfFile(NSSTr(AMark)));

Result:=True;

break;

end;

end;

end;

//DieseHilfsfunktionprüft,obfüreineRessource,dieeinenOrdnerrepräsentiert

//bereitseinübergeordneterOrdnermiteinerBookmarkexistiert.Fallsja,

//wirddieBookmarkimData-Objektzurückgeliefert

//DavondieserRessource/diesemOrdnerZugriffeaufalleUnterordner

//möglichsind,mussmannichtfürdutzendevonUnterordnerBookmarks

//anlegen.

functionGetBaseAppScopedBookMarkFromList(ADir:String;vardata:NSData):Boolean;

var

P,L,start:Integer;

Dir,AMark:string;

begin

Result:=false;

forL:=0toslBookmarks.Count-1dobegin

P:=Pos(#1,slBookMarks[L]);

ifP<>0thenbegin

Dir:=Copy(slBookMarks[L],1,P-1);

AMark:=Copy(slBookMarks[L],P+1,5000);

Page 217: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

AMark:=IncludeTrailingPathDelimiter(SandBoxBookmarksFolder)+AMark;

end;

start:=pos(Ansilowercase(Dir),Ansilowercase(ADir));

ifstart=1thenbegin

data:=TNSDATA.Wrap(TNSData.OCClass.dataWithContentsOfFile(NSSTr(AMark)));

Result:=True;

break;

end;

end;

end;

//Prüft,obeineBookmarkfürdieangefragteRessourceexistiert

//ADirkanneinOrdnerodereineDateisein

functionExistsAppScopedBookmarkForRes(ADir:String):Boolean;

var

P,L:Integer;

Dir,AMark:string;

NS:NSString;

begin

Result:=false;

forL:=0toslBookmarks.Count-1dobegin

P:=Pos(#1,slBookMarks[L]);

ifP<>0thenbegin

Dir:=Copy(slBookMarks[L],1,P-1);

end;

ifDir=ADirthenbegin

Result:=True;

break;

end;

end;

end;

//DieseFunktionvereinfachtdenZugriffaufRessoruceperApp-ScopedBookmark,

//indemmehrereSchritteineinerFunktionzusammengefasstwerdenund

Page 218: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

//somitdasHandlingdeutlichvereinfachtwird.

//NachdemAufrufdieserFunktionundderNutzungderRessource

//mussimProgrammablaufdieFunktion

//CanStopAccessingSecurityScopedResourceaufgerufenwerden,

//damitdiestartundstopAufrufewiederausbalanciertsind!!

functionGetAppScopedAccessToRes(ADir:String;varurl:NSURL):Boolean;

var

Data:NSData;

begin

Result:=false;

ifGetAppScopedBookMarkFromList(ADir,data)thenbegin

url:=HSW.FMXSandbox.TNSURL.Create;

ifGetResolvedAppScopedBookMark(Data,url)thenbegin

ifCanStartAccessingSecurityScopedResource(url)thenbegin

Result:=True;

endelsebegin

{$IFDEFDEBUG}

ifShowDebugInfosthenbegin

ShowMessage(‘KeinZugriffaufdasDirectorymöglich.BitteerneutmitÖffnen-Dialgauswählen.’);

end;

{$ENDIF}

end;

end;

end;

end;

//WiedieFunktionzuvor,nurdassbeiOrdnerngeprüftwird,

//obbereitseineBookmarkfüreinenübergeordnetenOrdnerbesteht

//unddieseverwendetwerdensoll

//AufrufmachtjenachProgrammlogikSinn

functionGetBaseAppScopedAccessToRes(ADir:String;varurl:NSURL):Boolean;

var

Data:NSData;

begin

Result:=false;

Page 219: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

ifGetBaseAppScopedBookMarkFromList(ADir,data)thenbegin

url:=HSW.FMXSandbox.TNSURL.Create;

ifGetResolvedAppScopedBookMark(Data,url)thenbegin

ifCanStartAccessingSecurityScopedResource(url)thenbegin

Result:=True;

endelsebegin

{$IFDEFDEBUG}

ifShowDebugInfosthenbegin

ShowMessage(‘KeinZugriffaufdasDirectorymöglich.BitteerneutmitÖffnen-Dialgauswählen’);

end;

{$ENDIF}

end;

end;

end;

end;

Initialization

ifAppScopedBookMarksEnabledthenbegin

//WenndieNutzungderAppscopedBookmarksvomSystemunterstütztwerden

//hierschonmaldieStringlistezurVerwaltungderBookmarks-Liste

//unddieentsprechendenAblageorteerzeugen

SandboxAppSupportPath:=IncludeTrailingPathDelimiter(GetHomePath)+‘Library’+

PathDelim+‘ApplicationSupport’+PathDelim+ChangeFileExt(ExtractFileName(paramstr(0)),”);

ifnotDirectoryExists(SandboxAppSupportPath)thenbegin

ForceDirectories(SandboxAppSupportPath);

end;

SandBoxBookmarksFolder:=IncludeTrailingPathDelimiter(SandboxAppSupportPath)+‘Bookmarks’;

ifnotDirectoryExists(SandBoxBookmarksFolder)thenbegin

ForceDirectories(SandBoxBookmarksFolder);

end;

SandboxAppScopeBookmarksfile:=IncludeTrailingPathDelimiter(SandboxAppSupportPath)+‘AppScopeBookmarks.dat’;

Page 220: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

slBookMarks:=TStringList.Create;

slBookMarks.Duplicates:=dupIgnore;

ifFileExists(SandboxAppScopeBookmarksfile)thenbegin

slBookMarks.LoadFromFile(SandboxAppScopeBookmarksfile);

end;

endelsebegin

UseSandboxing:=false;

end;

Finalization

ifAppScopedBookMarksEnabledthenbegin

slBookMarks.Free;

end;

end.

Atachment2:NewlyimplementedOpenandSavedialogsforsandboxing

BelowyouwillfindthemycurrentimplementationsoftheOpenandSavedialogs,andadirectoryselectiondialog.Thesedialoguesallowsandboxing.

ThisfunctionmustbeimplementedinadifferentunitthantheHSW.FMXSandbox.pasown,sincetheNSURLfunctionsareused,whichareimplementedintheMACApi.Foundation.pasandnotmyalternativeimplementation.Itwouldbepossible,purelytoincreasethesefunctionsinthesandboxunit,onewouldhaveinthecorrespondingNSURLfunctionsspecifytheMACApi.Foundationunitscope.IhavealsodonesonotbecauseIneedjustasinmyownprogramandUnitsystematics.

{$IFDEFMACOS}

//Functiontoselectafoldertocreatethepossibilityofabookmark

functionMACSelectDirectory(constATitle:string;varADir:string;CreateBookMark:Boolean):Boolean;

var

LOpenDir:NSOpenPanel;

LInitialDir:NSURL;

Page 221: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

LDlgResult:NSInteger;

Data:NSData;

begin

Result:=False;

LOpenDir:=TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel);

LOpenDir.setAllowsMultipleSelection(False);

LOpenDir.setCanChooseFiles(False);

LOpenDir.setCanChooseDirectories(True);

LOpenDir.setPrompt(NSSTR(‘Auswählen’));

//LOpenDir.setCanCreateDirectories(True);

ifADir<>”then

begin

LInitialDir:=TNSURL.Create;

LInitialDir.initFileURLWithPath(NSSTR(ADir));

LOpenDir.setDirectoryURL(LInitialDir);

end;

ifATitle<>”thenLOpenDir.setTitle(NSSTR(ATitle));

LOpenDir.retain;

try

LDlgResult:=LOpenDir.runModal;

ifLDlgResult=NSOKButtonthen

begin

ifLOpenDir.URL<>NILthenbegin

ADir:=LOpenDir.URL.path.UTF8String;

endelsebegin

ifLOpenDir.URLs.objectAtIndex(0)<>NILthenbegin

ADir:=string(TNSUrl.Wrap(LOpenDir.URLs.objectAtIndex(0)).relativePath.UTF8String);

end;

end;

ifFileExists(ADir)thenbegin

ADir:=ExtractFilePath(ADir);

end;

Result:=True;

Page 222: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

{$IFDEFUseSandbox}

if(AppScopedBookMarksEnabled)and(CreateBookMark)thenbegin

CreateAppScopedBookMark(Data,LOpenDir.URL);

end;

{$ENDIF}

end;

finally

LOpenDir.release;

end;

end;

//Functiontoselectthefile(open)withtheabilitytocreateabookmark

functionMACSelectFile(constATitle:string;varAFile:string;CreateBookMark:Boolean):Boolean;

var

LOpenDir:NSOpenPanel;

LInitialDir:NSURL;

LDlgResult:NSInteger;

Data:NSData;

begin

Result:=False;

LOpenDir:=TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel);

LOpenDir.setAllowsMultipleSelection(False);

LOpenDir.setCanChooseFiles(True);

LOpenDir.setCanChooseDirectories(false);

LOpenDir.setPrompt(NSSTR(‘Öffnen’));

//LOpenDir.setCanCreateDirectories(True);

ifAFile<>”then

begin

LInitialDir:=TNSURL.Create;

//LInitialDir.initFileURLWithPath(NSSTR(ExtractFilePath(AFile)));

ifFileExists(AFile)thenbegin

LInitialDir:=TNSURL.Wrap(TNSURL.OCClass.fileURLWithPath(NSSTR(AFile)));

endelsebegin

LInitialDir:=TNSURL.Wrap(TNSURL.OCClass.fileURLWithPath(NSSTR(ExtractFilePath(AFile))));

end;

Page 223: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

LOpenDir.setDirectoryURL(LInitialDir);

end;

ifATitle<>”then

LOpenDir.setTitle(NSSTR(ATitle));

LOpenDir.retain;

try

LDlgResult:=LOpenDir.runModal;

ifLDlgResult=NSOKButtonthen

begin

AFile:=string(TNSUrl.Wrap(LOpenDir.URLs.objectAtIndex(0)).relativePath.UTF8String);

Result:=True;

{$IFDEFUseSandbox}

if(AppScopedBookMarksEnabled)and(CreateBookMark)thenbegin

CreateAppScopedBookMark(Data,LOpenDir.URL);

end;

{$ENDIF}

end;

finally

LOpenDir.release;

end;

end;

//Functiontochooseanameforafilewiththepossibilityofthisfile

//Createandbookmarkit

functionMACSaveFile(constATitle:string;varAFile:string;CreateBookMark:Boolean):Boolean;

var

panelSaveDir:NSSavePanel;

pnInitialDir:NSURL;

LDlgResult:NSInteger;

Data:NSData;

Error:NSError;

begin

Result:=False;

panelSaveDir:=TNSSavePanel.Wrap(TNSSavePanel.OCClass.SavePanel);

panelSaveDir.setNameFieldStringValue(NSSTr(ExtractFileName(AFile)));

panelSaveDir.setAllowsOtherFileTypes(True);

Page 224: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

panelSaveDir.setPrompt(NSSTR(‘Sichern’));

panelSaveDir.setNameFieldLabel(NSStr(‘Sichernals:’));

ifAFile<>”thenbegin

pnInitialDir:=TNSURL.Create;

ifFileExists(AFile)thenbegin

pnInitialDir:=TNSURL.Wrap(TNSURL.OCClass.fileURLWithPath(NSSTR(ExtractFilePath(AFile))));

endelsebegin

pnInitialDir:=TNSURL.Wrap(TNSURL.OCClass.fileURLWithPath(NSSTR(ExtractFilePath(AFile))));

end;

panelSaveDir.setDirectoryURL(pnInitialDir);

end;

ifATitle<>”then

panelSaveDir.setTitle(NSSTR(ATitle));

panelSaveDir.retain;

try

LDlgResult:=panelSaveDir.runModal;

ifLDlgResult=NSOKButtonthenbegin

//AFile:=string(TNSUrl.Wrap(panelSaveDir.URLs.objectAtIndex(0)).relativePath.UTF8String);

ifpanelSaveDir.directoryURL<>NILthenbegin

AFile:=IncludeTrailingPathDelimiter(panelSaveDir.directoryURL.path.UTF8String)+panelSaveDir.nameFieldStringValue.UTF8String;

endelsebegin

ifpanelSaveDir.URL<>NILthenbegin

AFile:=panelSaveDir.URL.path.UTF8String;

end;

end;

Result:=True;

{$IFDEFUseSandbox}

if(AppScopedBookMarksEnabled)and(CreateBookMark)thenbegin

//ZunächstmussdieDateierzeugtwerden,daetwasvorhanden

//seinmuss,wodieBookmarkanknüpfenkann.

ifpanelSaveDir.directoryURL<>NILthenbegin

ifnotFileExists(AFile)thenbegin

Page 225: Author: Harry Stahl Delphi and FireMonkey are registered …docshare04.docshare.tips/files/29242/292424038.pdf · 2017. 3. 5. · Section 3: Provisioning and deployment 1. Submission

NSStr(AFile).writeToFile(NSStr(AFile),false);

end;

endelsebegin

ifpanelSaveDir.URL<>NILthenbegin

ifnotFileExists(panelSaveDir.URL.path.UTF8String)thenbegin

panelSaveDir.URL.path.writeToFile(panelSaveDir.URL.path,false);

end;

end;

end;

ifpanelSaveDir.directoryURL<>NILthenbegin

CreateAppScopedBookMark(Data,panelSaveDir.URL);

end;

end;

{$ENDIF}

end;

finally

panelSaveDir.release;

end;

end;

{$ENDIF}