von Gastuser » So 6. Sep 2015, 17:07
Hallo!
Danke @Manawyrm!
Schade, dann klappt das also doch noch nicht. Hatte extra einen Test eingebaut, dieser Art:
[Source]
unit OsCheck;
interface
Procedure Check4Win32;
//Function IsDos: Boolean;
Var
IsWin32: Boolean = False;
IsDos : Boolean = False;
implementation
function GetProcAddress(hMod: integer; Pname: Pchar):integer; stdcall;
external 'kernel32.dll' name 'GetProcAddress';
function GetModuleHandleA(lpFn: Pchar):integer; stdcall;
external 'kernel32.dll' name 'GetModuleHandleA';
function MessageBoxA(hWin: integer; title,Msg: Pchar; Style: integer):integer; stdcall;
external 'user32.dll' name 'MessageBoxA';
procedure ExitProcess(Exitcode: integer); stdcall;
external 'kernel32.dll' name 'ExitProcess';
Procedure Check4Win32;
Begin
if IsWin32 then
begin
MessageBoxA(0,'Cannot run without WDOSX or HXDOS DOS extender!','Oooops...',0);
ExitProcess($ff);
end;
End;
{$ASMMODE INTEL}
Function InWindows: Boolean; assembler;
Asm
mov ax, $1600
int $2F
End;
(*
Function IsDos: Boolean;
Begin
Result := Not (IsWin32 Or InWindows);
End;
*)
initialization
IsWin32 := GetProcAddress(GetModuleHandleA('kernel32.dll'),'Borland32') = 0;
IsDos := Not (IsWin32 Or InWindows);
end.
[/Source]
Dann im Quellcode:
[Source]
procedure TfpgGDICanvas.DoDrawArc(x, y, w, h: TfpgCoord; a1, a2: Extended);
var
SX, SY, EX, EY: Longint;
begin
{Stupid GDI can't tell the difference between 0 and 360 degrees!!}
if a2 = 0 then
Exit; //==>
{Stupid GDI must be told in which direction to draw}
{$IFNDEF wince}
if a2 < 0 then
if IsDos then dos_impt.SetArcDirection(FGc, AD_CLOCKWISE) else Windows.SetArcDirection(FGc, AD_CLOCKWISE)
else
if IsDos then dos_impt.SetArcDirection(FGc, AD_COUNTERCLOCKWISE) else Windows.SetArcDirection(FGc, AD_COUNTERCLOCKWISE);
{$ENDIF}
Angles2Coords(x, y, w, h, a1*16, a2*16, SX, SY, EX, EY);
{$IFNDEF wince}
Windows.Arc(Fgc, x, y, x+w, y+h, SX, SY, EX, EY);
{$ENDIF}
end;
procedure TfpgGDICanvas.DoFillArc(x, y, w, h: TfpgCoord; a1, a2: Extended);
var
SX, SY, EX, EY: Longint;
begin
{Stupid GDI can't tell the difference between 0 and 360 degrees!!}
if a2 = 0 then
Exit; //==>
{Stupid GDI must be told in which direction to draw}
{$IFNDEF wince}
if a2 < 0 then
if IsDos then dos_impt.SetArcDirection(FGc, AD_CLOCKWISE) else Windows.SetArcDirection(FGc, AD_CLOCKWISE)
else
if IsDos then dos_impt.SetArcDirection(FGc, AD_COUNTERCLOCKWISE) else Windows.SetArcDirection(FGc, AD_COUNTERCLOCKWISE);
{$ENDIF}
Angles2Coords(x, y, w, h, a1*16, a2*16, SX, SY, EX, EY);
{$IFNDEF wince}
Windows.Pie(Fgc, x, y, x+w, y+h, SX, SY, EX, EY);
{$ENDIF}
end;
[/Source]
dos_impt ist der Name meiner Unit, in der ich die SetArcDirection Funktion als Dummy implementiert habe.
Ich hatte gehofft, das das dann unter DOS funktioniert. Leider also doch nicht. Braucht also eine andere Vorgehensweise.
Ich dachte, ich könnte das so machen, da im Quellcode wirklich nur an den beiden gezeigte Stellen diese Funktion SetArcDirection aufgerufen wird. SOnst im gesamten Code an keiner Stelle. Hinzu kommt, das die Arc Funktion auch als Dummy in HxDOS implementiert ist.
Sinn oder Unsinn von GDI unter DOS?
Die Gui, die ich für DOS gerne fit machen würde ist für Windows und Linux lauffähig, Systemspezifische Teile sind in speziellen Ordnern. Die GUI ist so modular aufgebaut, das systemabhängige Teile später hinzugefügt werden können. Nun könnte man, um die GUI für DOS lauffähig zu machen, alle Grafikroutinen neu schreiben. Da sehe ich nun wieder keinen Sinn, weil viel zu aufwendig, zumal es ja HXDOS gibt, mit einer rudimentären GDI Schnittstelle.
Die wollte ich gerne nutzen, um nicht alles neu programmieren zu müssen.
Der Test unter WIndoes in der DOS BOX hat ebenso ergeben, das dieser Missing Import von SetArcDirection, von nur dieser einen Funktion vorliegt. Es kann nur noch sein, das andere wichtige Funktionen nur als Dummy vorliegen. Bei Ellipse und Arc ist das definitiv so, da kann es Probleme bei Radiobuttons oder anderen kreisförmigen Objekten geben. In diesem Fall gibt es aber unter DOS andere Funktionen, mit deren Hilfe diese Funktionalitäten ergänzt werden können sollten.
Der Sinn der GDI Schnittstelle für DOS ist also für mich die Hoffunung, eine GUI Bibliothek, die für Windows geschriben wurde, auch unter DOS nutzen zu können. Zumal nur ein einziger Missing Import auftritt. Alle anderen GDI Funktionen, die diese GUI nutzt, sind also in der HXDOS GDI Schnittstelle vorhanden. Das lockt mich, weiter zu experimentieren.
Da sollte sich doch eine Lösung finden lassen, diese GUI auch unter DOS verfügbar zu machen.
Nun suche ich einen anderen Weg, festzustellen, ob das GUI Programm unter Windows oder unter DOS (HXDOS) läuft.
Die Windows Funktion SetArcDirection legt fest, ob ein Bogen im Uhrzeigersinn oder entgegengesetzt gezeichnet wird. Windoes verlangt das, HXDOS nicht, dort ist die Richtung in der ein Bogen gezeichnet wird, egal. AM einfachsten wäre wohl doch eine Übersetzung für HXDOS in der dann SetArcDirection nicht aufgerufen wird. Wie obiger Quellcode zeigt, habe ich mich aber für den Aufruf einer Dummy Funktion entschieden. Offenbar funktioniert der Test, ob InDos oder InWin32 nicht zuverlässig.
Da frag ich mal: Welche zuverlässigere Möglichkeit gibt es da für den Test?
Hallo!
Danke @Manawyrm!
Schade, dann klappt das also doch noch nicht. Hatte extra einen Test eingebaut, dieser Art:
[Source]
unit OsCheck;
interface
Procedure Check4Win32;
//Function IsDos: Boolean;
Var
IsWin32: Boolean = False;
IsDos : Boolean = False;
implementation
function GetProcAddress(hMod: integer; Pname: Pchar):integer; stdcall;
external 'kernel32.dll' name 'GetProcAddress';
function GetModuleHandleA(lpFn: Pchar):integer; stdcall;
external 'kernel32.dll' name 'GetModuleHandleA';
function MessageBoxA(hWin: integer; title,Msg: Pchar; Style: integer):integer; stdcall;
external 'user32.dll' name 'MessageBoxA';
procedure ExitProcess(Exitcode: integer); stdcall;
external 'kernel32.dll' name 'ExitProcess';
Procedure Check4Win32;
Begin
if IsWin32 then
begin
MessageBoxA(0,'Cannot run without WDOSX or HXDOS DOS extender!','Oooops...',0);
ExitProcess($ff);
end;
End;
{$ASMMODE INTEL}
Function InWindows: Boolean; assembler;
Asm
mov ax, $1600
int $2F
End;
(*
Function IsDos: Boolean;
Begin
Result := Not (IsWin32 Or InWindows);
End;
*)
initialization
IsWin32 := GetProcAddress(GetModuleHandleA('kernel32.dll'),'Borland32') = 0;
IsDos := Not (IsWin32 Or InWindows);
end.
[/Source]
Dann im Quellcode:
[Source]
procedure TfpgGDICanvas.DoDrawArc(x, y, w, h: TfpgCoord; a1, a2: Extended);
var
SX, SY, EX, EY: Longint;
begin
{Stupid GDI can't tell the difference between 0 and 360 degrees!!}
if a2 = 0 then
Exit; //==>
{Stupid GDI must be told in which direction to draw}
{$IFNDEF wince}
if a2 < 0 then
if IsDos then dos_impt.SetArcDirection(FGc, AD_CLOCKWISE) else Windows.SetArcDirection(FGc, AD_CLOCKWISE)
else
if IsDos then dos_impt.SetArcDirection(FGc, AD_COUNTERCLOCKWISE) else Windows.SetArcDirection(FGc, AD_COUNTERCLOCKWISE);
{$ENDIF}
Angles2Coords(x, y, w, h, a1*16, a2*16, SX, SY, EX, EY);
{$IFNDEF wince}
Windows.Arc(Fgc, x, y, x+w, y+h, SX, SY, EX, EY);
{$ENDIF}
end;
procedure TfpgGDICanvas.DoFillArc(x, y, w, h: TfpgCoord; a1, a2: Extended);
var
SX, SY, EX, EY: Longint;
begin
{Stupid GDI can't tell the difference between 0 and 360 degrees!!}
if a2 = 0 then
Exit; //==>
{Stupid GDI must be told in which direction to draw}
{$IFNDEF wince}
if a2 < 0 then
if IsDos then dos_impt.SetArcDirection(FGc, AD_CLOCKWISE) else Windows.SetArcDirection(FGc, AD_CLOCKWISE)
else
if IsDos then dos_impt.SetArcDirection(FGc, AD_COUNTERCLOCKWISE) else Windows.SetArcDirection(FGc, AD_COUNTERCLOCKWISE);
{$ENDIF}
Angles2Coords(x, y, w, h, a1*16, a2*16, SX, SY, EX, EY);
{$IFNDEF wince}
Windows.Pie(Fgc, x, y, x+w, y+h, SX, SY, EX, EY);
{$ENDIF}
end;
[/Source]
dos_impt ist der Name meiner Unit, in der ich die SetArcDirection Funktion als Dummy implementiert habe.
Ich hatte gehofft, das das dann unter DOS funktioniert. Leider also doch nicht. Braucht also eine andere Vorgehensweise.
Ich dachte, ich könnte das so machen, da im Quellcode wirklich nur an den beiden gezeigte Stellen diese Funktion SetArcDirection aufgerufen wird. SOnst im gesamten Code an keiner Stelle. Hinzu kommt, das die Arc Funktion auch als Dummy in HxDOS implementiert ist.
Sinn oder Unsinn von GDI unter DOS?
Die Gui, die ich für DOS gerne fit machen würde ist für Windows und Linux lauffähig, Systemspezifische Teile sind in speziellen Ordnern. Die GUI ist so modular aufgebaut, das systemabhängige Teile später hinzugefügt werden können. Nun könnte man, um die GUI für DOS lauffähig zu machen, alle Grafikroutinen neu schreiben. Da sehe ich nun wieder keinen Sinn, weil viel zu aufwendig, zumal es ja HXDOS gibt, mit einer rudimentären GDI Schnittstelle.
Die wollte ich gerne nutzen, um nicht alles neu programmieren zu müssen.
Der Test unter WIndoes in der DOS BOX hat ebenso ergeben, das dieser Missing Import von SetArcDirection, von nur dieser einen Funktion vorliegt. Es kann nur noch sein, das andere wichtige Funktionen nur als Dummy vorliegen. Bei Ellipse und Arc ist das definitiv so, da kann es Probleme bei Radiobuttons oder anderen kreisförmigen Objekten geben. In diesem Fall gibt es aber unter DOS andere Funktionen, mit deren Hilfe diese Funktionalitäten ergänzt werden können sollten.
Der Sinn der GDI Schnittstelle für DOS ist also für mich die Hoffunung, eine GUI Bibliothek, die für Windows geschriben wurde, auch unter DOS nutzen zu können. Zumal nur ein einziger Missing Import auftritt. Alle anderen GDI Funktionen, die diese GUI nutzt, sind also in der HXDOS GDI Schnittstelle vorhanden. Das lockt mich, weiter zu experimentieren.
Da sollte sich doch eine Lösung finden lassen, diese GUI auch unter DOS verfügbar zu machen.
Nun suche ich einen anderen Weg, festzustellen, ob das GUI Programm unter Windows oder unter DOS (HXDOS) läuft.
Die Windows Funktion SetArcDirection legt fest, ob ein Bogen im Uhrzeigersinn oder entgegengesetzt gezeichnet wird. Windoes verlangt das, HXDOS nicht, dort ist die Richtung in der ein Bogen gezeichnet wird, egal. AM einfachsten wäre wohl doch eine Übersetzung für HXDOS in der dann SetArcDirection nicht aufgerufen wird. Wie obiger Quellcode zeigt, habe ich mich aber für den Aufruf einer Dummy Funktion entschieden. Offenbar funktioniert der Test, ob InDos oder InWin32 nicht zuverlässig.
Da frag ich mal: Welche zuverlässigere Möglichkeit gibt es da für den Test?