Archive for the ‘Delphi’ Category
Posted by jpluimers on 2014/08/06
A long while ago, I wrote about a (then overdue post) on .NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class.
I had been using a similar technique in Delphi since before I found out about the [WayBack] TRecall class and thought: I think my TTemporaryCursor is smarter, as it is based on interfaces.
TRecall (and the [WayBack] Vcl.Graphics descendants [WayBack] TBrushRecall, [WayBack] TFontRecall, and [WayBack] TPenRecall) store [WayBack] TPersistent properties using the Assign method. They were introduced in Delphi 6.
Too bad there are only [WayBack] very few people using TRecall as lots of TPersistent things warrant sasaving and restoring.
My [WayBack] TTemporaryCursor (now [WayBack] at bitbucket) class only stores an integer, so it cannot derive from TRecall. Besides it is based on IInterface which got introduced in Delphi 6, but was present as IUnknown since Delphi 3 (see [WayBack] Interface It! A quick guide to the ins and outs of interfaces in Delphi. By Jimmy Tharpe).
This means that TRecall could have been based on IInterface, so I wonder why it was not.
Note I’m not the first to publish about such a class (Malcolm Grooves wrote [WayBack] TCursorSnapshot, SwissDelphiCenter has [WayBack] TMyCursor, Nick Hodges published about [WayBack] TAutoCursor), it’s just that it has been in my tool box for so long, and written memento classes that you will see 2 articles on it this week.
In the mean time (this works with Delphi 2009 and up), I also wrote a small class that does similar things for any [WayBack] anonymous method. More on that tomorrow.
Back to TRecall: it is an example of [WayBack] the memento pattern in Delphi. The [WayBack] memento pattern allows you to restore state.
SourceMaking.com a.k.a. [WayBack] Design Patterns and Refactoring is a great site about [WayBack] Design Patterns, [WayBack] UML, [WayBack] AntiPatterns and [WayBack] Refactoring.
Most pattern example code is available in all of the C#, C++, Delphi, Java and PHP languages.
Great stuff!
One of the constructs for restoring state is a [WayBack] try … finally … end construct: it allows you to always execute something in the finally block, for instance restoring the state to right before the try block. Read the rest of this entry »
Posted in Conference Topics, Conferences, Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Design Patterns, Development, Diagram, Event, Software Development, UML | 14 Comments »
Posted by jpluimers on 2014/08/05
I’ve done a bit of WinWord automation and came across different locations for the API:
New Style:
Old Style:
Fun fact: there is no Old Style Word 2007 documentation any more. You might expect it at http://msdn.microsoft.com/en-us/library/ms263641(v=office.12) but it is not there.
Not so fun fact (and the reason I was looking for the Documents documentation), is because of this big bug ONLY in Office 2010 (it does not occur in Office 2000 .. 2007, and is fixed in 2013): The WordMeister » Bug Word 2010: Documents collection is not correctly maintained.
The only workaround is to run an Office Add-in, or VBA Macro. Both not feasible for external clients.
–jeroen
Posted in Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Office, Office 2007, Office 2010, Office 2013, Office Automation, Office VBA, Power User, Scripting, Software Development, VBScript | Leave a Comment »
Posted by jpluimers on 2014/08/04
Short answer: do not use the GlobalContainer.
Long answers are in this Spring4D thread: How is the GlobalContainer intended to be used? Are there important don’ts? – Google Groups.
Especially read this message by Stefan Glienke that shows you to setup your main program without using GlobalContainer at all.
Note that this doesn’t mean you should avoid a container at all.
Background information:
–jeroen
Posted in Delphi, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE5, Delphi XE6, Development, Software Development, Spring4D | 5 Comments »
Posted by jpluimers on 2014/07/29
ModelMaker Code Explorer (MMX for short) stores the keyboard shortcuts in the registry.
I’ve had it occur once that somehow most (about 95%) of the shortcuts got lost.
Two thinks I learned from resurrecting the shortcuts:
- MMX writes these settings when you exit Delphi
- Only a few keys (with lots of values under them) store the keys.
To resurrect them,
Read the rest of this entry »
Posted in Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 5, Delphi 6, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2014/07/24
Late binding sometimes is your friend:
Set objWord = CreateObject("Word.Application")
Wscript.Echo "Version: " & objWord.Version
Wscript.Echo "Build: " & objWord.Build
objWord.Quit
The accompanying Delphi code:
uses
System.Win.ComObj;
procedure TTestVersionAgnosticWordMainForm.GetWordApplicationInfoButtonClick(Sender: TObject);
var
WordApplication: OleVariant;
Version: OleVariant;
Build: OleVariant;
begin
WordApplication := CreateOleObject('Word.Application');
try
try
Version := WordApplication.Version;
Build := WordApplication.Build;
LogMemo.Lines.Add(Version);
LogMemo.Lines.Add(Build);
finally
WordApplication.Quit;
end;
finally
WordApplication := Unassigned; // release it
end;
end;
–jeroen
via: How Can I Determine Which Version of Word is Installed on a Computer? – Hey, Scripting Guy! Blog – Site Home – TechNet Blogs.
Posted in Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Scripting, Software Development, VBScript | 10 Comments »
Posted by jpluimers on 2014/07/23
A while ago, some of the TODO comments in my source code disappeared from the TODO list.
I wondered why, so I found this question: How set up todo list categories in Delphi 2010?.
The Delphi TODO item syntax in source code comments is like this (thanks Nelson H C Nepomuceno):
{ TODO 1 -cImportant :Do this!}
// TODO 1 -cImportant: Do this!
My comment there, after I found out I had done a stupid global search replace involving colons:
The important thing is the colon somewhere after the TODO. If you do not have the colon, then the TODO list will not show the comment. Anything after the colon will be the action item in the TODO list.
–jeroen
via: How set up todo list categories in Delphi 2010 – Stack Overflow.
Posted in Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 7, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2014/07/22
Found out where the StackOverflow Pascal has its origins: What happened to comments in syntax highlighter? – Meta Stack Overflow.
Like any syntax highlighter, it is not perfect (only a Delphi compiler driven highlighter would have a chance to be perfect), but it does a pretty good job and gets better over time.
–jeroen
Posted in Borland Pascal, Delphi, Delphi 1, Delphi 2, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, FreePascal, Pascal, Software Development, Turbo Pascal | Leave a Comment »
Posted by jpluimers on 2014/07/19
Though fully justified text is most often in print, and not much in user interfaces any more, this might come in useful one day (it is based on the GDI functions TextOut and SetTextJustification):
David Millington Posted: Have you ever wanted to draw fully justified text ie, text that adheres to both the left and right sides of the destination rectangle? It’s more complicated than it seems, and there’s definitely no inbuilt support in the VCL. But here’s how to do it, including an open-source unit you can drop into your applications and use.
Drawing fully justified text to a canvas | Parnassus – Delphi Consulting & Plugins.
–jeroen
via:
Posted in Delphi, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2014/07/17
I observe an increase of people not asking questions on Stack Overflow any more…
Today, two interesting questions caught my eye.
The first one was by Martijn Coppoolse about Is it possible to figure out whether a type’s property has a ‘stored’ flag or not, preferably without having to create an instance of that type? (note: emphasis is mine)
Then the most interesting one (note this is about old Turbo Pascal style object syntax that is still available in Delphi, yes polymorphism with the object keyword): Could you please remind me if Objects support polymorphism? by Roman Yankovsky.
–jeroen
PS: Martijn posted the solution he used:
So I tried looking at the StoredProc pointer, and I can differentiate between three states:
- nil, which means stored False;
- Pointer(1), which means that no stored flag was specified;
- an actual pointer, which means that a method was specified; and the pointer seems to point at the relevant method’s CodeAddress. However, we always use private methods for that, and those don’t seem to be enumerated by GetMethods.
Still, those three states are basically what I needed: don’t include an element when StoredProc = nil; when StoredProc = Pointer(1) make it compulsory, and make it optional otherwise when it’s a pointer.
Thanks a lot to all who helped! +Qing-Shan Xiao +Jeroen Wiert Pluimers +Asbjørn Heid
–jeroen
Posted in Delphi, Delphi 7, Development, Software Development | 3 Comments »
Posted by jpluimers on 2014/07/17
I’m not a real expert on LCID (the values like 1033 (aka 0x409 or $409) and 1043 (aka 0x413 or $413), but here are a few notes on stuff that I wrote a while ago to obtain shell32.dll resource strings for various LCIDs.
The most often used way to load resource strings is by calling the LoadString Windows API call which loads the string for the currently defined LCID.
To get them for a different LCID, there are two ways:
- Set the LCID for the current thread (don’t forget to notify the Delphi RTL you did this, and update FormatSettings)
- Write an alternative for LoadString that gets a string for a specific LCID (so you can keep the current thread in a different LCID)
The first method – altering the LCID of the current thread – is done using SetThreadLocale in Windows XP or earlier, and SetThreadUILanguage in Windows Vista/2008 and up (I’m not sure on the timeline of Windows Server versions, but I guess the split is between 2003 and 2008) as mentioned at SetThreadLocale and SetThreadUILanguage for Localization on Windows XP and Vista | words.
SetThreadLocale is deprecated, as Windows has started switching from LCID to Locale Names. This can cause odd behaviour in at least Delphi versions 2010, XE and XE2. See the answers at delphi – GetThreadLocale returns different value than GetUserDefaultLCID? for more information.
But even on XP it has the potential drawback of selecting language ID 0 (LANG_NEUTRAL) which selects the English language if it is available (as that is in the default search order). Both Writing Win32 Multilingual User Interface Applications and the answers to LoadString works only if I don’t have an English string table and Windows skipping language-specific resources and the Embarcadero Discussion Forums: How to load specific locale settingsd thread that describe this behaviour.
To work around that, you can do two things: store your resource strings in locale dependent DLLs, or (if you don’t write those DLLs yourself), write an alternative for LoadString.
I’ve done the latter for Delphi, so I could load strings for a specific LCID from the Shell32.dll.
For a full overview of all these strings, see http://www.angelfire.com/space/ceedee/shell32stringtables.txt
A few pieces of code.
You can get the full code at the BeSharp – Source Code Changeset 100520 (now at bitbucket too). Read the rest of this entry »
Posted in Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, internatiolanization (i18n) and localization (l10), Software Development | 4 Comments »