Fremdes Fenster mit DirectX Inhalt



  • Moin.
    Ich ändere die Größe eines fremden Fensters von einem Spiel. Leider scheint das Spiel nicht die Größenänderung zu bemerken, denn danach ist die Steuerung katastrophal und es gibt leichte Grafikfehler. Die Matrix scheint komplett aus den Fugen.
    Gibts ne Möglichkeit hier einzugreifen?

    void MoveResize()
    {
    	HWND hWindow = FindWindow(NULL, this->GetAnarchyWindowName().c_str());
    	if ( IsWindow(hWindow) )
    	{
    		long style = GetWindowLong(hWindow, GWL_STYLE);
    		style &= ~WS_CAPTION;
    		style &= ~WS_MINIMIZEBOX;
    		style &= ~WS_SYSMENU;
    
    		if (SetWindowPos(hWindow, NULL, 1, 1, 1680, 1050, SWP_FRAMECHANGED ) == TRUE )
    		{
    			SetWindowLong(hWindow, GWL_STYLE, style);
    			UpdateWindow(hWindow);
    		}
    	}
    }
    

    rya.


  • Mod

    Wenn die andere Software das nicht beherscht, dann wirst Du gar nichts machen können.
    Evtl. hat der Entwickler einmal die Größe bei Start ermittelt und bekommt nun nichts mehr mit und rechnet uach nichts mehr um...



  • Ich grabe den Beitrag mal aus. Das Spiel wurde gepatcht (hab den Hersteller darauf hingewiesen) und der Code funktioniert nun soweit.
    Kleine Frage da ichs mit der WinAPI nicht so habe:
    Welche Flags wären das beste für einen "Fake-Fullscreen"? Also Fenstermodus ohne Border und über der Taskbar. Sollte allerdings nach hinten gehen wenn das Fenster den Fokus verliert. Muss ich da die Lost-Focus Message abfangen und mit AlwaysOnTop aktivieren/deaktivieren?
    Vielen Dank für eure Hilfe.
    rya.



  • Am Besten, ich poste erst einmal etwas Code:

    // ToggleWndStyle: Wechsel zwischen Vollbild und normalem Fenster
    // prcSWNormal wird nur für den Wechsel in den normalen Modus benötigt
    void ToggleWndStyle(HWND hwnd, const RECT* prcSWNormal)
    {
    	LONG_PTR Style = GetWindowLongPtr(hwnd,GWL_STYLE);// Stil abfragen
    	RECT rc;
    	if(Style & WS_POPUP) // war im Vollbildmodus -> zurück in den Fenstermodus
    	{
    		Style = (WS_OVERLAPPEDWINDOW|WS_THICKFRAME|WS_VISIBLE);
    		rc = *prcSWNormal; // das Fenster soll die Größe des übergebenen Rechtecks erhalten
    		// SetMenu(hwnd,0); wird bei deiner Anwendung keine Rolle spielen
    	}
    	else
    	{
    		Style = (WS_POPUP|WS_MAXIMIZE|WS_VISIBLE);
    		SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
    	}
    	SetWindowLongPtr(hwnd, GWL_STYLE, Style);
    	SetWindowPos(hwnd,HWND_TOP,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,SWP_FRAMECHANGED|SWP_DRAWFRAME);
    	if(prcSWNormal) // wenn zurück in den Fenstermodus, kann das Fenster zentriert werden (s.u.)
    		CenterChild(hwnd,GetDesktopWindow());
    }
    
    void CenterChild(HWND hwndChild, HWND hwndParent)
    {
    	RECT rcWndParent;
    	RECT rcClient;
    	GetClientRect(hwndParent,&rcWndParent);
    	GetClientRect(hwndChild,&rcClient);
    	SetWindowPos(hwndChild,
    		HWND_TOP,
    		rcWndParent.left+(rcWndParent.right-rcWndParent.left-rcClient.right)/2,
    		rcWndParent.top+(rcWndParent.bottom-rcWndParent.top-rcClient.bottom)/2,
    		0,0,
    		SWP_NOSIZE);
    }
    

    Mit der Funktion sollte der Wechsel möglich sein. CenterChild ist nur optional, das Fenster wird dann lediglich in der Mitte des Bildschirms positioniert.
    Ein Aufruf könnte so aussehen:

    RECT rc;
    SetRect(&rc,0,0,800,600);
    ToggleWndStyle(hWnd,&rc);
    


  • Danke Dir.
    Mit

    style |= (WS_POPUP|WS_MAXIMIZE);
    

    funktioniert das nun. Das waren die Flags die ich gesucht habe. Den Rest werde ich noch anpassen.
    Nun noch ein Problem:

    Es sind viele Spieler dual-logged mit multiplen Accounts. Wie verhält sich FindWindow bei mehreren Fenstern mit gleichem Namen? Gibts da ne Möglichkeit? Hab nach FindFirstWindow gesucht, aber da scheints nichts zu geben...
    rya.



  • Ich habe den Code oben nachträglich noch einmal editiert, da er doch noch ein paar Probleme gemacht hat.

    FindWindow liefert imho das erste gefundene Fenster mit dem angegebenen Namen, daher ist es eine schlechte Wahl.
    Du könntest eventuell mit ShellExecuteEx jeweils die Programme starten, der Vorteil ist, dass du das Handle auf den jeweiligen Prozess geliefert bekommst. Die IDs der Prozesse kannst du nun in einem Container deiner Wahl mit Hilfe von GetProcessId(Handle_auf_den_Prozess) speichern.
    Nun kann man sich per EnumWindows die Top-Level-Fenster zukommen lassen und per GetWindowThreadProcessId (lpdwProcessId -Parameter) die IDs vergleichen, wenn diese übereinstimmen, hat man das passende Fenster.



  • Ich hab den Code nicht einfach kopiert, nur das rausgepickt was ich brauche :). Also das Flag. Den Rest krieg ich schon hin. Ich kopiere Code nie 1:1.

    Aber EnumWindows is was ich gesucht habe. Vielen Dank. So kann ich alle Fenster listen und nach "Anarchy Online" im Titel suchen. Dann diese in meinem Programm listen und dann kann der User das jeweilige Fenster selber resizen. Oder ich mach das per Timer und iterativ.. naja mal schauen :). Eventuell biete ich auch als beides als Option an. Das selber starten.. naja. Ich kanns schon einbauen, da mein Programm im Tray läuft wäre das vllt gar nicht so übel, aber nicht nötig denke ich.

    Eine kleine Frage hab ich noch zur WinAPI sorry :D. Hab die nie direkt benutzt, immer nur wxWidgets :P.
    Kann man das HWND einfach so per == vergleichen?
    rya.



  • Normalerweise ja, wenn du aber auf der sicheren Seite sein willst oder prozessübergreifend arbeitest, dann nimm das eben erwähnte GetWindowThreadProcessId und vergleiche die beiden IDs der Prozesse. Diese sind auf jeden Fall eindeutig.



  • Okay, vielen Dank an Dich :).



  • ich würde trotzdem noch DirectX CreateDevice hooken um auch DirectX die Fenstergröße mitzuteilen (BackBufferWidth etc...).


Log in to reply