![]() |
EnumWindowsProc -> EAccessError, OutOfResources
Heya. Ich versuche aus bestimmten Fenstern Buttons zu erstellen, was an sich auch recht gut klappt. Um auch immer die aktuellen Fenster in meinem Pogramm darzustellen, habe ich meine Procedure in einen Timer gegeben. Ich bekomme jedoch sobald man ein neues Fenster öffnet einen EAcessError oder ab und an auch einen OutOfResources. Ich habe bereits des öfteren nach meinem Fehler gesucht, kam auch immer zu einer bestimmten Zeile, welche ich anschließend wegestrichen hab um den kompletten Fehlerhaften Code zu erkennen. Jedoch kam ich schlussendlich nur noch zur Zeile 'application.run' und nun weiss ich irgendwie nicht mehr weiter. Darum wollte ich hier um Hilfe bitten.
Delphi-Quellcode:
Ich bin irgendwie der Meinung, dass der Fehler nicht an der Procedure selbst, sondern eher an der funktion liegt.
procedure TTaskbar.Tasks();
var i: Integer; Function EnumWindowsProc(Wnd: THandle): BOOL; StdCall; Var Capt: Array [0..128] of Char; Begin Result:=true; If IsWindowVisible(Wnd) and ((GetWindowLong(Wnd, GWL_HWNDPARENT)=0) or (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT))=GetDesktopWindow)) and ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW)=0) then begin SendMessage(Wnd, WM_GETTEXT, Sizeof(Capt), integer(@Capt)); //angezeigt bis 13. Buchstabe// Capt[13] := Chr( 0 ); SetLength(FensterInfo, length(FensterInfo)+1); inc(lengthvar); FensterInfo[High(FensterInfo)].Caption:=Capt; FensterInfo[High(FensterInfo)].Handle:=Wnd; end; end; begin SetLength(FensterInfo, 0); EnumWindows(@EnumWindowsProc, 0); if oldCount <> high(FensterInfo) then begin oldCount := high(FensterInfo); for i := 0 to high(Blabel) do Blabel[i].Free; for i := 0 to high(task) do task[i].Free; for i := 0 to high(taskicon) do taskicon[i].Free; for i := 0 to Length(FensterInfo) - 1 do begin taskhandle[i]:= FensterInfo[I].Handle; end; for i := 0 to Length(FensterInfo) - 1 do begin task[i]:= TImageEx.Create(nil); with task[i] do begin Parent := Taskbar; Picture.Bitmap.LoadFromResourceName(imageresDLL, 'task_normal'); Height := 26; Width := 100; Top := 12; Transparent := true; Stretch := true; if i <> 0 then Left := (i * 102) + 63 else Left := (i * 102) + 63; Tag := i; OnClick := TaskClick; OnMouseEnter := TaskOver; OnMouseLeave := TaskNormal; Show; //Repaint end; end; for i := 0 to Length(FensterInfo) - 1 do begin Blabel[i] := TLabel.Create(nil); with Blabel[i] do begin Parent := Taskbar; Enabled := true; AutoSize := false; Caption := taskpunkt(FensterInfo[i].Caption); Height := 27; Width := 74; Top := 19; visible := true; Color := clFuchsia; ParentColor := False; Transparent := True; Font.Color := clwhite; //OnClick := TaskClick; //OnMouseEnter := TaskOver; //OnMouseLeave := TaskNormal; if i <> 0 then Left := (i * 102) + 87 // Width * i + (i-2)*Height else Left := (i * 102) + 87; end; end; end; end; |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Hat keine ne Idee? :(
|
Re: EnumWindowsProc -> EAccessError, OutOfResources
Wie kommst du auf die Idee, dass die EnumWindows() zu übergebene Callback Procedure nur einen Parameter hat? Damit zerschiesst du den gesamten Stack!
Zitat:
![]() ![]() |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Und sollte Delphi nicht wegen der lage der EnumWindowsProc meckern?
bei mir hatte der es jedenfalls gemacht, als ich sowas versucht habe habe? Also die Procedur in einer anderen eingebettet war ... es meinte ich solle die gefälligst inzeln ablegen ._. |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Zitat:
Was soll man dazu noch sagen... |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Zitat:
ich kann mich jedenfalls nicht erinnern bei mir ein @ benötigt zu haben (außer halt bis auf das eine Mal, wo ich eine Prozedur in 'ner anderen "absichtlich" eingelagert hatte) ._. ich hab es jedenfalls so wie es im MSDN drinsteht gemacht und soweit ich das sah geht da Borland manchma seinen eigenen Weg ^^ |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Zitat:
Okay das mit dem 2. Parameter wusste ich nicht, muss es mal probieren. |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Zitat:
Ich zitiere hier nochmal das wichtigste... Zitat:
Zitat:
Er sollte meckern, da man keine lokalen Procedure als CallBack Funktionen übergeben darf. Und er meckert bei dir nicht, da du die Typensicherheit (die Typprüfung würde schliesslich meckern bei lokalen Proceduren als Parameter) mit dem @ Zeichen umgangen hast. Durch das @ Zeichen ermittelst du einen Pointer auf die Procedure und somit wird die gesamte Prüfung hinfällig. Ein Pointer ist ein Pointer und da kann man keine Procedure mit einer benötigten Parameterliste draus herauslesen. Versuch du mal bei einem Packet ohne Aufkleber und Text unbekannter Herkunft den Inhalt zu erraten, ohne das Packet zu öffnen. Alle Sicherheitsmerkmale die Delphi in der Beziehung bietet, hast du umgangen, somit ist es kein Wunder das er... a) abstürzt b) nicht meckert |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Zitat:
Hier mal meine überarbeitete Version der funktion
Delphi-Quellcode:
Das ist mit mittlerweile klar, nur ohne dieses @ zeichen, also ohne umgehen der Typsicherheit, funktioniert es ja nicht. Ich meine bei
Und er meckert bei dir nicht, da du die Typensicherheit (die Typprüfung würde schliesslich meckern bei lokalen Proceduren als Parameter) mit dem @ Zeichen umgangen hast.
Delphi-Quellcode:
@EnumWindowsProc kommt dann nicht genügend wirkliche Parameter und bei @arr ohne @ kann ich es zwar noch kompilieren, werde dann aber direkt in die zeile
begin
SetLength(Arr, 0); EnumWindows(@EnumWindowsProc, DWORD(@arr));
Delphi-Quellcode:
geschmissen, nachdem das Programm noch nichtmals richtig erschienen ist.
SetLength(arr^, length(arr^)+1);
Delphi-Quellcode:
type
TFensterInfo=record Handle: HWND; Caption: String; Icon: HIcon; end; FensterInfo= array of TFensterInfo; PFensterInfo= ^FensterInfo; var lengthvar: integer = 0; oldCount: Integer; function EnumWindowsProc(Wnd: HWND; lp: LPARAM): BOOL; stdcall; Var Capt: Array [0..128] of Char; arr: PFensterInfo; Begin Result:=true; arr := PFensterInfo(lp); If IsWindowVisible(Wnd) and ((GetWindowLong(Wnd, GWL_HWNDPARENT)=0) or (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT))=GetDesktopWindow)) and ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW)=0) then begin SendMessage(Wnd, WM_GETTEXT, Sizeof(Capt), integer(@Capt)); //angezeigt bis 13. Buchstabe// Capt[13] := Chr( 0 ); SetLength(arr^, length(arr^)+1); inc(lengthvar); arr^[High(arr^)].Caption:=Capt; arr^[High(arr^)].Handle:=Wnd; end; end; procedure TForm2.Tasks(); var i: Integer; arr: FensterInfo; begin SetLength(Arr, 0); EnumWindows(EnumWindowsProc, DWORD(@arr)); // für den teil siehe oben // end; |
Re: EnumWindowsProc -> EAccessError, OutOfResources
Ok, ich habe mich geirrt in 2 Dingen:
1. Die EnumWindowProc darf doch lokal sein! 2. EnumWindows() ist bei D5 u.a. noch so definiert, dass die EnumWindowProc als Pointer definiert wurde und nicht als Procedure Prototype. Hier ein funktionierender Code:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; procedure FormShow(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} type TFensterInfo = record Handle: HWND; Caption: String; Icon: HIcon; end; PFensterInfoList = ^TFensterInfoList; TFensterInfoList = Array Of TFensterInfo; Var WindowList: TFensterInfoList; Function EnumWindowsProc(Wnd: HWND; lp: LPARAM): LongBool; stdcall; Const coBufferSize = 2048; Var lList: PFensterInfoList; lCaption: String; lCapLen: Integer; Begin Result := True; lList := PFensterInfoList(lp); If IsWindowVisible(Wnd) and ((GetWindowLong(Wnd, GWL_HWNDPARENT)=0) or (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT))=GetDesktopWindow)) and ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW)=0) then begin SetLength(lCaption, coBufferSize); lCapLen := SendMessage(Wnd, WM_GETTEXT, coBufferSize, Integer(PChar(lCaption))); SetLength(lCaption, lCapLen); SetLength(lList^, Length(lList^)+1); lList^[High(lList^)].Caption := lCaption; lList^[High(lList^)].Handle := Wnd; end; end; procedure Tasks(); Begin SetLength(WindowList, 0); EnumWindows(@EnumWindowsProc, Integer(@WindowList)); End; procedure TForm1.FormShow(Sender: TObject); Var i: Integer; begin Tasks; For i := Low(WindowList) To High(WindowList) Do ListBox1.Items.Add(WindowList[i].Caption); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz