Delphi: Long Path in Windows

Trying to access very long filenames (including path) is not allowed in Windows.

Default maximum filename (including path) is 260 chars.

How to use very long filenames in Delphi

function FixLongPath(Filename: string): string;
begin
  if Filename.StartsWith('\\')=false then // network share!
  begin
    Filename:='\\?\'+Filename; // allows very long path
  end;
  Result:=Filename;
end;

var
  Filename: string;
begin
  Filename:=FixLongPath('C:\Looooooong\looooooong.txt');
  ...
end;

Tested: Works in Windows XP to Windows 11

Known Limitations

  • Windows XP doesn’t support it in ShellExecute.

Code Signing for Mac

Back in the day, when code signing was introduced, Apple didn’t provide any infrastructure for issuing code signing certificates, and thus folks had to provide their own signing identities, either by generating them internally or by requesting a code signing certificate from a CA. Since then Apple has started issuing code signing certificates (via the various Apple developer programs) and that has become the standard path. The fact that code signing still supports third-party code signing identities is now just an accident of history and thus we strongly recommend that you avoid this path in favor of using Apple-issued code signing certificates.

Specifically:

  • Non-Apple code signing identities have never been supported on iOS, iPhone OS, iPad OS.
  • On macOS, a non-Apple identity doesn’t buy you anything. There are two ways to distribute Mac software: The Mac App Store and Developer ID.
    • The Mac App Store has the same requirements as iOS-based platforms.
    • Non-Mac App Store code is checked by Gatekeeper, and Gatekeeper will only accept Developer ID-signed code. It treats code signed with a third-party identity the same as ad hoc signed code.

Going through Sectigo for an EV code signing certificate is not supported on the Apple platform, and it is recommended to obtain an Apple-issued code signing certificate.

Delphi: Detect Computer Shutdown

When you shutdown or restart system, Windows sends the WM_QUERYENDSESSION message to all running applications. Standard Delphi form has an OnCloseQuery event, that detects this message. In this procedure, you can let Windows close your application or try to deny it.

When you set the CanClose parameter to true, you are allowing Windows to shutdown, set it to false to try to disallow it. But remember, Windows can force your application to close even if you try to stop it.

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if MessageDlg('Are you sure you want to quit?', mtConfirmation, mbYesNoCancel, 0) = mrYes
    then CanClose := true
    else CanClose := false;
end;

Delphi: Detect Computer Sleep & Wake

Delphi: Detect Computer Sleep & Wake

When you click Sleep button, Windows sends the WM_POWERBROADCAST message to all running applications.

procedure WMPowerBroadcast(var AMessage: TMessage); message WM_POWERBROADCAST;

procedure TForm1.WMPowerBroadcast(var AMessage: TMessage);
const
  PBT_APMSUSPEND = 4;
  PBT_APMRESUMESUSPEND = 7;
begin
  case AMessage.WParam of
    PBT_APMSUSPEND:
    begin
      // save your DB stuff. NOTE: IIRC you are pretty limited in the time
      // you get to do this - 2 seconds ? may be the limit

      logfile.Add(DateTimeToStr(Now)+'> '+'Computer is getting sleep.');
      logfile.SaveToFile(logfilename);
    end;
    PBT_APMRESUMESUSPEND:
    begin
      // restore your DB connection
      //showmessage('we woke up');

      logfile.Add(DateTimeToStr(Now)+'> '+'Computer woke from sleep.');
      logfile.SaveToFile(logfilename);
    end;
  else
     // you're going to want to handle PBT_APMRESUMECRITICAL (XP and older systems) and PBT_APMRESUMEAUTOMATIC differently
     // IIRC you did not get notification of the suspend in this case
  end;
end;

Delphi: Detect Computer Shutdown

MBR vs GPT

When you connect a new drive to Windows, you need to choose between Master Boot Record (MBR) or GUID Partition Table (GPT). These are methods that hold information about how the data is stored on the drive.

  • MBR can have 4 primary partitions; GPT can have 128.
  • MBR can support up to 2TB; GPT handles up to 9.4ZB.
  • GPT is more resilient to errors.
  • MBR is good for older operating systems; GPT is more suitable for modern computers.

Compatibility (MBR vs GPT)

  • 64-bit Windows 11, 10, 8/8.1, 7, and Vista all require a UEFI-based system to boot from a GPT drive.
  • 32-bit Windows 10 and 8/8.1 require a UEFI-based system to boot from a GPT drive. There is no 32-bit version of Windows 11.
  • 32-bit Windows 7 and Vista cannot boot from a GPT drive.

APK vs AAB

APK: Android Application Package
AAB: Android App Bundle

Google has recently announced that developers need to upload AAB instead of APK format on the Play Store. This new update will allow developers to provide highly optimized apps for different mobile users.

AAB (Android App Bundle) basically a bundle of various APKs and other modules that help Google to provide highly optimized APKs according to the user’s android device. As of now, there are millions of android smartphones, every smartphone has different hardware functionalities like differences in process power, screen size, ram, and more. This leads to various errors in different smartphones. Therefore, to counter this type of error, Google has told developers to make a bundle of various APKs according to devices, and then Play Store will decide which APK should be installed in the user’s phone after inspecting its hardware and other basic information.

In the end, you’ll end up installing an APK, but AAB is merely for developers to help Google provide optimized APKs to its users.

Google Play uses the app bundle to generate and optimize APKs for distribution for different device configurations and languages. This makes your app smaller (on average, 15% smaller than a universal APK) and faster to download, which can lead to more installs and fewer uninstalls.

Delphi: Screensaver Tips

Open Screensaver Settings Dialog

var
  str: string;
  parameters: string;
begin
  str:='control';
  parameters:='desk.cpl,,@screensaver';
  ShellExecute(Handle, nil, PChar(str), PChar(parameters), nil, SW_SHOWNORMAL);
end;

Install Screensaver

uses Shellapi;

procedure InstallScreenSaver(const FileName: string);
begin
  ShellExecute(Application.Handle, 'open', PChar('rundll32.exe'), PChar('desk.cpl,InstallScreenSaver ' + FileName), nil, SW_SHOWNORMAL);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  InstallScreenSaver('c:\YourScreenSaverFile.scr');
end;

Set Screensaver

DosCommand1.CommandLine:='reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v SCRNSAVE.EXE /t REG_SZ /d '+'c:\YourScreenSaverFile.scr'+' /f';
DosCommand1.Execute;

Screensaver Caption

Add a value as #1 in RES file.