Laden...

Cursor in anderem Fenster verstecken

Erstellt von Stryder vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.025 Views
S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 14 Jahren
Cursor in anderem Fenster verstecken

Ich habe zur Zeit folgendes Problem:
Ich schreibe ein kleines Programm für meinen CarPC. Dieses holt sich das Handle eines externen Programms (Navigationssoftware).
Danach wird der Rahmen entfernt und das Fenster per SetParent in mein Programm integriert. Nun würde ich aber aus Touchscreen gründen gerne den Mauszeiger auf dem Navigationsprogramm entfernen.

Das gestaltet sich allerdings schwieriger als erhofft. Man kommt leider nur an den Cursor des eigenen Prozesses ran. Invoke geht auch nicht weil man aus einem Handle nur ein Form Element holen kann wenn man selbst Ersteller dieses ist.

Also was tun? Die Sendmessage API bietet leider nur die Funktion den Cursor zu verschieben.

Hat jemand noch eine Idee? Ein transparentes Bild wäre natürlich auch eine Möglichkeit, allerdings genauso schwierig wenn man keinen Zugriff auf den Cursor hat.

771 Beiträge seit 2009
vor 14 Jahren

Hallo,

um den Cursor ganz zu verstecken, könntest du die WinAPI-Funktion 'SetCursor' benutzen (mit NULL als Parameter),


[DllImport("user32.dll")]
static extern bool SetCursor(IntPtr hcur);

SetCursor(IntPtr.Zero);

Damit ist jedoch der Cursor generell versteckt.

Sollte das externe Fenster einen eigenen Cursor anfordern, dann wird der aber wieder angezeigt, sobald die Maus über dem Bereich ist. In dem Fall müßte man den Cursor für die intern registrierte Fenster-Klasse auf NULL setzen - dies könnte schwieriger werden...

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 14 Jahren

Hallo,

danke schon mal für den Tip. Aber leider passiert dabei gar nichts. Ich kann die Funktion so oft aufrufen wie ich will. Der Mauszeiger wird weder ausserhalb noch über der Form versteckt.
Es muss doch eine Möglichkeit geben die Cursor Eigenschaft für ein anderes Fenster von aussen zu bestimmen?

Vielleicht weiß jemand wie man das globale Cursor Icon per Code ändern kann?

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Stryder,

ich wüsste nicht, warum es mit der genannten Funktion nicht gehen sollte.

herbivore

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 14 Jahren

Dann mal hier einen Auszug aus dem Code:


IntPtr wind = com.getWindow("Notepad";);
while (wind.ToInt32() == 0)
{
       Thread.Sleep(100);
       wind = com.getWindow("Notepad";);
}
IntPtr par = this.Handle;

com.SetPar(wind, par);
int style = com.GetWindow(wind, GWL_STYLE);
com.SetWindow(wind, GWL_STYLE, WS_NOBORDER);
com.SetCurs(IntPtr.Zero);

com.SetWindowPosition(wind, 0, 0);
com.SetCurs(IntPtr.Zero); //auch nochmal nach der letzten Fenster Aktivität.

Leider passiert da soweit gar nichts. com ist eine eigene Klasse die die Methoden bereitstellt.

Hier dann noch der Ausschnitt aus der Com Klasse:


public IntPtr SetPar(IntPtr hWndChil, IntPtr hWndPar)
{
       return SetParent(hWndChil, hWndPar);
}

[DllImport("USER32.DLL";)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

const UInt32 SWP_NOZORDER = 0x0004;
const UInt32 SWP_SHOWWINDOW = 0x0040;

public bool SetWindowPosition(IntPtr hWnd, int x, int y)
{
       return SetWindowPos(hWnd, 0, x, y, 800, 422, SWP_NOZORDER | SWP_SHOWWINDOW);
}

[DllImport("user32.dll";)]
static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X,
int Y, int cx, int cy, uint uFlags);

public bool SetCurs(IntPtr cur)
{
       return SetCursor(cur);
}

[DllImport("user32.dll";)]
static extern bool SetCursor(IntPtr hcur);

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Stryder,

sorry, mit SetCursor kann man wohl nicht den Cursor für ein bestimmtes anderes Fenster setzen. Eine Funktion mit der man das kann, aber ich auf die Schelle aber auch nicht gefunden.

herbivore

771 Beiträge seit 2009
vor 14 Jahren

Dann probiere mal die ShowCursor(false)-Funktion aus: http://www.pinvoke.net/default.aspx/user32/ShowCursor.html

Der fensterspezifische Cursor ist in der WNDCLASS-Struktur hinterlegt, welche bei RegisterClass angegeben wird. Ich weiß jedoch nicht, wie man diese Struktur (bzw. dem hCursor-Member) nachträglich ändert (falls dieser Wert überhaupt != NULL ist).

Evtl. sollte man mal eine Suchmaschine nach einer C Lösung fragen und diese dann entsprechend p/invoken...

Edit:
Hier gibt es anscheinend die Lösung dafür, direkt bei MSDN:
http://msdn.microsoft.com/en-us/library/ms648380(VS.85).aspx


// Change the cursor for window class represented by hwnd. 

SetClassLong(hwnd,    // window handle 
    GCL_HCURSOR,      // change cursor 
    (LONG) hCurs2);   // new cursor 

d.h. einfach mittels http://www.pinvoke.net/default.aspx/user32/SetClassLong.html


const int GCL_HCURSOR = -12; // aus winuser.h

SetClassLong(hWnd, GCL_HCURSOR, 0L);

Evtl. dann in Kombination mit den anderen beiden Funktionen...

Edit 2: Für 64-Bit Windows müßtest du allerdings die SetClassLongPtr-Funktion verwenden (http://msdn.microsoft.com/en-us/library/ms633588(VS.85).aspx bzw. http://www.pinvoke.net/default.aspx/user32/SetClassLongPtr.html)

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 14 Jahren

Hm also bisher hab ich es noch nicht hinbekommen.
Es tut sich noch nichts. Bin nicht ganz sicher was ich als IntPtr für den neuen Cursor übergeben soll. Ist Zero da okay?

Ist das erstellen des Handles so in Orndung?

Hier mal mein Code:


HandleRef refhwnd = new HandleRef(null, wind);
com.SetClassLong(refhwnd, GCL_HCURSOR, IntPtr.Zero);


        public IntPtr SetClassLong(HandleRef hWnd, int nIndex, IntPtr dwNewLong)
        {
            if (IntPtr.Size > 4)
                return SetClassLongPtr64(hWnd, nIndex, dwNewLong);
            else
                return new IntPtr(SetClassLongPtr32(hWnd, nIndex, unchecked((uint)dwNewLong.ToInt32())));
        }

        [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")]
        public static extern IntPtr SetClassLongPtr64(HandleRef hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", EntryPoint = "SetClassLong")]
        public static extern uint SetClassLongPtr32(HandleRef hWnd, int nIndex, uint dwNewLong);