mikrocontroller.net

Forum: PC-Programmierung C# : Referenz auf Klasse einer statischen Funktion übergeben


Autor: Ing. ET (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
folgendes Problem:
Ich benutze die Win32-API und moechte alle Windows ueberpruefen.
Meine Code schaut so aus:
public delegate bool CallBack(int hwnd, int lparam);

[DllImport("user32.dll")]
public static extern int EnumWindows(CallBack callback, int param);


EnumWindows(cbWinName, 0);
CallBack cbWinName = new CallBack(fnWinName);

private static bool fnWinName(int hWnd, int lParam)
{
//Hier moechte auf Klassenelemente zugreifen
}

in der callback Funktion fnWinName moechte ich auf nicht-statische 
Klassen-Elemente zugreifen. Dieser Funktion wird lParam uebergeben, 
welcher im obigen Beispiel in der Funktion EnumWindows mit 0 festgelegt 
wird.

Mit C wuerde ich einfach eine Struktur auf (int) casten, dann kann ich 
in fnWinName darauf zugreifen
struct Sdata {...};
struct Sdata data;
EnumWindows(fnWinName, (int) &data);

int fnWinName(int hWnd, int lParam)
{
struct Sdata *p= (struct Sdata *)lParam;

}

Wie kann ich in C# sowas machen, d.h. in dem int-Argument eine Referenz 
auf einen Datenbereich, bzw. Klasse uebergeben?

Gruss, Juergen

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Referenzen macht man in c# in Methoden normalerweise mit dem 
Schlüsselwort ref. Das ist aber glaub ich auch das einzigste.

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder man nimmt das Beispiel von
http://pinvoke.net/default.aspx/user32.EnumWindows
als Vorlage...

Autor: Ing. ET (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>http://pinvoke.net/default.aspx/user32.EnumWindows

Danke fuer den Link.
Ich finde sehr interessant, dass man so einfach die Signatur von 
DLL-Funktionen abaendern kann. Ein 'int' und ein 'ref' haben zwar die 
gleiche Datengroesse (4 Bytes), aber trotzdem cool, dass es so einfach 
geht.


Die Deklaration in user32.dll:
WINUSERAPI BOOL WINAPI EnumWindows(WNDENUMPROC,LPARAM);
typedef BOOL(CALLBACK *WNDENUMPROC)(HWND,LPARAM);

abgeaendert in
private delegate bool EnumWindowsProc(IntPtr hWnd, ref SearchData data);

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ing. ET schrieb:
> Ich finde sehr interessant, dass man so einfach die Signatur von
> DLL-Funktionen abaendern kann.
da ist das Problem mit DLLs, die signatur steht dort überhaupt nicht 
drin, du kannst hinschreiben was du willst.

private delegate bool EnumWindowsProc(byte a, int b, string c);

das merkt auch erstmal niemand, bis zum starten der Funktion...

Autor: Ing. ET (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>da ist das Problem mit DLLs, die signatur steht dort überhaupt nicht
>drin, du kannst hinschreiben was du willst.

Da will ich auf einen Fehler in C# hinweisen.
Wenn man folgenden Code ausfuehrt:
[DllImport("user32.dll")]
public static extern bool GetWindowRect(int hWnd, ref Rectangle rc);


...

Rectangle rc = new Rectangle();
GetWindowRect(hwnd, ref rc);

x=rc.Width;
y=rc.Height;

dann kann man Verwirrung ernten:
In rc.Width und rc.Height stehen nicht die Weite/Hoehe, sondern die x/y 
Position der rechten unteren Ecke.
Vermutlich stimmt System.Drawing.Rectangle nicht mit der DLL-Struktur 
ueberein.
Ich habe das Problem geloest, indem ich die Weite mit rc.Width-rc.X 
errechne. Ob das bei Visual C# 2010 auch so ist, weiss ich nicht, ich 
verwende C# 2008 Express.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ing. ET schrieb:
> public static extern bool GetWindowRect(int hWnd, ref Rectangle rc);

das sollte man auf keine Fall so machen!!!! Denn in C# sind die 
strukturen/Klassen nicht dafür gedacht das sie von einer DLL verwendet 
werden. Wenn du z.b. ein 64bit system hast kann es schon sein das das 
alles nicht mehr passt. Du musst dafür die extra eine stuktur so 
anlegen:

[StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // x position of upper-left corner
            public int Top;         // y position of upper-left corner
            public int Right;       // x position of lower-right corner
            public int Bottom;      // y position of lower-right corner
        }


alles andere wird irgendwann schief gehen!

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ing. ET schrieb:
>>da ist das Problem mit DLLs, die signatur steht dort überhaupt nicht
>>drin, du kannst hinschreiben was du willst.
>
> Da will ich auf einen Fehler in C# hinweisen.
> Wenn man folgenden Code ausfuehrt:
>
>
> [DllImport("user32.dll")]
> public static extern bool GetWindowRect(int hWnd, ref Rectangle rc);
> 
> 
> ...
> 
> Rectangle rc = new Rectangle();
> GetWindowRect(hwnd, ref rc);
> 
> x=rc.Width;
> y=rc.Height;
> 
>
> dann kann man Verwirrung ernten:
> In rc.Width und rc.Height stehen nicht die Weite/Hoehe, sondern die x/y
> Position der rechten unteren Ecke.
> Vermutlich stimmt System.Drawing.Rectangle nicht mit der DLL-Struktur
> ueberein.

Nicht nur vermutlich, die Struktur ist unterschiedlich...
http://www.pinvoke.net/default.aspx/user32.getwindowrect
http://msdn.microsoft.com/en-us/library/dd162897(v...
http://msdn.microsoft.com/en-us/library/ms633519(VS.85).aspx

Autor: Ing. ET (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das sollte man auf keine Fall so machen!!!! Denn in C# sind die
>strukturen/Klassen nicht dafür gedacht das sie von einer DLL verwendet

Das habe ich mir schon gedacht, aber ich bin neu in C# eingestiegen und 
lerne die Sprache mit tutorials und google.
Der obige Code ist von einem Tutorial abgekupfert und er hat ja 
funktioniert, solange ich nur die .X/.Y members benutzt habe.

Also KEIN Fehler in C#, sondern im Tutorial.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.