Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi GetStartupInfoW(StartupInfoW) - Parameter (https://www.delphipraxis.net/94567-getstartupinfow-startupinfow-parameter.html)

Garfield 23. Jun 2007 13:32


GetStartupInfoW(StartupInfoW) - Parameter
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich möchte eine Console mit Unicode umleiten und dazu den Code aus meinem Beitrag anpassen. Also habe ich CreateProcess durch CreateProcessW ersetzt. CreateProcessW erwartet unter anderem den Parameter StartUpInfoW. Die neue StartUpInfoW wird mit

Delphi-Quellcode:
GetStartupInfoW(StartupInfoW);
erstellt. Wie es auch in diesem Beitrag angegeben. Und genau da hängt es bei mir. In der Unit Windows ist deklariert:

Delphi-Quellcode:
procedure GetStartupInfoW; external kernel32 name 'GetStartupInfoW';
Turbo Delphi erwartet nun nicht StartupInfoW sondern StartupInfoA. :gruebel:

Wo liegt hier der Fehler? In Turbo Delphi oder der Kernel32.dll (Version 5.1.2600.3119 (xpsp_sp2_gdr.070416-1301)).

Sunlight7 24. Jun 2007 00:17

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Moin!

Das liegt wohl an der Deklaration der Procedure:

Delphi-Quellcode:
type
  PStartupInfo = ^TStartupInfo;
  _STARTUPINFOA = record
    cb: DWORD;
    lpReserved: Pointer;
    lpDesktop: Pointer;
    lpTitle: Pointer;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: PByte;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;
  {$EXTERNALSYM _STARTUPINFOA}
  TStartupInfo = _STARTUPINFOA;
  STARTUPINFO = _STARTUPINFOA;
  {$EXTERNALSYM STARTUPINFO}

procedure GetStartupInfoA(var lpStartupInfo: TStartupInfo); stdcall;
procedure GetStartupInfoW(var lpStartupInfo: TStartupInfo); stdcall;

...

procedure GetStartupInfoA; external kernel32 name 'GetStartupInfoA';
procedure GetStartupInfoW; external kernel32 name 'GetStartupInfoW';
Das is in meinen D5 auch so drin.

Luckie 24. Jun 2007 03:15

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Das ist die Sauerei von Borland. Die Struktur ist nur als Ansi-Versin deklariert, aber siehaben trotzdem noch die zugehörige WideString Funktion deklariert, die dann aber die Ansi-Struktur benutzt. Da kann man ziemlich über aufs Maul fallen. Ist mibeim Usermanager passiert: Beim Eintragen in den Treeview stand nur Mist drinne, obwohl die Werte in Ordnung waren. Ambetsen du deklarierst dir das selber.

Dezipaitor 24. Jun 2007 08:58

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Aber ein Pointer ist doch ok?
Gut man muss natürlich wissen, dass der Pointer ein AnsiString oder ein WideString ist.

Garfield 24. Jun 2007 12:10

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Zitat:

Zitat von Sunlight7
Das is in meinen D5 auch so drin.

Also einmal falsch übersetzt, den Fehler nie bemerkt und immer weiter mitgeschleppt.

Zitat:

Zitat von Luckie
Das ist die Sauerei von Borland. Die Struktur ist nur als Ansi-Versin deklariert, aber siehaben trotzdem noch die zugehörige WideString Funktion deklariert, die dann aber die Ansi-Struktur benutzt. ...

Ganz so ist das nicht. Die StartupInfo ist schon als Ansi und Wide-Deklaration vorhanden:
Delphi-Quellcode:
type
  PStartupInfoA = ^TStartupInfoA;
  PStartupInfoW = ^TStartupInfoW;
  PStartupInfo = PStartupInfoA;
  _STARTUPINFOA = record
    cb: DWORD;
    lpReserved: PAnsiChar;
    lpDesktop: PAnsiChar;
    lpTitle: PAnsiChar;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: PByte;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;
  _STARTUPINFOW = record
    cb: DWORD;
    lpReserved: PWideChar;
    lpDesktop: PWideChar;
    lpTitle: PWideChar;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: PByte;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;
  _STARTUPINFO = _STARTUPINFOA;
  TStartupInfoA = _STARTUPINFOA;
  TStartupInfoW = _STARTUPINFOW;
  TStartupInfo = TStartupInfoA;
  {$EXTERNALSYM STARTUPINFOA}
  STARTUPINFOA = _STARTUPINFOA;
  {$EXTERNALSYM STARTUPINFOW}
  STARTUPINFOW = _STARTUPINFOW;
  {$EXTERNALSYM STARTUPINFO}
  STARTUPINFO = STARTUPINFOA;
Der Fehler liegt in den Zeilen:

Delphi-Quellcode:
procedure GetStartupInfoA(var lpStartupInfo: TStartupInfo); stdcall;
procedure GetStartupInfoW(var lpStartupInfo: TStartupInfo); stdcall;
Denn wegen TStartupInfo = TStartupInfoA wird in beiden Fällen Ansi verwendet. Ich habe mein Projekt um diese Unit erweitert:

Delphi-Quellcode:
unit myWindows;

interface

uses
  Windows;

procedure myGetStartupInfo(var lpStartupInfo: TStartupInfo); stdcall;
{$EXTERNALSYM myGetStartupInfo}
procedure myGetStartupInfoA(var lpStartupInfo: TStartupInfoA); stdcall;
{$EXTERNALSYM myGetStartupInfoA}
procedure myGetStartupInfoW(var lpStartupInfo: TStartupInfoW); stdcall;
{$EXTERNALSYM myGetStartupInfoW}

const
{$IFDEF MSWINDOWS}
  kernel32  = 'kernel32.dll';
{$ENDIF}

implementation

procedure myGetStartupInfo; external kernel32 name 'GetStartupInfoA';
procedure myGetStartupInfoA; external kernel32 name 'GetStartupInfoA';
procedure myGetStartupInfoW; external kernel32 name 'GetStartupInfoW';

end.
Damit läuft der Compiler erst einmal durch. Ob es richtig funktioniert muss ich noch testen lassen.

Zitat:

Zitat von Dezipaitor
Aber ein Pointer ist doch ok?
Gut man muss natürlich wissen, dass der Pointer ein AnsiString oder ein WideString ist.

Die StartupInfo ist kein String sondern ein Record.

marabu 24. Jun 2007 12:22

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Hallo Garfield,

natürlich ist die Struktur ein Record, aber dieser Record enthält in der W-Variante und in der A-Variante jeweils drei Zeiger, die sich lediglich in ihrer Typisierung unterscheiden. Es ist also eher eine kleine Nachlässigkeit bei der Qualitätskontrolle als ein Fehler bei der Entwicklung, den man Borland hier vorwerfen kann. Ich denke darauf wollte Dezipaitor hinaus.

Grüße vom marabu

Garfield 24. Jun 2007 14:43

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Moin marabu,

kann gut sein. Eben diese unterschiedliche Typisierung von PAnsiChar und PWideChar hat das Problem verursacht. Obwohl zunächst eine leere Struktur erstellt werden soll und die Zeiger in meinem Fall später gar nicht benötigt werden.

Delphi-Quellcode:
StartupInfoW.dwFlags    := STARTF_USESTDHANDLES
                         or STARTF_USESHOWWINDOW;
StartupInfoW.wShowWindow := SW_HIDE;  
StartupInfoW.hStdOutput := NewStdOut;
StartupInfoW.hStdError  := NewStdOut;
StartupInfoW.hStdInput  := NewStdIn;

Dezipaitor 24. Jun 2007 17:09

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
[quote="Garfield"]
Zitat:

Zitat von Sunlight7
Zitat:

Zitat von Dezipaitor
Aber ein Pointer ist doch ok?
Gut man muss natürlich wissen, dass der Pointer ein AnsiString oder ein WideString ist.

Die StartupInfo ist kein String sondern ein Record.

Zitat:

Zitat von marabu
Hallo Garfield,

natürlich ist die Struktur ein Record, aber dieser Record enthält in der W-Variante und in der A-Variante jeweils drei Zeiger, die sich lediglich in ihrer Typisierung unterscheiden. Es ist also eher eine kleine Nachlässigkeit bei der Qualitätskontrolle als ein Fehler bei der Entwicklung, den man Borland hier vorwerfen kann. Ich denke darauf wollte Dezipaitor hinaus.

Grüße vom marabu


Genau, ich bezog mich auf die 3 Pointer innerhalb des Records. Da es sich dabei um Zeiger handelt, ist es egal, ob Char oder Widechar. Es sind halt nur untypisierte Zeiger.
Anders ist es bei Records, in denen Array of Char oder Array of WideChar Deklarationen vorkommen. Diese müssen doppelt definiert werden, da sie beide unterschiedliche Größen besitzen.

Garfield 24. Jun 2007 17:22

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Zitat:

Zitat von Dezipaitor
Genau, ich bezog mich auf die 3 Pointer innerhalb des Records. Da es sich dabei um Zeiger handelt, ist es egal, ob Char oder Widechar. Es sind halt nur untypisierte Zeiger.

Wenn es egal wäre, hätte der Compiler nicht meckern sondern compilen müssen. Also dürfte es nicht egal sein. :gruebel:

Dezipaitor 24. Jun 2007 17:48

Re: GetStartupInfoW(StartupInfoW) - Parameter
 
Zitat:

Zitat von Garfield
Zitat:

Zitat von Dezipaitor
Genau, ich bezog mich auf die 3 Pointer innerhalb des Records. Da es sich dabei um Zeiger handelt, ist es egal, ob Char oder Widechar. Es sind halt nur untypisierte Zeiger.

Wenn es egal wäre, hätte der Compiler nicht meckern sondern compilen müssen. Also dürfte es nicht egal sein. :gruebel:

Semantisch ist es egal, syntaktisch jedoch nicht, da es sich eben um zwei verschiedene Strukturen handelt. Man kann aber durch explizite Typ-konvertierung, ohne Probleme von einem Record zum anderen umwandeln. Das geht eben nur, weil es Zeiger sind und keine festen Strukturen. (array)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz