Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit Verfügbarkeit der Funktion (https://www.delphipraxis.net/75290-problem-mit-verfuegbarkeit-der-funktion.html)

robert23 17. Aug 2006 08:28


Problem mit Verfügbarkeit der Funktion
 
Hallo, ich wollte jetzt in mein Programm mal ein bisschen Ordnung reinbringen.
Nun habe ich natürlich das Problem das es eine Funktionen und Prozeduren mehr werden
und ich sie dadurch einmal allgemein bekannt manchen muss.

Das ist die Funktion:
Delphi-Quellcode:
function TForm1.EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
var
  Title, ClassName: array[0..255] of char;
  Rec: PTable;
begin
  Result := True;
  GetWindowText(wHandle, Title, 255);
  GetClassName(wHandle, ClassName, 255);

  if (string(ClassName) = '#32770') AND AnsiContainsStr(string(Title), 'Message') then
    CloseWindow(wHandle);
  // Kontrolle einbauen ob Eintrag in TableList schon vorhanden
  if (string(ClassName) = '#32770') AND NOT AnsiContainsStr(string(Title), 'Lobby') then
  begin
    New(Rec);
    TableList.Add(Rec);
    Rec^.ID := GlobalID;  inc(GlobalID);
    Rec^.Handle := wHandle;
    Rec^.ClassName := string(ClassName);
    Rec^.Caption := string(Title);
    Rec^.Controlled := false;
  end;
end;
und ich habe gedacht ich kann das ganze folgend verfügbar machen.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, TlHelp32, StrUtils, Grids;

type
  TTable = Record
    ID: Integer;
    Handle: HWND;
    ClassName: string;
    Caption: string;
    Controlled: bool;
  end;
  PTable = ^TTable;

  TForm1 = class(TForm)
    Button_Search: TButton;
    Image1: TImage;
    Button_Ctrl: TButton;
    ListBox1: TListBox;
    function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
    procedure Button_SearchClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    ...
nun bekomme ich immernoch folgenden Fehler
Zitat:

undefinierter Bezeichner "EnumWindowsProc"
in folgendem Codeschnipsel (Funktion die über der EnumWindowsProc geschrieben wurde,sollte es nicht trotzdem verfügbar sein?)
Delphi-Quellcode:
procedure SearchTables;
var
a: integer;
begin
  Form1.ListBox1.Items.Clear;
  EnumWindows(@EnumWindowsProc,Integer(Form1.ListBox1));      // hier tritt der Fehler auf
  TableList.Pack;
  for a:=0 to TableList.Count-1 do
    Form1.ListBox1.Items.Add(PTable(TableList.Items[a]).Caption);
end;

mquadrat 17. Aug 2006 08:35

Re: Problem mit Verfügbarkeit der Funktion
 
Deine Methode befindet sich innerhalb der Klasse TForm1. Du musste also auch eine Instanz von TForm1 angeben, damit du die Methode benutzen kannst (in deinem Fall Form1).

Delphi-Quellcode:
Form1.EnumWindows

robert23 17. Aug 2006 08:43

Re: Problem mit Verfügbarkeit der Funktion
 
So meinst du das hoffentlich
Delphi-Quellcode:
EnumWindows(@Form1.EnumWindowsProc,Integer(Form1.ListBox1));
und folgende Fehlermeldung gibts dazu
Zitat:

Variable erforderlich

hoika 17. Aug 2006 09:33

Re: Problem mit Verfügbarkeit der Funktion
 
Hallo,

Schreibe die Methode EnumW. ausserhalb von TForm1,
am besten in einer ganz eigenständigen Unit (Name Tools ?).

Dann kannst du sie überall benutzen.

Heiko

Muetze1 17. Aug 2006 09:47

Re: Problem mit Verfügbarkeit der Funktion
 
... Mal ganz davon abgesehen, dass du die CallBack Procedure (EnumWindowProc) nicht zu einer Methode machen kannst, weil damit die Aufrufliste nicht mehr stimmt. Die EnumWindowProc muss eine einfache Funktion sein und darf keine Methode sein!

Grund: Die Methode bekommt vorne noch einen versteckten Self Parameter mit gegeben.

Ausserdem: Was soll bitte die "Export" Klausel an der Methode? Willst du wirklich die Methode exportieren? Ich denke nicht, dass du gerade an einer DLL schreibst, oder?

robert23 17. Aug 2006 09:53

Re: Problem mit Verfügbarkeit der Funktion
 
ok, die export kann weg.
Zu dem rest den du geschrieben hast, soll das jetzt heißen ich kann die funktion nicht
allgemein verfügbar machen?

Muetze1 17. Aug 2006 10:11

Re: Problem mit Verfügbarkeit der Funktion
 
Zitat:

Zitat von robert23
Zu dem rest den du geschrieben hast, soll das jetzt heißen ich kann die funktion nicht
allgemein verfügbar machen?

Klar kannst du es, aber nicht als Methode einer Klasse. Wie genau (als ein Beispiel), wurde schon gepostet:

Zitat:

Zitat von hoika
Schreibe die Methode EnumW. ausserhalb von TForm1,
am besten in einer ganz eigenständigen Unit (Name Tools ?).

Dann kannst du sie überall benutzen.


robert23 17. Aug 2006 10:17

Re: Problem mit Verfügbarkeit der Funktion
 
das habe ich gerade probiert, kommt immernoch der selbe fehler "Variable erforderlich"

Hawkeye219 17. Aug 2006 10:46

Re: Problem mit Verfügbarkeit der Funktion
 
Wenn du die Funktion - wie bereits vorgeschlagen - als einfache Routine vereinbarst, kannst du sie nach der Vereinbarung nutzen:

Delphi-Quellcode:
// Vereinbarung als *einfache* Routine, nicht als Methode
function MyEnumProc (aHandle: HWND; aData: LPARAM): BOOL; stdcall;
begin
  TStrings(aData).Add(IntToStr(aHandle));
end;

// Verwendung *nach* der Vereinbarung
procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Clear;
  EnumWindows(@MyEnumProc, Integer(ListBox1.Items));
end;
Gruß Hawkeye

NicoDE 17. Aug 2006 11:10

Re: Problem mit Verfügbarkeit der Funktion
 
Einer der Wege das ganze etwas zu verpacken (erster Schritt). Eine Unit mit einer Funktion die es ermöglicht eine Methode für jedes Fenster aufrufen zu lassen:
Delphi-Quellcode:
unit WndUtils;

interface

uses
  Windows;

type
  // Die Enumerierung wird abgebrochen wenn die Methode False zurückgibt.
  TEnumWndCallback = function(AWnd: HWND): Boolean of object;

function EnumWnd(ACallback: TEnumWndCallback): Boolean;

implementation

type
  PEnumWndParam = ^TEnumWndParam;
  TEnumWndParam = record
    Callback: TEnumWndCallback;
  end;

function EnumWndProc(AWnd: HWND; AParam: LPARAM): BOOL stdcall;
begin
  Result := PEnumWndParam(AParam).Callback(AWnd);
end;

function EnumWnd(ACallback: TEnumWndCallback): Boolean;
var
  Param: TEnumWndParam;
begin
  Param.Callback := ACallback;
  Result := EnumWindows(Pointer(Addr(EnumWndProc)), LPARAM(Addr(Param)));
end;

end.
In der benutzenden Klasse muss eine Methode vom Typ TEnumWndCallback implementiert werden:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Classes, Forms, Controls, StdCtrls;

type
  TForm1 = class(TForm)
  //...
  private
    { Private-Deklarationen }
    function EnumWndCallback(AWnd: HWND): Boolean;
  //...
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  WndUtils;

//...

function TForm1.EnumWndCallback(AWnd: HWND): Boolean;
begin
  //...
  Result := True; // Enumerierung fortsetzen
end;

//...

end.
Dann muss der Hilfsfunktion nur die Methode übergeben werden:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWnd(EnumWndCallback);
end;
Dadurch wird dann TForm1.EnumWndCallback für jedes Fenster aufgerufen.

Der nächste Schritt der Kapselung wäre eine eigene Klasse, die in ihrer EnumWndCallback das Standardverhalten implementiert.


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