30. Mai 1998

Datei & I/O

 

Wie verwandle ich MS-DOS-Dateinamen in lange Windows-95-Namen und umgekehrt?

von Sven Künzler 30. Mai 1998 [ab D2]

Es gibt in der Win32-Bibiliothek die Funktion GetShortPathName, die das MS-DOS-äquivalent zu einem langen Dateinamen liefert.

 
var buffer: Array[0..255] Of Char;
[...]
GetShortPathName('Langer Dateiname.TXT',buffer,sizeof(buffer));

Wenn man den kurzen Namen hat und den langen haben will, stellt man das wie folgt an:

uses ShellAPI;
[...]
var sfi: TSHFILEINFO;
[...]
SHGetFileInfo('kurzer~1.txt', 0, sfi, sizeof(sfi), SHGFI_DISPLAYNAME);

Der vollständige Pfadname steht dann in sfi.szDisplayName.

Das Problem mit der Funktion SHGetFileInfo besteht darin, dass je nach Explorer-Einstellung der Dateiname mit oder ohne Dateiendungen (wie z.B. .TXT) zurückgeliefert wird. Wenn dafür jemand eine Lösung hat, schreibe er sie mir bitte!

 

Wie kann ich aus meiner Applikation ein anderes Windows-Programm starten?

von Sven Künzler 30. Mai 1998 [ab D1]
Seit Windows 3.x gibt es dafür die Funktion WinExec.
WinExec('C:\WIN\SOL.EXE [Parameter ggf. hier]',SW_SHOWNORMAL);
Für 32-Bit-Programme empfiehlt MS, stattdessen CreateProcess zu benutzen. Das aufzurufen ist allerdings etwas länglich. Man kann sich aber mit ShellExecute behelfen:
uses ShellApi;
[...]
begin
  exeName:='C:\WIN\SOL.EXE';
  param:='[Parameter ggf. hier]'; 
  ShellExecute(Application.MainForm.Handle,NIL,PChar(exeName),
             PChar(Param),PChar(ExtractFilePath(exeName)),SW_SHOWNORMAL);

WinExec und ShellExecute koppeln das zu startende Programm von der aufrufenden Applikation ab. Um die eigene Applikation warten zu lassen, bis das andere Programm wieder beendet ist, wird es etwas komplizierter. Nun kommt man um CreateProcess wirklich nicht mehr herum:

   unit execapp;
   interface

   // Nur für D2/D3
   Function ExecAndWait(const Filename, Params: String; WindowState:
   Word): Boolean;

   implementation
   Uses Windows,SysUtils;

   Function ExecAndWait(const Filename, Params: String;
    WindowState: Word): Boolean;
    Var SUInfo: TStartUpInfo;
        ProcInfo: TProcessInformation;
        CmdLine: String;
    Begin
        CmdLine:='"'+Filename+'"'+Params;

        FillChar(SUInfo,SizeOf(SUInfo),#0);
        With SuInfo Do
        Begin
          cb:=SizeOf(SUInfo);
          dwFlags:=STARTF_USESHOWWINDOW;
          wShowWindow:=WindowState;
        End;

        Result:=CreateProcess(NIL,PChar(CmdLine),NIL,NIL,FALSE,CREATE_NEW_CONSOLE
            OR NORMAL_PRIORITY_CLASS, NIL, PChar(ExtractFilePath(FileName)),
            SUInfo,ProcInfo);

        If Result Then WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    End;
    end.
 

Wie kann ich die mit einem Dokument verknüpfte Applikationen starten?

von Sven Künzler 30. Mai 1998 [ab D2]

ShellExecute funktioniert wie ein Doppelklick im Explorer. Wenn man die Funktion auf eine Applikation anwendet, wird diese gestartet; übergibt man ShellExecute hingegen ein Dokument, so führt es die dazugehörige Applikation aus.
Will man zum Beispiel eine *.DOC-Datei mit MS Word ausdrucken, geht man wie folgt vor:

Uses ShellApi;

   [...]

   docName:='.\BEISPIEL.DOC';
   param:='/p'; // Veranlasst Word bzw. WordPad, das Dokument zu drucken
   ShellExecute(Application.MainForm.Handle,NIL,PChar(docName),
       PChar(Param),PChar(ExtractFilePath(docName)),SW_SHOWNORMAL);