C# : Referenz auf Klasse einer statischen Funktion übergeben

Gast #1962340
Lesenswert?
• ▲
▼
Hallo,
folgendes Problem:
Ich benutze die Win32-API und moechte alle Windows ueberpruefen.
Meine Code schaut so aus:
1
public delegate bool CallBack(int hwnd, int lparam);
2

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

6

7
EnumWindows(cbWinName, 0);
8
CallBack cbWinName = new CallBack(fnWinName);
9

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

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
1
struct Sdata {...};
2
struct Sdata data;
3
EnumWindows(fnWinName, (int) &data);
4

5
int fnWinName(int hWnd, int lParam)
6
{
7
struct Sdata *p= (struct Sdata *)lParam;
8

9
}

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

Gruss, Juergen
Gast #1963608
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:
1
WINUSERAPI BOOL WINAPI EnumWindows(WNDENUMPROC,LPARAM);
2
typedef BOOL(CALLBACK *WNDENUMPROC)(HWND,LPARAM);

abgeaendert in
1
private delegate bool EnumWindowsProc(IntPtr hWnd, ref SearchData data);
Gast #1963630
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...
Gast #1963680
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:
1
[DllImport("user32.dll")]
2
public static extern bool GetWindowRect(int hWnd, ref Rectangle rc);
3

4

5
...
6

7
Rectangle rc = new Rectangle();
8
GetWindowRect(hwnd, ref rc);
9

10
x=rc.Width;
11
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.
Gast #1963702
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!
#1963709
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:
>
>
1
> [DllImport("user32.dll")]
2
> public static extern bool GetWindowRect(int hWnd, ref Rectangle rc);
3
> 
4
> 
5
> ...
6
> 
7
> Rectangle rc = new Rectangle();
8
> GetWindowRect(hwnd, ref rc);
9
> 
10
> x=rc.Width;
11
> y=rc.Height;
12
>
>
> 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=VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms633519(VS.85).aspx
Gast #1963806
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren