Estinfo
Steps to recreateStep 1: Preparing input data
First I created 2D plain (.png) image from country border 20110308_maakond.dxf file, that I got from Estonian Land Board website using Google Sketchup. Then I created event and area masks using Gimp. Raster pattern image was created from orthophoto and area mask. To sets of images where created: 2x and 1x size. Larger images where created first, and then scaled down. This was done, to reduce off by one pixel errors and to get extra dataset to test on. Following images where created: | Step 2: Setting properties
2 identical size images where added to a form: event mask and raster image. Both images property of enabled was set to false - so click events would be handled by the form where they reside. Step 3: Event handling To get region change even, i tracked mouse move event. Problem with that is, it fires way to often. To reduce this amount timer was introduced. When 'first' move event was registered, then TODO: Continue |
Functionality
TODO: Add text
Main window
Interesting abnormalities:
Text to Speech
Main window
Interesting abnormalities:
- In delphi, programmer needs to explicitly tell the compiler if he wants to overload the procedure. This can be done by adding overload; directive after procedure definition.
Notification area
Weird bugs and trivia
- When menu was added to the trayicon, then menu shadowed the left click / double click events.
To fix this, Application.BringToFront(); was called. - Initially memo was aligned from bottom and other controls from left. When window was restored from Win 7 snap fill, then elements hight became larger, then window height.
To fix this, elements where added inside a panel and align was set to top (same for memo). - To enable speech, program uses imported SAPI 5.4 (Microsoft Speech Object Library) type library component wrappers, that where generated by Delphi XE IDE wizard.
Initially however, text was spoken synchronously and on Win Vista and 7, there was a mysterious bug in FPGA, that kept throwing "devision by zero". Bug was successfully fixed with changing word definition momentarily.
But as default mode kept blocking UI, then it was updated to asynchronous speech.
Functionality
More peculiar things:
- In delphi, programs are not asynchronous by nature. This becomes very obvious, when throwing UI events - thy start to be executed after your process call has finished.
There are many ways around the problem: - Share execution time in `Please don't make me hang` style - process call to Application.ProcessMessages;
- Using timer control for ad-hoc threading.
- Integrating calls with AsyncCalls threading library.
- Multitasking with threading control or etc.
- In delphi, (un)registering a global hotkey is weirdly simple task to accomplish. There is no direct need for Win API use.
Although if hotkey combination or handle is used, then RegisterHotKey will still fail.
Stick game
Game display
More peculiar things:
- In delphi, programmer can not directly access base class field or a function. (Self) pointer to the base class type is used to access function off of that.
- In delphi, programmer can not concatenate integers or other value types to a String with a `+` operator by default. IntToStr is used to convert Integers to Strings and reverse (parsing String) can be done with StrToInt.
- In delphi, there is an uncanny compiler precedence order. Parenthesis are used, to force right evaluation.
For example:
if amount > nNorm or amount < 1 then
gets interpreted as:
if (amount > (nNorm or amount)) < 1 then
while the correct way to write it would be:
if (amount > nNorm) or (amount < 1) then - In delphi xe, labels (controls in general) do not update as you change them. To invoke the update, refresh on the parent control needs to be called.
If programmer needs to make many updates to UI, it's updater can be turned off with BeginUpdate for some time, and turned back on later with EndUpdate.
Main window
Interesting abnormalities:
- In delphi, programmer can not have circular unit reference - meaning child node can't refer to it's parent.
Timer control is used to periodically check child value. Alternative would be to use an interface. - In delphi, programmer can easily create memory leaks, when dynamically creating new instances of objects.
Elements are instantiated with create method and one of following owner parameter {nil, Self, Application}. Where the owner is responsible for freeing the element.
Note, that user defined owner nil is the fastest, but programmer needs to provide a fail-proof memory freeing.
Just by setting element to nil (equavalient to null) does't mean that it'll get garbage collected. And try-finally with FreeAndNil with non nil owner, can be equally bad. ಠ_ಠ
Once game display is created, it is used again very much like a singelton, no new instance will be created. And for that one instance, it's memory is handled by Application. - In delphi xe, programmer can not simply run/debug more then one instance per time. It results in error being thrown, that tells executable can not be made.