Entwickler-Ecke

Open Source Projekte - frDrive


Delete - Mi 02.11.16 23:27
Titel: frDrive
- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Do 03.11.16 14:21

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delphi-Laie - Fr 17.03.17 00:13

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Das im Anhang enthaltene Package ist sowohl auf älteren Delphi Versionen (D7 PE) als auch auf neueren Versionen (D10.1 Starter) installierbar.


Es ist auch schon auf Delphi 6 installierbar.

Delphi 5 kommt hingegen mit dem Befehl


Delphi-Quelltext
1:
2:
3:
requires
  rtl,
  vcl;


nicht zurecht, findet die Packages nicht. Warum, weiß ich nicht. "requires" kennen nämlich auch Delphi 5 und sogar Delphi 4 schon.

Edit: Vorher mußte ich noch


Delphi-Quelltext
1:
{$ALIGN 8}                    


auskommentieren bzw. entfernen, also für den Compiler unsichtbar machen.


Delete - Fr 17.03.17 00:38

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - Fr 17.03.17 01:20

Man sollte noch einen Versions-Hinweis einbauen, z.B. so:

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:
...
    function GetFreeSize(ADriveLetter: Char): Int64;
    function GetDriverVersion : String;  //<---------------------------
    procedure GetDrives(AList: TStrings; ADriveType: ShortInt); overload;
    procedure GetDrives(AList: TStrings; ADriveType: TDriveTypes); overload;
    property Count: Integer read GetCount;
    property Info[Index: Integer]: TDriveInfo read GetDriveInfo;
  published
    property DriveLetter: string read FDriveLetter write SetDriveLetter;
    property DriveType: TDriveTypes read FDriveType write SetDriveType;
    property Eject: Boolean read FEject write SetEject;
    property DriverVersion: String read GetDriverVersion;   //<---------------------------
  end;
...
function TfrDrive.GetDriverVersion : String;
begin
  Result:= '3.0';
end;
//-------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
caption:= frDrive1.GetDriverVersion;
end;


Delete - Fr 17.03.17 02:03

- Nachträglich durch die Entwickler-Ecke gelöscht -


galagher - Sa 18.03.17 23:10

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Forum

Allgemeines:

TfrDrive ist eine nicht-visuelle Delphi Komponente, die einem Anwender dabei helfen soll:
- Laufwerke zu ermitteln und aufzulisten
- (externe) Laufwerke zu trennen / auszuwerfen
- gültige Laufwerke zu erkennen
>> Neu <<
- Laufwerk-Informationen auszulesen

Finde ich sehr interessant! So etwas suche ich gerade, könnte es gut gebrauchen, wenn es "automatisch" erkennt, wenn ich zB. einen USB-Stick anstecke, so, wie der Windows-Explorer das macht, also "bemerkt", dass das entsprechende Laufwerk jetzt bereit ist und beim Abziehen des Sticks auch dies erkennt.
Kann die Komponente das?


Delphi-Laie - Sa 18.03.17 23:42

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
So etwas suche ich gerade, könnte es gut gebrauchen, wenn es "automatisch" erkennt, wenn ich zB. einen USB-Stick anstecke, so, wie der Windows-Explorer das macht, also "bemerkt", dass das entsprechende Laufwerk jetzt bereit ist und beim Abziehen des Sticks auch dies erkennt.
Kann die Komponente das?


Probiere es doch einfach aus!

Nach meinen bescheidenen Kenntnissen ist so etwas (konkret: systemweite Überwachung bestimmter Ereignisse) nur über einen globalen Hook möglich, demnach benötigt man eine Dll-Datei. Hat diese trotzdem sehr gute Komponente jedoch nicht. Deshalb dürfte es nach meiner vorsichtigen Einschätzung damit nichts werden.


Delete - Sa 18.03.17 23:51

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - Sa 18.03.17 23:58

Geht ohne grossen Aufwand:

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:
unit Unit1; //20170318

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, DBT, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    UsbNotifyInfo : TDevBroadcastDeviceinterfaceA;
    UsbDeviceNotificationHandle : Pointer;
    Procedure UsbDeviceChangeNotification(Var Msg : TMessage); MESSAGE WM_DEVICECHANGE;
    { Private declarations }
  public
    { Public declarations }
    Procedure RegisterUsbNotification;
    Procedure UnregisterUsbNotification;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure MM(s:string); begin Form1.Memo1.lines.add(s); end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterUsbNotification;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnregisterUsbNotification;
end;

Procedure TForm1.RegisterUsbNotification;
Var
  Error : Cardinal;
Begin
  ZeroMemory(@UsbNotifyInfo, sizeof(UsbNotifyInfo));
  UsbNotifyInfo.dbcc_size := sizeof(TDevBroadcastDeviceInterfaceA);
  UsbNotifyInfo.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
  UsbNotifyInfo.dbcc_reserved := 0;
  UsbNotifyInfo.dbcc_classguid := StringToGuid('{A5DCBF10-6530-11D2-901F-00C04FB951ED}');
  UsbDeviceNotificationHandle := RegisterDeviceNotification(self.Handle, @UsbNotifyInfo, Cardinal(0));
  If UsbDeviceNotificationHandle = NIL Then
  Begin
    Error := GetLastError;
    ShowMessage(Format('Registering Device Notification failed, error code: %d', [Error]));
  End;
End;

Procedure TForm1.UnregisterUsbNotification;
Begin
  If (UsbDeviceNotificationHandle <> NILThen
  Begin
    UnregisterDeviceNotification(UsbDeviceNotificationHandle);
  End;
End;

Procedure TForm1.UsbDeviceChangeNotification(Var Msg : TMessage);
Var
  device : PDevBroadcastHdr;
  DeviceInfoBlock : PDevBroadcastDeviceInterface;
  MyDevice : String;
Begin
  If Msg.Msg = WM_DEVICECHANGE Then
  Begin
  Winapi.windows.Beep(2000,50);
    If Msg.WParam = DBT_DEVICEREMOVECOMPLETE Then
    Begin
      device := PDevBroadcastHdr(Msg.lParam);
      If device.dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE Then
      Begin
        DeviceInfoBlock := PDevBroadcastDeviceInterface(Msg.LParam);
        MyDevice := String(Pchar(@DeviceInfoBlock.dbcc_name));
        MyDevice := Uppercase(MyDevice);
       MM('REMOVAL: '+#13#10+MyDevice);
      End;
    End
    Else
    If Msg.WParam = DBT_DEVICEARRIVAL Then
    Begin
      device := PDevBroadcastHdr(Msg.lParam);
      If device.dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE Then
      Begin
        DeviceInfoBlock := PDevBroadcastDeviceInterface(Msg.LParam);
        MyDevice := String(Pchar(@DeviceInfoBlock.dbcc_name));
        MyDevice := Uppercase(MyDevice);
        MM('ARRIVAL: '+#13#10+MyDevice);
      End;
    End;
  End;
End;

end.


Delete - So 19.03.17 01:28

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - So 19.03.17 08:04

Leider stürzt das Programm ab bei FOnDeviceConnected und FOnDeviceDisconnected.
Version fehlt: function GetVersion: string; muss unter public


Delete - So 19.03.17 13:10

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - So 19.03.17 20:33

Crash beim Abziehen und/oder Anstecken eines USB-Sticks.


Delete - So 19.03.17 20:50

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - So 19.03.17 20:53

Das ist nicht die Ursache.


Delete - So 19.03.17 21:06

- Nachträglich durch die Entwickler-Ecke gelöscht -


t.roller - So 19.03.17 21:19

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Und nein, GetVersion muss nicht unter public sein. :)


Ich hatte es anders in der Unit1:


Delphi-Quelltext
1:
caption:= frDrive2.GetVersion;                    

statt

Delphi-Quelltext
1:
caption:= frDrive2.Version;                    


Aber wenn es public ist, kann man beide verwenden... :)

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


t.roller - So 19.03.17 21:27

Seltsam: Deine EXE funktioniert, die unveränderte Compilation mit XE7 führt zum Absturz.


Delete - So 19.03.17 21:30

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Do 30.03.17 19:03

Ich habe mir das jetzt nicht alles durchgesehen und auch noch nichts runtergeladen.

Aber weil ich mich vor sehr vielen Jahren auch mal mit der Auswertung von Laufwerken befaßt hatte, weiß ich noch, daß besonders die tatsächliche Verfügbarkeit die meiste Bedeutung hat.

Ich weiß jetzt nicht, ob in dem hier vorgestellten Projekt diese Typen schon berücksichtigt sind:
Ramdisk, Wechsellaufwerke (Disk,CD/DVD, Speziallaufwerke) mit oder ohne Datenträger, mit SUBST zugewiesene Laufwerke,
zugewiesene Netzlaufwerke

Ich hatte damals ein MO-Laufwerk, auf das ich (oh, das war ja sogar noch unter DOS) per Interrupt zugreifen wollte.
Außerdem hatte ich viele SUBST-Laufwerke und wollte vermeiden, daß auf diese Weise Substlaufwerke als "echte"
Laufwerke vorgetäuscht werden, weil es dann vielleicht Probleme bei direkten Hardwarezugriffen oder bei diversen Auswertungen gegeben hätte.

Das nur als Anregung, ggf. auch Laufwerkstypen einzubeziehen, an die vielleicht noch nicht gedacht wurde.


Delete - Fr 31.03.17 15:42

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Sa 01.04.17 11:43

Hallo, Frühlingsrolle.

Momentan komme ich nicht dazu. Mein damaliges Projekt war außerdem auf einem Rechner mit Windows 98, der momenatn aus Platzmangel irgendwo abgestellt ist. Da müßte ich erst mal alles wieder in Betrieb nehmen und gucken. Aber anscheinend hast Du meinen Hinweis nicht so gedeutet wie er gemeint war. Zwra weiß (noch) wirklich nicht, was und wie Du prüfst, aber aus dem von Dir hier gepostenen Codeschnipesel erkenne ich beispielsweise keine explizite Unterscheidung von z.B. Ramdisk und SUBST-Laufwerken. Die mögen zwar unter Wechsellaufwerke zugeordnet werden können (weiß ich jetzt nicht so genau, vermute ich aber) - aber unterscheidest Du dann auch wirklich die Laufwerkstypen?

Es ist z.B. ein gewaltiger Unterschied, ob ein Wechsellaufwerk ein Disklaufwerk (mit ziemlich eingeschränkter Kapazität) oder z.B. ein MO-Laufwerk ist, und auch da gibt es unterschiedliche Kapazitätsgrößen. Solche Unterscheidungen bei der Hardware-Erkennung meinte ich. Es könnte natürlich sein, daß ich solche Feinheiten damals tatsächlich nur per DOS-Interrupt ermitteln konnte und das mit Windows (wie vieles) gar nicht mehr möglich ist.

Aber versprochen: Sobald ich (in einigen Monaten) Zeit dafür habe, sehe ich mir das mal alles sorgfältig durch!


Delete - Sa 01.04.17 12:14

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Sa 01.04.17 16:20

Na gut, dann werde ich doch mal etwas schneller als eigentlich geplant raussuchen, wie ich das damals gemacht hatte, denn GetDrivetype war mir schon damals etwas zu primitiv. Jedenfalls könnte ich mir vorstellen, daß es Dir unter diesen Umständen doch was nutzen könnte (falls es nicht direkt auf Interrupts zugreift) ...

Bis die Tage.

EDIT: Gut, wenn man einen Server hat. Jetzt habe ich die Sachen doch auf die Schnelle gefunden. Das damals unter DOS war doch was anderes. Das hier hatte ich ab Delphi 4 getestet. Ich habe einfach mal das gesamte Verzeichnis in die ZIP-Datei gepackt, ohne jetzt zu prüfen, was davon wirklich nötig ist.

Vielleicht kannst Du/können auch andere damit was anfangen.


Delete - Sa 01.04.17 17:27

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Sa 01.04.17 19:39

Zu Deinen Fragen bzgl. "Base" und "Flag":

Base betrifft soviel ich in Erinnerung habe nur zugewiesene Laufwerke. Momentan habe ich keine Ramdisk und kein Substlaufwerk. Je nach Vernetzung kann da evtl. bei Netzlaufwerken auch was anderes als "\\" stehen. Ich hatte früher mal Kirschbaumnetz und das von PTS-DOS. Möglicherweise steht dann da was anderes. Steht bei mir unter "Base" also "\\", so sehe ich gleich (noch vor dem Laufwerksbuchstaben) daß es sich um Netzlaufwerke handelt. Unter "Bezeichnung" finde ich dann z.B. als Quell-Laufwerk "D-SHUTTLE" und dann habe ich z.B. unter "aktueller Pfad oder Quelle" die zugewiesenen Laufwerke "O" und und "Q" im Klartext als "\\MYLANSERVER\WWW" und "\\MYLANSERVER\D".

Das Flag stammt aus der erweiterten Pfad- und Dateinamenauswertung, mit der auch möglich ist, Dateigrößen über 2 GB (?) korrekt anzuzeigen. Sorry, daß ich jetzt nicht dazu komme, mir diese alten Quellen (von 2008) nochmal genau durchzusehen.
Es dürfte sich um "TVolumeInfoData" in der Unit "LAnalyse" handeln.

Ich weiß nur (wenn ich in die Quellen gucke) anhand meiner damaligen Kommentare, daß es auch mit Windows 98 und ME geteset wurde und je nach Version des Betriebs-Systems ggf. andere Sachen eingebunden werden müssen. Beispielsweie hatte ich die Fremdunit "Subst9x" lange Zeit mit Windows98 benutzt, um programmgesteuert Substlaufwerke jederzeit beliebig und vor allem schnell auf andere Pfade zu setzen.

Damals hatte ich noch kein Internet und habe darum noch viel mit Delphi gemacht. Ich bin ziemlich sicher, daß Du bei Auswertung des Betriebssystems mithilfe der von mir benutzten Sachen (wobei nur wenige von mir selbst stammen) auch noch Windows 98 unterstützen kannst. Was neuere Versionen als XP betrifft, dürfte es wahrscheinlich nicht soviel Neues geben außer den bescheuerten Restriktionen, die man ggf. beachten müßte falls sie Relevanz haben.

Danke für den Quelltext in der privaten Nachricht, aber ich weiß echt nicht, wann ich mir das ansehen kann.

Viel Erfolg weiterhin mit Deinem Projekt.

Nachtrag: Na gut, weil es ja eine einzige, komplette Unit ist, habe ich doch mal reingeguckt. Mein Problem dabei wäre aber nicht das Betriebssystem, sondern die Compilerversion. Die Unit enthält leider Bestandteile, durch die sie selbst mit der letzten mir verfügbaren Delphi-Version uncompilierbar ist. Da will ich erst gar nicht groß versuchen, drin rumzubasteln.

Beispielsweise kann ich mit diesen Anweisungen
_STORAGE_BUS_TYPE = (
BusTypeUnknown = $00,

nichts anfangen. = $00 und die folgenden werden bemängelt. Da wird dann bereits statt des Gleichheitszeichens eine schließende Klammer erwartet. Aber das ist nicht alles. Es gibt noch irgendwo andere Bemängelungen. Der Kommentar von jemandem, es auch schon mit Delphi 6 compilieren zu können, muß wohl eine Vorversion der Unit betreffen.

Suchmaschinensuche nach delphi "BusTypeUnknown" hat mir dann zwar Suche in der Delphi-PRAXiS HTTP://WWW.DELPHIPRAXIS.NET/543483-POST24.HTML geliefert, aber dann müßte ich Deine Unit auseinanderpflücken und das will ich nicht.


Delete - So 02.04.17 03:54

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - So 02.04.17 10:55

Danke für die Hinweise. Getestet hatte ich es aktuell mit Delphi 5 und habe auf einer anderen Bootpartition desselben Rechners auch noch Delphi 7. Aber es ist tatsächlich momentan bei mir auch eine Zeitfrage, sonst würde ich auch mal weider den Windows 98-Rechner hervorkramen, auf dem ich damals meine Tests gemacht hatte.


Delete - Fr 07.04.17 15:06

Hallo ! Mit Delphi 5 nicht compilierbar. Mit Delphi 7 geht's.

Allerdings erschließt sich mir der Sinn dieser Komponente nicht. Nach dem Einbinden der Komponente kann ich lediglich im Objektinspektor diverse Drivetypen anklicken, wobei ich dann z.B. sehe, daß Netzlaufwerke als "dtRemote" ausgewertet werden.

Aber wieso soll ich das alles innerhalb der Komponente auswählen? Gibt es denn kein Beispielprogramm, wo erkennbar wird, was die Komponente eigentlich im praktischen Einsatz macht?

Die paar Beispiele am Anfang des Threads sind nicht wirklich aufschlußreich, zumal es nur Fragmente sind, die teils auch gar nicht funktionieren bzw. fehlerhaft sind.

Sorry, aber für mich ist das nichts. Zu kompliziert in der Anwendung und vom Konzept her etwas zu weit oben angesiedelt.


Delete - Sa 08.04.17 01:52

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Sa 08.04.17 03:04

Nein. Es liegt bei Delphi 5 nicht am package. Ich hatte es angepaßt.

Es liegt an der Art der Speicherreservierung, wobei sich mir übrigens auch nicht erschließt, wieso man sowas überhaupt derart kompliziert macht. Ich habe selbst sehr komplexe Komponenten (als ich noch welche erstellt hatte) nie in reservierte Speicherbereiche ausgelagert.


Delphi-Quelltext
1:
2:
3:
4:
[Fehler] ufrDrive.pas(763): Undefinierter Bezeichner: 'AllocateHWnd'
[Fehler] ufrDrive.pas(763): Nicht genügend wirkliche Parameter
[Fehler] ufrDrive.pas(774): Undefinierter Bezeichner: 'DeallocateHWnd'
[Fataler Fehler] frDriveDesign_D5.dpk(32): Verwendete Unit 'src\ufrDrive.pas' kann nicht compiliert werden


Sorry, aber das Konzept der Unit, die Umständlichkeit und Art der Nutzung geben für mich persönlich keinen Sinn. Es bringt auch keinem etwas, sich mühsam in etwas einzuarbeiten, das einen völlig anderen Weg geht, als man es selbst tun würde. Mir ging es lediglich drum, etwas Hilfestellung bei standardmässig nicht berücksichtigten Laufwerksarten zu geben, mehr nicht.

Wahrscheinlich hätte ich solche Komponente so umgesetzt, daß dann alle ermittelbaren Infos zu allen Laufwerken bereits im Objektinspektor zu sehen wären.

Jeder macht etwas eben so, wie er es selbst brauchen kann. Mehr will ich jetzt dazu nicht mehr äusser und werde mich hier auch nicht mehr einklinken.


Delete - Sa 08.04.17 03:30

- Nachträglich durch die Entwickler-Ecke gelöscht -


jaenicke - Do 01.06.17 10:24

Die IFDEFs kannst du dir teilweise sparen:

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:
uses
  Classes, Windows, SysUtils, ShellAPI, Graphics, Messages
  {$IFNDEF DELPHI6_UP}, Forms{$ENDIF}
  {$IFDEF FPC}, LCLIntf{$ENDIF};

//...

constructor TfrDrive.Create(AOwner: TComponent);
var
  i: Byte;
begin
  inherited;
  for i := 0 to 3 do
    FIcons[i] := TIcon.Create;
  DoDeviceChange;
  FHWndProc := AllocateHWnd(WndProc);
end;

destructor TfrDrive.Destroy;
var
  i: Byte;
begin
  for i := 0 to 3 do
    FIcons[i].Free;
  DeallocateHWnd(FHWndProc);
  inherited;
end;

Getestet mit Delphi 10.2 und dem aktuellsten Lazarus Build.


Delete - Fr 30.06.17 14:40

- Nachträglich durch die Entwickler-Ecke gelöscht -