I'm running Delphi XE4 on a Windows 7 machine. I'd like to have one code base that can recognize whether to use CSIDL or KNOWFOLDERID.
Is there a way to use {$IFDEF XXXXXX) to conditionally compile different files in the uses section and to call different functions based on Windows XP or lower?
You very likely don't want to use conditional compilation for this. Doing so forces you to ship different executables for different versions of the operating system. That creates heavy installation complexity.
The usual approach to coping with the scenario is to using runtime branching rather than conditional compilation. So you would write code like this:
One thing that is crucial is that you must keep these if statements at as low a level as possible. You must hide these details from high level code. From the perspective of the high level code, it must ask for the location of a particular folder. The high level code must not contain any branching based on version.
The complication is that you cannot use load time linking for the branch that uses API functions that may not be present on the older supported platforms. So, instead of load time linking, use run time linking. There are lots of different ways to achieve that, but for system APIs, with modern versions of Delphi, delay loading is an excellent option.
Personally, I'm not averse to using CSIDL based APIs even now because I personally don't see MS removing the functionality any time soon. But the decision on whether or not to use CSIDL is obviously yours. I can certainly understand a desire not to use these APIs any more. It's clear that Microsoft don't want you to do so.
If you want to check for Windows version support then you are expected to use the new version helper APIs. I'm now aware that they have been included in the Windows units that ship with Delphi. Perhaps they are in the very latest but you may well have a version that does not have them. In which case you can use these: