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.
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
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. Read the rest of this entry »
Posted in Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, i18n internatiolanization and L10 Localization, Software Development | 4 Comments »