tag:blogger.com,1999:blog-53147453817787415172024-03-13T18:22:54.046+00:00LazPlanetAdnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.comBlogger108125tag:blogger.com,1999:blog-5314745381778741517.post-76625462842265228732020-05-12T18:29:00.000+01:002020-05-12T18:44:59.446+01:00How to Cross Compile on Lazarus<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-nRtzgov-KAs/XrfxqovhwnI/AAAAAAAACqE/OQo40HHzetcBWF_JDMh07tA1HWP1mRzkACNcBGAsYHQ/s1600/lazarus-cross-compile-postthumb.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" src="https://1.bp.blogspot.com/-nRtzgov-KAs/XrfxqovhwnI/AAAAAAAACqE/OQo40HHzetcBWF_JDMh07tA1HWP1mRzkACNcBGAsYHQ/s1600/lazarus-cross-compile-postthumb.png" /></a></div>
It's alive! It's working! We're compiling for other OSs that we don't have... easily!<br />
<br />
<a name='more'></a><br />
How many times have you thought of providing your software for a platform and was planning on running that OS just to create executables for it? I don't know about you, but it recently struck my mind, when I was attaching binaries to one of the <a href="https://gitlab.com/lazplanet/lua-inside-fpc">LazPlanet example</a> <a href="https://gitlab.com/lazplanet/lua-inside-fpc/-/releases">releases</a> on GitLab.<br />
<br />
Personally I don't like Windows. Many people say that it's easy to use and common, but I find it as a security and privacy nightmare, plus a bloat and very difficult to maintain. Think about updating browsers on both Windows and Linux. Linux has one command to update not just the browsers, but all of the software in the system. In Windows, you have to download things, install things one by one - which is a waste of time. Plus, Linux is free to download and <a href="https://www.gnu.org/" target="">Free as in freedom</a>. It was built by people just like us from all over the world.<br />
<br />
I use Linux most of the times and reduced the use of Windows as much as I can.<br />
<br />
I was thinking if I could build EXEs for Windows users, without going to a Windows machine. And it turns out it was possible! Through Cross Compilation!<br />
<h2 style="text-align: left;">
What is cross compiling and why is it important?</h2>
Simply put, cross compile lets us to create executables for a platform that we are not currently running.<br />
<br />
If I want to be more correct, cross compile means to compile for an architecture that the currently installed fpc can't handle by default. For example, if you have a 64bit Lazarus installed, it may be able to compile for 64bit just fine. But it can't compile for 32bit. For that you will have to use a cross compiler over your existing fpc compiler.<br />
<br />
Cross compile is even possible for operating systems that are not currently installed on your system. For example, you can compile for Windows from Linux operating system with cross compilers. Amazing!<br />
<br />
This saves you a ton of effort to maintain a separate OS for just building some EXEs. You can just install the cross compiler, set it up and forget all the trouble!<br />
You also get to streamline your development within a single platform, without ever having to leave the platform that you love so much!<br />
<br />
In this article we'll learn how to cross compile in Windows and Linux. Mac is a bit limiting for cross compilation. We can't compile for Mac unless we have a Mac machine. I don't have a Mac, so skipping Mac altogether. But if you're interested on Mac, <a href="https://wiki.lazarus.freepascal.org/Cross_compiling">try the wiki</a>. There are loads of examples on how to do things.<br />
<h2 id="what-s-up-with-32bit-and-64bit-">
What's up with 32bit and 64bit?</h2>
Some basic terminologies:<br />
<ul>
<li>x86 or i386/i686/80386 or i486/i686 = 32bit</li>
<li>x86_64 or x64 = 64bit</li>
<li>Win32 = Windows 32bit</li>
<li>Win64 = Windows 64bit</li>
</ul>
Remember that 64bit is a later architecture and 64bit operating systems can run 32bit applications just fine. But 32bit operating systems cannot run 64bit applications. Similarly, some older processors are 32bit only and cannot run 64bit operating systems. Generally 64bit applications and operating systems should run faster compared to 32bit. So why do we stick to 32bits? There are couple of reasons:<br />
<ul>
<li>some people do not have access to newer hardware, cannot afford it or are fine with existing hardware.</li>
<li>some people do not have 4GB or higher RAM which is needed to get most out of 64bit systems.</li>
</ul>
32bit is kind of an old architecture at this point. Many popular software have also stopped providing 32bit application files. Look around and you'll see loads of examples. Especially browsers, for example, Chromium browser. So should we care for 32bit builds? I think yes. Mostly because 32bit executables can run on both 32bit and 64bit OSs. If you want to build one executable format (which is fine for small projects), 32bit is excellent to support maximum possible users.<br />
<br />
Another reason would be to avoid pushing <a href="https://en.wikipedia.org/wiki/Planned_obsolescence">planned obsolescence</a> to the users who use our software. I think it's a nice idea that we should try to use our computers as long as possible or if that's not possible, pass it to who needs it. There are lots of people who need a computer but can't afford it. The world is filled with computer garbage already, so we should not try to make this worse.<br />
<br />
<h2 style="text-align: left;">
Video</h2>
Find the steps of this article in the <a href="https://youtu.be/7cQw8M3QwuQ" target="_blank">video</a> below:<br />
<br />
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube-nocookie.com/embed/7cQw8M3QwuQ" width="560"></iframe>
<br />
<h2 id="from-win64-to-win32">
From Win64 to Win32</h2>
This is if you have Lazarus 64 bit installation and want to build for Win32:<br />
<ul style="text-align: left;">
<li>Go to <a href="https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/">https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2032%20bits/</a>, then your Lazarus version</li>
<li>Download and install <code>fpc-a.b.c.i386-win32.exe</code>. When installing it will suggest a path like <code>C:\FPC\3.0.4</code>, but make it like <code>C:\lazarus\fpc\3.0.4</code>. On Select components screen, to keep things minimal, select Custom installation. Then make sure you have these selected:<ul>
<li>Free Pascal Utilities</li>
<li>GNU Make</li>
<li>GNU Debugger</li>
<li>Units</li>
</ul>
</li>
</ul>
<div style="text-align: left;">
* Do not select Minimum installation as it will show a nasty fpcres.exe not found error.</div>
<ul style="text-align: left;">
<li>Go to <strong>Project Options - Compiler Options - Config and Target</strong> and set: Target OS (-T) to Win32 Target CPU family (-P) to i386</li>
<li>Go to <strong>Tools - Options - Environment</strong> then set <strong>Compiler executable</strong> from default <code>C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe</code> to <code>$(LazarusDir)fpc\$(FPCVer)\bin\$(TargetCPU)-$(TargetOS)\fpc.exe</code></li>
</ul>
<h2 id="from-win32-to-win64">
From Win32 to Win64</h2>
This is if you have Lazarus 32 bit installation and want to build for Win64:<br />
<ul>
<li>Go to <a href="https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2032%20bits/">https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/</a>, then your Lazarus version</li>
<li>Download and install <code>lazarus-x.y.z-fpc-a.b.c-cross-i386-win32-win64.exe</code>. When installing it will suggest a path like <code>C:\FPC\3.0.4</code>, but make it like <code>C:\lazarus\fpc\3.0.4</code>. You can select Minimum installation.</li>
<li>Go to <strong>Project Options - Compiler Options - Config and Target</strong> and set: Target OS (-T) to Win64 Target CPU family (-P) to x86_64</li>
<li>Go to <strong>Tools - Options - Environment</strong> then make sure <strong>Compiler executable</strong> is set to <code>C:\lazarus\fpc\3.0.4\bin\i386-Win32\fpc.exe</code></li>
</ul>
<h2 id="use-build-modes-for-more-peace-of-mind">
Use Build modes for more peace of mind</h2>
Think about your software. You wrote an awesome piece of software, and you want your friends with Windows, both 32bit and 64bit, use them. You can surely change those settings everytime and hit build. But changing the settings and building 4 times is a nasty time-killer. Let's get it automated.<br />
<br />
For the sake of this example, let's assume we want to build both Win32 and Win64 builds of the same software.<br />
<ul>
<li>Hit the cog icon (beside Run button)</li>
<li>Click [...], click <strong>Create Debug and Release modes</strong> button</li>
<li>Select Release and click [+] button. This will create a copy of Release item. You can name it anything, but here we name it "win32"</li>
<li>Click the [+] button again and name it "win64"</li>
<li>Click OK</li>
<li>Edit <strong>Target file name (-o)</strong> to include <code>$(BuildMode)</code>. e.g. <code>project1_$(BuildMode)</code>. This will automatically add the build mode name with the executable name. e.g. project1_win32.exe, project1_win64.exe</li>
<li>Go to <strong>Config and Target</strong></li>
<li>With Build mode selected as win32, set:</li>
</ul>
<blockquote>
Target OS (-T) -> Win32<br />
Target CPU family (-P) -> i386</blockquote>
<ul>
<li>With Build mode selected as win64, set:</li>
</ul>
<blockquote>
Target OS (-T) -> Win64<br />
Target CPU family (-P) -> x86_64</blockquote>
Now when you are in the mood to build for both win32 and win64, click Run - Compile many Modes..., select both win32 and win64 and click OK. It will build executables for both.<br />
<br />
To build for a single mode, click the arrow beside the cog icon on toolbar, select either win32 or win64, then hit Run - Build or Run - Run.<br />
<br />
To simplify the instructions above I have skipped Debug build modes. But it is doable. Just select the "Debug" build mode while clicking [+] and continue from there. You may need to configure GDB executable in <strong>Tools - Options - Debugger - General</strong>.<br />
<br />
Wanna learn a neat trick? To easily determine if an executable file is 32bit or 64bit, you can open it in <a href="https://7-zip.org/">7-zip</a> and click <strong>Info</strong> button on the toolbar. It should show the <code>CPU</code> value as either <code>x86</code> or <code>x64</code>.<br />
<h2 id="cross-compiling-from-ubuntu-linux-to-windows">
Cross Compiling from Ubuntu / Linux to Windows</h2>
We would be compiling the cross compiler, so we'd need <code>make</code> installed. Don't worry, compiling won't be something difficult. It is just a matter of running a command, that's it. On Ubuntu/Debian you can run <code>sudo apt install make</code>, on Arch Linux you can run <code>sudo pacman -S make</code> on Terminal to install it. For other distros, consult your distro documentation.<br />
<br />
The fpcsrc path may be something like <code>/usr/lib/fpc/src/</code> or <code>/usr/share/fpcsrc/3.0.4</code> depending on your Linux distro. I've checked on Ubuntu/Debian, Arch Linux and Void Linux. They all have either of these 2 directories. If you find any other, let me know.<br />
<br />
<pre>#!/bin/sh
# To use the fpc version number later
# It has the version number, e.g. 3.0.4
export FPCVER=`fpc -iV`
# Navigate to the fpc source folder.
# One of them will fail, but this is normal. If it changes into a directory, you're fine.
cd /usr/lib/fpc/src/ || cd /usr/share/fpcsrc/$FPCVER
# Compile the cross-compiler for win32.
sudo make clean all OS_TARGET=win32 CPU_TARGET=i386
# It could take a minute or two, depending on your hardware
# Install the cross-compiler.
sudo make crossinstall OS_TARGET=win32 CPU_TARGET=i386 INSTALL_PREFIX=/usr
# You should see messages like: Installation package fpc-all for target i386-win32 succeeded
# Link the cross-compiler and place the link where Lazarus can see it.
sudo ln -sf /usr/lib/fpc/$FPCVER/ppcross386 /usr/bin/ppcross386
# You can do the same using Windows 64 bit as target.
export FPCVER=`fpc -iV`</pre>
<pre><pre>cd /usr/lib/fpc/src/ || cd /usr/share/fpcsrc/$FPCVER</pre>
sudo make clean all OS_TARGET=win64 CPU_TARGET=x86_64
sudo make crossinstall OS_TARGET=win64 CPU_TARGET=x86_64 INSTALL_PREFIX=/usr
sudo ln -sf /usr/lib/fpc/$FPCVER/ppcrossx64 /usr/bin/ppcrossx64
</pre>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Besides copy-pasting each line, you can save this as a <code>.sh</code> file and run <code>sh /path/to/the/file.sh</code> to run them automatically.<br />
<br />
You may have to run these commands again when fpc is updated on the system. No problem, just get back to this article to get to it.</div>
<h3 id="a-simple-way-to-cross-compile">
A. Simple way to cross compile</h3>
Let me show you the easiest cross compile settings you've ever seen!<br />
You can just:<br />
<ul>
<li>go to <strong>Project - Project Options - Compiler Options - Config and Target</strong></li>
<li>for Windows 32 bit, set <strong>Target OS (-T)</strong> to <strong>Win32</strong> and <strong>Target CPU family (-P)</strong> to <strong>i386</strong></li>
</ul>
Done!<br />
<br />
Now click <strong>Run - Build</strong>, and eventually project exe file for Windows 32 bit will be created in the project directory.<br />
<h3 id="b-advanced-but-more-dev-friendly-way-to-cross-compile">
B. Advanced, but dev friendly way to cross compile</h3>
In the long run this will help you be more efficient with your project setup.<br />
<ul>
<li>Start Lazarus.</li>
<li>Go to <strong>Project - Project Options - Compiler Options - Paths</strong></li>
<li>Click the cog icon (beside Run button on toolbar)</li>
<li>Click [...] beside Build modes, click <strong>Create Debug and Release modes</strong></li>
<li>With the "Release" selected, click the [+] button to add new build (it will copy configs from Release). Give it a name. e.g. "Win32"</li>
<li>Click OK to close Debug modes window</li>
<li>With the Build modes still selected as Win32, change your <strong>Target file name (-o)</strong> to anything else other than the default value. e.g. You can add <code>_win32</code> to the name, or <code>$(BuildMode)</code></li>
<li>With the Build modes selected as Win32, go to <strong>Config and Target</strong> and set the value for -T as <code>Win32</code> and -P as <code>i386</code></li>
<li>Click OK</li>
<li>Make sure that Win32 is selected as the build mode from the menu in the cog icon (arrow beside the cog icon on toolbar)</li>
<li>Now click Run - Build (We won't run it since we are on Linux. The build command will just create .exe file and won't run it.)</li>
</ul>
If everything went well, you should see a <code>Compile Project, Mode: Win32, OS: win32, CPU: i386, Target: proj_cross1_win32.exe: Success</code> message.<br />
You can do the same for Win64:<br />
<ul>
<li>Click the cog icon</li>
<li>Click the [...] button beside Build modes</li>
<li>Click the plus sign (if you have Win32 selected, it will copy configs from there)</li>
<li>Name it Win64 (or something else if you wish), then click OK</li>
<li>Now go to Paths. If you have <code>$(BuildMode)</code> you won't need to change <code>-o</code></li>
<li>Go to Config and Target, select -T as <code>Win64</code> and -P as <code>x86_64</code></li>
</ul>
If you want to check in a moment what it would look like on Windows, you can install <code>wine</code> and right click and run the .exe file with wine. It will emulate more of less how it would in Windows. You can even run this on ReactOS (the win32 version) if you want to.<br />
<br />
To easily determine if an executable is 32bit or 64bit on Linux, run <code>file /path/to/executable</code> and it should show something like <code>...PE32+ executable (GUI) x86-64..</code>. or <code>...PE32 executable (GUI) Intel 80386...</code> depending on the architecture.<br />
<br />
<a href="https://gitlab.com/lazplanet/cross-compile/-/releases" target="_blank">Download project source files</a> | <a href="https://gitlab.com/lazplanet/cross-compile" target="_blank">Browser source code</a><br />
<br />
<b>Ref:</b><br />
<ul>
<li>Instructions for any other platform: <a href="https://wiki.lazarus.freepascal.org/Cross_compiling">https://wiki.lazarus.freepascal.org/Cross_compiling</a></li>
<li>Cross compiling for Win32 from Linux: <a href="https://wiki.lazarus.freepascal.org/Cross_compiling_for_Win32_under_Linux">https://wiki.lazarus.freepascal.org/Cross_compiling_for_Win32_under_Linux</a></li>
</ul>
</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com17tag:blogger.com,1999:blog-5314745381778741517.post-39909007161352686212020-05-01T11:37:00.001+01:002020-05-02T15:03:47.358+01:00How to Run Lua Code Inside Lazarus Programs<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-G0epC7ytO5U/Xq1hhlCKpTI/AAAAAAAACp0/ksnd3l7gP-sWdUTJZa0qxRtiJ7Nv0_jdQCNcBGAsYHQ/s1600/lua-inside-lazarus-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Lua inside Lazarus projects blog thumbnail" border="0" data-original-height="150" data-original-width="200" src="https://1.bp.blogspot.com/-G0epC7ytO5U/Xq1hhlCKpTI/AAAAAAAACp0/ksnd3l7gP-sWdUTJZa0qxRtiJ7Nv0_jdQCNcBGAsYHQ/s1600/lua-inside-lazarus-thumb.jpg" title="Lua inside Lazarus projects blog thumbnail" /></a></div>
We're crazy! We're out of our minds! We're going to run Lua code, from inside our Lazarus code! 2 Languages at once!<br />
<a name='more'></a><br />
Lua is a programming language. Lazarus' Free Pascal is a programming language too. But did you know we can use Lua from Free Pascal? Interesting, right? One language inside the other.<br />
<br />
Lua was designed to be small, compact and user friendly. So embedding Lua inside another program is a no sweat task. We can have the taste of another language in our Free Pascal programs with a small footprint (~260kb on *nix, ~225kb on Windows).<br />
<br />
This can be especially useful if you want to let the user input some code and run it on the fly. This can help you create your own small IDE that can read code from a project file of your chosen syntax and run them! Or run some code that's only available on Lua and not FPC. Or anything else... sky is the limit.<br />
<br />
Let's start with a simple tutorial...<br />
<br />
<h3 style="text-align: left;">
Simple Tutorial</h3>
Start <a href="https://lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Program project (<b>Project - New Project - Program - OK</b>).<br />
Now click <b>File - Save All</b> (because we'll need to keep some dependent files inside our project folder).<br />
<br />
<h4 style="text-align: left;">
Common tasks:</h4>
1. Download <b>lua53.pas</b> from <a href="https://github.com/malcome/Lua4Lazarus/raw/master/lua53.pas">here</a> and keep it inside your project folder. If that file is not there anymore (due to future changes) get the file from <a href="https://github.com/malcome/Lua4Lazarus/archive/R150205.zip">this archive</a>. This file will let us use the <b>lua53</b> unit inside our uses clause and act like a bridge between Lua and Free Pascal.<br />
<br />
2. Download Lua dynamic libraries. Go to <a href="http://luabinaries.sourceforge.net/">http://luabinaries.sourceforge.net/</a> and scroll down to the <b>History</b> heading. Click on the latest 5.3.x release. For me it was <a href="https://sourceforge.net/projects/luabinaries/files/5.3.5/">https://sourceforge.net/projects/luabinaries/files/5.3.5/</a>.<br />
<br />
<ul style="text-align: left;">
<li>If you are using Windows, click the <b>Windows Libraries</b>, then <b>Dynamic</b>. Check if your Lazarus is 32bit or 64bit. Then download the archive and Microsoft Visual C++ Redistributable for that architecture. If you scroll down a bit you will be able to see which file is for which redistributable. e.g. I had <a href="https://www.microsoft.com/en-us/download/details.aspx?id=48145">2015 redistributable</a> installed and 32bit Lazarus installed, so I downloaded <b>lua-5.3.5_Win32_dll14_lib.zip</b>, extracted it, then copied the lua53.dll into my project folder.</li>
<li>If you are using Linux platform, click <b>Linux Libraries</b>, then download the one that is closest to your kernel version. (For me it was <b>lua-5.3.5_Linux44_64_lib.tar.gz</b>.) Then get the <b>libluaXX.so</b> file from the archive and put that into project folder.</li>
<li>If you are using Mac OS, click <b>Other Libraries</b> (Note: but I have not tested this on Mac)</li>
</ul>
<br />
Download the archive appropriate for you and extract it somewhere. Get either lua53.dll for Windows or liblua53.so for other platforms from there. Put the file inside the project folder. This file has the stuff that will run our Lua code.<br />
<br />
For Linux (and also I assume Mac) through, you'll have to do something extra.<br />
A. Open a terminal on the project folder, then run <b>sudo cp liblua53.so /usr/lib/</b><br />
B. Or, run the executable with <b>LD_LIBRARY_PATH=. ./proj_example1</b><br />
<br />
End of Common tasks. Now let's get back to tutorial...<br />
<br />
Copy-paste this on your pascal unit:<br />
<br />
<pre class="brush:pascal">program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}cthreads,{$ENDIF}{$ENDIF}
Classes
, lua53;
var
L: Plua_State;
result: integer;
begin
L := luaL_newstate();
luaL_openlibs(L);
result := luaL_dostring(L, 'print ("I''m Lua, but I''m running inside".." Lazarus!!")');
lua_close(L);
ReadLn('Press enter to exit...'); // To keep the terminal window open
end.
</pre>
<br />
So after all these my project folder looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-LoWB53frBkI/XqvwZj5C3aI/AAAAAAAACos/jcGtPPh9kSgQzAj5G2mbYJUqnjkyZFaAACNcBGAsYHQ/s1600/lua-project-setup-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Project files" border="0" data-original-height="222" data-original-width="507" height="140" src="https://1.bp.blogspot.com/-LoWB53frBkI/XqvwZj5C3aI/AAAAAAAACos/jcGtPPh9kSgQzAj5G2mbYJUqnjkyZFaAACNcBGAsYHQ/s320/lua-project-setup-01.png" title="Project files" width="320" /></a></div>
<br />
Now we are ready to run our program. Hit <b>Run - Run</b> (or F9).<br />
<br />
It should print the message from Lua as expected:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-zloNvgJXiq0/Xq1Yl1rTP_I/AAAAAAAACpo/ARrw7cLpt9wmhkI_Sw-hp6XZwCPfKt4cwCNcBGAsYHQ/s1600/lua-cli-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Lua code running inside a Free Pascal program in a Console program" border="0" data-original-height="342" data-original-width="677" height="161" src="https://1.bp.blogspot.com/-zloNvgJXiq0/Xq1Yl1rTP_I/AAAAAAAACpo/ARrw7cLpt9wmhkI_Sw-hp6XZwCPfKt4cwCNcBGAsYHQ/s320/lua-cli-01.png" title="Lua code running inside a Free Pascal program in a Console program" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<b>Troubleshooting</b><br />
<br />
On Windows, if you get a boring "The Application was Unable to Start Correctly (0xc000007b)" message when you run your program from explorer or file manager, then maybe you should try dll file from 32bit architecture. 64bit dlls cause this issue sometimes. You can also use <a href="http://www.dependencywalker.com/">Dependency Walker</a> to find out where the issue is. Just remember, the files will be for the target architecture you are building for.<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
Start <a href="https://lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Application project (<b>Project - New Project - Application - OK</b>).<br />
Now click <b>File - Save All</b> (because we'll need to keep some dependent files inside our project folder).<br />
<br />
Don't forget to follow the things under "<b>Common tasks</b>" heading above.<br />
<br />
Place 2 TMemos and a TButton. Change the Lines property of Memo1 to something like:<br />
<br />
<pre class="brush:text">print ("I'm Lua, but I'm running inside".." Lazarus!!")
</pre>
<br />
This way we'll have a simple code to execute when we run our program. We should also empty the Lines property of <b>Memo2</b> to let our output fill it in later. Add TLabels as you wish.<br />
<br />
Set the Caption property of Button1 to something like "Execute!" or anything you like. Your form should now look something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-khGAauNP8a0/Xq1VtjXhzzI/AAAAAAAACpE/-MKXV9NuzCYtkI7sQn8XuXuc5tQTn7jwQCNcBGAsYHQ/s1600/Lua-form-design-01.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Form design of the GUI program" border="0" data-original-height="398" data-original-width="689" height="184" src="https://1.bp.blogspot.com/-khGAauNP8a0/Xq1VtjXhzzI/AAAAAAAACpE/-MKXV9NuzCYtkI7sQn8XuXuc5tQTn7jwQCNcBGAsYHQ/s320/Lua-form-design-01.gif" title="Form design of the GUI program" width="320" /></a></div>
<br />
Double click the Button1 and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
var
L: Plua_State;
s: string;
begin
Memo2.Clear;
L:= lua_newstate(@alloc, nil);
try
luaL_openlibs(L);
lua_register(L, 'print', @print_func);
try
s:= Memo1.Text;
if luaL_loadbuffer(L, PChar(s), Length(s), 'example2') <> 0 then
Raise Exception.Create('');
if lua_pcall(L, 0, 0, 0) <> 0 then
Raise Exception.Create('');
except
Form1.Memo2.Lines.Add(lua_tostring(L, -1));
Form1.Memo2.SelStart:= 0;
Form1.Memo2.SelLength:= 0;
end;
finally
lua_close(L);
end;
end;
</pre>
<br />
Now put these functions before the <b>TForm1.Button1Click</b> procedure that you just edited:<br />
<br />
<pre class="brush:pascal">function print_func(L : Plua_State) : Integer; cdecl;
var
i, c: integer;
begin
c:= lua_gettop(L);
for i:= 1 to c do
Form1.Memo2.Lines.Add(lua_tostring(L, i));
Form1.Memo2.SelStart:= 0;
Form1.Memo2.SelLength:= 0;
Result := 0;
end;
function Alloc({%H-}ud, ptr: Pointer; {%H-}osize, nsize: size_t) : Pointer; cdecl;
begin
try
Result:= ptr;
ReallocMem(Result, nSize);
except
Result:= nil;
end;
end;
</pre>
<br />
<b>Note:</b> If you put them before the procedure you won't need <a href="https://en.wikipedia.org/wiki/Forward_declaration">forward declaration</a>. If you want to put them anywhere you want (before or after) you can just copy and paste just the whole function line before the <b>implementation</b> line, something like this:<br />
<br />
<pre class="brush:pascal">...
var
Form1: TForm1;
function print_func(L : Plua_State) : Integer; cdecl;
function Alloc({%H-}ud, ptr: Pointer; {%H-}osize, nsize: size_t) : Pointer; cdecl;
implementation
...
</pre>
<br />
<b>Why do we use cdecl?</b><br />
You will also notice there is a word "cdecl" at the end of the function lines. These are used when the function is meant to communicate with a C library. In our case, we are communicating with Lua which is written in C. So we use this feature.<br />
<br />
Now add <b>lua53</b> under uses clause:<br />
<br />
<pre class="brush:pascal">uses
...
, lua53;
</pre>
<br />
Now click Run - Run (or F9). It will show up on screen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-FKGQa4oYrGg/Xq1WIBg35II/AAAAAAAACpM/9AAPAe4VL_AxZ4CEUSPalR4BV47aPCS4wCNcBGAsYHQ/s1600/Lua-form-design-02.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Lua GUI application for running Lua code from inside Free Pascal program" border="0" data-original-height="398" data-original-width="689" height="184" src="https://1.bp.blogspot.com/-FKGQa4oYrGg/Xq1WIBg35II/AAAAAAAACpM/9AAPAe4VL_AxZ4CEUSPalR4BV47aPCS4wCNcBGAsYHQ/s320/Lua-form-design-02.gif" title="Lua GUI application for running Lua code from inside Lazarus program" width="320" /></a></div>
<br />
Now click the Execute button and it should show a message on the Memo to the right.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-5AbFtbjW7GU/Xq1WeX6RTpI/AAAAAAAACpU/3MKjAibljQ4eQa7Nt_UvInIis6Ds-8SLgCNcBGAsYHQ/s1600/Lua-gui-03.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Basic functionality is working" border="0" data-original-height="398" data-original-width="689" height="184" src="https://1.bp.blogspot.com/-5AbFtbjW7GU/Xq1WeX6RTpI/AAAAAAAACpU/3MKjAibljQ4eQa7Nt_UvInIis6Ds-8SLgCNcBGAsYHQ/s320/Lua-gui-03.gif" title="Basic functionality is working" width="320" /></a></div>
<br />
You can paste any Lua code and it should work. I tried a code example from <a href="https://www.tutorialspoint.com/lua/lua_variables.htm">tutorialspoint.com</a> (love their work by the way) which is something like this:<br />
<br />
<pre class="brush:text">-- Variable definition:
local a, b
-- Initialization
a = 10
b = 30
print("value of a:", a)
print("value of b:", b)
-- Swapping of variables
b, a = a, b
print("value of a:", a)
print("value of b:", b)
f = 70.0/3.0
print("value of f", f)
</pre>
<br />
Which should output like the screenshot below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-NgshkQgb7wA/Xq1XVv_Z8LI/AAAAAAAACpg/DAgYoM1V2kIRFn7C-DKrjBIi4TzX6lhKwCNcBGAsYHQ/s1600/Lua-gui-04.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Lazarus program running a variable example code written in Lua" border="0" data-original-height="398" data-original-width="689" height="184" src="https://1.bp.blogspot.com/-NgshkQgb7wA/Xq1XVv_Z8LI/AAAAAAAACpg/DAgYoM1V2kIRFn7C-DKrjBIi4TzX6lhKwCNcBGAsYHQ/s320/Lua-gui-04.gif" title="Lazarus program running a variable example code written in Lua" width="320" /></a></div>
<br />
Have fun with this amazing trick!<br />
<br />
<h3>
Download Sample Code ZIP</h3>
<h3>
<div style="font-size: medium; font-weight: 400;">
You can download the above example tutorial project's source code from <a href="https://www.dropbox.com/s/xyz7jws01axuvnk/lua-inside-fpc.zip?dl=1">here</a> or <a href="https://gitlab.com/lazplanet/lua-inside-fpc/-/releases">here</a>.</div>
<div style="font-size: medium; font-weight: 400;">
Size: 1.02MB</div>
<div style="font-size: medium; font-weight: 400;">
The package may contain compiled executable EXE file(s).<br />
<br />
We now have a GitLab.com page where (hopefully) all future project source codes will be available. You can also post issues and pull requests if you want to: <a href="https://gitlab.com/lazplanet/">https://gitlab.com/lazplanet/</a></div>
</h3>
<br />
<b>Ref:</b><br />
- Basics: <a href="http://lua-users.org/wiki/LuaInFreePascal">http://lua-users.org/wiki/LuaInFreePascal</a><br />
- Lots of examples: <a href="https://github.com/lainz/lainzcodestudio">https://github.com/lainz/lainzcodestudio</a><br />
- Lua4Lazarus bridge unit project: <a href="https://github.com/malcome/Lua4Lazarus">https://github.com/malcome/Lua4Lazarus</a><br />
- Example Lua code: <a href="https://www.tutorialspoint.com/lua/lua_variables.htm">https://www.tutorialspoint.com/lua/lua_variables.htm</a><br />
- Some more examples of Lua code usage: <a href="https://github.com/mvdhoning/dlua">https://github.com/mvdhoning/dlua</a><br />
- cdecl: <a href="https://freepascal.org/docs-html/ref/refsu71.html">https://freepascal.org/docs-html/ref/refsu71.html</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com3tag:blogger.com,1999:blog-5314745381778741517.post-33597640342037301492020-04-27T08:56:00.000+01:002020-05-13T11:51:02.174+01:00How to Install Lazarus on Ubuntu 20.04 LTS [with Video]<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-ZrK0UnyYuXc/XqaPWxIjvaI/AAAAAAAACog/INCyptvIXbkfMn_osvYxm0XqwfPYz5UpQCNcBGAsYHQ/s1600/lazarus-install-ubuntu-thumb.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" src="https://1.bp.blogspot.com/-ZrK0UnyYuXc/XqaPWxIjvaI/AAAAAAAACog/INCyptvIXbkfMn_osvYxm0XqwfPYz5UpQCNcBGAsYHQ/s1600/lazarus-install-ubuntu-thumb.png" /></a></div>
Ubuntu 20.04 LTS has been released recently, but installing Lazarus there from the official repos won't get you up and running. Let's see how Lazarus can be installed on 20.04 without issues.<br />
<a name='more'></a><br />
<br />
You can install Lazarus from Ubuntu Software. But wait till you see it burp a surprize error message!<br />
<br />
Apparantly the package for Lazarus available from Ubuntu Software, the official Ubuntu "software center", shows a "Can't find the lazarus executable /usr/lib/lazarus/2.0.6/lazarus" message on startup. The bug has been <a href="https://bugs.freepascal.org/view.php?id=36572">reported</a> and will be updated in future, but at the time of writing this, it was broken. So you'll need a guide to install it properly. Let me show you how you can install Lazarus on your Ubuntu 20.04 LTS installation without any hassle.<br />
<br />
Don't worry, I have made this easy for anyone to follow. So come along!<br />
<br />
There is even a video available to make things easier for you...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube-nocookie.com/embed/D1eQmgcFwGY" width="560"></iframe></div>
<br />
<br />
<b>Note</b>: If you don't have the issue above and you are satisfied with 1 or 2 version old package that you get from official repos, ignore this guide and stick to the version from Ubuntu Software.<br />
<br />
<h3 style="text-align: left;">
Step 0: Completely Remove Previous Lazarus Installs</h3>
Open <b>Ubuntu Software</b> from Activities overview. Search for "<b>lazarus</b>" and remove if any package is installed.<br />
<br />
Even after removing the packages, there might be some other packages or residual files from previous installs. So we remove all of those with:<br />
<br />
<pre class="brush:bash">sudo sh -c "apt autoremove fpc lazarus lazarus-ide \
lazarus-ide-2.0 lazarus-project fpc-source && \
rm -Rf /usr/lib/fpc && \
rm -Rf /usr/lib/lazarus && \
rm -Rf /usr/share/fpcsrc && \
rm -Rf /etc/lazarus && \
rm -rf /etc/fpc.* && \
rm -rf /etc/fpc-* && \
rm -rf /etc/fppkg* && \
rm -f ~/.fpc && \
rm -Rf ~/.lazarus"
</pre>
<br />
Run above on the Terminal app. (Open Activities overview, search "term", launch <b>Terminal</b> app, then copy and paste these commands in.)<br />
<br />
<i>* You will need to provide your root password of the system when you run sudo commands.</i><br />
<br />
<br />
<h3 style="text-align: left;">
Step 1: Update Your System</h3>
First update your system. You can use the **Software Updater** tool by launching it from Activities overview or run this on the Terminal app:<br />
<br />
<pre>sudo apt update && sudo apt upgrade
</pre>
<br />
<i>* You will need to provide your root password of the system when you run sudo commands or add/remove software.</i><br />
<br />
An update and upgrade is needed so that the dependencies we will be installing in a minute does not conflict with the currently installed versions.<br />
<br />
<br />
<h3 style="text-align: left;">
Step 2: Get the DEB Files</h3>
Download the deb files for Lazarus from <a href="https://lazarus-ide.org/">https://lazarus-ide.org</a><br />
<br />
(It should automatically detect your system architecture and offer you the appropriate files.)<br />
<br />
You will need to download all the 3 deb files for <code>lazarus-project</code>, <code>fpc-src</code> and <code>fpc-laz</code>.<br />
<br />
Now put the deb files in a separate directory. Only keep those 3 deb files in that folder and nothing else. This is because we'll run a magic command later.<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
Step 3: Install Them</h3>
</div>
Before installing, it is a good practice to uninstall the previous version of Lazarus to get a problem free installation. If you have a previous version of Lazarus installed, uninstall it. If you don't have it installed, follow along...<br />
<br />
Open the terminal on the directory with the 3 deb files. (Click the folder name on the top location bar and choose **Open in Terminal**.) Then run:<br />
<br />
<pre>sudo apt install binutils libgtk2.0-dev
</pre>
<br />
This will install all the dependencies for Lazarus. Then this to install Lazarus:<br />
<br />
<pre>sudo dpkg -i *
</pre>
<br />
This is the magic command I was talking about. It will install all 3 of those DEB files.<br />
<br />
<br />
<h3 style="text-align: left;">
Step 4: After Installing</h3>
After the installation finished, you can run it from the Activities overview. You can go there and then search for "<b>lazarus</b>" and it should show up. It will launch when you click the icon.<br />
<br />
After it launched, you will see a dialog box titled <b>Welcome to Lazarus IDE</b>. If it doesn't show any red icons you are fine. You can click <b>Start IDE</b> on that dialog box. This will make Lazarus appear on screen.<br />
<br />
You can right click the Lazarus icon on Dash and select <b>Add to Favorites</b> to add the icon on Dash for you to later access it from there.<br />
<br />
<br />
<h3 style="text-align: left;">
Bottom Line</h3>
You will be able to install Lazarus without any problems. But there is a caveat. It will not automatically update with your system. Since you've manually installed this, you'll have to manually update this yourself. Updating is easy though. Just download the deb files, keep them in a folder, then run `sudo dpkg -i *` on that folder and you're done!<br />
<br />
Although I would recommend switching to the Ubuntu Software version when this issue is fixed.
<br />
<br />
<b>Note:</b> If system upgrades trying to replace deb versions to repo versions on your system, you may need to hold the packages to their current version. (Thanks to Tony for pointing this out.) You may need to run <code>sudo sh -c "apt-mark hold lazarus-project && apt-mark hold fpc-src && apt-mark hold fpc-laz"</code>. If you want to revert this back, run the command with "unhold" instead of "hold". Details <a href="https://askubuntu.com/a/18656">here</a>. </div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com6tag:blogger.com,1999:blog-5314745381778741517.post-91133910774952448342019-03-22T10:16:00.000+00:002019-03-22T10:33:35.840+00:00How to do Basic REST API Implementation in Lazarus (with Weather API example)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-g5RbR9TkAMY/XJRzseT9OBI/AAAAAAAACi0/gerwRVyaoFA1wsttnUf7MAA3h31243g4ACLcBGAs/s1600/rest-api-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" height="150" src="https://3.bp.blogspot.com/-g5RbR9TkAMY/XJRzseT9OBI/AAAAAAAACi0/gerwRVyaoFA1wsttnUf7MAA3h31243g4ACLcBGAs/s200/rest-api-thumb.jpg" width="200" /></a></div>
REST APIs are "the thing" to learn these days. But how should we get it to work on Lazarus? Let's see...<br />
<a name='more'></a><br />
Does the word API ring any bell? If it doesn't, it means Application Programming Interface. If you have a service that you want to allow people to get access to, then you need a "standard" way to send or get the data. We need a standard so that everyone follows the standard and requests the data same way and gets the same result. This "standard" is called API. Think of it as a bridge between you and the service.<br />
<br />
As you may know, Windows has an API. Windows API is very common. You can control many aspects of Windows with the API (for example, <a href="https://lazplanet.blogspot.com/2014/02/show-hide-windows-taskbar-lazarus.html">hiding the taskbar</a>, <a href="https://lazplanet.blogspot.com/2013/05/create-form-fade-in-effect.html">make some window transparent</a> etc.) Similarly there are APIs for Facebook, Twitter, Instagram and many other popular services. These APIs allow people like us to communicate with the services and send various commands. For example, we can send a command from our app to post a photo to Facebook. This way we can automate things and customize how we want the service to work.<br />
<br />
REST API is just a fancy name for a URL based API service. With REST API we send commands to a service through URLs. When we access these URLs, the software on the server will then process the URL and the information within the URL then give you some results.<br />
<br />
Simple, right?<br />
<br />
It is extremely easy and a great option for a simple API implementation to allow access to data. Any basic language, even <a href="https://en.wikipedia.org/wiki/JavaScript">Javascript</a> (popular script language used in websites) is <a href="https://marmelab.com/blog/2015/03/10/deal-easily-with-your-rest-api-using-restful-js.html">able to request for data and process the results</a> just fine. So everyone loves it these days.<br />
<br />
You can test a REST API interface right now. Go to this URL: <a href="https://api.desktoppr.co/1/wallpapers/random">https://api.desktoppr.co/1/wallpapers/random</a><br />
<br />
The URL is basically asking for 1 wallpaper that is random. So after you access URL, the desktoppr.co server goes through its database and finds 1 random wallpaper from the collection of wallpapers they have and then returns a JSON response with information of the wallpaper.<br />
<br />
You will see many data in the output. If you are on Chrome or Chrome based browser, you will see a plain text output. If you are on Firefox you will see a organized output with JSON variable names and values beside them, something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-CJNSp3KUFR8/XJMEpQ2bb0I/AAAAAAAACho/oDw643NqRU47i0HUQ1H_ryPFEjFCL1NrgCLcBGAs/s1600/01.json-wallpaper-response.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="470" data-original-width="836" height="179" src="https://1.bp.blogspot.com/-CJNSp3KUFR8/XJMEpQ2bb0I/AAAAAAAACho/oDw643NqRU47i0HUQ1H_ryPFEjFCL1NrgCLcBGAs/s320/01.json-wallpaper-response.png" width="320" /></a></div>
<br />
On the above screenshot you will see some "url" values. The first "url" value is the wallpaper URL.<br />
<br />
On the output for Chrome or browsers other than Firefox, press Ctrl+F and search for the word "url" and find its value, something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-lcer_M6Eviw/XJMEu02_OeI/AAAAAAAAChs/Eyi1PbdxsFUzqNvnA5iI2mDPRP6T39SagCLcBGAs/s1600/02.json-wallpaper-response.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="306" data-original-width="924" height="105" src="https://4.bp.blogspot.com/-lcer_M6Eviw/XJMEu02_OeI/AAAAAAAAChs/Eyi1PbdxsFUzqNvnA5iI2mDPRP6T39SagCLcBGAs/s320/02.json-wallpaper-response.png" width="320" /></a></div>
<br />
You will find a link to image file. Copy the link and open it. You will find a random wallpaper. So, the system is working. desktoppr.co has a REST API setup for us and it is giving us data when we access special URLs.<br />
<br />
There are many other APIs similar to this. This API is public, but there are other REST APIs which require sign ups and API Keys to pass with the URL so that the server can detect any misuse of the service. But basics are the same.<br />
<br />
But how did I find this special URL? - You might ask. I found it here: <a href="https://www.desktoppr.co/api">https://www.desktoppr.co/api</a><br />
Every REST API has a documentation saying which URL structure you need to use with the service. Everytime you need to implement a REST API you can search on the internet for this reference for the API you want to implement.<br />
<br />
Also, we have covered some of the <a href="https://lazplanet.blogspot.com/2019/03/how-to-get-contents-of-url-in-2-ways.html">basic things needed for REST API</a>. So don't worry, we've got you covered for almost everything for REST API.<br />
<br />
Now that we got the hang of the basics, let's dive into a semi-tutorial now...<br />
<h3 style="text-align: left;">
Semi-tutorial</h3>
Start <a href="https://www.lazarus-ide.org/">Lazarus</a>.<br />
Create a new Application project (<b>Project - New Project - Application - OK</b>).<br />
Now save the project with <b>File - Save All</b>, in a folder for the project.<br />
<br />
Download and extract the <b>libeay32.dll</b> and <b>ssleay32.dll</b> files from <a href="https://indy.fulgan.com/SSL/">https://indy.fulgan.com/SSL/</a> into project folder, based on the FPC for the architecture you have installed (consult <b>Help - About Lazarus</b> to check). <a href="https://lazplanet.blogspot.com/2019/03/how-to-get-contents-of-url-in-2-ways.html">Details here</a>.<br />
<br />
Now draw a <b>Tbutton</b>, <b>TListBox</b> and a <b>TMemo</b> on the form.<br />
<br />
Double click on the button and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
var
listitemsjson:string;
J: TJSONData;
c: integer;
begin
listitemsjson := FPHTTPClientDownload('https://jsonplaceholder.typicode.com/todos');
J := GetJSON(listitemsjson);
for c := 0 to J.Count - 1 do
begin
try
ListBox1.Items.Add( J.Items[c].FindPath('title').AsString );
finally
end;
end;
end;
</pre>
<br />
<b>Explanation:</b> We are just using <a href="https://jsonplaceholder.typicode.com/">an test REST API website</a>. We seldom need REST API implementation to run some tests. Some good person has setup a dummy REST API website so that we can test our REST API implementation. We'll use that for this test project. Go ahead and open the link <a href="https://jsonplaceholder.typicode.com/todos">https://jsonplaceholder.typicode.com/todos</a> in browser.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-AwV001z5bxw/XJMLOlCDZyI/AAAAAAAACh8/N5ZqeHZ0hhYy_7R1gGqFqFVayvVZjgJfQCLcBGAs/s1600/04.json-todos.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="447" data-original-width="565" height="253" src="https://3.bp.blogspot.com/-AwV001z5bxw/XJMLOlCDZyI/AAAAAAAACh8/N5ZqeHZ0hhYy_7R1gGqFqFVayvVZjgJfQCLcBGAs/s320/04.json-todos.jpg" width="320" /></a></div>
<br />
You will see it has returned some test dummy json code so that we can work with it. It returned some dummy todo entries. I have highlighted the individual records with Cyan and Yellow color above so that you can guess where the individual records are.<br />
<br />
In our above code, we are getting output from the above URL and and keeping it inside <b>listitemsjson</b> variable. Then we are sending the code to GetJSON() function to get the JSON data to be extracted from the return we got.<br />
<br />
Then we loop through the JSON data and list the "title" value for each entry on our ListBox.<br />
<br />
Now that you are in Code view, add this function before the "<b>end.</b>" line (usually the last line in the unit):<br />
<br />
<pre class="brush:pascal">function TForm1.FPHTTPClientDownload(URL: string; SaveToFile: boolean = false; Filename: string = ''): string;
begin
// Result will be:
// - empty ('') when it has failed
// - filename when the file has been downloaded successfully
// - content when the content SaveToFile is set to False
Result := '';
With TFPHttpClient.Create(Nil) do
try
try
if SaveToFile then begin
Get(URL, Filename);
Result := Filename;
end else begin
Result := Get(URL);
end;
except
on E: Exception do
ShowMessage('Error: ' + E.Message);
end;
finally
Free;
end;
end;
</pre>
<br />
Now keep your cursor on the function line and press Ctrl+Shift+C to make a reference to the function on the class declaration.<br />
<br />
Also, add <b>fphttpclient, fpjson</b> and <b>jsonparser</b> under the uses clause:<br />
<br />
<pre class="brush:pascal">uses
..., ..., fphttpclient, fpjson, jsonparser;
</pre>
<br />
Add this under the first var clause of the unit:<br />
<br />
<pre class="brush:pascal">var
woeids: TStringList;
</pre>
<br />
Now switch to <b>Form View (F12)</b>. Double click the <b>ListBox </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.ListBox1Click(Sender: TObject);
var
listitemsjson:string;
J: TJSONData;
begin
listitemsjson := FPHTTPClientDownload('https://jsonplaceholder.typicode.com/todos/'+IntToStr(ListBox1.ItemIndex+1));
J := GetJSON(listitemsjson);
Memo1.Clear;
Memo1.Lines.Add( 'Title: ' + J.FindPath('title').AsString );
Memo1.Lines.Add( 'Completed: ' + J.FindPath('completed').AsString );
end;
</pre>
<br />
<b>Explanation:</b> This procedure is for handling the click event on the <b>ListBox1</b>. <b>ListBox1 </b>will have the todo entries listed. When the list items are clicked it will get the selected list item's index with <b>ListBox1.ItemIndex</b>. It is zero-based so we'll add 1 to it and pass it with the url.<br />
<br />
The URL is something like this:<br />
<a href="https://jsonplaceholder.typicode.com/todos/1">https://jsonplaceholder.typicode.com/todos/1</a><br />
<br />
Here, 1 is the index we are querying for. What it does is it returns the details of todo entry with id 1.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ue-VHENkZHc/XJMSlBvGRzI/AAAAAAAACiI/YDTNLJ6_F4cgG7QZTfJZTpa6ZGjMEyFaACLcBGAs/s1600/04.rest-api-todo-detail.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="151" data-original-width="400" height="120" src="https://3.bp.blogspot.com/-ue-VHENkZHc/XJMSlBvGRzI/AAAAAAAACiI/YDTNLJ6_F4cgG7QZTfJZTpa6ZGjMEyFaACLcBGAs/s320/04.rest-api-todo-detail.png" width="320" /></a></div>
<br />
We are just getting the details for the todo entries and showing it on the <b>TMemo </b>we created.<br />
<br />
Now <b>Run </b>the project (<b>Run - Run or F9</b>).<br />
<br />
Click the button. It will load the todo entries on the list box. It may take some time to load. Then click the list items to see more details about the todo entry.<br />
<br />
Now let's get into a real tutorial...<br />
<h3 style="text-align: left;">
Tutorial</h3>
This tutorial is similar to the above one. At least basics are same. We'll just use it for a different purpose. We'll look into a weather REST API program.<br />
<br />
Start <a href="https://lazarus-ide.org/">Lazarus</a>.<br />
Create a new Application Project (<b>Project - New Project - Application - OK</b>).<br />
<br />
We'll create the components on the form. Draw a <b>TEdit</b>, <b>TButton </b>and a <b>TMemo</b>. Also create labels as necessary, it is upto you. Empty the <b>Lines </b>and <b>Text </b>property of the <b>TMemo </b>and <b>TEdit </b>respectively.<br />
<br />
Double click on the <b>form </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormCreate(Sender: TObject);
begin
woeids := TStringList.Create;
end;
</pre>
<br />
Go to <b>Object Inspector</b> - select the Form - go to <b>Events</b> tab - click <b>OnDestroy</b> - click the <b>[...]</b> button beside it and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormDestroy(Sender: TObject);
begin
woeids.Free;
end;
</pre>
<br />
Switch to <b>Form view (F12)</b><br />
Double click on the <b>button </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
var
listitemsjson:string;
J: TJSONData;
c: integer;
begin
listitemsjson := FPHTTPClientDownload('https://www.metaweather.com/api/location/search/?query='+Edit1.Text);
J := GetJSON(listitemsjson);
ListBox1.Clear;
woeids.Clear;
for c := 0 to J.Count - 1 do
begin
try
ListBox1.Items.Add( J.Items[c].FindPath('title').AsString );
// we keep the woeid in a "virtual list" so that we can use it later
woeids.Add( J.Items[c].FindPath('woeid').AsString );
finally
end;
end;
end;
</pre>
<br />
The above code passes the input on the TEdit and passes it to metaweather.com to get the locations. The API takes a id named "WOEID", in order to see the weather for a location. The search function is great because we don't need to remember or keep all the woeids in our program. we can let the user search for it and it will give us the woeid to show the weather.<br />
<br />
Woeids are not friendly for the user. It is just a number. So we show the actual location names in the ListBox1. We keep the woeids of the found locations in a TStringList with matching order with the ListBox so that we can later use the same index number to find the woeid when a list item is clicked.<br />
<br />
Now switch to <b>Form view (F12)</b>. Now double click the <b>ListBox1 </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.ListBox1Click(Sender: TObject);
var
listitemsjson:string;
J: TJSONData;
YY,MM,DD : Word;
datestring: string;
begin
// prepare the date string for use on the URL
DeCodeDate (Date,YY,MM,DD);
datestring:=format ('%d/%d/%d',[yy,mm,dd]);
// get JSON response
listitemsjson := FPHTTPClientDownload(
'https://www.metaweather.com/api/location/'
+woeids.Strings[ListBox1.ItemIndex]
+'/'+datestring+'/');
J := GetJSON(listitemsjson);
// show the data
Memo1.Clear;
with J.Items[0] do begin
Memo1.Lines.Add( 'Weather state: ' + FindPath('weather_state_name').AsString );
Memo1.Lines.Add( 'Minimum Temp: ' + FloatToStrF( FindPath('min_temp').AsFloat, ffFixed, 8, 2 ) );
Memo1.Lines.Add( 'Maximum Temp: ' + FloatToStrF( FindPath('max_temp').AsFloat, ffFixed, 8, 2 ) );
Memo1.Lines.Add( 'Temp: ' + FloatToStrF( FindPath('the_temp').AsFloat, ffFixed, 8, 2 ) );
Memo1.Lines.Add( 'Wind speed: ' + FloatToStrF( FindPath('wind_speed').AsFloat, ffFixed, 8, 2 ) );
Memo1.Lines.Add( 'Air pressure: ' + FloatToStrF( FindPath('air_pressure').AsFloat, ffFixed, 8, 2 ) );
end;
end;
</pre>
<br />
We are getting the actual weather results this time. When the user clicks the location from the ListBox, the woeid for the location is sent to metaweather API to fetch the weather details for the location. The response looks something like <a href="https://www.metaweather.com/api/location/1915035/2019/3/21/">this</a> on Firefox:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-bG8TvqpLF-k/XJNpCB_jn8I/AAAAAAAACiU/FzFora6YnHQdeqneUEdcy0uMIup-CdLwwCLcBGAs/s1600/05.rest-api-weather-location-json.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="719" data-original-width="706" height="320" src="https://3.bp.blogspot.com/-bG8TvqpLF-k/XJNpCB_jn8I/AAAAAAAACiU/FzFora6YnHQdeqneUEdcy0uMIup-CdLwwCLcBGAs/s320/05.rest-api-weather-location-json.png" width="314" /></a></div>
<br />
The response has many data, so opening it on Firefox helps us understand the data better. We just need the data below the "0" (zero) element. Others are most probably data of the previous hours.<br />
<br />
We then present the data on our TMemo. We use FloatToStrF() function to format the data to double decimal places. You can also use round() - it is up to you.<br />
<br />
Now <b>Run </b>the project (<b>F9 or Run - Run</b>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-P7b4rdVRVO8/XJRdfBt-VYI/AAAAAAAACig/xa9lcq5xCCEyZzwACqZDrMxZW01BXZT2wCLcBGAs/s1600/06.rest-api-run.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="697" height="164" src="https://4.bp.blogspot.com/-P7b4rdVRVO8/XJRdfBt-VYI/AAAAAAAACig/xa9lcq5xCCEyZzwACqZDrMxZW01BXZT2wCLcBGAs/s320/06.rest-api-run.png" width="320" /></a></div>
<br />
Now search for a location. Choose an item from the list on the right. It will magically show you the weather.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-gCckmTYvSR0/XJRd-ycl_WI/AAAAAAAACio/y6pu2mRRAL0H7mqMr7CZEiRCRNYYzcLPgCLcBGAs/s1600/07.rest-api-search.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="697" height="164" src="https://2.bp.blogspot.com/-gCckmTYvSR0/XJRd-ycl_WI/AAAAAAAACio/y6pu2mRRAL0H7mqMr7CZEiRCRNYYzcLPgCLcBGAs/s320/07.rest-api-search.png" width="320" /></a></div>
<br />
This is a basic weather API implementation. There are many other out there. Feel free to try them out!<br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://www.dropbox.com/s/1y4dtttcxmfzul5/RESTApiBasics.zip?dl=1">here</a> or <a href="https://drive.google.com/uc?export=download&id=19QvnjNUpOEdXUpGQcd_MJ7eCQigUufVE">here</a>.<br />
Size: 2.93MB<br />
The package contains compiled executable EXE file. It has been compressed with UPX so some antivirus programs may see it as a false positive.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com5tag:blogger.com,1999:blog-5314745381778741517.post-24218102802104121032019-03-15T17:47:00.000+00:002019-03-16T04:21:44.291+00:00How to Get Contents of a URL (in 2 Ways)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-zb69x8Uh9cI/XIsrGEnaB9I/AAAAAAAACgM/z3pLTbPqbaIYvmmk4XKUEtrJBuvSdYT6wCLcBGAs/s1600/download-file-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" height="150" src="https://4.bp.blogspot.com/-zb69x8Uh9cI/XIsrGEnaB9I/AAAAAAAACgM/z3pLTbPqbaIYvmmk4XKUEtrJBuvSdYT6wCLcBGAs/s200/download-file-thumb.jpg" width="200" /></a></div>
The Web is an amazing place. What if we could download the contents of a link on the web to our own Lazarus program? Let's find out how!<br />
<a name='more'></a><br />
Getting the contents of a link can give us so much to do. We can communicate with servers or websites, get data from them, then parse and present the data in our program window just like we want to. And we can even use REST APIs to do amazing things.<br />
<br />
We can retrieve the contents of a link in 3 ways: fpHTTPClient, Synapse, Indy. There might be other ways, but these are the most popular.<br />
<br />
We'll see the first two in this article.<br />
<br />
<h3 style="text-align: left;">
fpHTTPClient Tutorial</h3>
This is the most simple of the 3, plus the library is bundled with Lazarus. So it is more convenient than the other ones.<br />
<br />
Start <a href="https://www.lazarus-ide.org/">Lazarus</a>.<br />
Create an Application Project (<b>Project - New Project - Application - OK</b>).<br />
<br />
Place 2 <b>TButton</b>s, <b>TEdit </b>and a <b>TMemo </b>on the form.<br />
Change <b>button1</b>'s Caption to "Download and Display" and <b>button2</b>'s to "Download and Save".<br />
Set the Text of Edit1 to <b>http://lazplanet.blogspot.com</b><br />
Also empty the <b>Memo1</b>'s <b>Lines </b>property and set its <b>ScrollBars </b>to <b>ssAutoVertical</b>.<br />
<br />
But what happens when we get large outputs and we need to resize the form? We can't have tiny components to fiddle around! To fix this you can enable the <b>akRight </b>for <b>Edit1 </b>under <b>Anchors</b>. And <b>akRight </b>and <b>akBottom </b>for <b>Memo1 </b>so that when the form is resized the components fill the form.<br />
<br />
Your form should look something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-kQeV2JPI2ao/XIvATlb1Q4I/AAAAAAAACgY/Yf76EMPZl8QMoVXYo0yvPtYz8FstNWwkQCLcBGAs/s1600/01.fphc-form-design.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="457" height="251" src="https://4.bp.blogspot.com/-kQeV2JPI2ao/XIvATlb1Q4I/AAAAAAAACgY/Yf76EMPZl8QMoVXYo0yvPtYz8FstNWwkQCLcBGAs/s320/01.fphc-form-design.png" width="320" /></a></div>
<br />
Switch to <b>Code View (F12)</b> and simply include <b>fphttpclient</b> in the uses clause:<br />
<br />
<pre class="brush:pascal">uses
...,
fphttpclient;
</pre>
<br />
Now add this function above the "end." line (usually the last line of the unit):<br />
<br />
<pre class="brush:pascal">function TForm1.FPHTTPClientDownload(URL: string; SaveToFile: boolean = false; Filename: string = ''): string;
begin
// Result will be:
// - empty ('') when it has failed
// - filename when the file has been downloaded successfully
// - content when the content SaveToFile is set to False
Result := '';
With TFPHttpClient.Create(Nil) do
try
try
if SaveToFile then begin
Get(URL, Filename);
Result := Filename;
end else begin
Result := Get(URL);
end;
except
on E: Exception do
ShowMessage('Error: ' + E.Message);
end;
finally
Free;
end;
end;
</pre>
<br />
Then put your cursor on the function line and press <b>Ctrl+Shift+C</b>.<br />
<br />
Now double click <b>button1 </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Text := FPHTTPClientDownload(Edit1.Text);
end;
</pre>
<br />
Double click <b>button2 </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button2Click(Sender: TObject);
begin
memo1.Text := FPHTTPClientDownload(Edit1.Text, True, 'test.txt');
end;
</pre>
<br />
The above will save the contents of the link to test.txt.<br />
<br />
Now this will easily work for http links. But for <b>HTTPS </b>links support (links that start with https://) you will have to do the following:<br />
<br />
Save the project in a folder. Then download the appropriate package from: <a href="https://indy.fulgan.com/SSL/">https://indy.fulgan.com/SSL/</a><br />
<br />
You can check the Help - About dialog. If it has <b>x86_64 </b>somewhere, then you are using 64 bit Lazarus. Otherwise you are probably using 32 bit version.<br />
<br />
Download the appropriate version of OpenSSL for you from the above URL. Then extract the <b>ssleay32.dll</b> and <b>libeay32.dll</b> file and keep them on the project directory.<br />
<br />
This is not required, but I'm mentioning this for fun... For the geeks out there, by default, your app is the architecture of your Lazarus architecture. More precisely, it is similar to the FPC installed. The matching architecture FPC should be installed for the target architecture you want to build for. If you want to compile for 32 bit from 64 bit Lazarus go to Project - Project Option - Compiler Options - Config and Target - Target CPU Family (-P). If you select i386 there, then get the 32 bit package from the above URL. Then <a href="https://freepascal.org/download.var">download and install the 32 bit FPC from here</a>. Also select the 32 bit FPC exe from Tools - Options - Environment - Compiler executable and show the GDB executable on Tools - Options - Debugger - General from your 32 bit fpc directory. [Please ignore this paragraph if you are not a geek!]<br />
<br />
If you don't include these dlls, it will raise an error when you would try to access a https link. So I would recommend to include these. Another way is to have the dlls in the system directory. On Linux, I think having the openssl package installed would be enough.<br />
<br />
Now <b>Run </b>the project <b>(F9 or Run - Run)</b> and test both buttons.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-lA9ZQhYSTsg/XIvHOfKUqYI/AAAAAAAACgs/p-W35faVTYs7ee0VDYHuMhT0qlr9HnvTQCLcBGAs/s1600/02.fphc-running-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="457" height="251" src="https://4.bp.blogspot.com/-lA9ZQhYSTsg/XIvHOfKUqYI/AAAAAAAACgs/p-W35faVTYs7ee0VDYHuMhT0qlr9HnvTQCLcBGAs/s320/02.fphc-running-c.png" width="320" /></a></div>
<br />
You may have to give these some time to download the data. Eventually you should see the content on the <b>Memo1 </b>and also a test.txt file on the project directory.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-z5vP3oH-J50/XIvHjyNGWZI/AAAAAAAACg0/_UgQvCW_yk8UPRXRMervu0LwOQtf3KN0QCLcBGAs/s1600/03.fphc-file-downloaded-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="400" data-original-width="682" height="187" src="https://2.bp.blogspot.com/-z5vP3oH-J50/XIvHjyNGWZI/AAAAAAAACg0/_UgQvCW_yk8UPRXRMervu0LwOQtf3KN0QCLcBGAs/s320/03.fphc-file-downloaded-c.png" width="320" /></a></div>
<br />
We'll do the same project in Synapse...<br />
<br />
<h3 style="text-align: left;">
Synapse Tutorial</h3>
Start <a href="https://www.lazarus-ide.org/">Lazarus</a> and create a new Application project (<b>Project - New Project - Application - OK</b>).<br />
Click <b>File - Save All</b> and save the project in a folder.<br />
<br />
Now <a href="http://www.ararat.cz/synapse/doku.php/download">get Synapse from here</a>. Download the <b>synapse.zip</b> file from under the title Stable release. Extract and put the folder inside your project folder.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-2UgZN3fldKE/XIvGidM2NuI/AAAAAAAACgk/kB6ocUZnaZMggaycp3pLXqnYCJmjD4GyQCLcBGAs/s1600/04.save-synapse-lib-files-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Save the synapse package content on your project folder" border="0" data-original-height="315" data-original-width="684" height="147" src="https://4.bp.blogspot.com/-2UgZN3fldKE/XIvGidM2NuI/AAAAAAAACgk/kB6ocUZnaZMggaycp3pLXqnYCJmjD4GyQCLcBGAs/s320/04.save-synapse-lib-files-c.png" title="Save the synapse package content on your project folder" width="320" /></a></div>
<br />
You should have a folder named <b>synapse40 </b>or something similar inside your project folder. Now go to <b>Project - Project Options - Compiler Options - Paths</b> and click the <b>[...]</b> button beside <b>Other unit files</b> and browse the source folder inside lib folder from the synapse folder. For example, <b>synapse40\source\lib</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Na3PyWju-xA/XIvKUomGdXI/AAAAAAAAChA/wuB-LgdK5kootRPt8u7Gt8IWTUZwD5yeACLcBGAs/s1600/05.synapse-lib-path-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Setting project options - other unit files - for synapse" border="0" data-original-height="538" data-original-width="816" height="210" src="https://4.bp.blogspot.com/-Na3PyWju-xA/XIvKUomGdXI/AAAAAAAAChA/wuB-LgdK5kootRPt8u7Gt8IWTUZwD5yeACLcBGAs/s320/05.synapse-lib-path-c.png" title="Setting project options - other unit files - for synapse" width="320" /></a></div>
<br />
Now switch to <b>Code view (F12)</b> and add <b>httpsend </b>in the <b>uses </b>clause.<br />
<br />
<pre class="brush:pascal">uses
...,
httpsend;
</pre>
<br />
If you want to use the https:// links then also add <b>ssl_openssl</b>. As a result it would become something like:<br />
<br />
<pre class="brush:pascal">uses
...,
httpsend, ssl_openssl;
</pre>
<br />
Now add this before the "end." line:<br />
<br />
<pre class="brush:pascal">function TForm1.SynapseDownload(URL: string; SaveToFile: boolean=False; TargetFile: string=''): string;
var
HTTPGetResult: Boolean;
HTTPSender: THTTPSend;
S: string;
begin
// Result will be:
// - empty ('') when it has failed
// - filename when the file has been downloaded successfully
// - content when the content SaveToFile is set to False
Result := '';
HTTPSender := THTTPSend.Create;
try
HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
if (HTTPSender.ResultCode >= 100) and (HTTPSender.ResultCode<=299) then begin
if SaveToFile = true then begin
HTTPSender.Document.SaveToFile(TargetFile);
Result := TargetFile;
end else begin
SetLength(S, HTTPSender.Document.Size);
HTTPSender.Document.Read(S[1], Length(S));
Result:=S;
end;
end;
finally
HTTPSender.Free;
end;
end;
</pre>
<br />
Then place your cursor on the function line and press Ctrl+Shift+C.<br />
<br />
Now create a similar form. Place 2 <b>TButton</b>s, a <b>TEdit </b>and a <b>TMemo</b>.<br />
Change <b>Caption </b>of <b>button1 </b>to "Download and Display" and <b>button2 </b>to "Download and Save".<br />
Set the Text of TEdit to: <b>http://lazplanet.blogspot.com</b><br />
Set <b>Lines </b>property of <b>Memo1 </b>to empty and set its <b>ScrollBars </b>to <b>ssAutoVertical</b>.<br />
<br />
Like previous project, you can enable the <b>akRight </b>for <b>Edit1 </b>under <b>Anchors</b>. And <b>akRight </b>and <b>akBottom </b>for <b>Memo1 </b>so that when the form is resized the components fill the form.<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-nB1GOS05Uls/XIvK-yo0zOI/AAAAAAAAChI/kyY500eAqOQAc1-va9qmDnNxJ2xPOnmIgCLcBGAs/s1600/06.synapse-form-design-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="361" data-original-width="458" height="252" src="https://4.bp.blogspot.com/-nB1GOS05Uls/XIvK-yo0zOI/AAAAAAAAChI/kyY500eAqOQAc1-va9qmDnNxJ2xPOnmIgCLcBGAs/s320/06.synapse-form-design-c.png" width="320" /></a></div>
<br />
Double click <b>button1 </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Text := SynapseDownload(Edit1.Text);
end;
</pre>
<br />
Double click <b>button2 </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Text := SynapseDownload(Edit1.Text, True, 'test.txt');
end;
</pre>
<br />
If you want your program to be able to access <b>https </b>links, then save the project in a folder. Then save the 2 dlls (<b>ssleay32.dll</b> and <b>libeay32.dll</b>) like previously on your project directory.<br />
<br />
Now <b>Run </b>the project (<b>F9 or Run - Run</b>). Now click the buttons to test. <b>button1 </b>should show the contents on the <b>Memo1</b>, <b>button2 </b>should download the contents on "test.txt".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-TOExE0F8w-8/XIvLXZNNytI/AAAAAAAAChQ/EPC0IDmJ9mg941vJjkOeT8-HqLQr6g4ZQCLcBGAs/s1600/07.synapse-running-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="361" data-original-width="458" height="252" src="https://3.bp.blogspot.com/-TOExE0F8w-8/XIvLXZNNytI/AAAAAAAAChQ/EPC0IDmJ9mg941vJjkOeT8-HqLQr6g4ZQCLcBGAs/s320/07.synapse-running-c.png" width="320" /></a></div>
<br />
<br />
You can also fetch links like: https://api.desktoppr.co/1/wallpapers/random<br />
This will give you JSON data about a random wallpaper everytime. You can then <a href="https://lazplanet.blogspot.com/2014/09/a-simple-json-parsing-example.html">parse the JSON data</a> to get the random wallpaper image URL, then download and <a href="https://lazplanet.blogspot.com/2014/08/how-to-set-desktop-wallpaper.html">set it as wallpaper</a>. This way you will get yourself a random wallpaper setter!<br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://drive.google.com/uc?export=download&id=1lGFBapcyiRWhMgJ6CXBl4nlzm2tEdwIa">here</a> or <a href="https://www.dropbox.com/s/b6nzuecc2htw136/DownloadContent.zip?dl=1">here</a>.<br />
Size: 4.29MB<br />
The package contains compiled executable EXE file. It has been compressed with UPX so some antivirus programs may see it as a false positive.<br />
<br />
Ref:<br />
<a href="http://wiki.lazarus.freepascal.org/fphttpclient">http://wiki.lazarus.freepascal.org/fphttpclient</a><br />
<a href="https://forum.lazarus.freepascal.org/index.php/topic,41401.msg287233.html#msg287233">https://forum.lazarus.freepascal.org/index.php/topic,41401.msg287233.html#msg287233</a><br />
<a href="http://wiki.freepascal.org/Synapse">http://wiki.freepascal.org/Synapse</a><br />
<a href="https://www.desktoppr.co/api">https://www.desktoppr.co/api</a>
</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com3tag:blogger.com,1999:blog-5314745381778741517.post-55083957408629801952019-03-07T10:36:00.002+00:002019-03-14T18:36:53.586+00:00How to Create a Calculator in Under 5 Minutes<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-i5BQz0Pnim0/XIDVZ-kce3I/AAAAAAAACfs/j0jrxANSKvwQwS39GrMZqqkpQsbBpP2MACLcBGAs/s1600/lazarus-easy-calculator-thu.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" height="150" src="https://2.bp.blogspot.com/-i5BQz0Pnim0/XIDVZ-kce3I/AAAAAAAACfs/j0jrxANSKvwQwS39GrMZqqkpQsbBpP2MACLcBGAs/s200/lazarus-easy-calculator-thu.jpg" width="200" /></a></div>
Computers are huge calculators. But how about making your own program to calculate things?! ...And under 5 minutes? How is it even possible?! Let's find out!<br />
<br />
<a name='more'></a><br />
<br />
We have made <a href="https://lazplanet.blogspot.com/2013/05/a-simple-calculator-project.html">calculators</a> in the past. It was a simple one, just to get an idea on how to do things around. But what about something more practical? Here you go, a nice new tutorial just for you.<br />
<br />
In this one, we'll create a simple calculator in under 5 minutes. Lazarus is a tool made for speed. So it is no wonder it is possible.<br />
<br />
Actually, I had made a calculator class some years back and forgot that I made it. About some weeks ago I got a notification on GitHub, so I thought to check back on old repos. There I found <a href="https://github.com/adnan360/simple-calculator-lazarus">this little gem</a>. I was amazed to see how easy it was to create a calculator. To say how easy it is, just 4 lines! And it works within this limit! How crazy!<br />
<br />
It's very easy, trust me. It comes down to just copy-pasting and dragging and dropping some components on the form.<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
Start <a href="https://www.lazarus-ide.org/">Lazarus</a>.<br />
Create a new project (<b>Project - New Project - Application - OK</b>).<br />
We will use a ready-made unit/class file for our calculator so that our work becomes easier. So first, save the project (<b>File - Save All</b>) in a folder of its own.<br />
<br />
Next, download and keep <a href="https://github.com/adnan360/simple-calculator-lazarus/raw/master/calculatorunit.pas">this file</a> inside the project folder. Make sure the name is <b>calculatorunit.pas</b>.<br />
<br />
Now add the calculatorunit under your <b>uses </b>clause:<br />
<pre class="brush:pascal">uses
..., ...
, calculatorunit;
</pre>
<br />
Also, add this under your first <b>var </b>clause in the unit:<br />
<pre class="brush:pascal">var
...;
Calculator: TCalculator;
</pre>
<br />
Now switch to form view (<b>F12 </b>or <b>View - Toggle Form/Unit View</b>) then double click the form and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormCreate(Sender: TObject);
begin
Calculator:=TCalculator.Create;
end;
</pre>
<br />
Now click on the <b>Object Inspector -> Events</b>, click on <b>OnDestroy</b>, then click the <b>[...]</b> button next to it and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormDestroy(Sender: TObject);
begin
Calculator.Free;
end;
</pre>
<br />
Now that we have got the boring stuff out of the way, let's design the form...<br />
<br />
Swith to form view (<b>F12</b>) and resize your form to a comfortable size. It's really your choice how you want it to look, so go ahead and give it the size you want.<br />
<br />
Now place a <b>TEdit </b>on the form. From <b>Object Inspector - Properties</b>, set <b>Name </b>to <b>edtDisplay</b>, set its <b>Font </b>to bigger size, maybe 16 or 18. We don't want anybody type in something on our display, so set <b>ReadOnly </b>to <b>True</b>. Also, we don't want the default "Edit1" text inside, so change the <b>Text </b>to 0.<br />
<br />
Is it done? Not yet. If you look at calculators, you would see that they always start showing the digits from the right and when digit gets longer it gradually gets to the left. To achieve this, we will have to set the <b>Alignment </b>property to <b>taRightJustify</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-t3dRZ15Zh4U/XIDBhten9ZI/AAAAAAAACeg/uCCg85zrMGMQ-IRdOy2ATOsSnN8GDDOWACLcBGAs/s1600/01-added-tedit-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="408" data-original-width="332" height="320" src="https://3.bp.blogspot.com/-t3dRZ15Zh4U/XIDBhten9ZI/AAAAAAAACeg/uCCg85zrMGMQ-IRdOy2ATOsSnN8GDDOWACLcBGAs/s320/01-added-tedit-c.png" width="260" /></a></div>
<br />
Next we'll create the buttons. Draw a single <b>TButton </b>on the form to make the start.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-aWNItYQ_toQ/XIDBlLPpNDI/AAAAAAAACek/5pBj24-N-usLI1Xpl8HcLBxIKp8oa4j4QCLcBGAs/s1600/02-added-tbutton-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="404" data-original-width="328" height="320" src="https://2.bp.blogspot.com/-aWNItYQ_toQ/XIDBlLPpNDI/AAAAAAAACek/5pBj24-N-usLI1Xpl8HcLBxIKp8oa4j4QCLcBGAs/s320/02-added-tbutton-c.png" width="259" /></a></div>
<br />
<br />
Set its <b>Font size</b> property to be a bit bigger, maybe 12. Now double click on the button and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
begin
Calculator.SendInput( TButton(Sender).Caption );
edtDisplay.Text:=Calculator.GetDisplay;
end;
</pre>
<br />
This procedure will get the button caption that was clicked and will pass it to the class. The TButton(Sender).Caption part takes care of that. Thanks to this code we don't need to say the name the button in order to get its Caption. This means we can use this procedure on any button regardless of Name it is given. The code gets the caption of the clicked button and passes it to the class for processing. Then we use the GetDisplay from our class to return the result of the input. Simple!<br />
<br />
You won't have to do anything special, for example, taking inputs, validating etc. The class will do all the hard work for you. Isn't she a beauty?!<br />
<br />
Also, we can use the same procedure for all the buttons. We'll now copy the buttons and forget about setting event procedures. When we copy something it keeps the original Event procedures automatically. This will keep this procedure linked with all the new buttons we copy and paste without a glitch.<br />
<br />
Below you can see, that if we copy the button, the original Button1Click procedure is also copied to the new button.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-h7hdOXg9UZM/XIDDEwZsCqI/AAAAAAAACe0/5pMZt1Q_RLATQV3Rp4gkVHYLuEjnqIcQgCLcBGAs/s1600/03-procedure-stays-after-copy-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Copying button also copies the event procedure in Lazarus" border="0" data-original-height="422" data-original-width="594" height="227" src="https://4.bp.blogspot.com/-h7hdOXg9UZM/XIDDEwZsCqI/AAAAAAAACe0/5pMZt1Q_RLATQV3Rp4gkVHYLuEjnqIcQgCLcBGAs/s320/03-procedure-stays-after-copy-c.png" title="Copying button also copies the event procedure" width="320" /></a></div>
<br />
<br />
Sweet!<br />
<br />
Now, your our work is easy. Just copy the button around and change <b>Captions </b>to make it something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-egmobfz_7WI/XIDMx9Z6InI/AAAAAAAACfI/F4hU_OiufSkH29gRybQ_ZH_md8RMuIELQCLcBGAs/s1600/04-added-all-buttons--c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="385" data-original-width="305" height="320" src="https://4.bp.blogspot.com/-egmobfz_7WI/XIDMx9Z6InI/AAAAAAAACfI/F4hU_OiufSkH29gRybQ_ZH_md8RMuIELQCLcBGAs/s320/04-added-all-buttons--c.png" width="253" /></a></div>
<br />
I have used Font size 12 for smaller buttons and 14 for number buttons.<br />
For backspace/erase button I used this character: ←<br />
<br />
That's it! You are done with building, now try running. Run the project (F9 or Run - Run).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-UAJkOi5BjZ0/XIDPeGj3tUI/AAAAAAAACfU/XgAHAa_KKz8S_c-H1CXHNTHNcomsqSaFQCLcBGAs/s1600/05-first-run-c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="edtDisplay shows a focus on running. We can fix this easily." border="0" data-original-height="385" data-original-width="305" height="320" src="https://1.bp.blogspot.com/-UAJkOi5BjZ0/XIDPeGj3tUI/AAAAAAAACfU/XgAHAa_KKz8S_c-H1CXHNTHNcomsqSaFQCLcBGAs/s320/05-first-run-c.png" title="edtDisplay shows a focus on running. We can fix this easily." width="253" /></a></div>
<br />
You will see that the calculator is working as it should. But when it is run, a selection selects the 0 in the edtDisplay. To fix that select edtDisplay and set TabStop to False.<br />
<br />
Now run again (F9) and enjoy!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-9UA-U5-XyIc/XIDQ6VKRgNI/AAAAAAAACfg/K6w9Qi0E-w0AOODtfdIYzM7tBSyjA5zxQCLcBGAs/s1600/06-calculator-second-run.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="385" data-original-width="305" height="320" src="https://1.bp.blogspot.com/-9UA-U5-XyIc/XIDQ6VKRgNI/AAAAAAAACfg/K6w9Qi0E-w0AOODtfdIYzM7tBSyjA5zxQCLcBGAs/s320/06-calculator-second-run.png" width="253" /></a></div>
<br />
This is not the end of course. How about a retro styled calculator? We can search for a <a href="https://commons.wikimedia.org/wiki/File:Vintage_Texas_Instruments_TI-1250_Red_LED_Pocket_Electronic_Calculator,_Made_in_USA,_Circa_1975_-_Price_Was_19.95_USD_(10649611933).jpg">retro electric calculator</a>, then <a href="https://lazplanet.blogspot.com/2014/04/shape-your-form-into-anything.html">shape the form into the image</a>. Also, we can show the digits in the exact glowing way the original electric calculator shows by following the digit display method used on the <a href="https://lazplanet.blogspot.com/2013/12/create-digital-clock-that-talks.html">talking clock</a> tutorial. The possibilities are endless!<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://drive.google.com/uc?export=download&id=1j8O_gmt36u3ApRZFWkn0FJRh_ZMFyM2e">here</a> or <a href="https://www.dropbox.com/s/9vh7bhffumt4hwx/easycalc.zip?dl=1">here</a>.<br />
Size: 761KB<br />
The package contains compiled executable EXE file. It has been compressed with UPX so some antivirus may see it as a false positive.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com0tag:blogger.com,1999:blog-5314745381778741517.post-65953701250122503902019-02-14T10:20:00.000+00:002019-02-14T10:24:28.084+00:00Lazarus 2.0.0 Released - With Many Tiny Changes<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="122" ilo-full-src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" src="https://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" width="162" /></a></div>
Lazarus 2.0 has been released. It is the second major release with FPC 3.0.4. It has many new minor changes to look for.<br />
<a name='more'></a><br />
I think you'll agree it is always a pleasure to see a new version of Lazarus. The stable
version of the Lazarus of version 2.0, with FPC 3.0.4 has been
announced on 5 February 2019. Some major changes include:<br />
<br />
<ul style="text-align: left;">
<li>Horizontal mouse scroll events (for special mice with horizontal scrolling capabilities)</li>
<li>High DPI improvements</li>
<li><a href="http://wiki.lazarus.freepascal.org/lazarus_pas2js_integration">pas2js</a> support - to create a browser or nodejs application</li>
<li>Code navigation improvements</li>
<li><a href="http://wiki.lazarus.freepascal.org/Lazarus_2.0.0_release_notes">and many more...</a></li>
</ul>
<br />
Here is how it looks on a typical Windows install:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-_0wdkVZ5KW4/XGU_lOSf3EI/AAAAAAAACeE/fcXmAKe0r8wFI11hzAaohVHHkzLMWWKwgCLcBGAs/s1600/Lazarus-2.0.0-on-windows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="760" data-original-width="1279" height="190" src="https://1.bp.blogspot.com/-_0wdkVZ5KW4/XGU_lOSf3EI/AAAAAAAACeE/fcXmAKe0r8wFI11hzAaohVHHkzLMWWKwgCLcBGAs/s320/Lazarus-2.0.0-on-windows.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I am not quite sure, but it seems menu icons had some minor changes, which makes it look even more professional than before. It brings out contrast between different features better, which was missing on the previous icons.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-GYfi9lq916A/XGU_tZHLfpI/AAAAAAAACeM/6622QbjS42MHrZEenX9ZKbbmVgH4PHiTQCLcBGAs/s1600/Lazarus-2.0.0-menu1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="556" data-original-width="328" height="320" src="https://2.bp.blogspot.com/-GYfi9lq916A/XGU_tZHLfpI/AAAAAAAACeM/6622QbjS42MHrZEenX9ZKbbmVgH4PHiTQCLcBGAs/s320/Lazarus-2.0.0-menu1.png" width="188" /></a></div>
<br />
<br />
<div style="clear: both; text-align: left;">
There are many other changes which are yours to explore! Go ahead, download Lazarus and try for yourself.</div>
<br />
As a sidenote, the fpc package for Free Pascal on Debian (Linux) has been changed to fpc-laz. You will have to adopt with the new name from now on. <br />
<br />
As usual, many thanks to the tireless effort that Lazarus Team has put to this release. We wouldn't have this wonderful product without them.<br />
<br />
<h3 style="text-align: left;">
What's New</h3>
The changes are <a href="http://wiki.lazarus.freepascal.org/Lazarus_2.0.0_release_notes">listed here</a> and <a href="http://wiki.freepascal.org/Lazarus_1.8_fixes_branch#Fixes_for_1.8.0_.28merged.29">here</a>.<br />
<br />
<h3 style="text-align: left;">
Download</h3>
The release is available for download at SourceForge:<br />
<a href="https://sourceforge.net/projects/lazarus/files/">https://sourceforge.net/projects/lazarus/files/</a><br />
<br />
Choose your CPU, OS, distro and then the "Lazarus 2.0" directory.<br />
<br />
Or from the homepage: <a href="http://www.lazarus-ide.org/index.php?page=downloads">http://www.lazarus-ide.org/index.php?page=downloads</a><br />
<br />
<br />
<b>Minimum requirements:</b><br />
Windows:<br />
2k, XP, Vista, 7, 8, 8.1 and 10, 32 or 64bit.<br />
<br />
FreeBSD/Linux:<br />
gtk 2.8 for gtk2, qt4.5 for qt, qt5.6 for qt5, 32 or 64bit.<br />
<br />
Mac OS X:<br />
10.5 to 10.12; Carbon (32bit), Cocoa (64bit, beta), qt and<br />
qt5 (32 or 64bit).<br />
<h3 style="text-align: left;">
Alternate Download</h3>
For people who are blocked by SF, the Lazarus releases from SourceForge are mirrored at:<br />
<a href="ftp://ftp.freepascal.org/pub/lazarus/releases/">ftp://ftp.freepascal.org/pub/lazarus/releases/</a><br />
and later at (after some time for synchronization)<br />
<a href="http://mirrors.iwi.me/lazarus/">http://mirrors.iwi.me/lazarus/</a><br />
<br />
<h3 style="text-align: left;">
How-to-Install Guide</h3>
<br />
You can <a href="http://lazplanet.blogspot.com/2013/03/how-to-install-lazarus.html">click here for an installation guide</a> for all Operating Systems.<br />
If you are an Ubuntu user then also see <a href="http://lazplanet.blogspot.com/2013/05/how-to-install-lazarus-108-on-ubuntu.html">this post for an exclusive guide for installing Lazarus 2.0.0 in Ubuntu</a> (you
can follow the same guide to install in previous or latest versions of
Ubuntu, such as 16.04 LTS, 18.04 LTS, 18.10 etc. or
any other debian based OS).<br />
<br />
<h3 style="text-align: left;">
Source</h3>
<a href="http://forum.lazarus-ide.org/index.php/topic,44161.0.html">Lazarus Forum Announcement Post</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com0tag:blogger.com,1999:blog-5314745381778741517.post-50360843556803312942018-12-15T18:54:00.000+00:002019-03-16T04:11:58.376+00:00How to Create Multilingual Programs in Lazarus<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-O_-MLGVxQP0/XBVH6uDQYSI/AAAAAAAACcc/bUt0r1dkuAEH5G8CcciyNvS8cb_HHEwHACLcBGAs/s1600/lazarus-i18n-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" height="150" src="https://3.bp.blogspot.com/-O_-MLGVxQP0/XBVH6uDQYSI/AAAAAAAACcc/bUt0r1dkuAEH5G8CcciyNvS8cb_HHEwHACLcBGAs/s200/lazarus-i18n-thumb.jpg" width="200" /></a></div>
Hola, ciào, bonjour! Today we're making our program speak different languages!<br />
<a name='more'></a><br />
I have worked on lozalization for phpBB and some other projects before - mainly in PHP and for my native language Bangla. I think it's kind of a magic, the way an interface changes into some other language. So I thought I would write on how to do the same thing on Lazarus. So here it is.<br />
<br />
In the old days, software used to have only one language on its interface. Things have changed since then. Now we like to have English, plus our own language. So, if you are writing a very useful program, it is great to have some of the popular languages on the same program. These days programs are becoming multi-lingual, supporting multiple languages - which is a great way to ensure accessibility for all. Especially for people who can't speak English. So let's get onto it.<br />
<br />
Localization is actually easy in Lazarus. You just need to get the hang of the basics, that's all.<br />
<br />
<h3 style="text-align: left;">
Easy Peasy Basics</h3>
Start <b>Lazarus</b>.<br />
Create a new <b>Application Project</b> (Project - New Project - Application - OK).<br />
Let's learn it through a test project. It will be very easy to learn for you step by step. If you're thirsty for more, I've got a Tutorial Project later on. So buckle up...!<br />
<br />
<h4 style="text-align: left;">
Step 1: Basic Implementation</h4>
For a basic localized application you need to:<br />
<br />
- Save your project in a folder (this is important)<br />
- Go to <b>Project Settings - i18n - Enable i18n</b> (this would enable multi-language support for our project)<br />
- Set a directory for po files (languages or locale). You can just type "languages" or "locale" to keep it inside your project directory.<br />
- Ensure that <b>Create/update .po file when saving a lfm file</b> is checked. Click <b>OK</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-pKdybxRmvgM/XBSf07u3WpI/AAAAAAAACZs/J9i7W55ajJEZksqb03_MptnWaqFWgstBACLcBGAs/s1600/i18n-project-settings-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="538" data-original-width="816" height="210" src="https://3.bp.blogspot.com/-pKdybxRmvgM/XBSf07u3WpI/AAAAAAAACZs/J9i7W55ajJEZksqb03_MptnWaqFWgstBACLcBGAs/s320/i18n-project-settings-.png" width="320" /></a></div>
<br />
- Go to Code View (F12) and add <b>DefaultTranslator</b> under uses clause<br />
- (Optional) Add a new <b>resourcestring</b> clause and define strings you want to be translated. Then use them like variables throughout your code. For example:<br />
<br />
<pre class="brush:pascal">resourcestring
HelloMessage = 'Hello World!';
CloseMessage = 'Closing your app... bye bye!';
</pre>
<b>Note:</b> Captions and other string based properties will be automatically added for translation without writing any code. Lazarus is awesome at this, so no worries. You just need to add strings that are not on properties in this clause.<br />
- Run the project (<b>F9</b> or <b>Run - Run</b>)<br />
<br />
The directory you set earlier on the project settings will be created and a projectname.po file will be created inside the directory for the strings you wrote earlier in the code.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-FZWDywqZ1h0/XBSkT1uBT_I/AAAAAAAACZ4/ssiQsgSsaLkHlTTVyxTEoUtZGXgjOMe5ACLcBGAs/s1600/i18n-strings-file-created-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="285" data-original-width="778" height="146" src="https://1.bp.blogspot.com/-FZWDywqZ1h0/XBSkT1uBT_I/AAAAAAAACZ4/ssiQsgSsaLkHlTTVyxTEoUtZGXgjOMe5ACLcBGAs/s400/i18n-strings-file-created-.png" width="400" /></a></div>
<br />
Everytime you Run/Save the project, this file will be updated with the added or changed string list. It will include all the string values in Captions, etc. of components, so you won't have to add them manually. Easy, isn't it?!<br />
<br />
Now, install <a href="https://poedit.net/">poedit</a>. poedit is free, open source and cross platform and we use it to edit translation files. Open the .po file in poedit and just hit save. This will automatically create a .mo file on the same directory.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-OyaAmy3Ez6c/XBSlu9av5oI/AAAAAAAACaE/BJ55lldBkx498vdsxScBWA1cneOFG1MjACLcBGAs/s1600/i18n-save-from-poedit-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="656" height="249" src="https://4.bp.blogspot.com/-OyaAmy3Ez6c/XBSlu9av5oI/AAAAAAAACaE/BJ55lldBkx498vdsxScBWA1cneOFG1MjACLcBGAs/s320/i18n-save-from-poedit-.png" width="320" /></a></div>
<br />
In case it complains about language not set, then click the <b>Set language </b>button and set <b>English (United States)</b> as the language and it should stop.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-4VDz6WqBkPY/XBSmfGkYOxI/AAAAAAAACaM/yRGloHAn4I43YfJw9d4IWMskdYn80vAAwCLcBGAs/s1600/i18n-mo-file-created-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="239" data-original-width="763" height="125" src="https://2.bp.blogspot.com/-4VDz6WqBkPY/XBSmfGkYOxI/AAAAAAAACaM/yRGloHAn4I43YfJw9d4IWMskdYn80vAAwCLcBGAs/s400/i18n-mo-file-created-.png" width="400" /></a></div>
<br />
Remember, .mo files will be used on runtime - on the exe. (.po files are ignored on runtime and are just for editing purposes. So .po files are just there for <i>us</i>, the developers.)<br />
<br />
<h4 style="text-align: left;">
Step 2: Adding Languages to Translations</h4>
Now copy the projectname.po file (on <b>languages</b> or <b>locale</b> folder) and paste into the same folder and rename to add 2-letter language name to its extension.<br />
<br />
For example, if you want to translate the strings to Spanish, copy the original .po file, then rename to projectname.es.po<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-teSvk7xDXzs/XBStBrqBgtI/AAAAAAAACak/SpFYF-p1E0k8oLaXtA7mlq7TDw-vQVGZwCLcBGAs/s1600/i18n-es-po-created-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="228" data-original-width="569" height="160" src="https://3.bp.blogspot.com/-teSvk7xDXzs/XBStBrqBgtI/AAAAAAAACak/SpFYF-p1E0k8oLaXtA7mlq7TDw-vQVGZwCLcBGAs/s400/i18n-es-po-created-.png" width="400" /></a></div>
<br />
If you are not sure what should be the 2-letter code for your language, check <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">here</a>. (The code should be under "ISO 639-1" column).<br />
<br />
Open with poedit, then translate the strings and save. The .mo file for the .po file in your language will be created.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-DbMAs38AzDs/XBSuZS-PCEI/AAAAAAAACaw/YnyKP6XGoygzslWDJW_6Rw0qA-IxBFyBACLcBGAs/s1600/i18n-es-mo-created-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="232" data-original-width="590" height="156" src="https://2.bp.blogspot.com/-DbMAs38AzDs/XBSuZS-PCEI/AAAAAAAACaw/YnyKP6XGoygzslWDJW_6Rw0qA-IxBFyBACLcBGAs/s400/i18n-es-mo-created-.png" width="400" /></a></div>
<br />
Whenever the project is run, you will see the updated strings in all of the .po files you created. To make it reflect on the exe, you should open the .po files in poedit and hit save. This will create the .mo files and the exe will see that.<br />
<br />
<h4 style="text-align: left;">
Step 3: Changing Language with Command Line</h4>
If you want to see how your program would look with certain language chosen, you can run your program with --lang [language code].<br />
<br />
For example, open Command prompt or Terminal and enter:<br />
<br />
<pre class="brush:pascal">cd /path/to/project
./project1.exe --lang es
</pre>
<br />
I don't know Spanish, but Google Translate says "Form" in Spanish is <i>Formulario</i>. So I translated the Form1 string into Formulario1 and Saved the project1.es.po file.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-TCzMQk02pQo/XBSvVzPRbfI/AAAAAAAACa4/OcdlijRtMUkS05nqiPCp6HHbVAo04Gg_gCLcBGAs/s1600/i18n-es-test-translated-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="656" height="249" src="https://1.bp.blogspot.com/-TCzMQk02pQo/XBSvVzPRbfI/AAAAAAAACa4/OcdlijRtMUkS05nqiPCp6HHbVAo04Gg_gCLcBGAs/s320/i18n-es-test-translated-.png" width="320" /></a></div>
<br />
Then went to project directory, then right-clicked with Shift key pressed at the same time and then selected <b>Open command window here</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-Yyxy-oh-9so/XBSrqi1epLI/AAAAAAAACaY/hnNDZO5P7Hkv7VymCTQJxX3GPJzvwUE-ACLcBGAs/s1600/i18n-open-cmd-dir-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="435" data-original-width="648" height="214" src="https://3.bp.blogspot.com/-Yyxy-oh-9so/XBSrqi1epLI/AAAAAAAACaY/hnNDZO5P7Hkv7VymCTQJxX3GPJzvwUE-ACLcBGAs/s320/i18n-open-cmd-dir-.png" width="320" /></a></div>
<br />
Now run the executable with <b>--lang es</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-KA7_mPrWsOs/XBSv9q-WnnI/AAAAAAAACbE/KCTMCYjvRGcDK51bpmCM_-reBwaWmpvJACLcBGAs/s1600/i18n-es-run-cmd-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="342" data-original-width="677" height="201" src="https://1.bp.blogspot.com/-KA7_mPrWsOs/XBSv9q-WnnI/AAAAAAAACbE/KCTMCYjvRGcDK51bpmCM_-reBwaWmpvJACLcBGAs/s400/i18n-es-run-cmd-.png" width="400" /></a></div>
<br />
This will show your application in Spanish language:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-dRfQeqKg4ok/XBSwc7TFJnI/AAAAAAAACbM/0VV6WUJEKEYPNEyplXmLJbyOpdPXtjnRACLcBGAs/s1600/i18n-es-run-app-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="278" data-original-width="336" height="264" src="https://4.bp.blogspot.com/-dRfQeqKg4ok/XBSwc7TFJnI/AAAAAAAACbM/0VV6WUJEKEYPNEyplXmLJbyOpdPXtjnRACLcBGAs/s320/i18n-es-run-app-.png" width="320" /></a></div>
<br />
You can also try sending this command line argument from Lazarus, which is great if you want to test your application in certain language from inside Lazarus. Go to <b>Run - Run Parameters</b>. Now enter <b>--lang es</b> under Command line parameters field, then click <b>OK</b>. Now hit Run - Run and your application should appear in Spanish language.<br />
<br />
<h4 style="text-align: left;">
Step 4: Changing Language on Runtime</h4>
Sometimes you may want to switch the interface language manually with a button or something. You can do that as well! You can use code like this:<br />
<br />
<pre class="brush:pascal">procedure TMainForm.MEnglishlanguageClick(Sender: TObject);
begin
SetDefaultLang('en');
end;
procedure TMainForm.MGermanLanguageClick(Sender: TObject);
begin
SetDefaultLang('de');
end;
</pre>
<br />
Also, you'll have to add LCLTranslator in the uses clause.<br />
<br />
So here, SetDefaultLang() procedure is setting the language. You can pass it the language code and the magic happens! All your components change language. How cool is that?!<br />
<br />
I hope you've learned the basics for translations for your programs. Now let's create a test project to see them in action!<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
Create a new Application project (<b>Projects - New Project - Application - OK</b>).<br />
Then you know the drill... save the project in a folder with File - Save All (it is important to save somewhere to generate language files later).<br />
Go to <b>Project - Project Options - i18n</b> and then check <b>Enable i18n</b> checkbox. Then enter <b>languages</b> under PO Output Directory. Make sure <b>Create/update .po file when saving a lfm file</b> is checked. Click OK.<br />
<br />
Now switch to code view (F12). Then add DefaultTranslator and LCLTranslator under uses clause:<br />
<br />
<pre class="brush:pascal">uses
..., ..., DefaultTranslator, LCLTranslator;
</pre>
<br />
Then paste this before implementation line:<br />
<br />
<pre class="brush:pascal">resourcestring
HelloMessage = 'Hello World!';
CloseMessage = 'Closing your app... bye bye!';
GreetMessage = 'Hey %0:s from %1:s country!';
</pre>
<br />
We are using placeholders %0:s and %1:s. We will replace them later with Name and Country values. Details later on.<br />
<br />
Switch to Form view (F12). Place 3 TGroupBoxes on the form. You many want to resize the form accordingly. Change their Caption properties to become something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-Z91Y6D70sT0/XBTv6bKkjsI/AAAAAAAACbY/WGUZS1BMq20BTnwe7NNo-0yKDGiCJVNaACLcBGAs/s1600/i18n-groupbox-structure-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="288" data-original-width="570" height="201" src="https://2.bp.blogspot.com/-Z91Y6D70sT0/XBTv6bKkjsI/AAAAAAAACbY/WGUZS1BMq20BTnwe7NNo-0yKDGiCJVNaACLcBGAs/s400/i18n-groupbox-structure-.png" width="400" /></a></div>
<br />
Now create 2 TLabels, 2 TEdits, 5 TButtons and change their Caption or Text to make them something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-lJwh0pcmaAQ/XBTx9HIYvII/AAAAAAAACbk/iA-aNE0WnZIjI-LR_pqzkLwOIBkpMeq3ACLcBGAs/s1600/i18n-form-layout-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="288" data-original-width="570" height="201" src="https://3.bp.blogspot.com/-lJwh0pcmaAQ/XBTx9HIYvII/AAAAAAAACbk/iA-aNE0WnZIjI-LR_pqzkLwOIBkpMeq3ACLcBGAs/s400/i18n-form-layout-.png" width="400" /></a></div>
<br />
Now let's change their Name property into something more meaningful. Change the Name of top left button to BtnMessage. Change the Name of the 3 language buttons to BtnEnglish, BtnSpanish and BtnBangla respectively. Name the 2 TEdits EdtName and EdtCountry. Then name the button below to BtnGreet.<br />
<br />
Double click BtnMessage and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.BtnMessageClick(Sender: TObject);
begin
ShowMessage(HelloMessage);
end;
</pre>
<br />
Double click BtnEnglish and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.BtnEnglishClick(Sender: TObject);
begin
SetDefaultLang('en');
end;
</pre>
<br />
Double click BtnSpanish and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.BtnSpanishClick(Sender: TObject);
begin
SetDefaultLang('es');
end;
</pre>
<br />
Double click BtnBangla and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.BtnBanglaClick(Sender: TObject);
begin
SetDefaultLang('bn');
end;
</pre>
<br />
Double click BtnGreet and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.BtnGreetClick(Sender: TObject);
begin
ShowMessage( format( GreetMessage, [EdtName.Text, EdtCountry.Text] ) );
end;
</pre>
With the above command we are formatting GreetMessage to replace the placeholders and pass the resulting string to be shown on our message.<br />
<br />
Remember that we placed <b>%0:s</b> and <b>%1:s</b> in the <b>GreetMessage</b> resourcestring?<br />
<br />
<pre class="brush:pascal">resourcestring
...
GreetMessage = 'Hey %0:s from %1:s country!';
</pre>
<br />
We have now replaced the placeholders in the string with format() function to show the Name and Country on the string.<br />
<br />
We could've used multiple parts of the string in multiple resourcestrings, but <a href="http://wiki.lazarus.freepascal.org/Getting_translation_strings_right#The_format.28.29_function">Lazaurs wiki suggests to use format and use placeholders</a>. This way translators can get a freedom, even if they need to change the order of the placeholders. In my experience, I have seen use of placeholders in famous projects. So, this is the best way to do this, trust me.<br />
<br />
Then select your form, then go to Object Inspector - Events tab. Click OnClose and click on [...] button beside it and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
ShowMessage(CloseMessage);
end;
</pre>
<br />
Now add your translations in the languages folder. Copy projectname.po twice and rename them to projectname.es.po and projectname.bn.po.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-rVu17k8RLHo/XBT5k0QL0xI/AAAAAAAACbw/K3mW160Y8NsIFibln2-cCSsIj92yx6LqQCLcBGAs/s1600/i18n-create-po-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="195" data-original-width="438" height="142" src="https://2.bp.blogspot.com/-rVu17k8RLHo/XBT5k0QL0xI/AAAAAAAACbw/K3mW160Y8NsIFibln2-cCSsIj92yx6LqQCLcBGAs/s320/i18n-create-po-.png" width="320" /></a></div>
<br />
Now open the files with poedit, go to Catalog - Properties and make sure language is set for each one, then save. This will create .mo files for each one.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-w-jUOTcXzA4/XBT6ft3dngI/AAAAAAAACb4/ZpsmPG-eFW8ErzNiB_ZfVK7YuQBcf3ZgQCLcBGAs/s1600/i18n-mo-created-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="281" data-original-width="441" height="203" src="https://3.bp.blogspot.com/-w-jUOTcXzA4/XBT6ft3dngI/AAAAAAAACb4/ZpsmPG-eFW8ErzNiB_ZfVK7YuQBcf3ZgQCLcBGAs/s320/i18n-mo-created-.png" width="320" /></a></div>
<br />
Now Translate the .po files and save. You can also download the project source code and use the translation files I used.<br />
<br />
Now run the project (Run - Run or F9). You should the form as usual.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-IgMpn2ru_eA/XBVBiZBVbJI/AAAAAAAACcE/HvM34eIUGXkeMQyF-qZj8HkKAEem8qc6QCLcBGAs/s1600/i18n-run-first-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="288" data-original-width="570" height="201" src="https://4.bp.blogspot.com/-IgMpn2ru_eA/XBVBiZBVbJI/AAAAAAAACcE/HvM34eIUGXkeMQyF-qZj8HkKAEem8qc6QCLcBGAs/s400/i18n-run-first-.png" width="400" /></a></div>
<br />
Then click the language buttons to change language.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-E974Nfq7478/XBVBphXQ0RI/AAAAAAAACcI/kJVwr4WXinA_lvjTwbLc5LtQ_xK73S3ywCLcBGAs/s1600/i18n-run-lang-change-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="288" data-original-width="570" height="201" src="https://4.bp.blogspot.com/-E974Nfq7478/XBVBphXQ0RI/AAAAAAAACcI/kJVwr4WXinA_lvjTwbLc5LtQ_xK73S3ywCLcBGAs/s400/i18n-run-lang-change-.png" width="400" /></a></div>
<br />
<br />
The messages should also work. If you click the message button you should see the localized version of the message.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-EZgTxkXNUE0/XBVBwPNNZII/AAAAAAAACcM/BGcFQB1gUNgjqB3cbZu35iU35h4Uj_P0gCLcBGAs/s1600/i18n-run-message-.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="124" data-original-width="376" height="105" src="https://4.bp.blogspot.com/-EZgTxkXNUE0/XBVBwPNNZII/AAAAAAAACcM/BGcFQB1gUNgjqB3cbZu35iU35h4Uj_P0gCLcBGAs/s320/i18n-run-message-.png" width="320" /></a></div>
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://drive.google.com/uc?export=download&id=1dCVx3biUCYGh5540kT27WTHArYuOjS7A">here</a>.<br />
Size: 783KB<br />
The package contains compiled executable EXE file. It has been compressed with UPX so some antivirus may see it as a false positive.<br />
<br />
Ref:<br />
<a href="http://wiki.lazarus.freepascal.org/Step-by-step_instructions_for_creating_multi-language_applications">http://wiki.lazarus.freepascal.org/Step-by-step_instructions_for_creating_multi-language_applications</a><br />
<a href="http://wiki.lazarus.freepascal.org/Translations_/_i18n_/_localizations_for_programs">http://wiki.lazarus.freepascal.org/Translations_/_i18n_/_localizations_for_programs</a><br />
<a href="http://wiki.lazarus.freepascal.org/Getting_translation_strings_right">http://wiki.lazarus.freepascal.org/Getting_translation_strings_right</a><br />
<a href="http://forum.lazarus.freepascal.org/index.php?topic=27047.0">http://forum.lazarus.freepascal.org/index.php?topic=27047.0</a>
</div>
</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com2tag:blogger.com,1999:blog-5314745381778741517.post-20349989405873350272018-05-01T08:45:00.001+01:002018-05-01T08:45:20.895+01:00Spotlight: CudaText - A Hot Replacement for Sublime Text, Written in Lazarus<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-fR7p3J8d5nA/WugYmT11_MI/AAAAAAAACXQ/Ei30RvhDFQ4fnT9Ef7V4IdeCoGke0QYvgCLcBGAs/s1600/cudatext_thumb.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" src="https://2.bp.blogspot.com/-fR7p3J8d5nA/WugYmT11_MI/AAAAAAAACXQ/Ei30RvhDFQ4fnT9Ef7V4IdeCoGke0QYvgCLcBGAs/s1600/cudatext_thumb.png" /></a></div>
Care for a replacement of Sublime Text, but Open Source? We got you covered...!<br />
<a name='more'></a><br />
By the way, congrats to LazPlanet for its 100th post! Congrats to you all readers for such a great community!<br />
<br />
<br />
Sublime Text is one of my favorites. It has many features that power users need. I love it so much, but I hate the fact that it is not open source. Well, guess what...? There is an alternative to Sublime Text, and it is <a href="http://wiki.freepascal.org/CudaText">written in Lazarus</a>! And the best part is, it can use plugins from Sublime. Cool!<br />
<br />
If nothing else, I would request you to <a href="http://www.uvviewsoft.com/cudatext/">visit CudaText homepage</a>. When it comes to websites it is not one of the flashiest ones, but the features and animations present there are bound to impress at least many of us. I got a feeling that it will impress you for sure. Just take 2 minutes to see those animations, and you'll like it even more.<br />
<br />
If you are interested to use it in your text editing, let's dive in...<br />
<br />
<h3 style="text-align: left;">
Installation</h3>
<br />
You can just download the files from here: <a href="https://sourceforge.net/projects/cudatext/files/release/">https://sourceforge.net/projects/cudatext/files/release/</a><br />
<br />
They have versions for Windows, Linux, Linux-arm (for Raspberry Pi etc.) Mac and BSD. Such a nice coverage!<br />
<br />
On Windows, you can just install with the setup file given. Python is preinstalled with the package.<br />
On linux/debian It is as easy as installing a deb file. You should be able to install it with a command:<br />
<pre>sudo dpkg -i "/path/to/cudatext.deb" && sudo apt-get -f install
</pre>
<br />
If you are not using debian (you don't have apt or dpkg), you may have to look into the tar.xz files, extract and run it directly from a directory, such as /opt or ~/bin. You can create a desktop file for it on /usr/share/local/applications or ~/.local/share/applications to show the shortcut on your Application menu. Such a .desktop file might be like this:<br />
<br />
<pre>[Desktop Entry]
Name=CudaText
GenericName=Text Editor
Comment=Advanced code editor. Syntax highlighting for 190+ languages. Supports all major encoding. Multi-carets and multi-selections. Implemented many editing commands found in common text editors. UI with tabs and sidebar. Search and replace with regex.
Exec=/usr/bin/cudatext %F
Terminal=false
Type=Application
StartupNotify=true
MimeType=text/plain;
Categories=Utility;TextEditor;
Icon=cudatext
</pre>
<br />
* Make sure to change the Exec line above to match the directory where you installed it.<br />
<br />
Arch Linux also has a great way of installing CudaText. Just run:<br />
<pre>yaourt -S cudatext --noconfirm
</pre>
<h3 style="text-align: left;">
Running and Tweaking it</h3>
<br />
If you are on linux, when you run it, you will probably get a screen like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-FjZoW7uCRbA/WuSrIIhvRMI/AAAAAAAACWY/zwdmzbSlT_ggffcHcKFJdY94VqwHcMM9QCEwYBhgL/s1600/001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="800" height="230" src="https://3.bp.blogspot.com/-FjZoW7uCRbA/WuSrIIhvRMI/AAAAAAAACWY/zwdmzbSlT_ggffcHcKFJdY94VqwHcMM9QCEwYBhgL/s320/001.png" width="320" /></a></div>
<br />
<br />
It might have an error saying:<br />
<pre>No Python engine (3.x) found. Python plugins don't work now. To make it ok:
write option "pylib__linux" to user.json. See info in default config: Options / Settings-default.
Loading session: history session.json
Startup: total: 320ms, including plugins: 0ms
</pre>
<br />
This happens only in Linux and is easy to fix.<br />
<br />
Just run:<br />
<pre>find /usr -name 'libpython3.*so*' 2>/dev/null
</pre>
<br />
You will get some output for where python library files are. I got an output like this on my system:<br />
<pre>/usr/lib/libpython3.so
/usr/lib/libpython3.6m.so
/usr/lib/libpython3.6m.so.1.0
</pre>
<br />
We would need that in a minute. Now go to <b>Options - Settings - user</b>. Now paste in this code:<br />
<pre>{
"pylib__linux" : "libpython3.so",
}
</pre>
<br />
Notice that I have used only filename and not path. If this filename does not work, try the above code with the filenames you get on your system. Save and Restart. The error should be gone.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-pj2SW_fbvAA/WuSsyZfTiVI/AAAAAAAACWg/axkLJITDsKIp4fkz09-SAc0DCaadAsWFwCLcBGAs/s1600/0002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="800" height="230" src="https://4.bp.blogspot.com/-pj2SW_fbvAA/WuSsyZfTiVI/AAAAAAAACWg/axkLJITDsKIp4fkz09-SAc0DCaadAsWFwCLcBGAs/s320/0002.png" width="320" /></a></div>
<br />
<br />
To make some space, you can click <b>View - Toggle Bottom Panel and View - Toggle Side Panel</b>.<br />
<br />
Then you can also click on the Project icon on the Sidebar to reveal the Project Manager, which you can use to open browse and view files within a folder.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-zEEqJw2FPZQ/WuSs3roIuRI/AAAAAAAACWk/hMGJFdOFHaofN_d_nIqFciW1_T1cwHWdwCLcBGAs/s1600/0003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="800" height="230" src="https://3.bp.blogspot.com/-zEEqJw2FPZQ/WuSs3roIuRI/AAAAAAAACWk/hMGJFdOFHaofN_d_nIqFciW1_T1cwHWdwCLcBGAs/s320/0003.png" width="320" /></a></div>
<br />
<br />
To spice up things a bit, you can choose an UI theme from <b>Options - Color Themes - UI</b>. If it prompts there is a Syntax theme with the same name, click OK.<br />
<br />
To get the same look as Sublime, you can choose ebony or sub. If you like the color of Atom, you should choose darkwolf or zeus. Although they are not exact, you can finetune it by mixing different Syntax themes with UI themes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-KKoUVo-NA10/WuSs9M7kjRI/AAAAAAAACWo/kYSLDh6Oquwt1O4VLnN1W9wYy3kg3YW3QCLcBGAs/s1600/0004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="800" height="230" src="https://1.bp.blogspot.com/-KKoUVo-NA10/WuSs9M7kjRI/AAAAAAAACWo/kYSLDh6Oquwt1O4VLnN1W9wYy3kg3YW3QCLcBGAs/s320/0004.png" width="320" /></a></div>
<br />
<br />
I am a fan of the darker ones, but there are lighter themes if you feel like it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Z3PphHLA2qo/WuStBcwMy2I/AAAAAAAACWs/P_KH5_t364wAW3d1vXg9HMxaXL87EwxLACLcBGAs/s1600/0005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="800" height="230" src="https://4.bp.blogspot.com/-Z3PphHLA2qo/WuStBcwMy2I/AAAAAAAACWs/P_KH5_t364wAW3d1vXg9HMxaXL87EwxLACLcBGAs/s320/0005.png" width="320" /></a></div>
<br />
<br />
When using darker ones, I have changed the icon color of the Project Manager toolbar, by clicking the cog icon and choosing feather_white_16x16 and restarting CudaText.<br />
<br />
Also, I entered these in my <b>Options - Settings - user</b>:<br />
<pre>{
"pylib__linux" : "libpython3.so",
"tab_size" : 4,
"font_name__linux" : "DejaVu Sans Mono",
"font_size__linux" : 11,
"minimap_show": true,
"minimap_sel_always": true,
"minimap_sel_border": false
}
</pre>
<br />
This is some fonts, indentation and minimap stuff. You can find more settings in Options - Settings - default to find out more settings you can tweak. Just copy the entry to the user file and change the setting as you want.<br />
<br />
<h3 style="text-align: left;">
Testing and Features</h3>
<br />
If you like the ctrl+p in Sublime or ctrl+shift+p in Atom, you can press F1 to bring in the Command Palette. This lists all the commands available in menus and such.<br />
<br />
You have very much everything that you need by default. Multi caret, Multi Selection, Snippets, Project Manager - everything I miss from Sublime.<br />
<br />
If I miss something dearly, I can install the sublime plugin for that thing.<br />
<br />
<h3 style="text-align: left;">
Plugins</h3>
<br />
Which brings us to a great feature - <i>Sublime Plugins on CudaText</i>. To install such a plugin simply go to <b>Plugins - Addons Manager - Install</b>. Now you can type in some name of a plugin, for example, "find in files". Select your desired option and press enter. Within some seconds you will get a message if you are sure you want to install it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-_Zb1FdfsMOs/WuStFbuaHmI/AAAAAAAACW0/yIiE_zLX_lo10lH3nFj-NAoP8bE10TtzgCLcBGAs/s1600/0006.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="261" data-original-width="417" height="200" src="https://2.bp.blogspot.com/-_Zb1FdfsMOs/WuStFbuaHmI/AAAAAAAACW0/yIiE_zLX_lo10lH3nFj-NAoP8bE10TtzgCLcBGAs/s320/0006.png" width="320" /></a></div>
<br />
<br />
Click OK. Then it will install and show the summary in a dialog box. It may tell you to restart CudaText.<br />
<br />
When you right click on a folder on Project Manager - Selected Directory - Find in Directory it will find your text in that folder. Neat!<br />
<br />
<br />
Honestly, it is a very close alternative to Sublime. What is even better is to have a replacement made in Lazarus. If you need any further info or help, <a href="http://wiki.freepascal.org/CudaText">visit this wiki page for CudaText</a>.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com11tag:blogger.com,1999:blog-5314745381778741517.post-52171311324984350332018-01-27T20:49:00.000+00:002018-01-29T19:30:40.405+00:00How to make a Simple Video Player in Lazarus<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-UuwfJLPEzGk/Wmzh8XDtV7I/AAAAAAAACV4/YzJDuJ2tmjM98P-ObmBD1Y1rslicNKK-wCLcBGAs/s1600/vlc_video_player_thumb.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" src="https://1.bp.blogspot.com/-UuwfJLPEzGk/Wmzh8XDtV7I/AAAAAAAACV4/YzJDuJ2tmjM98P-ObmBD1Y1rslicNKK-wCLcBGAs/s1600/vlc_video_player_thumb.png" /></a></div>
We like to watch videos. How about playing videos on our own player? In this article, we are going to create a fun, simple video player.<br />
<a name='more'></a><br />
Video players always fascinate me. I used to code with my brother to create many kinds of video players. We had fun creating them. We used Visual Basic 6 back then, because it was popular back then and easy to learn. We got to design our video players how we want them and used to implement creative features that we thought was cool. Such as, video players that change color, had custom themes, ID3 tagging, audio visualizers etc. Fun times!<br />
<br />
There has been many years since I have worked on a video player. Writing this tutorial sure brings back a bit of those memories for me.<br />
<br />
There are many libraries for video playback in Lazarus. They are listed here:<br />
<a href="http://wiki.freepascal.org/Video_Playback_Libraries">http://wiki.freepascal.org/Video_Playback_Libraries</a><br />
<br />
Some of them are cross platform, some are not. From them, I found PasLibVlc to be easier and more relatable. Although it requires VLC Media Player to be installed in the system but the plus point is that you can also run your video player on any system you can install VLC on, such as, windows, mac or linux/bsd. I am writing this for Windows, but you can adopt it easily for your platform.<br />
<br />
Many of you guys requested for this tutorial with our Contact page and Facebook page. So wrote this one for you. Hope it helps!<br />
<br />
<h3 style="text-align: left;">
Step 1: Install VLC Media Player</h3>
As we are using VLC's library, we would need to have VLC player installed.<br />
Get it from here: <a href="https://www.videolan.org/vlc/">https://www.videolan.org/vlc/</a><br />
Make sure you have the latest version installed.<br />
<br />
<h3 style="text-align: left;">
Step 2: Prepare</h3>
<b>Note:</b> It is better to try it on Lazarus 32 bit, even if you are using 64 bit Windows. Things install easily on 32 bit Lazarus. I have tried with Lazarus 32 bit and it works. 64 bit might not work as expected.<br />
<br />
Go to here: <a href="https://prog.olsztyn.pl/paslibvlc/">https://prog.olsztyn.pl/paslibvlc/</a><br />
Scroll down to "<b>Change Log</b>" on that. You will find a link to a file something like: <b>PasLibVlc_x.y.z.zip</b>. Download the file and extract it to a folder named <b>PasLibVlc</b>. Copy the folder to <b>C:\lazarus\components</b> so that the contents are in the folder: <b>C:\lazarus\components\PasLibVlc</b><br />
<br />
If you go inside the folder, you will see many folders. Go to <b>FreePascal</b> folder, then double click <b>PasLibVlcPlayer.lpk</b>. It will launch Lazarus with a window titled <b>Package PasLibVlcPlayer Vx.y.z</b>.<br />
<br />
Click <b>Compile</b>. Once finished, click <b>Use - Install</b>, click <b>Yes</b>. This will rebuild and restart Lazarus.<br />
<br />
After restart, you should see a new tab in the top toolbar named <b>PasLibVlc</b>.<br />
<br />
<h3 style="text-align: left;">
Step 3: Check Sample projects (optional)</h3>
You can find very useful examples on "C:\lazarus\components\PasLibVlc\FreePascal". To try something basic, I would recommend "DemoPasLibVlc" for checking out basic playback. Just double click "DemoPasLibVlc.lpi" and Run - Run (or F9).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-cGOZ7ZYYtGI/Wmxi8u6ljLI/AAAAAAAACUo/iGouAzckmvQMi2K_IpR_B-7qkXTKw3NPgCLcBGAs/s1600/Demo-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="405" data-original-width="531" height="244" src="https://2.bp.blogspot.com/-cGOZ7ZYYtGI/Wmxi8u6ljLI/AAAAAAAACUo/iGouAzckmvQMi2K_IpR_B-7qkXTKw3NPgCLcBGAs/s320/Demo-1.png" width="320" /></a></div>
<br />
Open a file and it should play. You will notice that it is slow and not responsive. To solve this, you can run the "DemoPasLibVlc.exe" outside Lazarus, from the project directory and it should run fine.<br />
<br />
For more detailed example of what it can do, you can try "DemoPasLibVlcPlayer". Just click on the Editbox there, open a file and click play.<br />
<br />
<h3 style="text-align: left;">
Step 4: Tutorial project</h3>
Now's the fun part, creating our own!<br />
<br />
Start Lazarus.<br />
Create a new Application Project (Project->New Project->Application->OK).<br />
<br />
Resize the form a bit to make some room. Click on <b>PasLibVlc </b>tab on toolbar and draw a <b>TPasLibVlcPlayer </b>on the form. It will be named <b>PasLibVlcPlayer1 </b>by default. What a mouthfull! Change its Name property to <b>vlcPlayer</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-_vG5FrTSwlA/Wmxi1JJuHSI/AAAAAAAACUk/G2FI0Tu-oqsjBAbrzTF0piVJxbTlAc1swCLcBGAs/s1600/paslibvlc-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="560" height="219" src="https://2.bp.blogspot.com/-_vG5FrTSwlA/Wmxi1JJuHSI/AAAAAAAACUk/G2FI0Tu-oqsjBAbrzTF0piVJxbTlAc1swCLcBGAs/s320/paslibvlc-01.png" width="320" /></a></div>
<br />
<br />
Set its <b>akBottom</b>, <b>akRight </b>Anchors to <b>True</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-H-PxJ4ZW94g/WmxjKNWPTRI/AAAAAAAACUs/t1pzo_1TvTcyFOd0B08TQ8-Ms__vPoEYwCLcBGAs/s1600/paslibvlc-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="156" data-original-width="212" src="https://2.bp.blogspot.com/-H-PxJ4ZW94g/WmxjKNWPTRI/AAAAAAAACUs/t1pzo_1TvTcyFOd0B08TQ8-Ms__vPoEYwCLcBGAs/s1600/paslibvlc-02.png" /></a></div>
<br />
Switch to <b>General </b>tab. Draw a <b>TPanel</b>. Position it at the bottom. This will have our buttons and controls.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/--sl7b-VCZZA/WmxjST2x6RI/AAAAAAAACU0/YtdKyKA8-vc0iySfjrvSZzz23mhJoM3jwCLcBGAs/s1600/paslibvlc-03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="560" height="219" src="https://3.bp.blogspot.com/--sl7b-VCZZA/WmxjST2x6RI/AAAAAAAACU0/YtdKyKA8-vc0iySfjrvSZzz23mhJoM3jwCLcBGAs/s320/paslibvlc-03.png" width="320" /></a></div>
<br />
Set all the <b>Anchors </b>to <b>True </b>except <b>akTop</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-h_7YI6TfMvI/WmxjPqv9SgI/AAAAAAAACUw/3cugKboAn7UUcbAjucg7LyWaNfBcs7gnwCEwYBhgL/s1600/paslibvlc-04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="153" data-original-width="200" src="https://3.bp.blogspot.com/-h_7YI6TfMvI/WmxjPqv9SgI/AAAAAAAACUw/3cugKboAn7UUcbAjucg7LyWaNfBcs7gnwCEwYBhgL/s1600/paslibvlc-04.png" /></a></div>
<br />
Empty its <b>Caption </b>and set <b>BevelOuter </b>to <b>bvNone</b>.<br />
Go to <b>Additional </b>tab on toolbar. Draw a <b>TBitBtn</b>. You can also use TButton, but TBitBtn gives us the ability to set an icon for the button. I have collected some icons to be used in this project from aiconica.net. They should be in the project download ZIP file.<br />
<br />
Create <b>TBitBtns </b>for <b>btnPlay</b>, <b>btnPause</b>, <b>btnOpen</b>, <b>btnOpenURL</b>. Give them appropriate <b>Caption </b>and set their icons with <b>Glyph </b>property.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-P2XvpVDFcq4/Wmxjbxo8yjI/AAAAAAAACU4/gknCiQjHQ9QDxmdWC--bvwhEjnOCp0VsACLcBGAs/s1600/paslibvlc-05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="396" data-original-width="595" height="212" src="https://2.bp.blogspot.com/-P2XvpVDFcq4/Wmxjbxo8yjI/AAAAAAAACU4/gknCiQjHQ9QDxmdWC--bvwhEjnOCp0VsACLcBGAs/s320/paslibvlc-05.png" width="320" /></a></div>
<br />
Go to <b>Common Controls</b> tab, and Draw 2 <b>TTrackBars </b>on the form, big one for position and smaller one for volume.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-2LvYv2FCelY/WmxjgtZBTVI/AAAAAAAACU8/-Cdk4OMr5iYfqvQ7H0JDqOlQ1bSwqXuWACLcBGAs/s1600/paslibvlc-06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="396" data-original-width="595" height="212" src="https://2.bp.blogspot.com/-2LvYv2FCelY/WmxjgtZBTVI/AAAAAAAACU8/-Cdk4OMr5iYfqvQ7H0JDqOlQ1bSwqXuWACLcBGAs/s320/paslibvlc-06.png" width="320" /></a></div>
<br />
Name the bigger one <b>trkPosition </b>and smaller one <b>trkVolume</b>. Set <b>Max </b>for trkVolume to 200, <b>Min </b>to 1 and <b>Position </b>to 100. Set <b>TickStyle </b>for both of them to <b>tsNone</b>.<br />
<br />
For <b>trkPosition</b>, set all the <b>Anchors </b>to <b>True </b>except <b>akBottom</b>. For <b>trkVolume</b>, set <b>akBottom </b>and <b>akLeft </b>to <b>False </b>and others to <b>True</b>.<br />
<br />
Draw a <b>TLabel </b>somewhere on the form and Name it <b>lblTime</b>. This is to show the playing time.<br />
<br />
Oh! I almost forgot. Go to <b>Dialogs </b>tab and place a <b>TOpenDialog </b>on the form somewhere. (Don't worry, it will not show on the form when run.) This will help us to show the Open dialog.<br />
<br />
Now your form should look something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-xYrRLFirh0o/Wmxjl_wPI4I/AAAAAAAACVA/IDFmPrhw0cY2R8xYUK78Oi2aJrMYHRMNgCLcBGAs/s1600/paslibvlc-07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="396" data-original-width="595" height="212" src="https://3.bp.blogspot.com/-xYrRLFirh0o/Wmxjl_wPI4I/AAAAAAAACVA/IDFmPrhw0cY2R8xYUK78Oi2aJrMYHRMNgCLcBGAs/s320/paslibvlc-07.png" width="320" /></a></div>
<br />
Now, there is a draw issue when the form is maximized and restored again. So right click the <b>vlcPlayer </b>component and Choose <b>Z-Order - Move to Front</b>.<br />
<br />
Now to fun part, the coding...<br />
Double click the <b>Play </b>button and write something like:<br />
<br />
<pre class="brush:pascal">procedure TForm1.btnPlayClick(Sender: TObject);
begin
vlcPlayer.Resume();
end;</pre>
<br />
See? writing a video player is not hard after all. Play button code is just one line!<br />
<br />
Switch to Form view (F12) and double click the <b>Pause </b>button and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.btnPauseClick(Sender: TObject);
begin
vlcPlayer.Pause();
end;</pre>
<br />
Double click on <b>Open </b>button and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.btnOpenClick(Sender: TObject);
begin
if OpenDialog1.Execute then begin
vlcPlayer.Play(WideString(OpenDialog1.FileName));
Caption := OpenDialog1.FileName;
end;
end;</pre>
<br />
Double click on <b>Open URL</b> button and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.btnOpenURLClick(Sender: TObject);
var
url: string;
begin
url := InputBox('Media URL', 'Please enter media URL/MRL', '');
if url <> '' then begin
vlcPlayer.Play(WideString(url));
Caption := url;
end;
end;</pre>
<br />
We create an inputbox to get the media url from the user. We just see if the Input is empty. If not, we send it to vlcPlayer component to be played. That's it. That's all there's to it. You would be able to enjoy online streams, YouTube, online radio streams right on your video player! How cool is that!<br />
<br />
Now select the <b>vlcPlayer</b>, go to <b>Events </b>tab from <b>Object Inspector</b> (on the left). We would create an event procedure for OnMediaPlayerLengthChanged. This would set the Maximum value for the seekbar (trkPosition) and would let us seek properly. So click <b>OnMediaPlayerLengthChanged </b>(you can resize Object Inspector or the column border if you can't see the whole name). Click the <b>[...]</b> button beside it and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.vlcPlayerMediaPlayerLengthChanged(Sender: TObject; time: Int64
);
begin
trkPosition.Max := vlcPlayer.GetVideoLenInMs();
end;</pre>
<br />
Now create a similar event for <b>OnMediaPlayerTimeChanged </b>and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.vlcPlayerMediaPlayerTimeChanged(Sender: TObject; time: Int64);
begin
if trkPosition.Tag = 0 then // not dragging with mouse
trkPosition.Position := vlcPlayer.GetVideoPosInMs();
lblTime.Caption:=vlcPlayer.GetVideoPosStr('hh:mm:ss');
end;</pre>
<br />
This will change the position to show how much the media has played on the seekbar when it plays. We are checking "trkPosition.Tag" with "if trkPosition.Tag = 0 then". We would make trkPosition.Tag to 1 when the user is dragging trkPosition. Because we don't want the position to change while the user is seeking the position bar.<br />
<br />
We could've used a variable for this, but trkPosition.Tag is convenient, so we can use it here. trkPosition.Tag can only have integer values, so we would set it to either 0 or 1.<br />
<br />
To make it work let's set the Tag correctly. Select <b>trkPosition </b>and create an <b>OnMouseDown </b>event and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.trkPositionMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
trkPosition.Tag := 1;
end;</pre>
<br />
Then create an <b>OnMouseUp </b>event and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.trkPositionMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
vlcPlayer.SetVideoPosInMs(trkPosition.Position);
trkPosition.Tag := 0;
end;</pre>
<br />
This should set the Tag correctly and manage the seeking (dragging the position).<br />
<br />
Select <b>trkVolume </b>and create an <b>OnChange </b>event, then enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.trkVolumeChange(Sender: TObject);
begin
vlcPlayer.SetAudioVolume(trkVolume.Position);
end;</pre>
<br />
And... you are done! Now hit Run - Run (or press F9).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-nNCvvSuqPzc/WmzY4F2g6GI/AAAAAAAACVg/CMfS6gPjDkwVPdiQnx6TvTs5nwYbne8XwCLcBGAs/s1600/lazplanet-video-player-lazarus-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Video Player made in Lazarus with PasLibVLC (preview)" border="0" data-original-height="396" data-original-width="595" height="212" src="https://1.bp.blogspot.com/-nNCvvSuqPzc/WmzY4F2g6GI/AAAAAAAACVg/CMfS6gPjDkwVPdiQnx6TvTs5nwYbne8XwCLcBGAs/s320/lazplanet-video-player-lazarus-1.png" title="Video Player made in Lazarus with PasLibVLC (preview)" width="320" /></a></div>
<br />
You can hit Open to open a media from your hard disk, or click Open URL button to open any stream URL to play in the player. For example, click Open URL and enter <b>https://www.youtube.com/watch?v=YE7VzlLtp-4</b> and it should play it for you! Awesome!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-GQul9SeurGs/WmzZ17N5PvI/AAAAAAAACVo/yMsiTEU1rUMNYo7oQzGhN9Z_h1QuP7xngCLcBGAs/s1600/lazplanet-video-player-lazarus-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="396" data-original-width="595" height="212" src="https://4.bp.blogspot.com/-GQul9SeurGs/WmzZ17N5PvI/AAAAAAAACVo/yMsiTEU1rUMNYo7oQzGhN9Z_h1QuP7xngCLcBGAs/s320/lazplanet-video-player-lazarus-2.png" width="320" /></a></div>
<br />
You can do all sorts of stuff with it. You can also research on the player component. This is just a basic for this component. There are lots of other useful features. Maybe it can simplify your daily tasks somehow, who knows!<br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://www.dropbox.com/s/c4w0c9vnetwktcy/vlc_video_player.zip?dl=0">here</a>.<br />
Or <a href="https://drive.google.com/uc?export=download&id=1yufROefQsbAXVjwAK9F0xvGJSBB4dmdz">here</a>.<br />
Size: 630KB<br />
The package contains compiled executable EXE file.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com17tag:blogger.com,1999:blog-5314745381778741517.post-38842054001099206162017-12-16T15:58:00.002+00:002017-12-16T15:58:53.082+00:00Lazarus 1.8 Released - With New Icons and High DPI Support<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="122" ilo-full-src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" src="https://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" width="162" /></a></div>
Lazarus 1.8 has been released. It is the first version with FPC 3.0.4. It has many visible and under the hood changes.<br />
<a name='more'></a><br />
As a fan it seems this version took the longest to release! Another stable version of the Lazarus of version 1.8, with FPC 3.0.4 has been announced on 7 December 2017. Some major changes include:<br />
<br />
<ul style="text-align: left;">
<li>Qt5 based new widgetset</li>
<li>High DPI option for LCL components</li>
<li>TToolButton to use arrows beside buttons</li>
<li>Some Clipboard and Menu improvements</li>
<li><a href="http://wiki.lazarus.freepascal.org/Lazarus_1.8.0_release_notes">and many more...</a></li>
</ul>
<br />
The look has been changed slightly. The toolbar button icons have changed.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-38rFTPeQhzY/WjU-uKmaHeI/AAAAAAAACTw/vMqEUloQgqA_z2NE_H7dPxTXbS-QgsluACLcBGAs/s1600/Lazarus-1.8-on-windows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="756" data-original-width="1278" height="189" src="https://1.bp.blogspot.com/-38rFTPeQhzY/WjU-uKmaHeI/AAAAAAAACTw/vMqEUloQgqA_z2NE_H7dPxTXbS-QgsluACLcBGAs/s320/Lazarus-1.8-on-windows.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Menu icons as well. It certainly looks more professional than before...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-s6m0aAEqAgY/WjVA-2mbzVI/AAAAAAAACT8/v9DBUQHvflAsdnplpyf4_azTWNXPzoZFgCLcBGAs/s1600/lazarus-1.8-run-menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="622" data-original-width="288" height="320" src="https://4.bp.blogspot.com/-s6m0aAEqAgY/WjVA-2mbzVI/AAAAAAAACT8/v9DBUQHvflAsdnplpyf4_azTWNXPzoZFgCLcBGAs/s320/lazarus-1.8-run-menu.png" width="148" /></a></div>
<br />
Also, I notice that the previous { public declarations } and { private declarations } are no more. That's a serious change for beginners, but I think professionals will like it.<br />
<br />
I'm sure there are many more changes out there. Feel free to explore!<br />
<br />
At the end, a thousand thanks to the Lazarus Developers for their hard work in this valuable project.<br />
<br />
<h3 style="text-align: left;">
What's New</h3>
The changes are <a href="http://wiki.lazarus.freepascal.org/Lazarus_1.8.0_release_notes">listed here</a> and <a href="http://wiki.freepascal.org/Lazarus_1.8_fixes_branch#Fixes_for_1.8.0_.28merged.29">here</a>.<br />
<br />
<h3 style="text-align: left;">
Download</h3>
The release is available for download at SourceForge:<br />
<a href="https://sourceforge.net/projects/lazarus/files/">https://sourceforge.net/projects/lazarus/files/</a><br />
<br />
Choose your CPU, OS, distro and then the "Lazarus 1.8" directory.<br />
<br />
Or from the homepage: <a href="http://www.lazarus-ide.org/index.php?page=downloads">http://www.lazarus-ide.org/index.php?page=downloads</a><br />
<br />
<br />
<b>Minimum requirements:</b><br />
Windows:<br />
2k, XP, Vista, 7, 8, 8.1 and 10, 32 or 64bit.<br />
optional qt 4.5 or 5.6 for qt apps<br />
<br />
FreeBSD/Linux:<br />
gtk 2.8 for gtk2, qt4.5 for qt, qt5.6 for qt5, 32 or 64bit.<br />
<br />
Mac OS X:<br />
10.5 to 10.12; Carbon (32bit), Cocoa (64bit, not stable), qt and qt5 (32 or 64bit).<br />
<br />
<h3 style="text-align: left;">
Alternate Download</h3>
For people who are blocked by SF, the Lazarus releases from SourceForge are mirrored at:<br />
<a href="ftp://ftp.freepascal.org/pub/lazarus/releases/">ftp://ftp.freepascal.org/pub/lazarus/releases/</a><br />
and later at (after some time for synchronization)<br />
<a href="http://mirrors.iwi.me/lazarus/">http://mirrors.iwi.me/lazarus/</a><br />
<br />
<h3 style="text-align: left;">
How-to-Install Guide</h3>
<br />
You can <a href="http://lazplanet.blogspot.com/2013/03/how-to-install-lazarus.html">click here for an installation guide</a> for all Operating Systems.<br />
If you are an Ubuntu user then also see <a href="http://lazplanet.blogspot.com/2013/05/how-to-install-lazarus-108-on-ubuntu.html">this post for an exclusive guide for installing Lazarus 1.0.10 in Ubuntu 13.04</a> (you can follow the same guide to install in previous or latest versions of Ubuntu, such as 12.04 LTS, 12.10, 13.10, 14.04 LTS, 16.04 LTS etc. or any other debian based OS).<br />
<br />
<h3 style="text-align: left;">
Source</h3>
<a href="http://forum.lazarus.freepascal.org/index.php/topic,39210.0.html">Lazarus Forum Announcement Post</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com0tag:blogger.com,1999:blog-5314745381778741517.post-12340018803018762362017-12-15T17:33:00.002+00:002017-12-15T20:12:56.016+00:00Supercharge Your Beginner Friends with this E-Book!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-IK4eeb3bRV4/WjQDuQExjsI/AAAAAAAACTY/JKBbld5UPCYMprFaJzptlp7g5aFjc2Z4gCLcBGAs/s1600/e-book-cover-thumb.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="200" height="150" src="https://1.bp.blogspot.com/-IK4eeb3bRV4/WjQDuQExjsI/AAAAAAAACTY/JKBbld5UPCYMprFaJzptlp7g5aFjc2Z4gCLcBGAs/s200/e-book-cover-thumb.png" width="200" /></a></div>
Many have the will to start learning Lazarus, but could not find an easy way to start. This e-book will give them the fuel to get started.<br />
<a name='more'></a><br />
<br />
Happy Holidays! What a joyful time of the year to get an e-book!<br />
<br />
I have written an e-book for beginners in Lazarus. This is great for people who want the very basics of programming and just wants to start somewhere. This free e-book is very short, concise and organized in such a way that anyone with a least effort can follow along, have fun and start coding in Lazarus.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-phQH8NW76mw/WjQCZVZdvUI/AAAAAAAACTI/nmnkGvC7F0QCz1wZz9tcWzNck2iu0-B3wCLcBGAs/s1600/lazarus-ebook-preview.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Lazarus E-book - Beginners' Guide to Lazarus IDE" border="0" data-original-height="554" data-original-width="801" height="221" src="https://3.bp.blogspot.com/-phQH8NW76mw/WjQCZVZdvUI/AAAAAAAACTI/nmnkGvC7F0QCz1wZz9tcWzNck2iu0-B3wCLcBGAs/s320/lazarus-ebook-preview.png" title="Lazarus E-book - Beginners' Guide to Lazarus IDE" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The pages are colorful so that it is fun to read and engaging</td></tr>
</tbody></table>
<br />
<h3 style="text-align: left;">
The chapters in the book</h3>
1: What is Lazarus?<br />
2: How to Install<br />
3: How to Create Your First Program<br />
4: How to Position Stuff on a Form<br />
5: How to Customize your<br />
6: How to use Events<br />
7: How to Save your Project<br />
8: How to Extend Code with Custom Functions and Variables<br />
9: Sharing Your Project<br />
10: Compiling and Sharing Your Executable<br />
<br />
The chapters are so short and so basic that anyone should be able to enjoy the journey towards the end.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-V1pVniZGTEo/WjQEkSsXCjI/AAAAAAAACTg/o6OfxOaV6WcVPA5Ef1nXDE8IHBTddjKTQCLcBGAs/s1600/lazarus-e-book-cover.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="531" data-original-width="373" height="320" src="https://3.bp.blogspot.com/-V1pVniZGTEo/WjQEkSsXCjI/AAAAAAAACTg/o6OfxOaV6WcVPA5Ef1nXDE8IHBTddjKTQCLcBGAs/s320/lazarus-e-book-cover.jpg" width="224" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cover of the E-book. Let's charge towards LazPlanet!</td></tr>
</tbody></table>
<br />
Another great thing is that this e-book is totally open source, licensed as CC BY 4.0. You can get the source files for the book here: <a href="https://github.com/adnan360/lazarus-beginners-guide">https://github.com/adnan360/lazarus-beginners-guide</a> . Everything from fonts to graphics, you can edit everything and you can release your own version of the e-book if you want. You can use this in commercial purpose as well.<br />
<br />
Since this is holiday season, sharing this as a virtual gift to your friends and close ones would be a great idea.<br />
<br />
<h3 style="text-align: left;">
Get it from here</h3>
<div>
<a href="https://github.com/adnan360/lazarus-beginners-guide/releases/download/v1.0.0/lazarus-beginners-guide.pdf">Download PDF</a></div>
<a href="https://github.com/adnan360/lazarus-beginners-guide/releases/download/v1.0.0/lazarus-beginners-guide.xhtml">Download in XHTML</a><br />
<a href="https://github.com/adnan360/lazarus-beginners-guide/releases">Releases page</a> - will have any future releases<br />
<br />
This is the first release of this book.<br />
<br />
Good luck on your journey to LazPlanet!<br />
<br />
<br /></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com3tag:blogger.com,1999:blog-5314745381778741517.post-66531580646895421872017-05-20T19:00:00.002+01:002017-05-20T19:00:39.423+01:00Make a simple Image Zoomer in 5 minutes!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Lw6u5APfQeM/WSCED-hSQoI/AAAAAAAACOo/JcDfz7cZDVczgoPgFF-DLc2kpron8IRCQCLcB/s1600/image-zoomer-in-lazarus.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="https://4.bp.blogspot.com/-Lw6u5APfQeM/WSCED-hSQoI/AAAAAAAACOo/JcDfz7cZDVczgoPgFF-DLc2kpron8IRCQCLcB/s200/image-zoomer-in-lazarus.gif" width="200" /></a></div>
Zooming is kind of fun! Here is a 5 minute image zoom tutorial with mouse scroll fun!<br />
<a name='more'></a><br />
We have 2 nifty events named <b>OnMouseWheelUp </b>and <b>OnMouseWheelDown </b>to tell when the user scrolled his mouse wheel.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-o8lpf99D6aI/WSCCuoclZVI/AAAAAAAACOc/BuHSeTnGRb4BLMydz_lUh6LaHllP7m98wCLcB/s1600/mouse-3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-o8lpf99D6aI/WSCCuoclZVI/AAAAAAAACOc/BuHSeTnGRb4BLMydz_lUh6LaHllP7m98wCLcB/s1600/mouse-3.gif" /></a></div>
<br />
Zooming is basically stretching the image to place it in a bigger area than the original. then the image looks bigger. We can use <b>StretchDraw </b>for this.<br />
<br />
We can combine these 2 and you will be seeing a result before you know it!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-LV7yqNhUHoU/WSCC8MRhJsI/AAAAAAAACOg/nEo0M-SrDW0Ne1cb4VD-MTd0Ac0bFXxLgCLcB/s1600/mouse-on-wheel.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-LV7yqNhUHoU/WSCC8MRhJsI/AAAAAAAACOg/nEo0M-SrDW0Ne1cb4VD-MTd0Ac0bFXxLgCLcB/s320/mouse-on-wheel.jpg" width="278" /></a></div>
<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
<br />
Start <a href="http://www.lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Application Project (Project->New Project->Application->OK).<br />
<br />
Draw a TImage (from Additional tab). Set a picture of your choice as its Picture property.<br />
<br />
Draw a TScrollBar. Set its HorzScrollbar->Tracking and VertScrollbar->Tracking property to True.<br />
<br />
<br />
<br />
<br />
Draw a TPaintbox inside the TScrollbox (start drawing from inside the TScrollbox to achieve this). Place it in the most top left position (or set Top to 0, Left to 0).<br />
<br />
<br />
<br />
<br />
Now switch to F12 to go to Code View. Add the following line just under the line TForm1 = class(TForm).<br />
procedure DrawImage;<br />
<br />
Put your cursor on the line and press Ctrl+Shift+C. This should elaborate the procedure automatically for you to write something in it. Write something like this:<br />
<br />
procedure TForm1.DrawImage;<br />
var<br />
ImageRect: TRect;<br />
begin<br />
ImageRect := Rect(0,0,(Image1.Picture.Width * ScaleFactor), (Image1.Picture.Height * ScaleFactor) );<br />
PaintBox1.Width := ImageRect.Right;<br />
PaintBox1.Height := ImageRect.Bottom;<br />
PaintBox1.Canvas.StretchDraw(ImageRect, image1.Picture.Bitmap);<br />
end;<br />
<br />
Just under the <b>Form1: TForm1;</b> line, insert this code:<br />
<br />
ScaleFactor:integer;<br />
<br />
Now switch to Form View (F12). Double click the form and enter:<br />
<br />
procedure TForm1.FormCreate(Sender: TObject);<br />
begin<br />
ScaleFactor:=1;<br />
end;<br />
<br />
We will set the default ScaleFactor to 1 to show the image as is at first when it loads. Then we manipulate the value to enlarge the image.<br />
<br />
Now go to Form View (F12). Select the TPaintBox. Go to Events and click the [...] button next to ScrollWheelDown and enter:<br />
<br />
procedure TForm1.ScrollBox1MouseWheelDown(Sender: TObject; Shift: TShiftState;<br />
MousePos: TPoint; var Handled: Boolean);<br />
begin<br />
// we don't want it to be less than 1<br />
if ScaleFactor > 1 then begin<br />
ScaleFactor:=ScaleFactor-1;<br />
DrawImage;<br />
end;<br />
end;<br />
<br />
Now again Go to Events and click the [...] button next to ScrollWheelUp and enter:<br />
<br />
procedure TForm1.ScrollBox1MouseWheelUp(Sender: TObject; Shift: TShiftState;<br />
MousePos: TPoint; var Handled: Boolean);<br />
begin<br />
// we allow 50 times zoom!<br />
if ScaleFactor < 50 then begin<br />
ScaleFactor:=ScaleFactor+1;<br />
DrawImage;<br />
end;<br />
end;<br />
<br />
These two above will control the mouse wheel scroll events. When the Wheel will scroll up it will zoom in and zoom out when scrolling down.<br />
<br />
Lastly, select PaintBox1, go to Events once again. Click the [...] button next to OnPaint. Now enter:<br />
<br />
procedure TForm1.PaintBox1Paint(Sender: TObject);<br />
begin<br />
DrawImage;<br />
end;<br />
<br />
This simple code will update the image when it is needed. Especially when it needs redraw (resize the window, minimize/restore, hide/show the window etc.)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h4 style="text-align: left;">
Run it!</h4>
Now run the project (F9 or Run->Run).<br />
<br />
This would show your shiny new form on your screen ready to be played with.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-rNr7p6GyXHc/WSB9agP9ZDI/AAAAAAAACOM/1XfjiFbdAGExOk-S7oLRIxezCX5SybySACLcB/s1600/zoom-final.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Image zoom in zoom out made with Lazarus in 5 minutes!" border="0" height="210" src="https://2.bp.blogspot.com/-rNr7p6GyXHc/WSB9agP9ZDI/AAAAAAAACOM/1XfjiFbdAGExOk-S7oLRIxezCX5SybySACLcB/s320/zoom-final.gif" title="Image zoom in zoom out made with Lazarus in 5 minutes!" width="320" /></a></div>
<br />
This is just a quick example of how to use mouse scroll and image stretching in simple code. You can enhance it if you like.<br />
<br />
Thanks to Achmad Davit for requesting this. <br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://www.dropbox.com/s/n1q2fg2udfwbso3/ImageScrollZoom.zip?dl=0">here</a>.<br />
Or <a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSdmVxVDRtalp4SWM">here</a>.<br />
Size: 566KB<br />
The package contains compiled executable EXE file.<br />
<br />
<br />
Ref:<br />
<a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TCanvas_StretchDraw.html">http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TCanvas_StretchDraw.html</a><br />
<a href="http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Using_the_non-native_StretchDraw_from_LazCanvas">http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Using_the_non-native_StretchDraw_from_LazCanvas</a><br />
<br />
<br /></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com1tag:blogger.com,1999:blog-5314745381778741517.post-66421783165312390492016-06-22T08:59:00.001+01:002016-06-22T12:00:08.778+01:00How to detect Mouse Events outside your Form<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-gsJz7ZAOnvw/V2pCz2rsY-I/AAAAAAAACL0/sXoX5Es1f3owyOrS9Q32OF4dJzcFg7OgACLcB/s1600/Systemwide-Mouse-events-thumb.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Form design for Systemwide mouse event capture in Free Pascal, Lazarus" border="0" height="150" src="https://3.bp.blogspot.com/-gsJz7ZAOnvw/V2pCz2rsY-I/AAAAAAAACL0/sXoX5Es1f3owyOrS9Q32OF4dJzcFg7OgACLcB/s200/Systemwide-Mouse-events-thumb.gif" title="Form design for Systemwide mouse event capture in Free Pascal, Lazarus" width="200" /></a></div>
In this article we find out what the user is doing with his mouse, even outside of the program. Let's conquer the whole system!<br />
<a name='more'></a><br />
<br />
We have events on components, such as OnClick, OnMouseDown, OnScrollDown etc. But unfortunately these events only work when the mouse is inside the form. But sometimes we need to get a view of what the user is doing on other programs or other windows (or in other words "System-wide"). These "System wide" events can be "caught" through a crazy thing called "hooks".<br />
<br />
A Hook is a function that you can tell Windows to run whenever something special happens. You can create a hook for keyboard to run it whenever a key is pressed. Then you can do something based on which key is pressed (in whichever window it is pressed). Today we are going to focus on mouse events. We will catch what the mouse is doing system wide. Wherever the mouse goes, we catch what the user is doing with it.<br />
<br />
<h4 style="text-align: left;">
What we'll do</h4>
We will catch when the left, middle and right mouse button is pressed, and additionally when the mouse wheel is scrolled up or down. These things are especially useful in cases like, to create such a program which can record a macro and repeat those tasks later, or create mouse gestures on touching the corner of the screen (like in Gnome 3), or maybe creating a form which acts like a menu so when the user clicks outside it closes... the possibilities are endless.<br />
<br />
<br />
<h4>
<div style="text-align: left;">
Any DLL need to be made? </div>
</h4>
Nope.<br />
Some Delphi/Pascal codes found on the internet demand to create a DLL file. DLL files are a mess and don't forget the <a href="https://en.wikipedia.org/wiki/DLL_Hell">DLL hell</a>. In this article, the whole code is Lazarus based and resides in the single .exe file with no DLL involved. Cool, right!<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
Start <a href="http://lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Application Project (Project->New Project->Application->OK).<br />
<br />
Draw a <b>TLabel </b>and a <b>TMemo</b>. Empty the <b>Lines </b>property and set the <b>Scrollbars </b>property to <b>ssVertical </b>of the Memo. Customize the form the way you like it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-AuWtyHrmwpQ/V2o-euc_RcI/AAAAAAAACLc/ThleEkOcQTU-PAuraT8RteSUuLr3p32aQCLcB/s1600/Systemwide-Mouse-events-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Form design for Systemwide mouse event capture in Free Pascal, Lazarus" border="0" height="264" src="https://4.bp.blogspot.com/-AuWtyHrmwpQ/V2o-euc_RcI/AAAAAAAACLc/ThleEkOcQTU-PAuraT8RteSUuLr3p32aQCLcB/s320/Systemwide-Mouse-events-1.gif" title="Form design for Systemwide mouse event capture in Free Pascal, Lazarus" width="320" /></a></div>
<br />
<br />
Optionally, you can set the <b>FormStyle </b>to <b>fsSystemStayOnTop</b>. It will <a href="https://lazplanet.blogspot.com/2014/01/always-on-top-lazarus-form.html">keep the form always on top</a> and let you see the events even when you click outside of the form.<br />
<br />
Switch to code view (F12). Now add "windows" unit to uses:<br />
<br />
<pre class="brush:pascal">uses
..., ..., windows;</pre>
<br />
Under the type clause enter this:<br />
<br />
<pre class="brush:pascal">type
...
...
MouseLLHookStruct = record
pt : TPoint;
mouseData : cardinal;
flags : cardinal;
time : cardinal;
dwExtraInfo : cardinal;
end;</pre>
<br />
Before the var clause enter:<br />
<br />
<pre class="brush:pascal">...
...
function LowLevelMouseHookProc(nCode, wParam, lParam : integer) : integer; stdcall;
var</pre>
<pre class="brush:pascal">...</pre>
<pre class="brush:pascal">... </pre>
<br />
This function will be our hook function. Windows will run it whenever there is a mouse event.<br />
<br />
Under the var clause declare a variable:<br />
<br />
<pre class="brush:pascal">var
...
...
mHook : cardinal;</pre>
<br />
Now we enter code for our hook function. Under the implementation clause enter: <br />
<br />
<pre class="brush:pascal">function LowLevelMouseHookProc(nCode, wParam, lParam : integer) : integer; stdcall;
// possible wParam values: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP
var
info : ^MouseLLHookStruct absolute lParam;
begin
result := CallNextHookEx(mHook, nCode, wParam, lParam);
with info^ do begin
Form1.Label1.Caption := 'X: '+IntToStr(pt.x)+' Y: '+ IntToStr(pt.y);
case wParam of
wm_lbuttondown : Form1.Memo1.Lines.Append(format('pressed left button (%d, %d)' , [pt.x, pt.y]));
wm_lbuttonup : Form1.Memo1.Lines.Append(format('released left button (%d, %d)' , [pt.x, pt.y]));
wm_mbuttondown : Form1.Memo1.Lines.Append(format('pressed middle button (%d, %d)' , [pt.x, pt.y]));
wm_mbuttonup : Form1.Memo1.Lines.Append(format('released middle button (%d, %d)' , [pt.x, pt.y]));
wm_rbuttondown : Form1.Memo1.Lines.Append(format('pressed right button (%d, %d)' , [pt.x, pt.y]));
wm_rbuttonup : Form1.Memo1.Lines.Append(format('released right button (%d, %d)' , [pt.x, pt.y]));
wm_mousewheel : begin
if smallInt(mouseData shr 16) > 0
then Form1.Memo1.Lines.Append('scrolled wheel (up)')
else Form1.Memo1.Lines.Append('scrolled wheel (down)');
end;
end;
end;
end;</pre>
<br />
Switch to Form view (F12), then double click on the form, and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormCreate(Sender: TObject);
const
WH_MOUSE_LL = 14;
begin
mHook := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseHookProc, hInstance, 0);
end;</pre>
<br />
Switch to form view again (F12), then select the form, go to Object Inspector -> Events, then click OnDestroy, then click the [...] button beside it. Now enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormDestroy(Sender: TObject);
begin
UnhookWindowsHookEx(mHook);
end;</pre>
<br />
Now run the project (F9 or Run -> Run).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-Asvs1QZJznc/V2o-oITMsiI/AAAAAAAACLk/Vj9hJd3Q85At4KTW1-1gzPw9TS3C4NEwgCLcB/s1600/Systemwide-Mouse-events-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Systemwide mouse event capture in Free Pascal, Lazarus" border="0" height="264" src="https://2.bp.blogspot.com/-Asvs1QZJznc/V2o-oITMsiI/AAAAAAAACLk/Vj9hJd3Q85At4KTW1-1gzPw9TS3C4NEwgCLcB/s320/Systemwide-Mouse-events-2.gif" title="Systemwide mouse event capture in Free Pascal, Lazarus" width="320" /></a></div>
<br />
Now, when you use this code on your project you will need to customize the LowLevelMouseHookProc() function to suit your needs. Try things yourself. The sky is the limit here!<br />
<br />
...And for the mouse position, it is better to <a href="https://lazplanet.blogspot.com/2013/04/mouse-cursor-position-get-set.html">use the Mouse.CursorPos.x or .y</a> because the solution in this article sometimes begets negative values, which might not be what you would like. The code is kept just to show how it is done in the hooks style.<br />
<br />
<div class="brush:pascal" style="text-align: left;">
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/VSs3JIJ9">here</a>.<br />
Or <a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSYlgtWGRIQmdrcjQ">here</a>.<br />
Size: 561KB<br />
The package contains compiled executable EXE file.<br />
<br />
Ref:<br />
<a href="https://www.experts-exchange.com/questions/21838717/Delphi-detect-a-left-right-mouse-click-anywhere-on-the-screen.html">https://www.experts-exchange.com/questions/21838717/Delphi-detect-a-left-right-mouse-click-anywhere-on-the-screen.html</a> - thanks to ZhaawZ, his answer helped greatly</div>
</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com6tag:blogger.com,1999:blog-5314745381778741517.post-90938104286300142202016-04-25T09:11:00.001+01:002016-04-25T09:15:24.262+01:00How to Make a Text Scroller Animation<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-4ljmRIV9M3I/Vx3P2RMRumI/AAAAAAAACHI/sAs4XGbprUoAr0CuCl936I7B_hxaO5xOACLcB/s1600/text-scroller-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="https://3.bp.blogspot.com/-4ljmRIV9M3I/Vx3P2RMRumI/AAAAAAAACHI/sAs4XGbprUoAr0CuCl936I7B_hxaO5xOACLcB/s200/text-scroller-thumb.jpg" width="200" /></a></div>
At the end of a movie or in our application, we could use some text scrolling fun! But how to do that? Let's see...<br />
<a name='more'></a><br />
The text scroller in the Lazarus About dialog box made me think of the days when I used to code text scrollers all day in VB6! Component based, owner drawn, timer based, loop based and all that stuff! Inspired and fired up I was hitting keystrokes and writing this article at the middle of the night.<br />
<br />
So yeah!<br />
Let's scroll some text!<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
<br />
Start <a href="http://www.lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Application project (Project->New Project->Application->OK).<br />
<br />
Draw a TPanel. Make it a bit big to fit in the form... as you wish!<br />
<br />
Inside that TPanel draw a TLabel. (To make sure it is created inside the TPanel, start the drawing from inside the area of the TPanel. Or if you misplaced it, just Cut the TLabel, right click the TPanel and click Paste.)<br />
<br />
With the TLabel selected, click the [...] button beside the "Anchor" property and go to "Left anchoring" part of the window. Select the Panel1 that you just created as the Sibling. Then on the bottom of the drop down you will see 3 buttons. Click the button in the right side (that says "Center control horizontally..." when you move your mouse over it).<br />
<br />
This will center the Label, based on Panel1. This will keep its center position even if you resize the Panel, so it will be a piece of cake to move around and play with it later on! Sweet!<br />
<br />
Now, with the Label still selected, change the "Alignment" (not "Align") property to taCenter. Now edit the Caption property value to any text you desire, but try to make it long and remember that you can enter new lines!<br />
<br />
Now our form should look something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-WOiprTuMGWE/Vx3M5sTHXMI/AAAAAAAACGw/MIR15kss4v0Ry24850rxGQIJ-Na1BQMvgCLcB/s1600/Text-scroller-form-design-lazarus-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://4.bp.blogspot.com/-WOiprTuMGWE/Vx3M5sTHXMI/AAAAAAAACGw/MIR15kss4v0Ry24850rxGQIJ-Na1BQMvgCLcB/s320/Text-scroller-form-design-lazarus-1.gif" width="320" /></a></div>
<br />
<br />
Now our items are almost ready! Now drop a TTimer (from "System" tab). Set its Interval as 60 (or any value to control the speed). Double click, and enter the code:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Timer1Timer(Sender: TObject);
begin
if label1.BoundsRect.Bottom <= 0 then begin //reset position
Label1.Top := Panel1.Height;
end else begin // scroooolll!
Label1.Top := Label1.Top - 1;
end;
end;
</pre>
<br />
<br />
You can change the 1 in the code "Label1.Top - 1". It will increase the speed, but it is entirely up to you.<br />
<br />
We used "label1.BoundsRect.Bottom" because it is simpler to look at! If you want to avoid it, you can write it like this:<br />
<pre class="brush:pascal"> if label1.Top + label1.Height <= 0 then begin
//...
</pre>
<br />
Or may be like this:<br />
<pre class="brush:pascal"> if label1.Top <= -(label1.Height) then begin
//...
</pre>
<br />
Now move the label a bit to the bottom so that it appears to be rising from the bottom. My form layout now looks something like this...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-gOyUmlez46k/Vx3NHE_ibmI/AAAAAAAACG0/0W48nlFJ0HMKqcbXjq8YEdnhKl4jgWdXQCLcB/s1600/Text-scroller-form-design-lazarus-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://1.bp.blogspot.com/-gOyUmlez46k/Vx3NHE_ibmI/AAAAAAAACG0/0W48nlFJ0HMKqcbXjq8YEdnhKl4jgWdXQCLcB/s320/Text-scroller-form-design-lazarus-2.gif" width="320" /></a></div>
<br />
<br />
Now Run the Project (F9 or Run -> Run).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-TBU6Nqv15pI/Vx3NM9KnhLI/AAAAAAAACG4/2DQko71S1VMA3vp4S0UQ1WWy8mbjqwOsgCLcB/s1600/Text-scroller-lazarus-simple-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://1.bp.blogspot.com/-TBU6Nqv15pI/Vx3NM9KnhLI/AAAAAAAACG4/2DQko71S1VMA3vp4S0UQ1WWy8mbjqwOsgCLcB/s320/Text-scroller-lazarus-simple-1.gif" width="320" /></a></div>
<br />
<br />
Now you'll have a scrolling text on your screen! Voila!<br />
<br />
<br />
<h3 style="text-align: left;">
Horizontal Text Scrolling</h3>
<br />
Same way you can make a horizontal scroller. Just change the "Anchors" property accordingly (Top anchoring, Sibling, Center control vertically...). Then change the code, like this:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Timer1Timer(Sender: TObject);
begin
if label1.BoundsRect.Right <= 0 then begin
Label1.Left := Panel1.Width;
end else begin
Label1.Left := Label1.Left - 1;
end;
end;</pre>
<div class="brush:pascal" style="text-align: left;">
<br /></div>
<div class="brush:pascal" style="text-align: left;">
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/DEgWwwBm">here</a>.<br />
Or <a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSeVlDX3NHZFhDWXc">here</a>.<br />
Size: 598KB<br />
The package contains compiled executable EXE file.</div>
</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com2tag:blogger.com,1999:blog-5314745381778741517.post-16722615234301237212015-09-16T00:54:00.000+01:002015-09-16T00:54:57.370+01:00Create a web browser in 3 minutes using Chromium engine! (fpCEF3)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-gl8Pmsbzh8Q/VfiqH3YFmjI/AAAAAAAACEk/HFKlTuavuPk/s1600/thumb-lazarus-chrome-webbrowser-1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-gl8Pmsbzh8Q/VfiqH3YFmjI/AAAAAAAACEk/HFKlTuavuPk/s1600/thumb-lazarus-chrome-webbrowser-1.jpg" /></a></div>
We'll learn how to create a web browser even quicker than you can install one! All using the people's favorite chromium engine!<br />
<a name='more'></a><br />
Well, we had a popular post on LazPlanet about <a href="http://lazplanet.blogspot.com/2013/10/browser-in-lazarus-with-gecko-pt1.html">creating a web browser using the GeckoPort v1</a>. That was a great way to create a browser and I love Gecko because it is the darling of open source! But it was an old version of Gecko and the newer version does not seem to work.<br />
<br />
So, today, we have a solution for a browser made with a more updated engine. It will harness the pure goodness of the <a href="https://bitbucket.org/chromiumembedded/cef">Chromium Embedded Framework (CEF)</a> and <a href="http://wiki.freepascal.org/fpCEF3">its implementation on Free Pascal, named fpCEF3</a>. <br />
<br />
Although Chrome <a href="http://www.forbes.com/sites/anthonykosner/2012/08/02/googles-new-chrome-browser-can-take-over-your-webcam-should-you-be-scared/">has done</a> <a href="http://www.dailymail.co.uk/sciencetech/article-2544539/Is-Chrome-spying-YOU-Cyber-criminals-use-Google-browsers-voice-recognition-software-listen-conversations.html">things</a> that <a href="https://www.privateinternetaccess.com/blog/2015/06/google-chrome-listening-in-to-your-room-shows-the-importance-of-privacy-defense-in-depth/">truly-privacy-minded people don't like</a>. But it is a fast web browser engine that is increasingly becoming popular. We all know that <a href="http://readwrite.com/2013/02/13/browser-maker-opera-ditches-presto-in-favor-of-webkit#!">Opera ditched its own-coded engine "Presto"</a> and <a href="http://webscripts.softpedia.com/blog/Opera-Will-Use-Google-s-Blink-Not-WebKit-Like-It-Announced-Initially-342806.shtml">started using "Blink"</a>, a variant of the Chromium engine, as their focused engine. <a href="https://en.wikipedia.org/wiki/Usage_share_of_web_browsers#Summary_tables">Google Chrome also has a good bite in browser market share</a>. Chrome is also running in the <a href="https://en.wikipedia.org/wiki/ChromeBook">Chromebooks</a> pioneered by Google. So, we can say that Chromium has done something right and we're going to learn to build a browser out of that goodness.<br />
<br />
<a href="https://github.com/dliw/fpCEF3">FpCEF3</a> is a great project that we should all adore. It will let us use the Chromium engine right in our Lazarus project. And it is possible to use it in Windows, Linux and Mac OS platforms. But in this article, we are using Windows. (You can adopt this tutorial for the other platforms quite easily if you know your way around.)<br />
<br />
So without further ado, let's make this browser...<br />
<br />
<br />
<h3 style="text-align: left;">
Download & Install fpCEF3</h3>
1. First of all, we need to download fpCEF3. You can <a href="https://github.com/dliw/fpCEF3/releases">download revision 23 (or version 3.1750)</a> from <a href="https://github.com/dliw/fpCEF3/archive/v3.1750.zip">here</a> . (I have used the revision no 23 which is very important for the next step. I'll explain later.)<br />
<br />
[<br />
But if you are ready to experiment any later revisions, feel free to do so. (I have instructions for it later, don't worry.) For getting the latest revision, you can use <a href="http://sourceforge.net/projects/win32svn/">Win32SVN</a> and summon the commands in terminal:<br />
<br />
<pre>cd /D c:\lazarus\components
svn co https://github.com/dliw/fpCEF3</pre>
<br />
(You can always change the c:\lazarus part with your Lazarus installation if you have lazarus installed elsewhere in your computer. If you've done this, then skip the next step, step 2, and continue after that.) <br />
]<br />
<br />
2. <b>Extract & Copy</b> the folder to the <b>Components </b>directory inside your <b>Lazarus installation</b> (this is usually <b>C:\Lazarus\Componenets</b>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Be5trLBIzlg/VfFtE_x_CMI/AAAAAAAACCo/egFOGn3wU3Q/s1600/CEF-browser-in-Lazarus-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="http://2.bp.blogspot.com/-Be5trLBIzlg/VfFtE_x_CMI/AAAAAAAACCo/egFOGn3wU3Q/s400/CEF-browser-in-Lazarus-1.gif" width="400" /></a></div>
<br />
<br />
3. Now go inside the folder, then inside "<b>Component</b>" folder, then double click <b>cef3.lpk</b>. (You can also use Package->Open Package file (lpk)... from inside Lazarus to open this file.)<br />
<br />
This will open up Lazarus with a "Package" window for CEF3 like below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-TGPase8Pylw/VfFuR_UT_aI/AAAAAAAACC0/HFKFuAZ18Jc/s1600/CEF-browser-in-Lazarus-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://2.bp.blogspot.com/-TGPase8Pylw/VfFuR_UT_aI/AAAAAAAACC0/HFKFuAZ18Jc/s400/CEF-browser-in-Lazarus-2.gif" width="397" /></a></div>
<br />
<br />
4. Click on <b>Compile</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-TUxDJ5q3yuY/VfFw5MH-16I/AAAAAAAACC8/uYDRT-VqIvc/s1600/CEF-browser-in-Lazarus-3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="http://1.bp.blogspot.com/-TUxDJ5q3yuY/VfFw5MH-16I/AAAAAAAACC8/uYDRT-VqIvc/s320/CEF-browser-in-Lazarus-3.gif" width="320" /></a></div>
<br />
5. After the Compiling has completed (the messages window will show a "<b>Success</b>" message), click <b>Use -> Install</b>. Click <b>Yes </b>to rebuild Lazarus.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-lXhqbN5sGus/VfFxFf7IiTI/AAAAAAAACDE/2Z9T7UiXCHw/s1600/CEF-browser-in-Lazarus-4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="http://1.bp.blogspot.com/-lXhqbN5sGus/VfFxFf7IiTI/AAAAAAAACDE/2Z9T7UiXCHw/s320/CEF-browser-in-Lazarus-4.gif" width="320" /></a></div>
<br />
Give it some time to rebuild. Lazarus will restart. Upon restart you'll now see a new "Chromium" tab in the toolbar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-3rnfsle-eM8/VfFyyPeBceI/AAAAAAAACDQ/C-N-i7XiipA/s1600/CEF-browser-in-Lazarus-5.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="74" src="http://2.bp.blogspot.com/-3rnfsle-eM8/VfFyyPeBceI/AAAAAAAACDQ/C-N-i7XiipA/s320/CEF-browser-in-Lazarus-5.gif" width="320" /></a></div>
<br />
<br />
In the meanwhile let's download CEF...<br />
<br />
<h3 style="text-align: left;">
Download CEF</h3>
[ Note: I was very specific about <a href="https://github.com/dliw/fpCEF3/releases">getting the 23 revision (or version 3.1750) of FPCEF3</a>. This version is able to use CEF version 3.1750. If you have got yourself any other revision of fpCEF3, be sure to check the version number or commit messages to look for the appropriate version of CEF to be downloaded for it to work. ]<br />
<br />
1. <b>Download CEF</b> (version 3.1750) from <a href="http://www.magpcss.net/cef_downloads/index.php?file=cef_binary_3.1750.1738_windows32.7z">here</a> or <a href="https://cefbuilds.com/">here</a> .<br />
<br />
2. Download & Install <b>7-zip</b> from <a href="http://www.7-zip.org/">here</a>. You'll need 7-zip to extract the file above.<br />
<br />
3. Now <b>extract </b>the file and keep it that way. We'll only need the "<b>Release</b>" & "<b>Resources</b>" folders from this hotchpotch and jam packed file.<br />
<br />
<h3 style="text-align: left;">
Create the browser in 3 minutes!</h3>
The previous steps were just preparations -- which you'll only have to do once. Now that we're done with those boring setups now we get back in our real business... the browser.<br />
<br />
Start <a href="http://www.lazarus-ide.org/">Lazarus</a>.<br />
<br />
Create a new Application project (<b>Project->New Project->Application->OK</b>).<br />
<br />
Save the Project (<b>File -> Save All</b>) in a directory.<br />
<br />
Now, in the project directory copy the <b>Resources </b>Folder from <b>CEF package</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-g8qp_8RiK8A/VfGQiGkirEI/AAAAAAAACDg/25qk09gycGc/s1600/CEF-browser-in-Lazarus-6.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="lazarus, freepascal, webbrowser, chromium" border="0" height="259" src="http://4.bp.blogspot.com/-g8qp_8RiK8A/VfGQiGkirEI/AAAAAAAACDg/25qk09gycGc/s320/CEF-browser-in-Lazarus-6.gif" title="Copy the Resources folder directly where your project files are" width="320" /></a></div>
<br />
And then copy all the<b> files inside</b> the <b>Release </b>folder from CEF package, and paste it directly into the <b>project directory</b>. See the screenshot below if you need help understanding (click to enlarge).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ZkrtG-mJwEo/VfGQsAFn-8I/AAAAAAAACDo/hdBOws5c7sM/s1600/CEF-browser-in-Lazarus-7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Copy the files inside the Release folder into the project folder, fpCEF, web browser, lazarus, free pascal" border="0" height="213" src="http://2.bp.blogspot.com/-ZkrtG-mJwEo/VfGQsAFn-8I/AAAAAAAACDo/hdBOws5c7sM/s320/CEF-browser-in-Lazarus-7.jpg" title="Copy the files inside the Release folder into the project folder" width="320" /></a></div>
<br />
Drop a new TEditButton (from Misc tab) in to the form. Set its properties like this:<br />
Name = edtURL<br />
Align = alTop<br />
ButtonCaption = Go<br />
<br />
The result is as follows:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-jiXgnHfsn14/VfGRhv4bDGI/AAAAAAAACDw/-trgrAtls30/s1600/CEF-browser-in-Lazarus-8.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="First, we add the location bar - lazarus, freepascal, webbrowser, chromium" border="0" height="236" src="http://1.bp.blogspot.com/-jiXgnHfsn14/VfGRhv4bDGI/AAAAAAAACDw/-trgrAtls30/s320/CEF-browser-in-Lazarus-8.gif" title="First, we add the location bar" width="320" /></a></div>
<br />
Now we'll have a nice Location bar/Address bar at the top.<br />
<br />
Now Drop a new TChromium (from Chromium tab) in the form. Set its properties:<br />
<br />
Name = Chromium<br />
Align = alClient<br />
<br />
It will fit the Chromium component nicely in the form's blank area.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-DF5G2fVYg-Q/VfGSHQrCM4I/AAAAAAAACD4/du1_MWfDnvo/s1600/CEF-browser-in-Lazarus-9.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Simple Chromium Web Browser with fpCEF, lazarus ide, free pascal" border="0" height="236" src="http://1.bp.blogspot.com/-DF5G2fVYg-Q/VfGSHQrCM4I/AAAAAAAACD4/du1_MWfDnvo/s320/CEF-browser-in-Lazarus-9.gif" title="Form design for fpCEF web browser" width="320" /></a></div>
<br />
<br />
Now double click the Form1 item in the Object Inspector and enter the code:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormCreate(Sender: TObject);
begin
CefResourcesDirPath:='Resources';
CefLocalesDirPath:='Resources\locales';
CefInitDefault;
edtURL.Text:='http://lazplanet.blogspot.com';
end;</pre>
<br />
Now that you are in the Code view, add the cef3types & cef3lib unit in the uses clause:<br />
<br />
<pre class="brush:pascal">uses
..., ..., ...
, cef3types, cef3lib;</pre>
<br />
Now add the following code on edtURL's OnButtonClick event (select the edtURL component, go to Event tab, click the [...] button beside OnButtonClick item):<br />
<br />
<pre class="brush:pascal">procedure TForm1.edtURLButtonClick(Sender: TObject);
begin
Chromium.Load(UTF8Decode(edtURL.Text));
end;</pre>
<br />
Now add the following code on Chromium's OnLoadEnd event (select the Chromium component, go to Event tab, click the [...] button beside OnLoadEnd item):<br />
<br />
<pre class="brush:pascal">procedure TForm1.ChromiumLoadEnd(Sender: TObject; const Browser: ICefBrowser;
const Frame: ICefFrame; httpStatusCode: Integer);
begin
edtURL.Text:=UTF8Encode(Browser.MainFrame.Url);
end;</pre>
<br />
Voila! Done! Well under 3 minutes!<br />
<br />
Now Run the project (F9 or Run -> Run). Click the "Go" button.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-4cWSdD76xZY/VfGWL1pWRRI/AAAAAAAACEE/487L7TPkNFE/s1600/CEF-browser-in-Lazarus-10.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="running the web browser , lazarus, freepascal, webbrowser, chromium" border="0" height="229" src="http://3.bp.blogspot.com/-4cWSdD76xZY/VfGWL1pWRRI/AAAAAAAACEE/487L7TPkNFE/s320/CEF-browser-in-Lazarus-10.gif" title="Your new web browser is running!" width="320" /></a></div>
<br />
You'll see the LazPlanet website load in your newly made web browser! You can change the code on the TForm1.FormCreate procedure to set another URL as the homepage.<br />
<br />
Now browse all you want with your new browser! Happy surfing!<br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/MWPFjW2v">here</a>.<br />
<a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSUncyc3Q0MWUyU2c"></a><br />
Size: 926 KB<br />
The package contains compiled executable EXE file.<br />
<br />
<b>Ref:</b><br />
<a href="http://wiki.freepascal.org/fpCEF3">http://wiki.freepascal.org/fpCEF3</a><br />
<a href="https://github.com/dliw/fpCEF3">https://github.com/dliw/fpCEF3</a><br />
<a href="http://www.magpcss.net/cef_downloads/">http://www.magpcss.net/cef_downloads/</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com33tag:blogger.com,1999:blog-5314745381778741517.post-1473024668642074492015-07-19T11:09:00.000+01:002015-07-19T11:28:35.378+01:00How to make a Simple Dictionary in 5 Minutes!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-2sZnd3Na4zo/VatvI3MfBFI/AAAAAAAACBg/3lNbRK0QPgA/s1600/funny-pictures-cat-dictionary-cheezburger.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="136" src="http://2.bp.blogspot.com/-2sZnd3Na4zo/VatvI3MfBFI/AAAAAAAACBg/3lNbRK0QPgA/s200/funny-pictures-cat-dictionary-cheezburger.jpg" width="200" /></a></div>
Dictionary is one of the fun challenges of programming. Learn how to make a dictionary in this quick tutorial.<br />
<a name='more'></a><br />
Dictionary programmes are fun all by itself. The storage, retrieval and searching etc. are very exciting. And what about creating a dictionary in your own mother tongue? While you're at it, how about using the code to reprogramme the software to show what basic Pascal procedures do! Once you understand the code, you can shape it whatever you want. I hope you're salivating!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-ewYnOY3dWbI/Vat0Re_z4rI/AAAAAAAACBw/oMpy9T31gdo/s1600/funny-face-book-Grumpy-cat.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Funny cat" border="0" height="320" src="http://3.bp.blogspot.com/-ewYnOY3dWbI/Vat0Re_z4rI/AAAAAAAACBw/oMpy9T31gdo/s320/funny-face-book-Grumpy-cat.jpg" title="Funny cat" width="259" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">We, now a days... We don't like to <br />
look-up words in bulky old books <br />
called dictionary... we search it!</td></tr>
</tbody></table>
<br />
So we are going to use a simple tab-delimited dictionary file for our simple dictionary. The syntax of the data would be:<br />
<br />
<pre>word1<tab>meaning1
word2<tab>meaning2
word3<tab>meaning3
word4<tab>meaning4
...
...</pre>
<br />
We would use TStringList.LoadFromFile() to load the file data into our program. Then using TStringList's DelimitedText we would separate the words and definitions and show it.<br />
<br />
So everything is there in Lazarus already. So it would be a walk in the park for us, trust me!<br />
<br />
<br />
<h3 style="text-align: left;">
Create the Data</h3>
First, let's create the data file that would hold all the words and the meanings.<br />
<br />
Create a folder/directory for the Simple Dictionary project. On that directory save a file named "Dictionary.txt". On that file put the text below using notepad (or any other plain text editor like Notepad++, gedit etc.):<br />
<br />
EDIT: Click <a href="http://pastebin.com/2Km5XyiM">this link</a>, then copy the code under the "Raw Paste Data" heading. The following code does not have tab characters. (Blogger strips them.)<br />
<br />
<textarea style="height: 216px; width: 403px;">a First letter of English alphabet
a1 Very good
abc Basics
apple A red fruit
b Second letter of English alphabet
bad Not good
bag Holder of things
bank Keeper of money
big Large in size
c Third letter of English alphabet
cake Baked food
camp Mobile home!</textarea>
<br />
<br />
Make sure you save the file.<br />
<br />
<h3 style="text-align: left;">
Editing the data file</h3>
The above is a data code given just as a sample to get you started. You can edit the code to add your words and definitions.<br />
<br />
You can edit the data file in Excel or any other spreadsheet program (like LibreOffice, OpenOffice, gnumeric etc.) Or any of the plain text editors would suffice.<br />
<br />
<h4 style="text-align: left;">
On Notepad++:</h4>
Open the file. If you want to use UTF8 characters, click Encoding->Convert to UTF-8 Without BOM. Edit the file. Save it as usual.<br />
<br />
<h4 style="text-align: left;">
On other plain text editors</h4>
You can use any other plain text editor for editing the dictionary file. Just open it, ensure that UTF-8 encoding is selected, then edit, save, done!<br />
<br />
<h4 style="text-align: left;">
On Excel:</h4>
If you want to work with words/definitions in other language except English, Excel may dissapoint you. Excel does not support UTF8 characters in Tab delimited Plain text files. If you still wish to use a spreadsheet program, use OpenOffice/LibreOffice (explained below).<br />
<br />
Open the file with Ctrl+O and use "Text files" in the filter. Click Next. Make sure "Tab" checkbox is selected. And also, select "{none}" in the Text qualifier. Click Finish.<br />
<br />
For saving, just use Ctrl+S like any normal file. Just click Yes if a message appears for saving in text delimited format.<br />
<br />
<h4 style="text-align: left;">
On OpenOffice/LibreOffice:</h4>
Summon the Open dialog, Ctrl+O.<br />
Select the "Text CSV" filter (not the other "Text" option, otherwise it will open it in Writer). After opening the file a dialog box will appear.<br />
<br />
Make sure that "Tab" is selected as separator. Delete the value in the "Text Delimiter" field. If you are using any language other than English, try changing the Character Set to "Unicode (UTF-8)". (Failing to do so may corrupt your file.)<br />
<br />
When saving, click "Keep current format", if a dialog box appears.<br />
<br />
<h3 style="text-align: left;">
Project</h3>
Start <a href="http://lazarus.freepascal.org/">Lazarus</a>.<br />
<br />
Create a new Application Project (<b>Project->New Project->Application->OK</b>).<br />
<br />
Draw <b>2 GroupBoxes</b>. One to the left, other to the right. Change the <b>Caption </b>of the left one to "<b>Search</b>" and the right one to "<b>Definition</b>".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-utADIfdkzeE/Vatfi3ApYCI/AAAAAAAACAc/j8gYeaMSYaM/s1600/Simple-Dictionary-Lazarus-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://1.bp.blogspot.com/-utADIfdkzeE/Vatfi3ApYCI/AAAAAAAACAc/j8gYeaMSYaM/s320/Simple-Dictionary-Lazarus-1.gif" width="320" /></a></div>
<br />
Draw a <b>TEdit </b>and a <b>TListBox </b>on the <b>Groupbox to the left</b>. The TEdit is going to be our search box and the ListBox is going to hold our words. <b>Empty </b>the <b>Text </b>property of <b>Tedit</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-jkhkXITLNNM/Vatfznj1P5I/AAAAAAAACAk/8mxNQSk3JDA/s1600/Simple-Dictionary-Lazarus-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://4.bp.blogspot.com/-jkhkXITLNNM/Vatfznj1P5I/AAAAAAAACAk/8mxNQSk3JDA/s320/Simple-Dictionary-Lazarus-2.gif" width="320" /></a></div>
<br />
Draw 2 <b>TMemo</b> inside the groupbox to the right.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-G3WTjKk6rRE/Vatf453tYZI/AAAAAAAACAs/Pvdf3HO7_50/s1600/Simple-Dictionary-Lazarus-3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://1.bp.blogspot.com/-G3WTjKk6rRE/Vatf453tYZI/AAAAAAAACAs/Pvdf3HO7_50/s320/Simple-Dictionary-Lazarus-3.gif" width="320" /></a></div>
<br />
<b>Memo2 </b>will be a hidden TMemo that will store our definitions. So Select Memo2 and set Visible to False.<br />
<br />
Select Memo1 and set the Scrollbars property to ssAutoVertical.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-5uak5aSxWeM/VatgCNQQ_jI/AAAAAAAACA0/r1N7h_4mk-E/s1600/Simple-Dictionary-Lazarus-4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://1.bp.blogspot.com/-5uak5aSxWeM/VatgCNQQ_jI/AAAAAAAACA0/r1N7h_4mk-E/s320/Simple-Dictionary-Lazarus-4.gif" width="320" /></a></div>
<br />
Empty the Lines property of both the Memo1 and Memo2.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-xMALy-cThuI/VatgIvYl5II/AAAAAAAACA8/HqKJJKhvjYQ/s1600/Simple-Dictionary-Lazarus-5.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://3.bp.blogspot.com/-xMALy-cThuI/VatgIvYl5II/AAAAAAAACA8/HqKJJKhvjYQ/s320/Simple-Dictionary-Lazarus-5.gif" width="320" /></a></div>
<br />
Double click on Form1 and enter the code below:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormCreate(Sender: TObject);
var
myLine: String;
Lines, Parts: TStringList;
begin
if FileExistsUTF8('Dictionary.txt') then begin
try
Parts := TStringList.Create;
Lines := TStringList.Create;
Lines.LoadFromFile('Dictionary.txt');
// in case the word lines are in bad order
Lines.Sort;
for myLine in Lines do begin
if Trim(myLine) <> '' then begin // we ignore empty lines
Split(#9, myLine, Parts); // #9 means tab
ListBox1.Items.Add(Parts.Strings[0]);
Memo2.Lines.Add(Parts.Strings[1]);
end;
end;
finally
if Parts <> nil then FreeAndNil(Parts);
if Lines <> nil then FreeAndNil(Lines);
end;
end else begin
ShowMessage('Dictionary file not found!');
Close;
end;
end;</pre>
<br />
<b>Explanation:</b><br />
This procedure is undoubtedly the most important procedure of this project. We get the lines in the dictionary data file into our TStringList, which is obviously named "Lines".<br />
<br />
Now, we have all the tab seperated word and its meaning. E.g. Word1<tab>Meaning. Now we need to seperate the word from the meaning, So that we can show all the words in the ListBox and store the definitions in our TMemo named Memo2. So how can we seperate the two? We will use the "Split" procedure that we'll enter next.<br />
<br />
So, the Word and Meaning will be returned in our another TStringList, "Parts". Parts[0] will have the word and Parts[1] will have the meaning. We can then easily store them where needed so we can access them when searched for.<br />
<br />
<br />
Now that you are in Code view, paste the following procedure code before the "end." line (before the last line):<br />
<br />
<pre class="brush:pascal">procedure TForm1.Split(Delimiter: Char; Str: string; ListOfStrings: TStrings);
begin
ListOfStrings.Clear;
ListOfStrings.Delimiter := Delimiter;
ListOfStrings.StrictDelimiter := True;
ListOfStrings.DelimitedText := Str;
end;</pre>
<br />
<b>Explanation:</b><br />
This procedure will help us to get the word and definition from the data lines.<br />
<br />
This procedure just utilizes the TStringList's power of Delimiting text. But for this we have to set the delimiter (in our case its "tab"). If you don't get it, don't worry, it's not important. It just works "under the hood".<br />
<br />
Now take your cursor to the definition name and press Ctrl+Shift+C. This will create a declaration of the procedure where needed in order to make it usable in our code.<br />
<br />
Now switch to Form view (F12) and double click the TEdit. Now enter the following code:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Edit1Change(Sender: TObject);
var
i: Integer;
query, searchitem: string;
begin
// We would search case insensitive to make
// it easy for the user. That's why uppercase.
query := UpperCase(Edit1.Text);
for i := 0 to ListBox1.Count-1 do begin
// Same. Uppercase because we are searching
// Case insensitive.
searchitem := UpperCase(ListBox1.Items[i]);
if LeftStr(searchitem, Length(query)) = query then begin
ListBox1.ItemIndex := i;
ListBox1Click(Sender);
// We selected the first found item, so we don't need
// to search more... so we quit searching
Exit;
end;
end;
end;</pre>
<br />
<br />
This will enable us to search from the word list. I have used the partial list search technique.<br />
<br />
Now switch to Form view (F12). Then double click on the ListBox and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.ListBox1Click(Sender: TObject);
begin
if ListBox1.ItemIndex >= 0 then
Memo1.Text:=Memo2.Lines[ListBox1.ItemIndex];
end;</pre>
<br />
<br />
<h4 style="text-align: left;">
Explanation:</h4>
First, we check if the index 0 or more. When no item is selected, the ItemIndex is -1. If that time, somehow this click event is triggered, it would raise an error because "Memo2.Lines[ListBox1.ItemIndex]" part would not work. Lines[-1] would return nothing. So we make sure we don't get that error.<br />
<br />
After that we retrieve the definition. Remember what Memo2 is for? It holds all the definitions of our data file. And we've stored all these definitions exactly in the index position of the ListBox1. So, we just get the definition with the selected index number of the ListBox.<br />
<br />
<h4 style="text-align: left;">
Saving it</h4>
Now save the project using File->Save all. Choose to save in the project folder that you created at the beginning of the article (and where "Dictionary.txt" file is).<br />
<br />
Now that you've saved the project we are ready to Run the project. Press F9 (or Run->Run) to run the project.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-dctkEQLMx3M/Vatj8YiQ2WI/AAAAAAAACBI/2Uh_-Iu4twQ/s1600/Simple-Dictionary-Lazarus-6.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://1.bp.blogspot.com/-dctkEQLMx3M/Vatj8YiQ2WI/AAAAAAAACBI/2Uh_-Iu4twQ/s320/Simple-Dictionary-Lazarus-6.gif" width="320" /></a></div>
<br />
Write something to search in our new dictionary...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-sbMlwtLl1Ls/VatkJCsMePI/AAAAAAAACBQ/PHw9ETtzsw4/s1600/Simple-Dictionary-Lazarus-7.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://3.bp.blogspot.com/-sbMlwtLl1Ls/VatkJCsMePI/AAAAAAAACBQ/PHw9ETtzsw4/s320/Simple-Dictionary-Lazarus-7.gif" width="320" /></a></div>
<br />
There you go! A simple dictionary for your enjoyment.<br />
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/NYKh4Nbf">here</a>.<a href="https://db.tt/XCO9id6W"></a><br />
Or <a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSUncyc3Q0MWUyU2c">here</a><a href="http://bit.ly/pascal_pong_game"></a><br />
Size: 609 KB<br />
The package contains compiled executable EXE file.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com4tag:blogger.com,1999:blog-5314745381778741517.post-66004208882366578002015-06-25T17:24:00.000+01:002015-06-27T19:46:06.015+01:0010 Things you did not know about Lazarus<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="122" ilo-full-src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" width="162" /></a></div>
In this useful article we see some of the less known but handy tools or features that Lazarus has<br />
<a name='more'></a><br />
Lazarus is a cross platform RAD IDE tool to develop applications for your need. Lazarus is a great IDE but its marketing efforts are poor, but if you are used to the Lazarus wiki then you will find out the true treasures in this IDE. It is packed with hundreds of features, yet the users know a little about them. Those features can cut some minutes of work from your daily life for your ease. Here are some interesting features that you might not know about:<br />
<br />
<h3 style="text-align: left;">
1. Component List (with Search and categorization)</h3>
Press Ctrl+Alt+P. This will bring out the components list and you can search the component you want or simply just click it. It can't get any easier than this!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-IVScI2046Qc/VYwjZuBLixI/AAAAAAAAB_Q/RJYAUnzTn8M/s1600/Component-List.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Component List dialog box in Lazarus" border="0" height="320" src="http://3.bp.blogspot.com/-IVScI2046Qc/VYwjZuBLixI/AAAAAAAAB_Q/RJYAUnzTn8M/s320/Component-List.gif" title="Component List dialog box in Lazarus" width="294" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Component List. It can't get any easier than this!</td></tr>
</tbody></table>
<br />
<h3 style="text-align: left;">
2. Jump to definition hotlink By control+clicking</h3>
Click a variable name or procedure/function by pressing Ctrl.<br />
This is particularly useful if you are unsure of any procedure definition or the source declaration of any variable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-5GuMiMx0R98/VYwkm5HSIkI/AAAAAAAAB_Y/6P88LuaL0IM/s1600/Code-Hotlink-Definition-Search-Lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Ctrl+Click code definition search in Lazarus" border="0" height="320" src="http://3.bp.blogspot.com/-5GuMiMx0R98/VYwkm5HSIkI/AAAAAAAAB_Y/6P88LuaL0IM/s320/Code-Hotlink-Definition-Search-Lazarus.gif" title="Ctrl+Click code definition search in Lazarus" width="294" /></a></div>
<br />
<h3 style="text-align: left;">
3. $IFDEF compiler directives (OS+CPU architecture)</h3>
This is not actually a feature of Lazarus but more of FPC. But many don't know it can be done in Lazarus. I am listing it for those people who might underestimate Lazarus just of not knowing this feature exists. A simple code would be:<br />
<pre class="brush:pascal">{$IFDEF WINDOWS}
<span class="Apple-tab-span" style="white-space: pre;"> </span>showmessage('Windows!');
<span class="Apple-tab-span" style="white-space: pre;"> </span>{$IFDEF WIN32}
<span class="Apple-tab-span" style="white-space: pre;"> </span>showmessage('32 Bit Windows!');
<span class="Apple-tab-span" style="white-space: pre;"> </span>{$ENDIF}
<span class="Apple-tab-span" style="white-space: pre;"> </span>{$IFDEF WIN64}
<span class="Apple-tab-span" style="white-space: pre;"> </span>showmessage('64 Bit Windows!');
<span class="Apple-tab-span" style="white-space: pre;"> </span>{$ENDIF}
{$ENDIF}
{$ifdef LINUX}
<span class="Apple-tab-span" style="white-space: pre;"> </span>showmessage('Linux!');
{$endif}
{$ifdef Darwin}
<span class="Apple-tab-span" style="white-space: pre;"> </span>showmessage('Mac OS!');
{$endif}
</pre>
<br />
<br />
EDIT: It seems Lazarus has a feature about compiler directives after all which you may not know was in Lazarus! As leledumbo mentions about this feature in his comment, Lazarus has a <a href="http://wiki.lazarus.freepascal.org/New_IDE_features_since#Low-lighting_inactive_.24IFDEF_code">"low-lighting inactive" code feature since version 1.2</a>. This feature lightly dims the compiler directives that currently does not apply to your OS/architecture/compiler. Although it is just a cosmetic feature, this might help someone understand the directives better and identify correct block of code quickly.<br />
<br />
There are tonnes of more ways you can use compiler directives. You can look in the following links:<br />
<a href="http://forum.lazarus.freepascal.org/index.php?topic=15869.0">Lazarus Forum: Is there a list of $IFDEF XXXXX Declarations?</a><br />
<a href="http://www.freepascal.org/docs-html/prog/progap7.html">FPC Manual: Compiler defines during compilation</a><br />
<a href="http://www.askingbox.com/tip/lazarus-detect-operating-system-compiler-switch">Lazarus: Detect Operating System (Compiler Switch)</a><br />
<a href="http://wiki.freepascal.org/Conditional_compilation">Lazarus wiki: Conditional compilation</a><br />
<a href="http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide">Lazarus wiki: Multiplatform Programming Guide</a><br />
<br />
<h3 style="text-align: left;">
4. Procedure List</h3>
Press Alt+G.<br />
This will show you a list of procedures/functions in the current unit. This is extremely helpful when you have hundreds of procedures that cannot be found with just scrolling the code. You can double click any procedure/function from the list to jump to it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-NGeUQLw0puI/VYwloL7r8tI/AAAAAAAAB_g/bVgoPz2ly1M/s1600/procedure-list-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://2.bp.blogspot.com/-NGeUQLw0puI/VYwloL7r8tI/AAAAAAAAB_g/bVgoPz2ly1M/s320/procedure-list-lazarus.gif" width="320" /></a></div>
<br />
For this purpose you can also use Code Explorer (available from View menu) shows uses, types, variables, procedures of the project. But this will take time to expand some plus signs. ... whichever suits you.<br />
<br />
<h3 style="text-align: left;">
5. Tab Order manager</h3>
Available from View->Tab Order.<br />
This dialog enables you to review your tab order arrangements in the form components. Tab order is basically a way to control which component gets focus after which component. You can order/re-order the tab order from this dialog box by clicking the arrow buttons.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-CuQl7IcmVYM/VYwmcKqNK9I/AAAAAAAAB_o/Zj8wNsWOg8c/s1600/Tab-order-editor-lazarus.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Tab Order editor in Lazarus" border="0" height="320" src="http://3.bp.blogspot.com/-CuQl7IcmVYM/VYwmcKqNK9I/AAAAAAAAB_o/Zj8wNsWOg8c/s320/Tab-order-editor-lazarus.gif" title="Tab Order editor in Lazarus" width="253" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tab order editor dialog: <br />
defines how user will navigate <br />
through components by pressing tab</td></tr>
</tbody></table>
<br />
Another feature is that you can automatically order the components by using how you positioned the components in the form (using their Left and Top property). This is a handy feature when you are fighting a deadline or just this is a meh affair to you.<br />
<br />
<h3 style="text-align: left;">
6. ToDo List</h3>
Available from View->ToDo List menu.<br />
This is a very useful feature when you don't remember where you put your todo comments. If you don't know what a todo comment is, it is basically a note to yourself that you need to do something in the code later. Test it by putting something like this in your code:<br />
<br />
<pre>// TODO: I will update it later</pre>
<br />
Now if you summon the ToDo List, it will show that comment. You can jump to your ToDo by clicking on it.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-XXZYqzMHO58/VYwn1_MuBdI/AAAAAAAAB_0/e2JvwaZ7s0E/s1600/ToDo-List-dialog-Lazarus.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="ToDo List in Lazarus IDE" border="0" height="223" src="http://4.bp.blogspot.com/-XXZYqzMHO58/VYwn1_MuBdI/AAAAAAAAB_0/e2JvwaZ7s0E/s320/ToDo-List-dialog-Lazarus.gif" title="ToDo List dialog" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ToDo List dialog</td></tr>
</tbody></table>
<br />
<h3 style="text-align: left;">
7. Code Refactoring</h3>
Actions available from Source->Refactoring menu.<br />
I know less about code Refactoring. I have used this feature to rename variables throughout my code of a project which it did quite splendidly. It has other tools which I believe is worth its place.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8gShutwn5-E/VYwoWaPgE_I/AAAAAAAAB_8/Xqp-RoqqHYQ/s1600/Refactoring-menu-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239" src="http://3.bp.blogspot.com/-8gShutwn5-E/VYwoWaPgE_I/AAAAAAAAB_8/Xqp-RoqqHYQ/s320/Refactoring-menu-lazarus.gif" width="320" /></a></div>
<br />
<h3 style="text-align: left;">
8. Clean Directory</h3>
Available from File->Clean Directory menu.<br />
This is especially useful when you want to distribute your project code without the temporary files created during compile. You can also specify any custom file format that you want to be removed.<br />
<br />
<h3 style="text-align: left;">
9. Export Code as HTML</h3>
Available from File->Export as HTML menu.<br />
Lazarus has its way of showing code. I mean its colors, font spacing etc. When you copy and paste it, it no longer has the beauty of those syntax highlighted colors that we love. If you want to retain those colors & share it with a friend then why not try this feature?<br />
<br />
<h3 style="text-align: left;">
10.Code Templates </h3>
(Tools-> Code Templates..., triggered by Ctrl+J)<br />
This is a power feature for every programmer. Just check out the shortcuts in Tools->Code Templates... menu. You can type in these shortcuts and press Ctrl+J to have some code created for you. Cool!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-1FXaaCk0-JA/VYwpK4kX9jI/AAAAAAAACAE/tLKnNU_2ZBc/s1600/Code-templates-dialog-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Code Templates dialog" border="0" height="300" src="http://1.bp.blogspot.com/-1FXaaCk0-JA/VYwpK4kX9jI/AAAAAAAACAE/tLKnNU_2ZBc/s320/Code-templates-dialog-lazarus.gif" title="Code Templates dialog" width="320" /></a></div>
<br />
You can also add a code if you want. Just add a pipe character where you want your cursor to be when the code is inserted. I have used such features with Notepad++ (with Fingertext plugin) and with Sublime Text and it feels awesome to type code, believe me!<br />
<br />
You can get more help on how to create your own code templates here: <a href="http://wiki.lazarus.freepascal.org/IDE_Window:_Code_Templates">Lazarus Wiki: IDE Window: Code Templates</a>.<br />
<br />
<br />
Lazarus has some amazing features that can make creating programs a breeze! Try them, I'm sure you'll love them!</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com6tag:blogger.com,1999:blog-5314745381778741517.post-76747015324565608462015-05-05T20:16:00.000+01:002015-05-05T20:16:22.655+01:00How to Create Components on Runtime<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-U1yKGbZpcBo/VUkUVM9ReLI/AAAAAAAAB84/q_ZxED-AfcE/s1600/create-components-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Creating components on runtime on exe" border="0" src="http://2.bp.blogspot.com/-U1yKGbZpcBo/VUkUVM9ReLI/AAAAAAAAB84/q_ZxED-AfcE/s1600/create-components-thumb.jpg" title="Creating components on runtime on exe" /></a></div>
The good thing about programming is that you can do almost anything you wish. Even create components out of thin air!<br />
<a name='more'></a><br />
Today we are going to learn how to create Buttons, Labels, Edits right at the time when the exe is running.<br />
<br />
<h3 style="text-align: left;">
Basics</h3>
Before getting our hands dirty, let's get our basics straight. Before this article, LazPlanet had another article quite similar to this: <a href="http://lazplanet.blogspot.com/2013/04/clone-your-form-into-many.html" target="_blank">How to clone your forms into many</a>. Be sure to check that out if you're interested.<br />
<br />
If you are scared that the code might be difficult, don't worry. Creating components are just dead simple. We create an instance of class of the component and then more gracefully give some properties to it. That's it! It's just that simple.<br />
<br />
If you want to add some event to it, it's easy as well.<br />
<br />
Let's see this sample code for creating buttons:<br />
<br />
<pre class="brush:pascal">var
btn:Tbutton;
begin
btn:=Tbutton.Create(nil);
// we say that place button inside Form1
btn.parent := Form1;
// set properties for new button
btn.top := 10;
btn.Left := 10;
btn.Caption := 'Click me!';
end;
</pre>
<br />
So, we have 3 steps to creating a component on the fly (or in the runtime):<br />
1. Create an instance of the component class<br />
<pre class="brush:pascal">btn:=Tbutton.Create(nil);</pre>
<br />
2. Set its parent<br />
<pre class="brush:pascal">btn.parent := Form1;</pre>
<br />
3. Set properties to it (just like we always do in the Object Inspector->Properties):<br />
<pre class="brush:pascal"> btn.top := 10;
btn.Left := 10;
btn.Caption := 'Click me!';</pre>
<br />
Additionally if you want to have an event attached to it, just point a procedure to the event:<br />
<br />
<pre class="brush:pascal">btn.OnClick := @btnClickEvent;</pre>
<br />
And btnClickEvent might be like this:<br />
<br />
<pre class="brush:pascal">procedure TForm1.btnClickEvent(Sender: TObject);
begin
ShowMessage('Button clicked!');
end;</pre>
<br />
I said it was easy! Right!<br />
<br />
<h3 style="text-align: left;">
Tiny project</h3>
Let's get a tiny project running before the actual sample project.<br />
<br />
Start <a href="http://www.lazarus-ide.org/" target="_blank">Lazarus</a>.<br />
<br />
Create a new Application Project (Project->New Project->Application->OK).<br />
<br />
Draw a TButton on the form. It would be named "Button1".<br />
<br />
Double click on it and enter:<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
var
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn: TButton;
begin
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn := TButton.Create(Button1);
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn.parent := Form1;
<span class="Apple-tab-span" style="white-space: pre;"> </span>// set properties for new button
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn.top := (random(300));
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn.Left := (random(300));
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn.Caption := inttostr(random(9999));
<span class="Apple-tab-span" style="white-space: pre;"> </span>// set the click event to this procedure
<span class="Apple-tab-span" style="white-space: pre;"> </span>// so that new buttons also have 'cloning'
<span class="Apple-tab-span" style="white-space: pre;"> </span>// on its click event
<span class="Apple-tab-span" style="white-space: pre;"> </span>btn.OnClick := @Button1Click;
end;</pre>
<br />
Now run the project (F9 or Run->Run).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-UF3TfpSn7t4/VUj2TZSvATI/AAAAAAAAB7s/oCXiQuxrluY/s1600/clone-buttons-lazarus-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Creating components on runtime on exe" border="0" height="264" src="http://2.bp.blogspot.com/-UF3TfpSn7t4/VUj2TZSvATI/AAAAAAAAB7s/oCXiQuxrluY/s320/clone-buttons-lazarus-1.jpg" title="Creating components on runtime on exe" width="320" /></a></div>
<br />
<br />
Now click the Button several times. You will see the button get 'cloned'.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-09QRcx6LmxM/VUj2u_L2JPI/AAAAAAAAB70/zNJifbU28rk/s1600/clone-buttons-lazarus-2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Creating components on runtime on exe" border="0" height="264" src="http://3.bp.blogspot.com/-09QRcx6LmxM/VUj2u_L2JPI/AAAAAAAAB70/zNJifbU28rk/s320/clone-buttons-lazarus-2.jpg" title="Creating components on runtime on exe" width="320" /></a></div>
<br />
<h3 style="text-align: left;">
Real Project</h3>
Now that we got our simple project working, we can focus on the real project. This project will be easy as well. We will just structure it a bit better, that's all.<br />
<br />
Start <a href="http://www.lazarus-ide.org/" target="_blank">Lazarus</a>.<br />
<br />
Create a new Application Project (Project->New Project->Application->OK).<br />
<br />
Draw 3 Tbuttons side by side. Set caption like below:<br />
button1 -> Create Buttons<br />
button2 -> Create TEdits<br />
button3 -> Create Shapes<br />
<br />
Resize the form if you need to.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-1WYqGLp3a-E/VUj4YzKzIDI/AAAAAAAAB8A/fOIWKU4H7D0/s1600/clone-real-project-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Place 3 buttons on your form" border="0" height="258" src="http://4.bp.blogspot.com/-1WYqGLp3a-E/VUj4YzKzIDI/AAAAAAAAB8A/fOIWKU4H7D0/s400/clone-real-project-1.jpg" title="Place 3 buttons on your form" width="400" /></a></div>
<br />
Now Draw 1 TPanel below the first Tbutton. While you have it selected change some properties from the Object Inspector. Set its BevelOuter to bvLowered. Also, empty its Caption, so that there is no "Panel 1" text in the middle of the panel.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-gLJ1en9O-oI/VUj5Uo2H8VI/AAAAAAAAB8I/IOQkR60srAk/s1600/clone-real-project-2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="lazarus, Set properties of TPanel" border="0" height="258" src="http://1.bp.blogspot.com/-gLJ1en9O-oI/VUj5Uo2H8VI/AAAAAAAAB8I/IOQkR60srAk/s400/clone-real-project-2.jpg" title="Set properties of TPanel" width="400" /></a></div>
<br />
Now right click the TPanel and select Copy. Then right click the form and choose Paste. The Panel will be copied with the name Panel2. Position it under the second Tbutton.<br />
<br />
Again Copy the last TPanel, select the form and paste. The new Tpanel will be automatically named Panel3. Position it under the third Tbutton.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Fw1fYuk4k5E/VUj6gZCfOTI/AAAAAAAAB8U/tpnrdoN38AY/s1600/clone-real-project-3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="lazarus, Form layout is done" border="0" height="253" src="http://4.bp.blogspot.com/-Fw1fYuk4k5E/VUj6gZCfOTI/AAAAAAAAB8U/tpnrdoN38AY/s400/clone-real-project-3.gif" title="Form layout is done" width="400" /></a></div>
<br />
Double click the button1 and enter the code below:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
var
btn:TButton;
begin
// we create an instance of a 'virtual' Tbutton
btn := TButton.Create(nil);
// we place the button inside Panel1
btn.parent := Panel1;
// position the button randomly & set caption
btn.top := (random( Panel1.Height - btn.Height ));
btn.Left := (random( Panel1.Width - btn.Width ));
btn.Caption := inttostr(random(9999));
// set the click event
btn.OnClick := @WhatToDo;
end;</pre>
<br />
Now that we are in code view, let's do another thing. Paste the procedure somewhere under the implementation clause. If you are unsure, place it before the last line that says "end." (not end semicolon).<br />
<br />
<pre class="brush:pascal">procedure TForm1.WhatToDo(Sender: TObject);
begin
ShowMessage('Click event works!');
end;</pre>
<br />
Now put your cursor on the procedure name and press Ctrl+Shift+C.<br />
<br />
WhatToDo is just a test to see if the click event works on the 'virtually' created buttons. You can do whatever you want.<br />
<br />
If you want to use any properties of the clicked button, use it with (Sender as TButton).PropertyName. But this only works for TButton. We want to reuse our function to be used with other type of components as well. So we would use another solution... (Sender as TControl).PropertyName.<br />
<br />
<h4 style="text-align: left;">
**How to use property when type of Sender component is unknown</h4>
Simple. Use (Sender as TControl).PropertyName<br />
<br />
For example, if you want to get the Caption of the clicked component use (Sender as TControl).Caption, like as follows:<br />
<br />
<pre class="brush:pascal">procedure TForm1.WhatToDo(Sender: TObject);
begin
ShowMessage('Clicked on ... '+(Sender as TControl).Caption);
end;</pre>
<br />
If you want to get the type of the sender in a string, use Sender.ClassName:<br />
<br />
<pre class="brush:pascal">procedure TForm1.WhatToDo(Sender: TObject);
begin
ShowMessage('You clicked on a '+Sender.ClassName);
end;</pre>
<br />
Seems like a lot of discussion. But don't worry, we are all set.<br />
<br />
Now back to our tutorial.<br />
<br />
Go to form view if our are not (press F12). Go ahead and double click button2 and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button2Click(Sender: TObject);
var
edt: TEdit;
begin
// we create an instance of a 'virtual' Tbutton
edt := TEdit.Create(nil);
// we place the tedit inside Panel1
edt.parent := Panel2;
// position the tedit randomly & set caption
edt.top := (random( Panel2.Height - edt.Height ));
edt.Left := (random( Panel2.Width - edt.Width ));
edt.Text := inttostr(random(9999));
// set the click event
edt.OnClick := @WhatToDo;
end;</pre>
<br />
Go to form view (F12). Now again double click button3 and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button3Click(Sender: TObject);
var
shp: TShape;
begin
// we create an instance of a 'virtual' Tbutton
shp := TShape.Create(nil);
// we place the tedit inside Panel1
shp.parent := Panel3;
// position the tedit randomly
shp.top := random( Panel3.Height - shp.Height );
shp.Left := random( Panel3.Width - shp.Width );
// we make the shape random
shp.Shape := TShapeType(random( 8 ));
// we make its color random
shp.Brush.Color := RGBToColor(
random(255),
random(255),
random(255)
) ;
// set the click event
shp.OnClick := @WhatToDo;
end;</pre>
<br />
Here, the command is like before. We only give our shapes a random shape and we give each one a random color. So each shape is different than other.<br />
<br />
Now Run the project to see your hard work! (Press F9 or Run-> Run.)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-r0XIJgandHE/VUj7R1WXhHI/AAAAAAAAB8c/SWMfaPE02ww/s1600/clone-real-project-4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="http://2.bp.blogspot.com/-r0XIJgandHE/VUj7R1WXhHI/AAAAAAAAB8c/SWMfaPE02ww/s320/clone-real-project-4.gif" width="320" /></a></div>
<br />
Now click the buttons to test!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-IrQIkoWObjU/VUj7mvmGrxI/AAAAAAAAB8k/e89t5ewcDwY/s1600/clone-real-project-5.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="http://3.bp.blogspot.com/-IrQIkoWObjU/VUj7mvmGrxI/AAAAAAAAB8k/e89t5ewcDwY/s320/clone-real-project-5.gif" width="320" /></a></div>
<br />
<h3>
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/Ivkd1Pbq">here</a>.<a href="https://db.tt/XCO9id6W"></a><br />
Or <a href="https://drive.google.com/uc?export=download&id=0B9WrDtlrEzlSYmFNNldUaWphbnc">here</a><a href="http://bit.ly/pascal_pong_game"></a><br />
Size: 588 KB<br />
The package contains compiled executable EXE file.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com5tag:blogger.com,1999:blog-5314745381778741517.post-26147968762620540752015-04-07T20:12:00.000+01:002015-04-07T20:13:12.585+01:00Lazarus 1.4 RC3 is available and why you should test it<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" height="122" ilo-full-src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" width="162" /></a></div>
Lazarus 1.4 RC3 has been released. There are a lots of awaited updates and fixes. See how much Lazarus has evolved.<br />
<a name='more'></a><br />
Lazarus 1.4 Release Candidate 3 has been released. A <a href="http://forum.lazarus.freepascal.org/index.php/topic,27985.0.html">forum post</a> has confirmed the news.<br />
<br />
<b>This version has some major changes, this is why developers urge to test it with your existing projects.</b> It can live as a secondary installation, so you don't need to worry about messing up the existing stable installation of Lazarus. Developers say that if you don't report any misbehavior now, they may be unable to consider the fix for the 1.4.x branch.<br />
<br />
The major change in this version is that all LCL resources are changed from LRS to RES. What this means is now you can edit those resources with a resource editor even after building your exe.<br />
<br />
<h3 style="text-align: left;">
Ummm... Did I smell new features?!</h3>
Besides testing, you can have the taste of freshly baked features, such as:<br />
- The toolbar can now have new tabs (or pages)<br />
- You can rearrange the components and put them in your desired pages (awesome!)<br />
- Auto-Indent now supports "tab only".<br />
- The compiler messages now have a "quick fix" option:<br />
"Compiler message marks. Each compiler message shows an icon in the left gutter, a wavy underline in the text and a mark on the right gutter. You can right click on the left icon to get context actions, e.g. Quick Fixes."<br />
- In the form designer, now you can undo moving, resizing, deleting any component (neat!)<br />
- "The Help/Help menu starts the lhelp help viewer and shows all CHM files"<br />
- "The Inspector now supports multi selection. For example delete multiple files or set properties."<br />
- "You can drag files from other applications and drop them on Inspector to add files to the project."<br />
- The Messages window has been rewritten. Now supports separate header for every tool, searching & filtering in messages, on the fly language switching, changing colors<br />
- There are more changes... <a href="http://wiki.lazarus.freepascal.org/Lazarus_1.4.0_release_notes">check out yourself</a><br />
<br />
1.4 RC3 version is built with fpc 2.6.4. So no surprizes there.<br />
<br />
At the end, a thousand thanks to the Lazarus Developers for their hard work in this valuable project.<br />
<br />
<h3 style="text-align: left;">
What's New</h3>
The complete list of changes are <a href="http://wiki.lazarus.freepascal.org/Lazarus_1.4.0_release_notes">listed here</a>.<br />
<br />
<h3 style="text-align: left;">
Download</h3>
The release is available for download at SourceForge:<br />
<a href="http://sourceforge.net/projects/lazarus/files/">http://sourceforge.net/projects/lazarus/files/</a><br />
<br />
Choose your CPU, OS, distro and then the "Lazarus 1.4 RC3" directory.<br />
<br />
<br />
<br />
<b>Minimum requirements:</b><br />
Windows: 98, 2k, XP, Vista, 7, 32 or 64bit.<br />
On 64bit it is recommended to use the 32bit IDE.<br />
Win98 IDE needs building with flag -dWIN9XPLATFORM.<br />
FreeBSD/Linux: gtk 2.8 or qt4.5, 32 or 64bit.<br />
Mac OS X: 10.5 to 10.10, 10.9+ debugging requires -gw,<br />
LCL only 32bit, non LCL apps can be 64bit.<br />
<h3 style="text-align: left;">
Alternate Download</h3>
For people who are blocked by SF, the Lazarus releases from SourceForge are mirrored at:<br />
<a href="ftp://freepascal.dfmk.hu/pub/lazarus/releases/">ftp://freepascal.dfmk.hu/pub/lazarus/releases/</a><br />
and later at (after some time for synchronization)<br />
<a href="http://michael-ep3.physik.uni-halle.de/Lazarus/releases/">http://michael-ep3.physik.uni-halle.de/Lazarus/releases/</a><br />
and<br />
<a href="http://mirrors.iwi.me/lazarus/">http://mirrors.iwi.me/lazarus/</a><br />
<br />
<h3 style="text-align: left;">
How-to-Install Guide</h3>
<br />
You can <a href="http://lazplanet.blogspot.com/2013/03/how-to-install-lazarus.html">click here for an installation guide</a> for all Operating Systems.<br />
If you are an Ubuntu user then also see <a href="http://lazplanet.blogspot.com/2013/05/how-to-install-lazarus-108-on-ubuntu.html">this post for an exclusive guide for installing Lazarus 1.0.10 in Ubuntu 13.04</a> (you can follow the same guide to install in previous or latest versions of Ubuntu, such as 12.04 LTS, 12.10, 13.10, 14.04 LTS, 15.04 etc. or any other debian based OS).<br />
<br />
<h3 style="text-align: left;">
Source</h3>
<a href="http://forum.lazarus.freepascal.org/index.php/topic,27985.0.html">Lazarus Forum Announcement Post</a><br />
<a href="http://wiki.lazarus.freepascal.org/Lazarus_1.4.0_release_notes">Wiki - 1.4.0 Release Notes </a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com0tag:blogger.com,1999:blog-5314745381778741517.post-48388737768039513552015-01-12T18:33:00.000+00:002015-01-19T17:22:36.716+00:00Everything about using 2 forms... or more!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--5DHM4WwsxM/VLQTHcYD0II/AAAAAAAAB1c/kPJf1Hm3djA/s1600/lazarus-multi-forms.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Multiple forms in Lazarus IDE" border="0" src="http://3.bp.blogspot.com/--5DHM4WwsxM/VLQTHcYD0II/AAAAAAAAB1c/kPJf1Hm3djA/s1600/lazarus-multi-forms.gif" height="150" title="Multiple forms in Lazarus IDE" width="200" /></a></div>
We love forms, right? So why have only one? Why not two?! Let's learn how to create multiple forms, manage them and use them as dialog boxes.<br />
<a name='more'></a><br />
When we create a new Application Project, we get one form with our project. We love forms because every GUI project that we start, it starts from a form, a blank form. Then it gradually grows to a full application. We could consider it a building block for our applications.<br />
<br />
For some projects it is okey to have one form. But for some others, we need extra forms. For example, a form might be needed for an About dialog, or a Settings dialog.<br />
<br />
There is a way for using multiple forms. And in this little must-read tutorial, we're gonna learn how to use and manage multiple forms in our project.<br />
<br />
<h3 style="text-align: left;">
Creating the project (as usual)</h3>
Start <a href="http://lazarus.freepascal.org/">Lazaurs</a>.<br />
<br />
First we need a project. If you have one open it. But it is better to create a new project just for this practice. To create a new project start Lazarus and then click Project -> New Project, select "Application" from the list, then press OK.<br />
<br />
This will create a project with one Form in it. It is of no surprise that by default the form is named Form1. Okey, so let's continue...<br />
<br />
<h3 style="text-align: left;">
Creating a new Form</h3>
We already have a single form. Now we want to add another form. So, <b>click File -> New Form</b>. You will see a new form titled "Form2" in the screen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-DuOIpSrVkHw/VLQO7mkLIKI/AAAAAAAAB1Q/vUZI58ZIQ9k/s1600/lazarus-new-form-menu.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Lazarus New form on menu" border="0" src="http://4.bp.blogspot.com/-DuOIpSrVkHw/VLQO7mkLIKI/AAAAAAAAB1Q/vUZI58ZIQ9k/s1600/lazarus-new-form-menu.gif" height="320" title="Lazarus New form on menu" width="233" /></a></div>
<br />
Now that you have created another form it is better to save the project to understand how they work. So, go ahead and click File -> Save All... and save the project. You can use the default file names, don't worry!<br />
<br />
So you have saved project1.lpi, unit1.pas and unit2.pas.<br />
<br />
<h3 style="text-align: left;">
How to see all your forms in current project and switch between them</h3>
If you have followed the instructions correctly, now you have 2 forms in your project. If you don't trust me, press <b>Shift + F12</b> to bring up the "View Project Forms" dialog. In this dialog you will see all the forms the current project has.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-zHX2nZ7uzdQ/VIfoivSSrAI/AAAAAAAABzw/1nmgfCe2jD0/s1600/View-project-forms-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="View Project Forms window in Lazarus IDE, triggered by Shift + F12" border="0" src="http://1.bp.blogspot.com/-zHX2nZ7uzdQ/VIfoivSSrAI/AAAAAAAABzw/1nmgfCe2jD0/s1600/View-project-forms-1.jpg" height="232" title="View Project Forms window shows all the forms in current project. It can be triggered by Shift + F12" width="320" /></a></div>
<br />
You can <b>double click</b> on the forms from the list of that dialog to bring it up in the form design view. This will switch to that form to let you design it. You can also try the Window menu to switch between forms.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-JRMUzJ5cZj8/VIfqfZNtMuI/AAAAAAAABz8/zok-RMNPFl4/s1600/switch-forms-menu-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Switching forms in Lazarus is also possible with menus" border="0" src="http://3.bp.blogspot.com/-JRMUzJ5cZj8/VIfqfZNtMuI/AAAAAAAABz8/zok-RMNPFl4/s1600/switch-forms-menu-lazarus.gif" height="268" title="Switching forms in Lazarus is also possible with menus" width="320" /></a></div>
Additionally, I hope you remember that we press <b>F12 </b>to switch between form and code view.<br />
<br />
<h3 style="text-align: left;">
Showing one Form from another Form</h3>
<br />
Suppose we want to show Form2 from Form1. Form1 will have a button. When the user clicks it, Form2 will show.<br />
<br />
So, switch to Form1, draw a TButton on the form. Set its Caption as "Show Form2" from the Object Inspector. Double click it and enter...<br />
Well wait. We want to use Form2 in our code. But that <b>won't work</b>. Try writing "form2" and pressing Ctrl+Space. It won't autocorrect. That means <b>Form2 is not found by Form1</b>!<br />
<br />
Although you have saved both unit1.pas and unit2.pas in the same project directory, Pascal won't find it right away. You will have to manually add it to the uses clause of Form1's code (Unit1). We will have to point a finger and tell Pascal that we want to use the TForm present in Unit2 in our code. If we don't, Pascal won't find it itself. It is similar to the situation when you add path to a library directory, still you need to add the unit name(s) in the uses clause. Or else, pascal won't add the library unit itself. That's the way Pascal works.<br />
<br />
So in the Form1 code's uses clause, we'll have to add Unit2 in order to use Form2 in our code.<br />
<br />
<pre class="brush:pascal">unit Unit1;
//...
//...
uses
..., ...,
Unit2;</pre>
<br />
<b>(Remember, uses clause only knows the Unit name, not the form name. So we've used Unit2, not Form2.)</b><br />
<br />
To show Form2, the code would be: Form2.Show; Now we can write it since we have added Form2 in the uses clause. You will have to add the unit name to uses clause whenever you want to use one form from another.<br />
<br />
Now let's get back to the button. Double click it then add the code:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;</pre>
<br />
Now Run the Project (F9 or Run -> Run). Then click the button. Form2 will show. That means our code is working!<br />
<br />
The code is working. But when you would want to use Form1 from Form2 it will give you a circular reference error. To avoid this, we should add an implementation clause then dump our reference under it. We'll be looking into this problem a bit further. But for now, delete the Unit2 from uses and add an implementation clause and keep it there:<br />
<br />
<pre class="brush:pascal">unit Unit1;
//...
//...
uses
..., ... {,
Unit2};
implementation
uses
Unit2;</pre>
<br />
<h3 style="text-align: left;">
Accessing Form1 from Form2</h3>
<br />
We tried accessing Form2 from Form1. Now its time to to do the opposite: access Form1 from Form2.<br />
<br />
Now here's an important note, if you add unit1 in the uses clause of unit2, it wouldn't work. It will raise unit2.pas(xxx,yyy) Fatal: Circular unit reference between Unit2 and Unit1.<br />
<br />
<pre class="brush:pascal">unit Unit2;
uses
..., ..., unit1;
// This code is wrong! It will raise a Circular unit reference error.</pre>
<br />
So a solution to this problem is adding ANOTHER uses clause under implementation clause.<br />
<br />
<pre class="brush:pascal">unit Unit2;
uses
..., ...;
implementation
uses
Unit1;</pre>
<br />
And also in Unit1 if you haven't done it, go ahead and make the change:<br />
<br />
<pre class="brush:pascal">unit Unit1;
//...
uses
//...
//...
implementation
uses
Unit2;</pre>
<br />
Now, with this cool tip you can use both forms back and forth.<br />
<br />
<br />
<h3 style="text-align: left;">
Testing the link</h3>
<br />
You can add some buttons to test whether the link between the forms work.<br />
<br />
Draw 2 buttons on Form1. Code Button1click like: <br />
<pre>Form2.Show;</pre>
<br />
Code Button2click like:<br />
<pre>Form2.Color:=clRed;</pre>
<br />
Draw 1 button on Form2 and code on its click event:<br />
<pre>Form1.Color:=clGreen;</pre>
<br />
You get the idea.<br />
<br />
<h3 style="text-align: left;">
Making Form2 appear first</h3>
When we run the project, Form1 usually comes first on the screen. How can we set some other form as the first one? Let's see...<br />
<br />
Go to Project -> Project Options. Then under Project Options click Forms. You would see 2 lists. The list on the right doesn't matter to us right now.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-tojjgkAA5vI/VLP9s8k1E7I/AAAAAAAAB1A/YwH72QCSsYc/s1600/first-form-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="How to set the default form to form2 in Lazarus " border="0" src="http://2.bp.blogspot.com/-tojjgkAA5vI/VLP9s8k1E7I/AAAAAAAAB1A/YwH72QCSsYc/s1600/first-form-lazarus.gif" height="243" title="How to set the default form to form2 in Lazarus " width="400" /></a></div>
<br />
Select Form2 from the list on the left and click the Up arrow icon. Make sure that Form2 is the topmost item. Then click OK.<br />
<br />
The topmost item on that list appears first.<br />
<br />
<h3 style="text-align: left;">
Showing Forms as Dialog Boxes</h3>
<br />
If you want to show a form as a dialog box, its easy! Here's the code:<br />
<br />
Form2.ShowModal;<br />
<br />
It does the following:<br />
(1) It shows the form<br />
(2) Locks the parent form from which it was triggered<br />
(3) Halts running code after the line Form2.ShowModal.<br />
<br />
When the user closes the form (or hits the OK button or maybe something else to close it) the code after the line resumes to execute.<br />
<br />
We can use this behavior to capture the settings that the user put in the dialog.<br />
<br />
<h3 style="text-align: left;">
Reading settings from a Modal form</h3>
Suppose, the modal form is our dialog box. So we want to update something according to the settings that the user changed. How could we do it?<br />
<br />
There are many ways to do that. One of the ways is described in the <a href="http://wiki.freepascal.org/Form_Tutorial#Passing_Variables_to_Other_Forms">Free Pascal/Lazarus Wiki</a>. Well, you can follow that instructions. But I think I should write in my own way which I find simpler.<br />
<br />
We would use something called a <a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Forms_TCustomForm_ModalResult.html">ModalResult property</a> of the modal form. The default value for ModalResult is mrNone. If the value of it changes, the modal form automatically closes and the .ShowModal returns the value of the ModalResult. We can set its value to mrOK, mrCancel, mrIgnore etc. In that case the value will be returned to the parent form. This is a very logical workflow for handling modal forms and great for handling all the cases possible.<br />
<br />
Let's suppose we have 2 forms - Form1 is our parent form and Form2 is our modal form. On form1 I drop a button. And on form2 I create TEdit and two buttons btnOK and btnCancel. So:<br />
<br />
1. On the OK button of the Form2 I set ModalResult to mrOK.<br />
<br />
<pre class="brush:pascal">procedure TForm2.btnOKClick(Sender: TObject);
begin
// the parent form will get the mrOK value
ModalResult:=mrOK;
end;</pre>
<br />
...And the Cancel button would have:<br />
<br />
<pre class="brush:pascal">procedure TForm2.btnCancelClick(Sender: TObject);
begin
ModalResult:=mrCancel;
end;</pre>
<br />
2. This will let the parent form's code to continue where it left off. So, we can now access every component in modal form.<br />
<br />
<pre class="brush:pascal">procedure TForm1.Button1Click(Sender: TObject);
begin
// we detect that ok button has been pressed
if Form2.ShowModal = mrOK then begin
Form1.Caption:=Form2.Edit1.Text;
end;
end;</pre>
<br />
All the possible values for ModalResult (copy-pasted from the Controls unit):<br />
<pre class="brush:pascal"> mrNone = 0;
mrOK = mrNone + 1;
mrCancel = mrNone + 2;
mrAbort = mrNone + 3;
mrRetry = mrNone + 4;
mrIgnore = mrNone + 5;
mrYes = mrNone + 6;
mrNo = mrNone + 7;
mrAll = mrNone + 8;
mrNoToAll = mrNone + 9;
mrYesToAll = mrNone + 10;
mrClose = mrNone + 11;
mrLast = mrClose;</pre>
<br />
So, now you are ready to make multiple forms appear in your project.<br />
So go on and make some forms!<br />
<br />
<br />
<br /></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com14tag:blogger.com,1999:blog-5314745381778741517.post-34584802166871256502014-11-18T09:09:00.002+00:002014-11-18T10:19:55.292+00:00Find out the smallest number from two numbers<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-RUFxHvT6awg/VGsIypMCRuI/AAAAAAAABv4/gqVav5JqAJU/s1600/min-number.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="minimum number between two numbers in Lazarus, Free Pascal" border="0" src="http://1.bp.blogspot.com/-RUFxHvT6awg/VGsIypMCRuI/AAAAAAAABv4/gqVav5JqAJU/s1600/min-number.jpg" title="minimum number between two numbers in Lazarus, Free Pascal" /></a></div>
This is usually a very basic task for beginner programmers. Find out the smaller from two numbers.<br />
<a name='more'></a><br />
<br />
There are many basic problems that a beginner programmer has to solve. One of the most popular is finding the smallest number out of two.<br />
<br />
Luckily, Free Pascal has a ready-made function for that. <a href="http://www.freepascal.org/docs-html/rtl/math/min.html">The function is Min()</a> and can be found under the math unit. The function is very easy. Even you can write it yourself. Just see the code:<br />
<br />
<pre class="brush:pascal">// Copied from the math unit.
// We don't need to write it ourselves.
function Min(a, b: Extended): Extended;inline;
begin
if a < b then
Result := a
else
Result := b;
end;</pre>
<br />
The function pasted here is for Extended numbers. But it has declarations for Integer, Int64 and Extended. Writing functions for all these types will be cumbersome for you. So, it is nicely packed in the math unit.<br />
<br />
Basically, what it does is return the number which is smaller between the two provided. <br />
<br />
<h3 style="text-align: left;">
The syntax</h3>
<br />
The syntax of Min() function is very simple. Just input two numbers. They can be Integer, Int64 or Extended. So it pretty much covers every number you can think of:<br />
<br />
<pre class="brush:pascal">function Min(
a: Integer;
b: Integer
):Integer; overload;
function Min(
a: Int64;
b: Int64
):Int64; overload;
function Min(
a: Extended;
b: Extended
):Extended; overload;</pre>
<br />
<h3 style="text-align: left;">
Example Console Program</h3>
Start <a href="http://lazarus.freepascal.org/">Lazarus</a>.<br />
<br />
Now add the math unit to the uses clause:<br />
<pre class="brush:pascal">uses
..., ..., math;</pre>
<br />
Now add a var clause before the begin block:<br />
<br />
<pre class="brush:pascal">var
x,y: integer;</pre>
<br />
(You can change this to single, double, extended according to needs.)<br />
<br />
<br />
Now paste the following code in the begin...end block:<br />
<br />
<pre class="brush:pascal">begin
WriteLn('Write two integers (press enter after each):');
ReadLn(x);
ReadLn(y);
WriteLn('The smaller one is: ', Min(x,y) );
ReadLn;
end.</pre>
<br />
We are basically taking two numbers through the ReadLine statements then passing the values to the Min() function. Min function then returns the minimum number.<br />
<br />
The resulting code is as follows:<br />
<br />
<pre class="brush:pascal">program proj_min_num;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, math;
var
x,y: integer;
begin
WriteLn('Write two integers (press enter after each):');
ReadLn(x);
ReadLn(y);
WriteLn('The smaller one is: ', Min(x,y));
ReadLn;
end.</pre>
<br />
Now Run the Project (Run-> Run or press F9).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-I-AGEp6O1po/VGsMmFBNDtI/AAAAAAAABwE/SBVNTrvtWfs/s1600/min-number-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Minimum number between two numbers in Lazarus, Free Pascal" border="0" src="http://3.bp.blogspot.com/-I-AGEp6O1po/VGsMmFBNDtI/AAAAAAAABwE/SBVNTrvtWfs/s1600/min-number-lazarus.gif" height="195" title="Minimum number between two numbers in Lazarus, Free Pascal" width="320" /></a></div>
<br />
Test it with two numbers on each line. You should get the minimum number between the two inputs.<br />
<h3 style="text-align: left;">
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/aSea8hOp">here</a>.<br />
Or <a href="http://bit.ly/min-number">here</a> <br />
Size: 71 KB<br />
The package contains compiled executable EXE file.<br />
<br />
Ref:<br />
<a href="http://www.freepascal.org/docs-html/rtl/math/min.html">http://www.freepascal.org/docs-html/rtl/math/min.html</a> </div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com0tag:blogger.com,1999:blog-5314745381778741517.post-61070408726902373892014-10-16T12:37:00.003+01:002014-10-16T12:37:48.137+01:00Lazarus 1.2.6 (with FPC 2.6.4) Released!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" height="122" ilo-full-src="http://3.bp.blogspot.com/-oA9UpWFum6w/Ubtes8bszUI/AAAAAAAABB0/R2a6EWkKgeE/s1600/Lazarus-Logo.png" width="162" /></a></div>
Lazarus 1.2.6 has been released. It is the third version with FPC 2.6.4. It is basically a bug fix release but worth upgrading. <br />
<a name='more'></a><br />
<br />
Lazarus is getting bug-free everyday. Here is another stable release of Lazarus - version 1.2.6. It has FPC 2.6.4. The previous version 1.2.4 also had this version of FPC. This version has many new bug fixes. You can look at the <a href="http://wiki.lazarus.freepascal.org/Lazarus_1.2_fixes_branch#Fixes_for_1.2.6_.28Merged.29">changes here</a>.<br />
<br />
Lazarus 1.2.6 is a better version than 1.2.4 because many bugs have been fixed and recommended to upgrade. As previous versions, this version also allow multiple instances of Lazarus running on Windows. <a href="http://forum.lazarus.freepascal.org/index.php/topic,26134.msg160016.html#msg160016">People have been telling</a> that Lazarus 1.2.6 also works with Wine under Linux. That's definitely great to hear.<br />
<br />
The look of this version is similar to the previous version of Lazarus. No real change there...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-L6GeRpX3Res/VD-sareg5AI/AAAAAAAABuU/o91yF-w7kM8/s1600/Lazarus-1.2.6-fpc-2.6.4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Screenshot of Lazarus 1.2.6 with FPC 2.6.4 running under Windows 7" border="0" src="http://4.bp.blogspot.com/-L6GeRpX3Res/VD-sareg5AI/AAAAAAAABuU/o91yF-w7kM8/s1600/Lazarus-1.2.6-fpc-2.6.4.gif" height="189" title="Screenshot of Lazarus 1.2.6 with FPC 2.6.4 running under Windows 7" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
At the end, a thousand thanks to the Lazarus Developers for their hard work in this valuable project.<br />
<br />
<h3 style="text-align: left;">
What's New</h3>
The changes are <a href="http://wiki.lazarus.freepascal.org/Lazarus_1.2_fixes_branch#Fixes_for_1.2.6_.28Merged.29">listed here</a>.<br />
<br />
<h3 style="text-align: left;">
Download</h3>
The release is available for download at SourceForge:<br />
<a href="http://sourceforge.net/projects/lazarus/files/">http://sourceforge.net/projects/lazarus/files/</a><br />
<br />
Choose your CPU, OS, distro and then the "Lazarus 1.2.4" directory.<br />
<br />
Or from the homepage: <a href="http://lazarus.freepascal.org/index.php?page=downloads">http://lazarus.freepascal.org/index.php?page=downloads</a><br />
<br />
<br />
<b>Minimum requirements:</b><br />Windows: 98<br />FreeBSD/Linux: gtk 2.8 or qt4.5, 32 or 64bit<br />Mac OS X: 10.5 for Intel cpus, 10.4 for PowerPC, LCL only 32bit,<br /> non LCL apps can be 64bit<br />
<br />
<h3 style="text-align: left;">
Alternate Download</h3>
For people who are blocked by SF, the Lazarus releases from SourceForge are mirrored at:<br />
<a href="ftp://freepascal.dfmk.hu/pub/lazarus/releases/">ftp://freepascal.dfmk.hu/pub/lazarus/releases/</a><br />
and later at (after some time for synchronization)<br />
<a href="http://michael-ep3.physik.uni-halle.de/Lazarus/releases/">http://michael-ep3.physik.uni-halle.de/Lazarus/releases/</a><br />
and<br />
<a href="http://mirrors.iwi.me/lazarus/">http://mirrors.iwi.me/lazarus/</a><br />
<br />
<h3 style="text-align: left;">
How-to-Install Guide</h3>
<br />
You can <a href="http://lazplanet.blogspot.com/2013/03/how-to-install-lazarus.html">click here for an installation guide</a> for all Operating Systems.<br />
If you are an Ubuntu user then also see <a href="http://lazplanet.blogspot.com/2013/05/how-to-install-lazarus-108-on-ubuntu.html">this post for an exclusive guide for installing Lazarus 1.0.10 in Ubuntu 13.04</a> (you can follow the same guide to install in previous or latest versions of Ubuntu, such as 12.04 LTS, 12.10, 13.10, 14.04 LTS etc. or any other debian based OS).<br />
<br />
<h3 style="text-align: left;">
Source</h3>
<a href="http://forum.lazarus.freepascal.org/index.php/topic,26134.0.html">Lazarus Forum Announcement Post</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com1tag:blogger.com,1999:blog-5314745381778741517.post-89600295843037523662014-10-13T11:54:00.002+01:002014-10-13T11:54:20.223+01:00Find out if the Computer is Connected to the Internet<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-qFsY3mbVAwQ/VDuvO9dX5GI/AAAAAAAABuA/nSkbCbzz1N0/s1600/connected-thumb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-qFsY3mbVAwQ/VDuvO9dX5GI/AAAAAAAABuA/nSkbCbzz1N0/s1600/connected-thumb.jpg" /></a></div>
If you are doing something that depends on an internet connection, you would probably want to check if internet is available. That's what we are going to detect today.<br />
<a name='more'></a><br />
<br />
<br />
Today we will learn to check if the computer that our program is running is connected to the internet or not.<br />
<br />
This is just like a code snippet. In fact I found this one accidentally when searching for something. I found delphidabbler.com which is made for delphi, but most of the things also apply to Lazarus/Free Pascal. Delphidabbler.com is a great website if you know what you are doing.<br />
<br />
<br />
So the code I found is:<br />
<br />
<pre class="brush:pascal">uses
..., windows, wininet;
function IsInternetConnected: Boolean;
var
Flags: Windows.DWORD; // flags to pass to API function
begin
Flags := 0;
Result := WinInet.InternetGetConnectedState(@Flags, 0);
end;</pre>
<br />
The function will return True if the machine is connected to internet and False if its not.<br />
<br />
(By the way, it uses windows unit. So you can guess that it will not work with any platforms other than Windows.)<br />
<br />
We can use this code to build an example project.<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
Start <a href="http://lazarus.freepascal.org/">Lazarus</a>. <br />
Create a new Application Project (Project -> New Project -> Application -> OK).<br />
Place a TLabel and a TTimer (from System tab). You can resize your form and customize it the way you like. My form looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-AqpRBSYSz44/VDupa7uGL4I/AAAAAAAABto/-K1KiEf3Ako/s1600/is-connected.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-AqpRBSYSz44/VDupa7uGL4I/AAAAAAAABto/-K1KiEf3Ako/s1600/is-connected.gif" /></a></div>
<br />
Double click the TTimer (or Timer1) and enter the following code:<br />
<br />
<pre class="brush:pascal">// credits: delphidabbler.com
procedure TForm1.Timer1Timer(Sender: TObject);
var
Flags: Windows.DWORD; // flags to pass to API function
begin
Flags := 0;
if (WinInet.InternetGetConnectedState(@Flags, 0)) then
Label1.Caption:='Connected'
else
Label1.Caption:='Disconnected';
end;</pre>
<br />
Now scroll to the top of the code and add the two units in the uses clause:<br />
<br />
<br />
<pre class="brush:pascal">uses
..., ..., windows, wininet;</pre>
<br />
Now Run the project (F9 or Run -> Run).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-6XdhLjm2m3U/VDurN85rBDI/AAAAAAAABt0/cmhvFa_xAzA/s1600/is-connected-lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-6XdhLjm2m3U/VDurN85rBDI/AAAAAAAABt0/cmhvFa_xAzA/s1600/is-connected-lazarus.gif" /></a></div>
<br />
Now if the computer is connected to the internet, it will show "Connected". And if its not, the label will show "Disconnected".<br />
<br />
This code can be utilized in many ways. For example, if you're going to download a file from the internet you can check the connection before continuing. You can then prompt the user to get connected if he is not. Or maybe offering products to the user when he is online.<br />
<br />
<h3 style="text-align: left;">
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://db.tt/XCO9id6W">here</a>.<a href="https://db.tt/XCO9id6W"></a><br />
Or <a href="https://drive.google.com/uc?id=0B9WrDtlrEzlSaVBlX3lZMThJU3c&export=download">here</a><a href="http://bit.ly/pascal_pong_game"></a> <br />
Size: 543 KB<br />
The package contains compiled executable EXE file.<br />
<br />
<b>Ref:</b><br />
<a href="http://snippets.delphidabbler.com/">http://snippets.delphidabbler.com</a></div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com1tag:blogger.com,1999:blog-5314745381778741517.post-31612112291843189552014-10-04T07:33:00.000+01:002018-05-01T07:11:53.601+01:00Create a Pong game for yourself<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-4vH60iJ2_-Q/VC-HTLT57AI/AAAAAAAABsM/gEW8HgqFtDE/s1600/ping_pong.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Pong game" border="0" src="https://2.bp.blogspot.com/-4vH60iJ2_-Q/VC-HTLT57AI/AAAAAAAABsM/gEW8HgqFtDE/s1600/ping_pong.png" title="Pong game" /></a></div>
Everybody likes to play games. It gets even better if you play the game you made yourself.<br />
<a name='more'></a><br />
<a href="http://en.wikipedia.org/wiki/Pong">Pong game</a> was one of the most primitive <a href="http://lazplanet.blogspot.com/search/label/Games">graphical computer game</a> made in the early 1970s. Since then the gaming industry has evolved so much. And so did the graphics, bringing in many other types of games in the table. But still Pong game is considered to be the Hello World of Game Development. If you want to try learning to make games you should try to make a Pong Game first. It is easy to understand and easy to code.<br />
<br />
<h3 style="text-align: left;">
The Pong Game</h3>
<br />
<a href="http://en.wikipedia.org/wiki/Pong">The Pong game</a> was first introduced in 1972 by Atari Inc. It was in minimalistic game having two dimensional graphics. With the graphical capabilities just flourishing for the computers the Pong game was exciting for the gamers. Atari even made cabinet style gaming machine for Pong game. It is the game that basically started the video game industry. So it was a real game-changer.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-R8MtXunzRTQ/VC-GsGGDAvI/AAAAAAAABsE/azZGr-jYXgw/s1600/pong.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Pong game" border="0" src="https://2.bp.blogspot.com/-R8MtXunzRTQ/VC-GsGGDAvI/AAAAAAAABsE/azZGr-jYXgw/s1600/pong.jpg" title="Pong game" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Pong game</td></tr>
</tbody></table>
<br />
<br />
The game consists of two "paddles" and a ball. Among the two paddles, one is controlled by the user and another is controlled by the computer. The ball bounces from one paddle to another. And if the ball misses the paddle, it's game over. Simple.<br />
<br />
In this tutorial we will implement a single paddle game with very basic physics and with only 2 components on the form. And instead of placing the paddle in the side we will position it to the bottom.<br />
<br />
The original game has Artificial Intelligence but ours wouldn't have that. So relax!<br />
<br />
This tutorial will let you eliminate the complexity of drawing and focus on the logic of the game.<br />
<br />
<h3 style="text-align: left;">
Tutorial</h3>
<br />
Start <a href="http://lazarus.freepascal.org/">Lazarus</a>.<br />
<br />
Create a new Application Project (Project -> New Project -> Application -> OK). First resize the form to a comfortable size. I have resized mine to: Width = 460 & Height = 340 .<br />
<br />
Set the form's Color to clBlack. This color will be the background of our game. Games are better in Black backgrounds, don't you think?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oqoisGSIous/VC-I_MsP6EI/AAAAAAAABsY/C05RQD4qT3Q/s1600/Lazarus-Pong-Game-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="254" src="https://3.bp.blogspot.com/-oqoisGSIous/VC-I_MsP6EI/AAAAAAAABsY/C05RQD4qT3Q/s1600/Lazarus-Pong-Game-1.gif" width="320" /></a></div>
<br />
Draw 2 TShapes on the form (TShape is available in the Additional tab). Set one Component's name as "Ball" and another as "Paddle". Set the Shape of the "Ball" to stCircle. It is better to set both the Width and Height of the ball to same. Size the "Paddle" to something you like.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-2DdFLZil01s/VC-JEIswmqI/AAAAAAAABsg/J0CBR1s75no/s1600/Lazarus-Pong-Game-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="254" src="https://2.bp.blogspot.com/-2DdFLZil01s/VC-JEIswmqI/AAAAAAAABsg/J0CBR1s75no/s1600/Lazarus-Pong-Game-2.gif" width="320" /></a></div>
<br />
Set the Form's Caption to "Pascal Ping Pong - Use left and right arrow to move the paddle". This text will be shown when the player hasn't scored yet. This will help a newbie player to understand how play the game.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-gKBgRS1YZqU/VC-JLVUyLRI/AAAAAAAABso/JmGOXtVjdKQ/s1600/Lazarus-Pong-Game-3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="254" src="https://4.bp.blogspot.com/-gKBgRS1YZqU/VC-JLVUyLRI/AAAAAAAABso/JmGOXtVjdKQ/s1600/Lazarus-Pong-Game-3.gif" width="320" /></a></div>
<br />
Draw a TTimer in the form (from System tab). Place it anywhere you like because it is going to be hidden in runtime. Set its Interval property to 30.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ISjgq7NYKfM/VC-JVSrj0rI/AAAAAAAABsw/WPzMtOwIo8g/s1600/Lazarus-Pong-Game-4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://1.bp.blogspot.com/-ISjgq7NYKfM/VC-JVSrj0rI/AAAAAAAABsw/WPzMtOwIo8g/s1600/Lazarus-Pong-Game-4.gif" width="320" /></a></div>
<br />
See how our form looks and look at the Object Inspector to check if yours look the same (click to zoom).<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
Coding...</h3>
<br />
Now, let's get to our coding. Switch to Code View by pressing F12. Add code below before the first type clause:<br />
<br />
<pre class="brush:pascal">const
// This determines how much the paddle moves in one
// press of an arrow key
PaddleMoveAmount = 15;</pre>
<br />
Also, add the LCLType unit in the uses clause because we would need keyboard keycodes to capture user input (VK_LEFT, VK_RIGHT etc.):<br />
<br />
<pre class="brush:pascal">uses
..., LCLType;</pre>
<br />
Now add the following code in the first var clause in the unit:<br />
<br />
<pre class="brush:pascal">var
//...
// We store the player's score in this variable
// We would reset this to zero on Game Over
score: integer;
// We set which direction the ball is moving.
// DirectionLeft defines horizontal direction.
// DirectionTop defines vertical direction.
DirectionLeft, DirectionTop: Boolean;</pre>
<br />
Now select the Form and go to Events tab on the Object Inspector. Then click the [...] button next to OnKeyDown and enter the code:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
begin
// ---- Move left or right ---- //
if key = VK_LEFT then begin
if (Paddle.Left > PaddleMoveAmount ) then
Paddle.Left := Paddle.Left - PaddleMoveAmount
else if (paddle.Left > 0) then
Paddle.Left := 0;
end else if key = VK_RIGHT then begin
if (Paddle.Left + Paddle.Width < ClientWidth - PaddleMoveAmount) then
Paddle.Left := Paddle.Left + PaddleMoveAmount
else if (Paddle.Left + Paddle.Width < ClientWidth) then
Paddle.Left := ClientWidth - Paddle.Width;
end;
end;</pre>
<br />
What we are doing here is we are detecting if the user pressed left arrow. If he presses it we will make some less on the Left property to move the paddle to left. If the space on the left is less than 15 pixels then we make it move to 0 pixels to the left. Through the code we make sure that it does not go beyond the left boundary of the form.<br />
<br />
We will do the same for moving to the right. In this case we will move it until it hits the right edge.<br />
<br />
Now Double click Timer1 and enter:<br />
<br />
<pre class="brush:pascal">procedure TForm1.Timer1Timer(Sender: TObject);
begin
// ---- Move the ball according to its direction ---- //
if DirectionLeft then Ball.Left := Ball.Left-5
else Ball.Left := Ball.Left+5;
if DirectionTop then Ball.Top := Ball.Top-5
else Ball.Top := Ball.Top+5;
// ---- Collision ---- //
// top boundary
if Ball.Top < 0 then
DirectionTop := not DirectionTop;
// left and right boundary
if (Ball.Left < 0) or (Ball.Left + Ball.Width > ClientWidth) then
DirectionLeft := not DirectionLeft;
// detect hit on the paddle
if (
(Ball.Left > Paddle.Left)
and (Ball.Left + Ball.Width < Paddle.Left + Paddle.Width)
and (Ball.Top + Ball.Height >= Paddle.top)
and (DirectionTop = False)
) then begin
DirectionTop:=not DirectionTop;
inc(score); // same as score + 1
Caption:='Your score: '+IntToStr(score);
end;
// ---- You lose! The ball has sinked to the bottom ---- //
if Ball.Top > Paddle.Top then begin
Caption:='You lose! Your score was: '+IntToStr(score);
Timer1.Enabled:=False;
Sleep(5000);
Ball.Left:=0;
Ball.Top:=0;
score:=0;
Caption:='Your score: 0';
Timer1.Enabled:=True;
end;
end;</pre>
<br />
The code is well-commented. So I think you will understand the code yourself.<br />
<br />
<br />
Now run the Project (Run->Run or F9). Move the paddle with Left and Right arrow keys on the keyboard and enjoy!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/--XQ4NocLJbU/VC-L2N6SEUI/AAAAAAAABs8/YOK7wmDcXdU/s1600/Ping-Pong-Game-Lazarus.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://2.bp.blogspot.com/--XQ4NocLJbU/VC-L2N6SEUI/AAAAAAAABs8/YOK7wmDcXdU/s1600/Ping-Pong-Game-Lazarus.gif" width="320" /></a></div>
<br />
<br />
<h4 style="text-align: left;">
Pause function </h4>
If you want to add the Pause functionality, then change the Form's OnKeyDown event procedure code like the following:<br />
<br />
<pre class="brush:pascal">procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
begin
// ---- Move left or right ---- //
if Timer1.Enabled then begin
if key = VK_LEFT then begin
if (Paddle.Left > PaddleMoveAmount ) then
Paddle.Left := Paddle.Left - PaddleMoveAmount
else if (paddle.Left > 0) then
Paddle.Left := 0;
end else if key = VK_RIGHT then begin
if (Paddle.Left + Paddle.Width < ClientWidth - PaddleMoveAmount) then
Paddle.Left := Paddle.Left + PaddleMoveAmount
else if (Paddle.Left + Paddle.Width < ClientWidth) then
Paddle.Left := ClientWidth - Paddle.Width;
end;
end;
// ---- Pause or Unpause ---- //
if key = VK_P then
Timer1.Enabled := not Timer1.Enabled;
end;</pre>
<br />
At the bottom of the code we add an if statement for P keypress. On P key press we invert the Timer1.Enabled property. If it's True it will be made False. If it's False it will be made True. Our ball moving mechanism is in the Timer1. So if we Disable Timer1, the ball movement will stop making the game paused.<br />
<br />
We don't want the paddle to move when it's on pause mode. So we add an if statement to our previous left-right key code.<br />
<br />
Now whenever the user presses the P key, the game will pause. Another press on P will resume the game.<br />
<br />
So, there you have it. Your very own game made by you! Go on, have fun with it!<br />
<br />
<h3 style="text-align: left;">
Download Sample Code ZIP</h3>
You can download the above example tutorial project's source code from <a href="https://www.dropbox.com/s/0mo8d0vx23o6j9a/PingPong.zip?dl=1">here</a><br />
Or here: <a href="http://bit.ly/pascal_pong_game">http://bit.ly/pascal_pong_game</a> <br />
Size: 592 KB<br />
The package contains compiled executable EXE file.</div>
Adnan Shameemhttp://www.blogger.com/profile/03795435968155667026noreply@blogger.com2