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 plötzlich Probleme mit RegisterDeviceNotification (https://www.delphipraxis.net/112063-ploetzlich-probleme-mit-registerdevicenotification.html)

Shadow 14. Apr 2008 15:51


plötzlich Probleme mit RegisterDeviceNotification
 
Hallo alle zusammen,

hab hier ein kleines Problem und so langsam weiß ich nciht mehr weiter.. vielleicht kann mir ja jemand helfen...

Ich habe den unten angehängten Code genutzt um zu erkennen ob ein usb stick eingesteckt / abgezogen wird.
Der Code läuft auch ohne Probleme (compiliert mit Delphi4)

Nach eienr Umstellung auf Turbo Delphi bekomme ich bei der RegisterDeviceNotification bei GetLast Error 13 (The data is invalid.).

Verstehe nicht woher das kommt liegt das an einer compieroption ? Komisch das es mit dem älteren compiler geht.

Muß das dringend wieder zum laufen bekommen :( Bin für jede Hilfe dankbar :)


Lg
Andre



Delphi-Quellcode:
// Component to detect when usb devices are connected or disconnected
// using RegisterDeviceNotification

unit U_Usb;

interface

uses
  Windows, Messages, SysUtils, Classes, Forms;

type

    PDevBroadcastHdr = ^DEV_BROADCAST_HDR;
    DEV_BROADCAST_HDR = packed record
      dbch_size: DWORD;
      dbch_devicetype: DWORD;
      dbch_reserved: DWORD;
    end;

    PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
    DEV_BROADCAST_DEVICEINTERFACE = record
      dbcc_size: DWORD;
      dbcc_devicetype: DWORD;
      dbcc_reserved: DWORD;
      dbcc_classguid: TGUID;
      dbcc_name: short;
    end;

const
     GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
     DBT_DEVICEARRIVAL           = $8000;         // system detected a new device
     DBT_DEVICEREMOVECOMPLETE    = $8004;         // device is gone
     DBT_DEVTYP_DEVICEINTERFACE  = $00000005;     // device interface class

type

  TComponentUSB = class(TComponent)
  private
    FWindowHandle: HWND;
    FOnUSBArrival: TNotifyEvent;
    FOnUSBRemove: TNotifyEvent;
    procedure WndProc(var Msg: TMessage);
    function USBRegister: Boolean;
  protected
    procedure WMDeviceChange(var Msg : TMessage); dynamic;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property OnUSBArrival: TNotifyEvent read FOnUSBArrival write FOnUSBArrival;
    property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;
  end;

implementation

constructor TComponentUSB.Create(AOwner : TComponent);
begin
     inherited Create(AOwner);
     FWindowHandle := AllocateHWnd(WndProc);
     USBRegister;
end;

destructor TComponentUSB.Destroy;
begin
     DeallocateHWnd(FWindowHandle);
     inherited Destroy;
end;

procedure TComponentUSB.WndProc(var Msg: TMessage);
begin
     if (Msg.Msg = WM_DEVICECHANGE) then begin
        try
           WMDeviceChange( Msg );
        except
              Application.HandleException(Self);
        end;
     end
     else
         Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TComponentUSB.WMDeviceChange(var Msg : TMessage);
var
   devType: Integer;
   Datos: PDevBroadcastHdr;
begin
     if (msg.WParam=DBT_DEVICEARRIVAL) or (msg.WParam=DBT_DEVICEREMOVECOMPLETE) then begin
        Datos := PDevBroadcastHdr(msg.LParam);
        devType := Datos^.dbch_devicetype;
        if devType=DBT_DEVTYP_DEVICEINTERFACE then begin // USB Device
           if msg.WParam=DBT_DEVICEARRIVAL then begin
              if Assigned( FOnUSBArrival ) then
                 FOnUSBArrival( Self );
           end else begin
               if Assigned( FOnUSBRemove ) then
                  FOnUSBRemove( Self );
           end;
        end;
     end;
end;

function TComponentUSB.USBRegister: Boolean;
var
   dbi: DEV_BROADCAST_DEVICEINTERFACE;
   size: Integer;
   r: Pointer;
begin
     Result := False;
     size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
     ZeroMemory( @dbi, size );
     dbi.dbcc_size := size;
     dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
     dbi.dbcc_reserved := 0;
     dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVICE;
     dbi.dbcc_name := 0;

     r := RegisterDeviceNotification( FWindowHandle,
                                      @dbi,
                                      DEVICE_NOTIFY_WINDOW_HANDLE
                                     );
     if Assigned( r ) then Result := True;

end;

end.
[edit=SirThornberry]Text korrigiert - aus "hab ihr.." wird "hab hier.." - Mfg, SirThornberry[/edit]

Shadow 15. Apr 2008 08:55

Re: plötzlich Probleme mit RegisterDeviceNotification
 
Hat keiner ne Idee ? :(

SirThornberry 15. Apr 2008 09:01

Re: plötzlich Probleme mit RegisterDeviceNotification
 
mach mal aus
Delphi-Quellcode:
DEV_BROADCAST_DEVICEINTERFACE = record
einfach
Delphi-Quellcode:
DEV_BROADCAST_DEVICEINTERFACE = packed record
Du kannst ja auch mal mit dem Debugger durchsteppen ob sizeof wirklich den richtigen Wert angibt. Wenn nicht liegts wohl daran das die Elemente im Record anders aligned sind als in Delphi4.

Shadow 15. Apr 2008 09:07

Re: plötzlich Probleme mit RegisterDeviceNotification
 
Ja an SizeOf dachte ich gestern abend auch schon .. bin gerade am testen ...

SirThornberry 15. Apr 2008 09:11

Re: plötzlich Probleme mit RegisterDeviceNotification
 
was ich nicht ganz verstehe ist das du DEV_BROADCAST_HDR definierst aber dann gar nicht in deiner eigenen Struktur verwendest.
Anstelle von
Delphi-Quellcode:
PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
DEV_BROADCAST_DEVICEINTERFACE = packed record
  dbcc_size: DWORD;
  dbcc_devicetype: DWORD;
  dbcc_reserved: DWORD;
  dbcc_classguid: TGUID;
  dbcc_name: short;
end;
hätte ich es dann so erwartet:
Delphi-Quellcode:
DEV_BROADCAST_DEVICEINTERFACE = packed record
  dbcc_hdr: DEV_BROADCAST_HDR;
  dbcc_classguid: TGUID;
  dbcc_name: short;
end;

Shadow 15. Apr 2008 09:14

Re: plötzlich Probleme mit RegisterDeviceNotification
 
Also packed hat erstmal so nix gebracht ... unter delphi4 hat die Struktur ne größe von 32 unter Turbo nur 30
wird also daran liegen nur egal was ich recordfeld ausrichten unter den Compileroptionen rum spiele es scheint sich nix zu ändern an der größe der Struktur ... auf alle fälle ist es schon mal die richtige Spur...hmm

SirThornberry 15. Apr 2008 09:16

Re: plötzlich Probleme mit RegisterDeviceNotification
 
dann müsstest du mal prüfen wie groß DWord, short und TGui in den verschiedenen Delphiversionen sind und die Datentypen entsprechend anpassen. Ohne TGui ist die Struktur 14 Bytes groß.

Shadow 15. Apr 2008 09:29

Re: plötzlich Probleme mit RegisterDeviceNotification
 
Jups ... habs eben mal getestet also

unter delphi 4

Gesamte Struktur 32

DWORD 4
GUI 16
Short 2


unter turbo

Gesamte Strukut 30

DWORD 4
GUI 16
Short 2


Kann also nur noch daran liegen wie das Record abgelegt wird.

Shadow 15. Apr 2008 09:47

Re: plötzlich Probleme mit RegisterDeviceNotification
 
Sooo .. also in Delphi 4 ist unter compiler Optionen "Ausgerichtete Recordfelder" anktiviert was einer
Compileroption von {$A+} entspricht und siehe da wenn ich die setze geht es .. die Struktur ist dann ebenfalls 32 und
die RegisterDeviceNotification liefert das ersehnte Ergebnis :cheer:

Danke für deine Hilfe Jens.

Lg Andre


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:40 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