Autor |
Beitrag |
drasir
Hält's aus hier
Beiträge: 15
|
Verfasst: 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:
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:
Quelltext 1: 2:
| HANDLE h; h= CreateFile("\\\\.\\PPJoyIOCTL1",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); |
In Delphi einfach:
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 raziel: Delphi-Tags hinzugefügt
|
|
wulfskin
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: 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
Hält's aus hier
Beiträge: 15
|
Verfasst: Di 19.12.06 20:15
Aha, auf das "packed" wär ich schon NIE gekommen
Also so?
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 raziel: Delphi-Tags hinzugefügt
|
|
wulfskin
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Di 19.12.06 20:32
Ja fast, so ist es richtig : Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| TJoyStickState = packed record Signature: Cardinal; NumAnalog: Byte; 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
Hält's aus hier
Beiträge: 15
|
Verfasst: Di 19.12.06 20:38
So gibt das auch viel mehr Sinn
Danke schonmal bis hier!
Was mir jetzt noch Kopfzerbrechen bereitet:
Delphi-Quelltext 1:
| #define JOYSTICK_STATE_V1 0x53544143 |
das wär unter Delphi $53544143 ?
und
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 raziel: Delphi-Tags hinzugefügt
|
|
wulfskin
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: 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
Hält's aus hier
Beiträge: 15
|
Verfasst: 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
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 20.12.06 19:21
_________________ 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
Hält's aus hier
Beiträge: 15
|
Verfasst: 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
Hält's aus hier
Beiträge: 15
|
Verfasst: Do 21.12.06 13:03
Hm also ich habe jetzt folgendes:
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..8] of Integer; NumDigital: Byte; Digital: Array [0..16] of 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
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 21.12.06 16:17
drasir hat folgendes geschrieben: | Hm also ich habe jetzt folgendes:
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..8] of Integer; NumDigital: Byte; Digital: Array [0..16] of 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 ...
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
Hält's aus hier
Beiträge: 15
|
Verfasst: 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:
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..8] of Integer; NumDigital: Byte; Digital: Array [0..16] of 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
Delphi-Quelltext 1:
| DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,@joy,sizeof(joy),nil,0,d,nil); |
richtig?
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 (@ Christian 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
|
Verfasst: 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
|
Verfasst: 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
|
Verfasst: 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
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 14.08.12 13:05
Moin und in der EE!
gerdich hat folgendes geschrieben : | 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 hathor 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...
gerdich hat folgendes geschrieben : | 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!
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
|
Verfasst: Di 14.08.12 18:07
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 public 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-1] of Integer; NumDigital: shortint; Digital: packed Array [0..ndigital-1] of 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,nil) then 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.
|
|
|