With Statement, do we need the feature?

There is one feature of the pascal language which should be very handy to use and make a code much simpler but actually like a double edged sword, it can help you to solved a case, but also can kill you with problems in the future, that is the “with” statement.

Example of a “with” statement:

with TButton.Create(Self) do
begin
  Parent := Self;
  Name := 'btnTest';
  SetBounds(10,10,100,30);
  Caption := Caption + 'Test Button';
  Visible := True;
end;

This looks good and no problem here, but you can see that there is Caption property which we want to set the caption property of the button object to Caption + ‘Test Button’, where the Caption here intended to be the form’s caption property, but of course the value of the button will be use as there is no object identifier before the Caption, we need to explisitly mention the object like this

with TButton.Create(Self) do
begin
  Parent := Self;
  Name := 'btnTest';
  SetBounds(10,10,100,30);
  Caption := Self.Caption + 'Test Button';
  Visible := True;
end;

Looks good right, then you may think again, hey the “with” statement feature support multiple object, so why don’t we add Self to the “with” statement, so there will be no object defined, just the method or properties only, that will much reduce the code. Here is the updated example:

with TButton.Create(Self), Self do
begin
  Parent := Self;
  Name := Name + '_btnTest';
  SetBounds(10,10,100,30);
  Caption := Caption + 'Test Button';
  Visible := True;
end;

Isn’t this great, no need to define the object, but you will surely face a big problem here, as you can see, SetBound is also a method of a form where you mention in the “with” statement with Self. If you run the code, you will find the setBounds will set the form instead of the button.

This is just a simple example, but it shows you how dangerous it is, I like a more verbose code, Delphi already have inline var, it can help to shorten a code like the code below:

var b := TButton.Create(Self);
b.Parent := Self;
b.Name := Name + '_btnTest';
b.SetBounds(10,10,100,30);
b.Caption := Caption + 'Test Button';
b.Visible := True;

Well, that is just an extra of two character for each line of code, but it save a lot of trouble. You can think that “Hey, I know what I’m doing with the “with” statement, I will surely guard the code in the “with” statement block from ambiguity”, it is fine for you to think that, it just that why bother yourself with a dangerous code, you face a lot more problem with the “with” statement, it just to shorten a code, so you can avoid doing that safely, not something “need to do”

I’m thinking that at least if the with statement can be changed to be able to use a dot (a feature from the “with” statement implementation of visual basic) before accessing the “with” statement object properties, that will add more security, at least it help to see that it tries to access object properties of the “with” statement, not the object from outside the “with” statement block, but still there will be ambiguity problem when using more than one object in the “with” statement.

Maybe if you can also add an alias for each object in the “with” statement and you can use the alias or not to use the alias just to solve the ambiguity problem, then maybe the “with” statement will be much useful and powerful. This features might be a better solution to cover the need for shortened code, but for me, I’m the “pascal guy”, verbosity in the code is very important for me 😊

So in summary, what I think about the “with” statement is that it is a dangerous code feature, can be avoided, and not something “need to do”

Iwan CS

Do We Need to Check Object Reference

In Delphi, we will often create an object, use it, then destroyed it. All object in Delphi need to be destroyed in order to prevent memory leaked (a condition where the object still occupy a block of memory even when the application already terminated, thus making the object don’t have an owner to destroy it). On a simple project where we just use objects that we put on the form at design time (a term to tell a time where we design our form before the application is run), the objects is owned by the form, thus it will automatically destroyed when the form destroyed, so we don’t have to think about the memory leaked.

This behaviour is making development much easier, we don’t have to manage the objects lifecycle ourself, but this condition is not suitable for a much bigger projects where we need to use a lot more forms and other objects that if we make them automatically created and destroyed by Delphi will make our program consume a lot of memory that wasted the resources as not all of the forms and objects needs to be created at first run, they should be run or created when needed. This is what we call as “Created at run time”.

When we create object at run time, we must make sure the object gets destroyed when the application terminated. Luckily, Delphi can help us handle most of runtime object destruction, in Delphi if we create an object descended from a TComponent, i has an owner parameter. This parameter is important, it defines who the owner of the object, and then this owner will be responsible to destroy all the objects it owned.

There are few type of owner we can assigned to an object we create, they are:

  • A Component, an object that descended from TComponent
  • Application object, an object that owns the application
  • Nil, no object owned them

When we assigned an object to a component, then when that component destroyed, the object also gets destroyed. When we assigned an object to an application object, then that object gets destroyed only when application terminated. When we assigned nil to the owner of the object, we really need to handle the destruction of the object ourself, it won’t gets destroyed even if the application terminated.

So it should be easy right, just set the owner of all the object to a component or application object, it will be solved automagically by Delphi, well, not quite true nor false, it depends on what we need with that object we created. If we need an object that will be used as long as the object’s owner alive, then you can use that method. But when we need to recreate the object many times while the object’s owner still alive, then we can’t use the method. For example, we want a button in a form create another form as a dialog form to do something, and it is possible to click many times on that same button with the same routine that will show a dialog form, then we will face a problem with the dialog form lifecycle.

Everytime we create an object, it will consume a block of memory until we destroyed the object, so even though we assigned an owner of the object to the form, then as long as the form hasn’t destroyed, then all the objects we create will stay alive and stay at the memory, and if we just creates the object every time we press that button, then it will create a lot of objects and consume more memory block, then finally we will face an out of memory problem if we have a lot of object that created this way.

So what is the solutions? There are few ways to solve this problems, I will only discuss one of them. Yes, like the title of this blog said, to check the object reference before we create a new object. So most of the time, we better to always check an object reference before we create another object (I will discuss later about why I mention most of the time, it really means not all the time 😊). To check for an object reference, there are several ways to do it.

We can use the Assigned method where it takes a pointer as the parameter. The pointer should be an address (in memory) of the object we want to check. This method will check whether the address specified in the parameter still point to a valid object’s reference address, but it is important to know and remember that it will only check whether the address specified is assigned to an object’s reference adress or unassigned (nil). So even if we check the variable that stored the object’s reference address with assigned method, we still can’t make sure whether the object already destroyed or not.

We can also use a direct comparison of an object with nil, the result is the same with Assigned method before. The syntax is like this:

if MyObject <> nil then

Well this looks like a much better way to check an object reference, so why is there Assigned method? Assigned method is a method to check a valid pointer, so it can also check for a valid procedural variable without executing the procedure.

So if a direct comparison for an object with nil can do the job well, do we still need assigned method to check of an object reference? Assigned method actually doing the same thing like the code above for an object reference, it just that it can also check for a valid procedural variable correctly, so in my opinion, we better use assigned method for all object reference checking, this will make it easier to remember and for uniformity of our code.

There is still something very important we need to discuss, it is true that we just need to check for the object reference whether it still a valid object or not, but how to make sure an object already destroyed and the reference address already unassigned (nil)? To destroy an object, we use Free method, but this method will only free the reference object, not the reference address, the reference address will still hold the object’s reference address, thus when we check using assigned method or compare it with nil directly, it will still return a valid object’s reference address but not a valid object. So to make it correctly destroy the object and object’s reference address we need to set the reference address to nil. So it will looks like this:

MyObject.Free;
MyObject := nil;

That code will make sure that MyObject will no longer hold the object and the object’s reference address and this code snippet will work correctly and safely:

if not Assigned(MyObject) then
begin
  MyObject := TForm1.Create(self);
end;

A complete simple object creation snippet will look like this one:

if not Assigned(MyObject) then
begin
  MyObject := TForm1.Create(self);
  try
    MyObject.ShowModal;
  finally
    MyObject.Free;
    MyObject := nil;
  end;
end;

In that code sample, you need to make sure to use ShowModal, so the form won’t get destroyed after it is created.

There is actually a method provided by Delphi to make it easier to destroy an object correctly, that is the FreeAndNil method, it basically do the same thing as the code I mention above, that is to free and set nil to the reference address.

So, why not always use FreeAndNil to all objects we create, well this is the part to discuss where I mention before that I use “most of the time” to check for an object reference. As the project goes bigger and bigger, you might face a condition where you can’t or you don’t want to control the variable that store the object’s reference address. Then with this condition, you can only destroy the object, but you can’t set the object’s reference address to nil, so you can’t use the object reference checking method to make sure you create the object only once and will not consume more memory.

Then what can we do when we face this kind of condition? Actually there is no way to check without knowing the reference address that stored somehow, but in my case, there is a solutions. In my case I face the problem for forms object, where I don’t want to maintain the variable that store the form object’s reference address. In Delphi, all created forms’ reference address will also stored in the TScreen object, it is in the Screen.Forms property to be exact. This property hold all forms object that created at design time or at run time. So we just need to check whether our form that we want to recreate is exists in the Screen.Forms list.

With this method, we just need to assigned an event on the Form’s OnClose event to set the Action to caFree, so when the form closed, the form’s object will be destroyed automagically, and we don’t have to check the form’s reference address using Assigned method or direct comparison to nil method. Here is the code snippet to check for the form instance before we recreate it:

function IsFormLoaded(AFormName : string) : boolean;
begin
  Result := False;
  for var i := 0 to Screen.FormCount - 1 do
  begin
    if CompareText(Screen.Forms[i].Name, AFormName) then
    begin
      Result := True;
      break;
    end;
  end;
end;

So the answer to the question “Do We Need to Check Object Reference”, it’s definitely a yes and in my opinion, you always need to make this method as your coding habit to make less bug in the future.

That’s all I need to say this time, if you have any question or want to discuss more, feel free to comment. There will be a webinar “FreeAndNil() – Delphi Developer Debate” by Embarcadero, don’t missed it and make sure you register it here : https://blogs.embarcadero.com/freeandnil-delphi-developer-debate/

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy to Windows, Linux, macOS, iOS, and Android. There is a great discount promo until June 30, 2022, please visit our store and you can order directly here: https://www.interaktif.solutions/product-category/embarcadero/

Iwan CS

Delphi 27th Birthday – Why I Love Delphi

Delphi turns to 27 today, happy birthday to Delphi 🥳🥳🥳 I really love Delphi since I learned it years ago. For me, what I love about Delphi are:

  • Compiled very fast
  • Compiled to native code
  • Easy deployment, just put everything in a single folder and my application can be run directly, don’t even need to be installed, just a full copy can run the application, can even run from a flash disk
  • I can easily inherit a component and create a new derivative component with extra features I wanted
  • There are a lot of low level wrapper library that I can use, but if I need some custom implementation of the low level library, I can easily create my own wrapper or just extend from existing wrapper library.
  • Code compatibility with older version of Delphi, I can easily load old project and compiled it to newer version of Delphi
  • I can create Android and iOS application without learning new language, you can even debug Android Application
  • I can also create web application without a deep knowledge of html, css and js with the help of pas2js technology that implemented with full drag and drop form designer by TMS WebCore. There are also a lot of other web application technologies that use Delphi language to create a Web Application like Intraweb, Raudus, Unigui, and others

The main thing I love Delphi is that I can keep up to date with the latest technology without needing to learn new language. For me, learning new language cost times, with having a good and deep knowledge of a single language, I can focused more on the core problem of the application business development instead of working hard and took a lot of time to learn a new language on how to do things.

With the single source and capability to target multiple platform greatly reduce the development time and teams, I only needed the same team to develop desktop and mobile apps. I have developed a robust and flexible platform independent application framework that enables my goals to be achieved. The same framework can be used to develop a VCL framework and FMX framework so that I need only to focus on designing the layout and functions of the form and all other general internal processes like to setting up the datasets, connect to servers, user management, menu management, will use the application framework library I have developed.

That’s my story of why I love Delphi, so what’s yours 😊

Contoh Aplikasi dengan Form Login

Artikel ini merupakan bagian dari #DelphiCodingSeries dengan sub tema #LogonSystem yang diharapkan akan membahas hingga metode otentifikasi dan otorisasi pengguna mempergunakan protokol komunikasi token keamanan.

Pada seri pertama ini, saya akan mencoba untuk memberikan contoh salah satu cara untuk membuat sebuah aplikasi yang akan menampilkan form login untuk meminta informasi nama pengguna beserta kata kunci terlebih dahulu sebelum pengguna dapat mengakses dan mempergunakan aplikasi kita.

Sebenarnya ada banyak sekali teknik untuk menampilkan form login untuk meminta data akses pengguna, namun tujuannya pasti sama, yaitu memastikan aplikasi kita tidak dapat diakses atau memiliki akses yang terbatas jika pengguna belum memberikan informasi akses pengguna yang benar. Nah saya akan mencoba untuk menerapkan salah satu teknik form login, yaitu teknik yang hanya akan menampilkan form login dan saat pengguna berhasil memberikan nama pengguna dan kata kunci yang benar, maka form login akan tertutup dan aplikasi akan ditampilkan.

Berikut ini tampilan form login :

Form Login

Berikut ini contoh tampilan aplikasi

Tampilan Aplikasi

Terlihat seperti cara yang sederhana dan seperti biasanya kita membuat aplikasi, dimana kita hanya perlu menambahkan form login, namun perlu diingat bahwa pada Delphi hanya ada 1 form yang merupakan Project Mainform, dan aplikasi akan diakhiri jika Project Mainform ditutup. Nah yang jadi masalah adalah jika kita buat form login sebagai form yang dibuat pertama kali, maka form login akan menjadi Project Mainform, yang berarti kita tidak bisa benar – benar menutup form login dan hanya bisa menyembunyikan form tersebut saat pengguna berhasil login. Namun jika kita buat form login setelah form pada aplikasi kita dibuat, maka form aplikasi kita dan form login keduanya tampil bersamaan. Kondisi kedua ini adalah salah satu cara teknik lain membuat form login. Namun pada artikel ini saya akan menerapkan bagaimana kita bisa menampilkan hanya form login, namun tetap menjadikan form pada aplikasi kita sebagai Project Mainform.

Berikut adalah penjelasan metode yang saya pergunakan untuk mencapai target tersebut:

Persiapan Proyek

Buat sebuah aplikasi baru, kemudian tambahan 1 form sebagai form login dan 1 datamodule. Ubah tampilan form login sesuai kebutuhan. Kemudian kita perlu mengubah urutan pembuatan object dengan mengubah urutan pada daftar Auto Create Forms dari Project Options | Application | Forms seperti berikut ini :

Project Options | Application | Forms

Pastikan urutan object pada form seperti pada gambar yaitu Datamodule, Form Aplikasi, Form Login

Ubah Project Source Code

Untuk dapat menerapkan konsep tersebut, maka kita buat perubahan pada Project Source Code. Untuk membuka Project Source Code adalah melalui menu Project | View Source, atau klik kanan pada node project tersebut, kemudian pilih menu View Source, seperti pada gambar berikut:

Menu Project | View Source

Kamudian dapat kita liat potongan Project Source Code yang akan kita ubah seperti contoh berikut:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.ShowMainForm := False;
  TStyleManager.TrySetStyle('Puerto Rico');
  Application.CreateForm(TdmAPI, dmAPI);
  Application.CreateForm(TfrmMain, frmMain);
  Application.CreateForm(TfrmLogin, frmLogin);
  Application.Run;
end.

Delphi akan otomatis menetapkan kelas form pertama yang dibuat sebagai Project Mainform, dalam hal ini TfrmMain adalah Project Mainform. Datamodul harus dibuat sebelum TfrmMain karena datamodul akan berisi koneksi database yang diperlukan oleh semua form sehingga harus dibuat lebih dulu dibanding semua form lainnya. Kemudian bisa kita lihat ada baris tambahan sebelum baris CreateForm yang perlu diperhatikan yaitu :

Application.ShowMainForm := False;

Baris ini merupakan kunci untuk metode kita yang merupakan sebuah rutin untuk menyembunyikan Project Mainform. Kita tidak bisa hanya menerapkan nilai property Visible := False pada form aplikasi kita, karena Project Mainform pasti akan ditampilkan dan tidak melihat nilai dari property tersebut..

Sampai disini kita sudah berhasil membuat form login ditampilkan terlebih dahulu dan Project Mainform tidak ditampilkan. Pada artikel berikutnya kita akan bahas bagaimana cara kita bisa memeriksa hak akses pengguna dan menampilkan Project Mainform jika berhasil. Saya telah siapkan contoh proyek di github yang dapat diakses untuk pembelajaran mandiri, silahkan komen jika ada yang ingin ditanyakan atau dibahas.

Berikut link github : Delphi VCL Example Project for login form

Bergabunglah bersama komunitas programmer Delphi di Komunitas Penggemar Pemrograman Delphi di Telegram atau di Komunitas Penggemar Pemrograman Delphi di Facebook

Ikuti juga channel Publikasi “Dev Tools” by ICL yang merupakan channel kami untuk update informasi mengenai update maupun promo produk Development Tools yang kami pasarkan. Saat ini kami telah bekerja sama dengan 3 vendor Development Tools, yaitu Embarcadero Technology, Fast Report, dan DevExpress

Happy Coding

Updated Dev C++

Embarcadero Dev C++ adalah sebuah “Integrated Development Environment” (IDE) yang lengkap dan gratis untuk pengembangan aplikasi dengan bahasa pemrograman C++. Compiler C++ yang dipergunakan adalah dari TDM-GCC atau dapat juga mempergunakan compiler berbasis GCC lainnya. Dev C++ adalah salah satu proyek open source yang didukung dan disponsori oleh Embarcadero Technology yang merupakan pengembangan dari Bloodshed Dev C++ dan Orwell Dev C++. Dev C++ dikembangkan dengan mempergunakan Delphi, dan versi terbaru dari Dev C++ dikembangkan kembali dengan mempergunakan Delphi versi 10.4 dan diluncurkan dengan versi 6.x. Saat ini versi stabil adalah versi 6.2.

Salah satu keuntungan IDE Dev C++ adalah bahwa IDE ini berjalan secara native di sistem operasi Windows, sehingga hemat penggunaan memory dan performa yang tinggi sehingga memberikan pengalaman pengembangan bahasa C++ yang nyaman dan cepat, disertai code editor yang cukup lengkap dalam mempermudah dan mempercepat pengembangan aplikasi.

Dalam versi terbaru ini, tim pengembang Dev C++ fokus pada pembaharuan aplikasi untuk dapat dicompile dengan Delphi 10.4 dan dapat menerapkan VCL Style untuk menampilkan IDE Dev C++ dengan tampilan yang lebih modern dan menarik. Terdapat beberapa style yang dapat dipilih, salah satunya yang menjadi favorite semua pengembang adalah Dard Mode yang diterapkan oleh style dengan nama Black Pearl. Selain itu ada beberapa style lain yang dapat dipilih untuk disesuaikan dengan mood developer

Untuk mendownload Dev C++ dapat melalui link berikut : Dev-C++ Overview – Free Tools – Embarcadero Website,atau jika ingin mendownload Source Code atau ingin ikut berkontribusi, silahkan ke Embarcadero/Dev-Cpp: A fast, portable, simple, and free C/C++ IDE (github.com). Jangan lupa berikan bintang untuk proyek ini jika anda menyukainya

Happy Coding

Back to Writing

Hello,

It’s been a while since my last writing about Delphi Programming Tips & Tricks, i’ve been very busy with my work, don’t have enough time to spend some time to write, but i will try my best to begin writing again.

For the last two years, I’ve been busy doing the best i can to reintroduce Delphi in Indonesia Programming Community, i’m actively participates in several Social Media like Facebook  Groups and Telegram Groups. With the release of a long waited important feature in Delphi, which is a fully functional Free Version of Delphi called Community Edition (https://www.embarcadero.com/products/delphi/starter), i see that a lot of new programmer coming to try and learn Delphi, specially for the mobile development tools.

There are also a lot of new teachers or lecturers teach Delphi Programming, but unfortunately they still using the old Delphi 7 version as it is a well known as the best Delphi ever and the last Delphi version too, they did not know about the new Delphi version which support multiple platform. But as they ask in the group and we encourage them to use the Community Edition of Delphi, now most of them is using the Community Edition, and slowly most of them know about the latest Delphi version. It’s a long and hard work to get there, but me and my fellow Delphi developer friends, will try the best to give support as much as we can.

So please follow my blog to get more Delphi Tips & Trick from my experience or from many source that i gathered and improved

 

Cheers

Iwan CS

Create Class By Name

I have build a framework of application that help me to boost the production time, there are a lot of things that i need to make it as flexible as possible and the goal is to have a minimum of coding time and more on design time with drag and drop only, that goal is still long way to go. One of them is a way to create an instance of a class at runtime of course. So I’ve been searching the internet to find a way to do it with minimum effort on the application layer development, and the only thing I’ve found at that time is to use Classes.GetClass method, that is about 10 years ago. The problem for using this method is that we still need to put the classes.RegisterClass and Classes.UnregisterClass somewhere in our code. In my first version framework, I put it in a TDataModule that i design to store all common component there. But that was a huge mistake, my framework was not easy to develop and was not scalable. So I’ve upgraded my framework and this time i put both method in the initialization and finalization respectively in each unit. This method is working perfectly up until now. But some heavy discussion with my friend make my upgrade my knowledge again to get better way to do the same thing.

Continue reading

Print Carbon Copy with Fastreport

If you wish to create a report that need to be printed in multiple pages with most of the content is the same, here is one of the solution.
Before that i want to explain why i need this method, i need this method because sometimes we need a report that print the exact same data but need to be in multiple pages at once, we usually do this using a dot matrix printer and 2 or more sheet of pre printed carbon paper.
Now that i need to print on an empty paper but have the same effect like a carbon copy, i have to handle problem on how to print the exact data multiple times but with a little different information on each page. Examples :
Copy 1 : For Customer
Copy 2 : For Sales
Copy 3 : For Administrator
So to do this, here is what we need to do.
We will use PrepareReport to do the trick.
Here is the code sample
frxrprtReport.Variables.Variables[‘CarbonCopy’] :=  QuotedStr(‘Copy 1 : For Customer’);
frxrprtReport.PrepareReport;
frxrprtReport.Variables.Variables[‘CarbonCopy’] :=  QuotedStr(‘Copy 2 : For Sales’);
frxrprtReport.PrepareReport(False);
frxrprtReport.Variables.Variables[‘CarbonCopy’] :=  QuotedStr(‘Copy 3 : For Administration’);
frxrprtReport.PrepareReport(False);
frxrprtReport.ShowPreparedReport;
So as you can see, you send the text for the information you need to put differently for each of carbon copy. That’s only an example, you can do a lot other the same way.
Notice that only the first PrepareReport is not using argument, because we want to clear previous report just to make sure
Iwan CS

Delphi XE Object Inspector Shortcut

Sometime i need to find an object properties on the object inspector pane quickly, before i found a new way, i use the scroll bar then search for the properties, now i found a new way.

To search for an object properties faster, you have to know the name of the properties first then you have to activate the Object Inspector Pane, either by pressing F11 or by selecting it using the mouse or by pressing the Return Key when focusing on the component, then the focus will be default to the object properties value, now to search for the property we want, you must press the TAB key then the focus will move to the object properties name. From there you can start typing the property name and it will focus to the first property that has the name similar to what you type

Iwan CS

Delphi XE Build Group

One feature i like in Delphi XE is the Build Group. This feature make me build or compile my multiple project, multiple module quickly. This feature will store projects and packages that we want to be Compiled/Build/Clear together into a Build Name. You can have multiple Build Group of course. With this feature i can just choose a build name, let say Client that will just compile the GUI package and the Client Application that my Project Group actually consist of more packages and application. This feature is very handy if you are working with a lot of projects and packages.

To use this feature:

– First click on the Show Build Group Pane on the project manager pane

– Then click on the New Build Group button

– Then set the build group name

– Then select all projects and packages that need to be in one build group

To use the build group

– First click on the Show Build Group Pane on the project manager pane

– Then choose the build name you want to build

– then click on the Compile/Build/Clear button on the build group pane

That’s all.

Iwan CS