Difference between revisions of "Windows Programming Tips"

From Free Pascal wiki
Jump to navigationJump to search
(Added getting special folders section)
Line 148: Line 148:
 
   CoInitialize(nil);
 
   CoInitialize(nil);
 
END.
 
END.
 +
</delphi>
 +
 +
===Getting special folders (My documents, Desktop, local application data, etc)===
 +
Often it is useful to get the location of a special folder such as the desktop. The example below shows how you can get the LocalAppData directory - where the Lazarus installer stores its configuration by default.
 +
Look in the shlobj unit for more defines that let you look up the Desktop, Recycle Bin, etc.
 +
<delphi>
 +
uses
 +
...
 +
shlobj;
 +
 +
var
 +
  AppDataPath: Array[0..MaxPathLen] of Char; //Allocate memory
 +
...
 +
begin
 +
...
 +
    AppDataPath:='';
 +
    SHGetSpecialFolderPath(0,AppDataPath,CSIDL_LOCAL_APPDATA,false);
 +
    writeln('Your local appdata path is: ' + AppDataPath);
 +
</delphi>
 +
 
</delphi>
 
</delphi>

Revision as of 17:25, 5 January 2012

This page is dedicated to desktop Windows programming tips.

Other Interfaces

Platform specific Tips

Interface Development Articles

Articles about Windows Programming

  • High DPI - How to make your application DPI-aware on Windows 7.
  • Aero Glass - How to apply Aero Glass effect in a Lazarus Form on Windows 7.
  • Windows Icon - How to design your icon with the right sizes.
  • Inno Setup Usage - How to create setup files with File Association support.

Code snippets

Listing all available drives

<delphi> program listdevices;

{$ifdef fpc}{$mode delphi}{$endif} {$apptype console}

uses

 Windows;

var

 Drive: Char;
 DriveLetter: string;

begin

 WriteLn('The following drives were found in this computer:');
 WriteLn();
 // Search all drive letters
 for Drive := 'A' to 'Z' do
 begin
   DriveLetter := Drive + ':\';
  
   case GetDriveType(PChar(DriveLetter)) of
    DRIVE_REMOVABLE: WriteLn(DriveLetter + ' Floppy Drive');
    DRIVE_FIXED:     WriteLn(DriveLetter + ' Fixed Drive');
    DRIVE_REMOTE:    WriteLn(DriveLetter + ' Network Drive');
    DRIVE_CDROM:     WriteLn(DriveLetter + ' CD-ROM Drive');
    DRIVE_RAMDISK:   WriteLn(DriveLetter + ' RAM Disk');
   end;
 end;
 // Also add a stop to see the result under Windows
 WriteLn();
 WriteLn('Please press <ENTER> to exit the program.');
 ReadLn(DriveLetter);

end. </delphi>

Creating a shortcut (.lnk) file

Taken from forum post by Lainz: Windows Startup post on forum

<delphi> UNIT shortcut;

INTERFACE

 uses windows;
 FUNCTION createShortcut(lnkpos : widestring; dstfn,dstargs,dstwdir,descr,iconfn : AnsiString; iconnum : longint) : boolean;
 // create a windows shortcut file (*.lnk)@lnkpos.
 // example: createSohrtcut('c:\test.lnk','c:\pascal\myprog.exe','-L 1000','c:\pascal','A nice Program.','c:\pascal\myprog.exe',0);

IMPLEMENTATION

TYPE REFCLSID = PGUID; REFIID = PGUID;

CONST CLSID_ShellLink : TGUID = '{00021401-0000-0000-C000-000000000046}'; IID_IShellLink : TGUID = '{000214EE-0000-0000-C000-000000000046}'; IID_IPersistFile : TGUID = '{0000010b-0000-0000-C000-000000000046}'; CLSCTX_INPROC_SERVER = 1;

FUNCTION CoInitialize(p : pointer) : HRESULT; stdcall; external 'ole32.dll'; FUNCTION CoUninitialize(p : pointer) : HRESULT; stdcall; external 'ole32.dll'; FUNCTION CoCreateInstance(a:REFCLSID; b:pointer; c:DWORD; d:REFIID; e:pointer) : HRESULT; stdcall; external 'ole32.dll';

TYPE PPISHellLink = ^PISHellLink; PISHellLink = ^ISHellLink; ISHellLink = packed record

 QueryInterface : FUNCTION(basis,id,p : pointer) : Hresult; stdcall;
 AddRef : FUNCTION(basis : pointer) : Hresult; stdcall;
 Release : FUNCTION(basis : pointer) : Hresult; stdcall;
 GetPath : pointer;
 GetIDList : pointer;
 SetIDList : pointer;
 GetDescription : pointer;
 SetDescription : FUNCTION(basis : pointer; descr : Pchar) : Hresult; stdcall;
 GetWorkingDirectory : pointer;
 SetWorkingDirectory : FUNCTION(basis : pointer; descr : Pchar) : Hresult; stdcall;
 GetArguments : pointer;
 SetArguments : FUNCTION(basis : pointer; args : Pchar) : Hresult; stdcall;
 GetHotkey : pointer;
 SetHotkey : pointer;
 GetShowCmd : pointer;
 SetShowCmd : pointer;
 GetIconLocation : pointer;
 SetIconLocation : FUNCTION(basis : pointer; iconfile : Pchar; icon : longint) : Hresult; stdcall;
 SetRelativePath : pointer;
 Resolve : pointer;
 SetPath : FUNCTION(basis : pointer; path : Pchar) : Hresult; stdcall;

end;

PPIPersistFile = ^PIPersistFile; PIPersistFile = ^IPersistFile; IPersistFile = packed record

 QueryInterface : FUNCTION(basis,id,p : pointer) : Hresult; stdcall;
 AddRef : FUNCTION(basis : pointer) : Hresult; stdcall;
 Release : FUNCTION(basis : pointer) : Hresult; stdcall;
 GetClassID : FUNCTION(basis,p : pointer) : Hresult; stdcall;
 IsDirty : FUNCTION(basis : pointer) : Hresult; stdcall;
 Load : FUNCTION(basis : pointer; fn : Pchar; dw : dword) : Hresult; stdcall;
 Save : FUNCTION(basis : pointer; fn : Pchar; dw : dword) : Hresult; stdcall;
 SaveCompleted : FUNCTION(basis : pointer; fn : Pchar) : Hresult; stdcall;
 GetCurFile : FUNCTION(basis : pointer; fn : PPchar) : Hresult; stdcall;

end;


FUNCTION createShortcut(lnkpos : widestring; dstfn,dstargs,dstwdir,descr,iconfn : AnsiString; iconnum : longint) : boolean; VAR psl : PPISHellLink; psp : PPIPersistFile; BEGIN

 createShortcut := FALSE;
 if CoCreateInstance(@CLSID_ShellLink,nil,CLSCTX_INPROC_SERVER,@IID_IShellLink,@psl)=0 then begin

// writeln('got IShellLink');

   if  (psl^^.setPath(psl,@dstfn[1])=0)
   and (psl^^.SetArguments(psl,@dstargs[1])=0)
   and (psl^^.SetWorkingDirectory(psl,@dstwdir[1])=0)
   and (psl^^.SetDescription(psl,@descr[1])=0)
   and (psl^^.SetIconLocation(psl,@iconfn[1],iconnum)=0)
   and (psl^^.queryInterface(psl,@IID_IPersistFile,@psp)=0) then begin
     if psp^^.save(psp,@lnkpos[1],0)=0 then createShortcut := true;   
     psp^^.release(psp);
   end;
   psl^^.Release(psl);
 end;

END;

BEGIN

 CoInitialize(nil);

END. </delphi>

Getting special folders (My documents, Desktop, local application data, etc)

Often it is useful to get the location of a special folder such as the desktop. The example below shows how you can get the LocalAppData directory - where the Lazarus installer stores its configuration by default. Look in the shlobj unit for more defines that let you look up the Desktop, Recycle Bin, etc. <delphi> uses ... shlobj;

var

 AppDataPath: Array[0..MaxPathLen] of Char; //Allocate memory

... begin ...

   AppDataPath:=;
   SHGetSpecialFolderPath(0,AppDataPath,CSIDL_LOCAL_APPDATA,false);
   writeln('Your local appdata path is: ' + AppDataPath);

</delphi>

</delphi>