Autor Beitrag
drasir
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Di 19.12.06 19:35 
Hi,

ich würde gern mitt "PPJoy" von meinem Programm aus Joystickdaten an Windows geben. Das Programm bietet dafür eine Schnittstelle via "DeviceIOcontrol".

Leider gibt es dazu nur C-SampleCode. Kann mir jemand weiterhelfen?

Das wichtigste folgendes:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
#pragma pack(push,1)    /* All fields in structure must be byte aligned. */
typedef struct
{
 unsigned long  Signature;             /* Signature to identify packet to PPJoy IOCTL */
 char           NumAnalog;             /* Num of analog values we pass */
 long           Analog[NUM_ANALOG];    /* Analog input values */
 char           NumDigital;            /* Number of digital values we pass */
 char           Digital[NUM_DIGITAL];  /* Digital input values */
} JOYSTICK_STATE;
#pragma pack(pop)


Wie sieht die Structur in Delphi aus?

Seh ich das richtig das:

ausblenden Quelltext
1:
2:
HANDLE h;
h= CreateFile("\\\\.\\PPJoyIOCTL1",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);


In Delphi einfach:

ausblenden Delphi-Quelltext
1:
2:
3:
Var H:Thandle;
...
h:=CreateFile("\\\\.\\PPJoyIOCTL1",GENERIC_WRITE,FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,nil);


ist?


Unter www.geocities.com/deonvdw/PPJoy.htm -> Supported Interfaces -> Virtual Joystick -> Sample
findet man auch ein komplettes C-Program.

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Di 19.12.06 20:02 
Hallo,

wie wärs denn mit ausprobieren? ;)
Aber sieht auf den ersten Blick gut aus, ein struct übersetzt du dann mit einem (packed) record.

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Di 19.12.06 20:15 
Aha, auf das "packed" wär ich schon NIE gekommen :)

Also so?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Type JoyStruct = packed record
      Signature:longint;
      NumAnalog: char;
      Analog: array of longint;
      NumDigital: char;
      Digital: array of char;
end;


Mit den Arrays bin ich mir nicht so sicher...

Ist long Analog[NUM_ANALOG]; = Analog: array of longint; oder wie?

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Di 19.12.06 20:32 
Ja fast, so ist es richtig ;):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
TJoyStickState = packed record
  Signature: Cardinal; //Vorzeichenloser 32-bit Wert
  NumAnalog: Byte; //Char ist das selbe, aber hier sieht man das es um kein Zeichen geht
  Analog: Array [0..NUM_ANALOG] of Integer;
  NumDigital: Byte;
  Digital: Array [0..NUM_DIGITAL] of Byte;
end;
Übrigens, bei dem packed bin ich mir nicht so sicher!

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Di 19.12.06 20:38 
So gibt das auch viel mehr Sinn :)

Danke schonmal bis hier!

Was mir jetzt noch Kopfzerbrechen bereitet:

ausblenden Delphi-Quelltext
1:
#define  JOYSTICK_STATE_V1  0x53544143					



das wär unter Delphi $53544143 ?

und

ausblenden Quelltext
1:
2:
3:
4:
#define PPORTJOY_IOCTL(_index_)  \
  CTL_CODE (FILE_DEVICE_PPORTJOY, _index_, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_PPORTJOY_SET_STATE    PPORTJOY_IOCTL (0x0)


Ich brauche IOCTL_PPORTJOY_SET_STATE für den DeviceIOControl Aufruf...

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Di 19.12.06 23:33 
Hallo,

da erste stimmt soweit.
Das zweite kenne ich leider auch nicht, sieht aber nach einem Macro aus. Aber da gibt es noch andere Spezialisten, die dir da sicherlich weiterhelfen können!

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Mi 20.12.06 11:08 
Dann hoffe ich mal das besagte Experten meinen Thread sehen :)

Deine Posts haben mir aber auch schon sehr weitergeholfen! Danke!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 20.12.06 19:21 
user profile icondrasir hat folgendes geschrieben:
ausblenden Quelltext
1:
2:
3:
4:
#define PPORTJOY_IOCTL(_index_)  \
  CTL_CODE (FILE_DEVICE_PPORTJOY, _index_, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_PPORTJOY_SET_STATE    PPORTJOY_IOCTL (0x0)


Ich brauche IOCTL_PPORTJOY_SET_STATE für den DeviceIOControl Aufruf...

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt


Laut Dokumentation des PSDK sieht das CTL_CODE-Makro so aus:
ausblenden Quelltext
1:
2:
3:
#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)


Mit den dazugehörigen Definitionen:
ausblenden Quelltext
1:
2:
3:
4:
#define METHOD_BUFFERED                 0
#define METHOD_IN_DIRECT                1
#define METHOD_OUT_DIRECT               2
#define METHOD_NEITHER                  3


Sowie den Zugriffsrechten:
ausblenden Quelltext
1:
2:
3:
4:
#define FILE_ANY_ACCESS                 0
#define FILE_SPECIAL_ACCESS    (FILE_ANY_ACCESS)
#define FILE_READ_ACCESS          ( 0x0001 )    // file & pipe
#define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe


Übersetzt sich das ganze einfach durch entsprechende Left-Shifts um die angegebene Anzahl an Bits.

Sollte also etwa so hier (vereinfacht) aussehen:

ausblenden Delphi-Quelltext
1:
2:
const
    IOCTL_PPORTJOY_SET_STATE = FILE_DEVICE_PPORTJOY shl 16 + _index_ shl 2;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Mi 20.12.06 21:12 
Super! Werde das gleich morgen ausprobieren!

Btw. mit dem Handy finde ich es jetzt nicht, aber wie mach ich die Delphi-Code Tags?
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 21.12.06 13:03 
Hm also ich habe jetzt folgendes:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
Type TJSS = packed record
  Signature: Cardinal; 
  NumAnalog: Byte; 
  Analog: Array [0..8of Integer;
  NumDigital: Byte;
  Digital: Array [0..16of Byte;
end;

var
  Form1: TForm1;
  joy:tjss;
  H:Thandle;
  ret:longbool;
  rsize:dword;

Const _index = $0;
      JoyStick_State_V1 = $53544143;
      FILE_DEVICE_UNKNOWN = $00000022;
      IOCTL_PPORTJOY_SET_STATE = FILE_DEVICE_UNKNOWN shl 16 + _index shl 2;
... 

procedure TForm1.Button1Click(Sender: TObject);
var c:poverlapped;
    d:cardinal;
begin
h:=CreateFile('\\\\.\\PPJoyIOCTL1',GENERIC_WRITE,FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
joy.Signature:=Joystick_State_V1;
joy.NumAnalog:=8;
joy.Analog[1]:=100;
joy.NumDigital:=16;
joy.Digital[1]:=1;
ret:=DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,@joy,sizeof(joy),nil,0,d,nil);
closehandle(h);


Leider passiert da genau nichts...
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 21.12.06 16:17 
user profile icondrasir hat folgendes geschrieben:
Hm also ich habe jetzt folgendes:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
Type TJSS = packed record
  Signature: Cardinal; 
  NumAnalog: Byte; 
  Analog: Array [0..8of Integer;
  NumDigital: Byte;
  Digital: Array [0..16of Byte;
end;

var
  Form1: TForm1;
  joy:tjss;
  H:Thandle;
  ret:longbool;
  rsize:dword;

Const _index = $0;
      JoyStick_State_V1 = $53544143;
      FILE_DEVICE_UNKNOWN = $00000022;
      IOCTL_PPORTJOY_SET_STATE = FILE_DEVICE_UNKNOWN shl 16 + _index shl 2;
... 

procedure TForm1.Button1Click(Sender: TObject);
var c:poverlapped;
    d:cardinal;
begin
h:=CreateFile('\\\\.\\PPJoyIOCTL1',GENERIC_WRITE,FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
joy.Signature:=Joystick_State_V1;
joy.NumAnalog:=8;
joy.Analog[1]:=100;
joy.NumDigital:=16;
joy.Digital[1]:=1;
ret:=DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,@joy,sizeof(joy),nil,0,d,nil);
closehandle(h);


Leider passiert da genau nichts...


Man beachte die von mir markierten Stellen ...
Das _index war nur für dich, um zu zeigen, wo Du die 0x0 aus dem Makro einsetzen solltest ...
ausblenden Delphi-Quelltext
1:
      IOCTL_PPORTJOY_SET_STATE = FILE_DEVICE_PPORTJOY shl 16 + $0 shl 2;					

Das FILE_DEVICE_PPORTJOY hatte schon seine Berechtigung: Diese Konstante müsste bei Dir irgendwo in den Headern deklariert sein; kann sie im MSDN nicht finden.

Und zu guter Letzt eine kleine Einführung in C-Strings ;-)

Die Zeichenfolge '\\' in C heißt so viel wie Ich will hier nen \ haben. Das ist in C notwendig, da ein einfacher \ in einem C-String ein Escape-Zeichen ist. Ferner steht das '\\\\.\\PPJoyIOCTL'L hinter dem String für Unicode. Wäre die korrekte Übersetzung des Strings also '\\.\PPJoyIOCTL'

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
drasir Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 21.12.06 17:40 
Das mit dem Index ist mir dann auch aufgefallen... Allerdings sollte die Deklaration mit "_index = $0" doch "0x0" entsprechen oder?

Das FILE_DEVICE_PPORTJOY ist im c-Header so deklariert:

[C]
#define FILE_DEVICE_PPORTJOY FILE_DEVICE_UNKNOWN
[/C]

Ich bin deshalb davon ausgegangen das ich auch direkt "FILE_DEVICE_UNKNOWN" benutzen kann.

Den Wert dazu kannte Delphi nicht, habe ihn aber mit ein bisschen googlen als $00000022 identifiziert.

Das mit dem '\\' wusste ich nicht, das 'l' dahinter ist aber eigentlich eine '1' (eins) die die Nummer des virtuellen Joysticks representiert (von 1-16).

Jetzt hab ich also:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
Type TJSS = packed record
  Signature: Cardinal; 
  NumAnalog: Byte;
  Analog: Array [0..8of Integer;
  NumDigital: Byte;
  Digital: Array [0..16of Byte;
end;

var
  Form1: TForm1;
  joy:tjss;
  H:Thandle;
  ret:longbool;
  rsize:dword;

Const JoyStick_State_V1 = $53544143;
      FILE_DEVICE_UNKNOWN = $00000022;
      IOCTL_PPORTJOY_SET_STATE = FILE_DEVICE_UNKNOWN shl 16 + $0 shl 2;

procedure TForm1.Button1Click(Sender: TObject);
var c:poverlapped;
    d:cardinal;
      a:pjoyinfoex;
    s:string;
begin
h:=CreateFile('\\.\PPJoyIOCTL1',GENERIC_WRITE,FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
joy.Signature:=Joystick_State_V1;
joy.NumAnalog:=8;
joy.Analog[1]:=100;
joy.NumDigital:=16;
joy.Digital[1]:=1;
ret:=DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,@joy,sizeof(joy),nil,0,d,nil);
closehandle(h);
end;


Es geht aber immernoch nicht...

ist denn meine übersetzung von

[c]
DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,&JoyState,sizeof(JoyState),NULL,0,&RetSize,NULL)
[/c]

in

ausblenden Delphi-Quelltext
1:
DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,@joy,sizeof(joy),nil,0,d,nil);					


richtig?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 22.12.06 21:01 
Fragen wir mal anders: Bekommst Du für H ein gültiges Handle?

Sources: Für C-Sources bitte CS-Tags (C#) nehmen. Reines C kann dieses Forum (noch) nicht ... (Oder wurden die CPP schon umgesetzt (@user profile iconChristian S.)???

@PPORTJOY: Aso, solche Dinge immer mit Übersetzen, sonst kommt's nur zu Verwirrungen ... Die VCL-Sources und Header-Übersetzungen der RTL sind u.a. deshalb relativ beschissen, weil sie teilweise nur Schrott übersetzt haben, der für den Normalen Menschen geht, und alles was nicht gebraucht wurde, ignoriert ...

Wenn Du vom C-Source und deinem Delphi-Source n ASM-Listing hast, kannsch Dir sagen, ob's korrekt is *g* (Bitte nur die besagte Routine, mit Zeilenmarkierungen der Originalsources: CPU-Fenster --> Gemischte Anzeige)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
gerdich
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 13.08.12 22:29 
Der Code funktoniert bis auf kleine Fehler ganz gut.

Allerdings darfst Du das Datei-Handle nicht gleich wieder schliessen, sonst ist die Wirkung gleich wieder null. Ein Joystick-Signal im Mikrosekundenbereich ist wirkungslos.

Du solltest das Datei-Handle zu Beginn des Formulars öffnen (create) und beim Beenden (destroy) freigeben. Dann wirst Du sehen, dass alle Joystickbefehle gut ankommen. Ich habe es getestet.
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 14.08.12 07:30 
Auch wenn Du nagelneu bist: ACHTE IN ZUKUNFT AUF DAS DATUM! -> Letzter Eintrag verfasst: Fr 22.12.06 21:01
gerdich
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 14.08.12 12:15 
Das Datum habe ich schon gesehen.
Der Thread ist aber immer noch im Internet und hat keine Lösung gefunden.
Das Problem ist weiterhin brandaktuell: Sony Sixaxis läuft über ppjoy.

Ich wäre froh gewesen, ich hätte meine Antwort schon vorher im Netz gefunden.
Es hat mich etwas Zeit gekostet das herauszufinden.

Ich wollte noch den Code dazu setzen. Zum Glück habe ich es nicht getan, da sich offensichtlich niemand mehr dafür interessiert.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 14.08.12 13:05 
Moin und :welcome: in der EE!

user profile icongerdich hat folgendes geschrieben Zum zitierten Posting springen:
Das Datum habe ich schon gesehen.
Der Thread ist aber immer noch im Internet und hat keine Lösung gefunden.
Hm, das ist wohl etwas unglücklich gelaufen. :| Ich schätze mal, dass user profile iconhathor dich nicht verärgern wollte, sondern einen der hier gelegentlich auftretenden Thread-Archäologen vermutet hat. ;) Da geht´s dann ja nicht um Lösungen, sondern nur um Aufmerksamkeit... :zwinker:

user profile icongerdich hat folgendes geschrieben Zum zitierten Posting springen:
Ich wollte noch den Code dazu setzen. Zum Glück habe ich es nicht getan, da sich offensichtlich niemand mehr dafür interessiert.
Selbstverständlich sind wir in der EE immer an Lösungen interessiert, auch wenn die Frage schon etwas älter ist. Wenn du also eine Lösung beitragen kannst (und noch möchtest :?), bist du hier bei uns immer herzlichen Willkommen! :beer:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
gerdich
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 14.08.12 18:07 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  Tioctrl = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ioctrl: Tioctrl;

implementation

{$R *.dfm}
Const JoyStick_State_V1 = $53544143;
      pp_joy_axis_min=1;
      pp_joy_axis_max=32767;
      FILE_DEVICE_UNKNOWN = 34;
      set_state=0;
      method_buffered=0;
      file_any_access=0;
      nanalog=8;
      ndigital=16;

Type TJSS = packed record
  Signature: Cardinal;
  NumAnalog: shortint;
  Analog: packed Array [0..nanalog-1of Integer;
  NumDigital: shortint;
  Digital: packed Array [0..ndigital-1of shortint;
end;
var
  IOCTL_PPORTJOY_STATE: cardinal;
  joy:tjss;
  H:Thandle;
  ret:longbool;
  rsize:dword;

function ctl_code(device_type:word;access:byte;func:word;method:byte):cardinal;
begin
 result:=device_type;
 result:=result shl 2;
 inc(result,access);
 result:=result shl 12;
 inc(result,func);
 result:=result shl 2;
 inc(result,method)
end;

procedure Tioctrl.FormCreate(Sender: TObject);
begin
 h:=CreateFile('\\.\PPJoyIOCTL1',GENERIC_WRITE,FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
 if h=Invalid_handle_value then caption:='Ladefehler ' else caption:='ok ';
end;

procedure Tioctrl.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 closehandle(h)
end;


procedure Tioctrl.FormKeyPress(Sender: TObject; var Key: Char);
var d:cardinal;
    rc:cardinal;
    t:integer;
const
  digitalkey='1234567890qwertz';
  analogkey='asdfghjk';
begin
 joy.Signature:=Joystick_State_V1;
 joy.NumAnalog:=nanalog;
 joy.NumDigital:=ndigital;
 t:=pos(key,digitalkey);
 if t>0 then joy.Digital[t-1]:=1-joy.Digital[t-1]
 else
 begin
  t:=pos(key,analogkey);
  if t>0 then
   if joy.Analog[t-1]=pp_joy_axis_min then joy.Analog[t-1]:=pp_joy_axis_max
   else joy.Analog[t-1]:=pp_joy_axis_min
 end;
 ioctl_pportjoy_state:=ctl_code(FILE_DEVICE_UNKNOWN,file_any_access,set_state,method_buffered);
 if not DeviceIoControl(h,IOCTL_PPORTJOY_STATE,@joy,sizeof(joy),nil,0,d,nilthen
 begin
  rc:=getlasterror;
  if rc=2 then caption:=caption+'Treiber entfernt' else caption:=caption+'iocontrol-Fehler '+inttostr(rc)
 end
end;


var init_t:integer;
initialization
begin
 for init_t:=0 to nanalog-1 do joy.Analog[init_t]:=(pp_joy_axis_max+pp_joy_axis_min)div 2;
 for init_t:=0 to ndigital-1 do joy.Digital[init_t]:=0
end;

end.


Man sieht:
Nur wenige kleinere Änderungen:
- C-char entspricht Delphi-shortint (Hier unwichtig, solange keine negativen Werte).
- [0..n] sind n+1 Elemente.
- shl von #0 ist sinnlos.
...

Im Wesentlichen war der Code ganz korrekt. Nur durfte man das Handle nicht gleich wieder schliessen, sonst blieb keine Wirkung zurück.

ppjoy kann jetzt von Delphi aus verwendet werden, um verschiedenste Eingabegeräte (u.a. Midi-controller und Sony sixaxis) einzulesen und damit beliebige Programme zu steuern.
ppjoy erscheint als neuer Joystick.

Mit ppjoy kann man nun auch programmgesteuert auf eine andere Applikation einwirken, die auf Joystick- oder Tastatureingaben (oder anderes wartet). Dazu braucht man nun auch kein Windows-Handle mehr, sondern die Wirkung betrifft alle Applikationen, wie ein Hardware-Joystick, eine Hardware-Maus oder eine Hardwaretastatur.