September 7, 2009 by mzemaitis
Recently I had a very hard to find bug-problem with closing my application (made in Delphi).
It just refused to respond to Windows shutdown messages and prevented Windows to shutdown and restart..
I spent a lot of hours investigating this problem.
Initially the first part of the problem, because I was showing a dialog for "Really close?" and preventing closing if some files are not saved, this was done in FormCloseQuery and it was stupid approach, because FormCloseQuery doesn’t know if windows is shutting down and thus preventing shutdown.
Than, I made a Message listeners for windows asking applications query for shutdown : WM_QueryEndSession and WM_EndSession.
The problem remained: the messages were received only second time. The first time when Windows was shutting down the application was still preventing shutdown, and only for the second Shutdown call, the messages were received and Application quit.
So something else was corrupting even the messages queue.
After some time, I accidentally came under another Form in same application, which also had FormCloseQuery, this time it was really needed because this Form was closing with fading effect and Query was preventing close until fader finished. So that was the second part of the problem.
Again I needed to listen for Shutdown messages in this Form.
So to conclude: you need to listen for Windows shut down Messages and Queries in every form that has FormCloseQuery or better yet avoid it, if you want to let windows shutdown normally. Also to note: Delphi made apps, on Windows shutdown exit instantly without freeing objects, so be careful and it is a good practice to listen to Shutdown procedure and to call your own Closing procedure manually.
More code examples on this soon..
Posted in Delphi tips | Tagged FormCloseQuery WM_QueryEndSession | Leave a Comment »
March 27, 2009 by mzemaitis
Lately, I had a simple task to save and load some short strings in file.
The quickest and fastest way is to do it with streams (TFileStream or TMemoryStream).
Because in Delphi 2009 string type strings are Unicode so they are also double byte sized than in previous Delphi strings.
So you need to be very strict to write exact BYTES of the string, not characters, because character size is now 2 Bytes!
For Writing String to any stream use this Function :
The reading of string shoud be also exact with character size in mind. Because you can read only half of string:
function ReadStreamInt(Stream : TStream) : integer;
begin
Stream.ReadBuffer(Result, SizeOf(Integer));
end;
function ReadStreamStr(Stream : TStream) : string;
var
StrLen : integer;
TempStr : string;
begin
TempStr := '';
StrLen := ReadStreamInt(Stream);
if StrLen > -1 then
begin
SetLength(TempStr, StrLen);
//Here you should also check the character size
//Reading Bytes!
Stream.ReadBuffer(Pointer(TempStr)^, StrLen * SizeOf(Char));
result := TempStr;
end
else Result := '';
end;
Then you can write functions for writing and loading strings for example:
function SaveToDFile( FileName: String; sDescr : string; ) : boolean;
var MemStr: TMemoryStream;
begin
MemStr:= TMemoryStream.Create;
try
try
WriteStreamStr( MemStr, sDescr );
MemStr.SaveToFile(FileName);
result := True;
except
on E:EWriteError do result := False;
end;
finally
MemStr.Free;
end;
end;
function LoadFromDFile( FileName: String; var sDescr : string; ) : boolean;
var MemStr: TMemoryStream;
begin
MemStr:= TMemoryStream.Create;
try
try
MemStr.LoadFromFile(FileName);
sDescr := ReadStreamStr( MemStr );
result := True;
except
on E:EReadError do result := False;
end;
finally
MemStr.Free;
end;
end;
Hope it helps some.
Posted in Delphi tips | Tagged Delphi 2009, Strings Write Read Stream | Leave a Comment »
February 19, 2009 by mzemaitis
Microsoft introduced new TTS voice called "Anna" on Vista OS. Sadly it is only available for Vista and no separate download option for Windows XP users, personally I still use Windows XP on many machines.
You can find more info about TTS (Text To Speech engines on Microsoft site). New voice "Anna" is more clear and more natural, than any other voice available on XP versi0ns.
Still, there is an option to use "Anna" voice on XP for FREE. You need to download and install Microsoft Street And Trips 2009 !
It is available for FREE (60 day trial version is download-able from Microsoft here ). Its huge, about 1,5 GB, so you need some place on your hard disk for download.
So download and install Streets 2009. With it also Microsoft nice "Anna" TTS engine is installed to pronounce (speak) street names.
You can enjoy this product for 60 days, or uninstall it the same day — "Anna" engine will not be uninstalled ! Cool.
It is still left on system.
You can check its properties through Control Panel’s Speech category settings.
Enjoy!
PS. It is also possible to extract only TTS Anna setup files (About 32 MB). But still you should download Streets at first. Then after installation start, look for temp folder where temporary installation files were extracted. Most probably it will be your User’s "Documents and Settings/Local settings/Temp" Folder. Look for TTS.
Posted in Software | Tagged Anna, engine, TTS, Windows, XP | 1 Comment »
November 13, 2008 by mzemaitis
For those who are searching TCoolTrayIcon component written by Troels Jakobsen to support newest Delphi versions.
It’s a comprehensive component for adding icons to the traybar, allowing you to put a tray icon in your own programs. Can hide, show program button on Taskbar, show hide hint balloons and similar. The original component you can find on Troel’s website here: http://subsimple.com/delphi.asp
It’s freeware, so you can use it freely.
The problem is, it was updated very long ago, and supports Delphi versions until 6, though it should function ok till 2007 version.
As with Delphi 2009, where all string and char become full Unicode, version on Troel’s website isn’t compatible with Delphi 2009 anymore.
No problem. Sebastian Zierer already made some changes to support Unicode chars. You can find TCoolTrayIcon component for Delphi 2009 on his website : http://tib.s.songbeamer.eu/downloads/Cooltray.zip or you can download same copy here from my website: Download TCoolTrayIcon zip package
Update: 2008.11.12 fixes for Delphi 2009
Update: 2009.09.04 with Delphi 2010 package
Posted in Delphi components | Tagged TCoolTrayIcon component Delphi 2009 | Leave a Comment »
April 16, 2008 by mzemaitis
Some notes about Windows Desktop Search, well, for some people it may be a very good tool. I thought it should help me a lot to find my files. But wait, what a resource eater this WDS is, and really after 2 years of using it I didn’t become satisfactory with search results at all.
So I decided to uninstall it. Everything should be as always when you uninstall any MS program – simple, but really not for WDS.
I uninstalled it from “Add/Remove programs” control panel. OK, finished, restart. WDS doesn’t start and seems gone.
But later, when I pressed F3 in MyPC for file searching, and instead of standard simple windows search I SEE all again Windows Desktop Search, damn… Seems, it wasn’t full uninstall. Then I thought, I will install it again a fresh copy, and then I will uninstall. I downloaded an WDS EN 3.01 version from Microsoft website. Installed it. Going to remove in “Add/Remove Programs”, well…. it shows no WDS is installed (even with “Show updates” option). WTF. Though it clearly runs with my every computer start. So how to get rid of this thing without reinstalling all my pc??
Searching the google…
I found some information from Microsoft:
http://www.microsoft.com/technet/prodtechnol/windows/search/dtstshoot.mspx .
But man I didn’t install neither MSN search toolbars, nor other MS stuff, just WDS. Not useful information.
Found some instructions from Kotsar Andrew:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1456784&SiteID=1 .
OMG you need to create a WDS uninstall information manually, because I didn’t find such uninstall information even in my Windows dir (it should be hidden system folder with $KB….).
(.
But then again I found a very good instructions here:
http://www.davidarno.org/2007/10/26/how-to-remove-windows-desktop-search/ .
Well seems I am not the only one here with WDS. Luckily I had another computer with WDS installed and uninstall information present there. So you need to copy that information to your Windows directory (for WDS 3.01 it should be $NtUninstallKB917013$, hidden system folder ) and manually run spuninst.exe. Then it should uninstall.
Posted in Software | Tagged Desktop Search uninstall | Leave a Comment »
April 16, 2008 by mzemaitis
I’ll share some tip on File Creation in Delphi. Some day I had to make a solution to create same file stream a lot times in a cycle and to show it at regular intervals (it was opened in another application). Well, if file is already created and time interval get’s too short, you might get an exception, that file is "in use on another process" and even setting file permissions doesn’t help:
1: var File : TFileStream
2: File := TFileStream.Create(OutputFile, fmCreate or fmShareExclusive)
The solution is, first to check out if file is in use. We could use Windows API CreateFile function for this task:
1: function IsFileInUse(FileName: TFileName): Boolean;
2: var HFileRes: HFILE;
3: begin
4: Result := False;
5: if not FileExists(FileName) then Exit;
6: HFileRes := CreateFile( PChar(FileName), //Windows API Create
7: GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING,
8: FILE_ATTRIBUTE_NORMAL, 0);
9: Result := (HFileRes = INVALID_HANDLE_VALUE);
10: //returns false File handle if file is in use
11: if not Result then CloseHandle(HFileRes); //Deny and close handle
12: end;
Then you can check if file is in use:
1: if NOT IsFileInUse(OutputFile)
2: then File := TFileStream.Create(OutputFile, fmCreate or fmShareExclusive);
update: Zarko Gajis from About.com made another universal function for checking if "FileIsInUse" here:
Programmatically Check If File is In Use – Delphi Code
Posted in Delphi tips | Tagged FileStream Create Error | Leave a Comment »