Changing Default Windows 95/98 Printer With Persistence

TPrinterSetupDialog is a non-visual component that can be used to change the default Windows printer, but it does not provide
persistence of the default printer for the next time a program is run.

Borland's Q&A 1272 and Q&A 804
give clues about how to implement persistence for Windows 95/98, but are missing details and do not provide a complete working
example, especially using TPrinterSetupDialog to select the printer.

The following should be a complete D3/D4 example of how to change the Windows 95/98 default printer -- WITH persistence (tested with
D3/Win 95 and D4/Win 98):

procedure TFormSystemMaintenance.BitBtnSetupClick(Sender: TObject);
    Device      :  ARRAY[0..cchDeviceName] OF CHAR;
    Driver        :  ARRAY[0..MAX_PATH] OF CHAR;
    DriverPort:  STRING;
    Port          :  ARRAY[0..MAX_PATH] OF CHAR;
    hDMode  :  THandle;
    s             :  ARRAY[0..64] OF CHAR;
    WinIni    :  TIniFile;
    WinIniFileName:  ARRAY[0..MAX_PATH] OF CHAR;
  IF   PrinterSetupDialog.Execute
    // Enter here if "OK"  selected in TPrinterSetupDialog

    // Based on Borland Q&A 1272 "Chaning (sic) Windows Default Printer"
    // and Borland Q&A 804 "Getting the Printer driver and port name
    // from TPrinter".  These Q&As are informative, but incomplete
    // for changing the Windows default printer in Win 95/98.
    Printer.GetPrinter(@Device, @Driver, @Port, hDMode);

    // For some reason "Driver" is never defined here by GetPrinter.
    // Let's get "Driver,Port" from the Win.INI file "Devices" section
    GetWindowsDirectory(WinIniFileName, SizeOf(WinIniFileName));
    StrCat(WinIniFileName, '\win.ini');
    WinIni := TIniFile.Create(WinIniFileName);
      // Lookup Driver,Port in INI file "Devices" section
      DriverPort := WinIni.ReadString('devices', Device, '<undefined>');

      // Update INI "Windows" section -- this is the Windows default printer
      WinIni.WriteString('windows', 'device',
                         Device + ',' + DriverPort)

    // Flush INI cache
    WritePrivateProfileString(NIL, NIL, NIL, WinIniFileName);

    // Broadcast system wide message about win.ini change
    s := 'windows';
    SendMessage(HWND_BROADCAST, WM_WININICHANGE,0, Cardinal(@s));

For a complete project that implements this,  look for the PrinterDefault.ZIP download under TPrinterSetupDialog at

efg's Computer Lab:
Delphi Books:

Earl F. Glynn     E-Mail:
Overland Park, KS  USA