Abmessungen eines ActiveX-Controls verändern (ATL)



  • Hallo,

    schon wieder so viel Text von mir... Ich hoffe, jemand nimmt sich die Zeit das hier durch zu lesen. Naja, wenigstens versuche ich eine umfangreiche Beschreibung des Problems zu liefern... 😉

    Ich versuche, die Größe eines ActiveX-Controls zu ändern (eigentlich reicht die richtigte Einstellung der Abmessung zum Initialisierungszeitpunkt aus, idealerweise möchte ich die sie trotzdem jederzeit ändern können).

    Das hier hab ich bisher erreicht:

    Bei Programmstart hat es eine Default-Größe von 192x192 (woher auch immer gerade diese Werte stammen...).

    Ich bin über die einigermaßen vielversprechende Methode ATL::CWindow::ResizeClient( int nWidth, int nHeight, BOOL bRedraw = 1 ) gestolpert, das prinzipiell seine Arbeit zu machen scheint, da sich das eingebettete OpenGL Renderdevice mit der neuen Größe korrekt neu zeichnet. Allerdings bleibt der sichtbare Ausschnitt im ActiveX Control Test Container gleich, sprich bei einer Vergrößerung sehe ich nur einen 192x192-Ausschnitt der Szene. Nach dem Aufruf von ResizeClient liefert GetClientRect korrekte Werte. Verändere ich allerdings die Größe des Test Containers, so wird das OnSize meines Controls ausgelöst, in dem GetClientRect wieder die ursprünglichen Abmessungen 192x192 liefert. 😕 In meinem Fall bedeutet das, dass das OGL-Device wieder in seiner ursprünglichen Größe gezeichnet wird.

    Im IE hingegen ist das Verhalten interessanterweise etwas anders, aber leider auch nicht korrekt: Hier wird auch der sichtbare Ausschnitt scheinbar korrekt mitskaliert, allerdings nur beim ersten Mal. Ändere ich die Abmessungen des IE-Fensters wird die Größe des Controls wie im Test Container zurückgesetzt. Ab diesem Zeitpunkt ist das verhalten gleich dem im Test Container: Der sichtbare Ausschnitt bleibt gleich, die Änderung der Größe kommt anscheinend an, da das OGL-Device korrekt vergrößert wird (allerdings ist wie gesagt nur ein Ausschnitt sichtbar).

    Kann mir bitte jemand dieses merkwürdige Verhalten erklären? (Nachdem ich jetzt endlich mal die Richtlinien gelesen habe, füge ich 'ne kurze Info zu meinen Kenntnissen an: Erfahrener Programmierer, habe aber kaum COM-, AX-, ATL-, MFC- oder GDI-Kenntnisse).

    Danke!


  • Mod

    IMHO bist Du auf dem falschen Dampfer. Wenn es sich um ein ActiveX Contreol handelt, dann musst Du auf SetExtent reagieren!

    Es kann sein dass ein ActiveX Control ein Fenster ist, muss aber nicht...



  • Auf SetExtend *reagieren*? Du meinst SetExtend *verwenden*? Oder hab i was falsch verstanden?

    Also wenn ich SetExtend aufrufe, dann passiert erstmal garnichts... 😕

    SIZEL size = { 500, 500 };
    
    	m_bResizeNatural = TRUE;
    	SetExtent( DVASPECT_CONTENT, &size );
    
    	HDC hdc = GetDC();
    
    	RECT rc;
    	rc.right = 500;
    	rc.bottom = 500;
    	CreateContext( hdc, rc ); // Anm: hier wird mein OGL-Device kurzerhand neu erstellt
    
    	ReleaseDC( hdc );
    
    	GetClientRect( &rc );
    
    	WCHAR tempstr[128]; 
    	wsprintf( tempstr, L"size of client is now: %d x %d", rc.right - rc.left, rc.bottom - rc.top );
    	OutputDebugString( tempstr );
    

    size of client is now: 192 x 192

    auch das OpenGL-Device, das ich probeweise mit dem aktuellen HDC einfach mal neu erstelle, lässt vermuten, dass sich nichts geändert hat, da es wieder die selbe Größe hat.

    Hab jetzt auch mit SetViewportExtEx herumgespielt, ohne Ergebnis.



  • iko79 schrieb:

    Kann mir bitte jemand dieses merkwürdige Verhalten erklären?

    Nagut, muss ja nicht sein. Inzwischen wäre ich schon glücklich über eine simple Antwort auf die Frage: Wie kann ich die Größe meines AX- (oder ODE-, whatever) Objekts verändern?


  • Mod

    Ich dachte Du schreibst selbst ein Active-X Control!

    Wo "lebt" denn dieses Active-X Control?
    Für die Größe gibt es entsprechende Properties. Im Dialog-Editor kannst Du die Größe entsprechend bestimmen...



  • Dialog-Editor? Ich glaube, wir reden aneinander vorbei. Ich schreibe ja mein ActiveX Control selbst. Weiß nicht, wodurch ich jetzt impliziert habe, das nicht zu tun..? Mein AX-Ding lebt wie gesagt in IE bzw. vorübergehend im Test Container.

    Inzwischen hab ich rausgefunden, dass das hier (überschreiben der Methoden GetExtent und SetExtent) funktioniert, ich also den umgekehrten Weg gehen muss (was nicht selbstverständlich ist, finde ich):

    STDMETHODIMP CRTSClientObj::GetExtent( DWORD dwDrawAspect, SIZEL *psizel )
    {
    	if( dwDrawAspect & DVASPECT_CONTENT )
    		AtlPixelToHiMetric( &m_size, psizel );
    	else
    	{
    		std::cerr << "CRTSClientObj::GetExtent -> aspect " << dwDrawAspect << " not implemented!" << std::endl;
    		return DV_E_DVASPECT;
    	}
    
    	return S_OK;
    }
    
    STDMETHODIMP CRTSClientObj::SetExtent( DWORD dwDrawAspect, SIZEL *Psizel )
    {
    	return E_FAIL;
    }
    

    Das funktioniert mal zum Initialisierungszeitpunkt. Was mir jetzt noch fehlt, ist, dem übergeordneten Container irgendwie mitteilen zu können, dass sich *meine* Größe geändert hat, damit er mich anhand dieser Methoden entsprechend neu zeichnet.


Anmelden zum Antworten