Sunday, December 16, 2007

How to use unmanaged Win32 DLL in Delphi 2007 for .NET?

In this example, I will use GetCurrentThemeName in UxTheme.dll

Static/pre-binding:

function GetCurrentThemeName(pszThemeFileName: StringBuilder; cchMaxNameChars: Integer; pszColorBuff: StringBuilder; cchMaxColorChars: Integer; pszSizeBuff: StringBuilder; cchMaxSizeChars: Integer): HRESULT; stdcall; external 'UxTheme.dll';

Dynamic/post bidning:
This is a bit tricky.
  1. Add System.Runtime.InteropServices into uses clause.
  2. Add the function type and use [MarshalAs(UnmanagedType.LPWSTR)] for string parameter.
  3. Use Marshal.GetDelegateForFunctionPointer.
Confusing? Here is the example in Delphi 2007 for .Net

type
TGetCurrentThemeName = function(
[MarshalAs(UnmanagedType.LPWStr)]pszThemeFileName: string; cchMaxNameChars: Integer;
[MarshalAs(UnmanagedType.LPWStr)]pszColorBuff: string; cchMaxColorChars: Integer;
[MarshalAs(UnmanagedType.LPWStr)]pszSizeBuff: string; cchMaxSizeChars: Integer): HRESULT; stdcall;

var
H: THandle;
PAddr: IntPtr;
GetCurrentThemeName: TGetCurrentThemeName;
ThemeFilename, ColorBuff, SizeBuff: String;

begin
H := LoadLibrary('UxTheme.dll');

try

if H<>0 then
begin
PAddr := GetProcAddress(H, 'GetCurrentThemeName');
GetCurrentThemeName := TGetCurrentThemeName( Marshal.GetDelegateForFunctionPointer(PAddr, typeof(TGetCurrentThemeName)) );

SetLength(
ThemeFilename, 200);
SetLength(
ThemeFilename, 200);
SetLength(
SizeBuff, 200);

GCThemeName(
ThemeFilename, 200, ThemeFilename, 200, SizeBuff, 200);
end;

finally
FreeLibrary(H);
end;

end;

If you are looking for more Win32 API, here is a good site to visit http://www.pinvoke.net/default.aspx/uxtheme.GetCurrentThemeName

No comments: