Bild auf Größe von CStatic skalieren



  • Hallo,
    hab das mit dem Überschreiben mal ausprobiert:
    so wie ich das sehe muss ich

    BOOL CTestKlasse::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    

    überschreiben und die WM_DRAW Nachricht selber bearbeiten:

    BOOL CTestKlasse::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
    	// TODO: Fügen Sie hier Ihren spezialisierten Code ein, und/oder rufen Sie die Basisklasse auf.
    	if(message == WM_PAINT)
    	{
    		PAINTSTRUCT ps;
    		//Begin drawing
    		CDC* hDC = BeginPaint(&ps);
    
    		CDC dcMemory;
    		dcMemory.CreateCompatibleDC(hDC);
    		HBITMAP OldBit = (HBITMAP) dcMemory.SelectObject((HGDIOBJ) m_hBild);
    		CRect rect;
    		GetClientRect(&rect);
    
    		hDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcMemory,0,0,2048,1536,SRCCOPY   );
    
    		dcMemory.SelectObject(OldBit);
    		ReleaseDC(&dcMemory);
    
    		EndPaint(&ps);
    		return 0;
    
    	}
    	else
    	{
    			return CStatic::OnWndMsg(message, wParam, lParam, pResult);
    	}
    
    }
    

    Das klappt jetzt auch, allerdings ist das Problem, dass die Farben in dem Bild sehr komisch aussehen:
    http://www.mehringskoetter.de/files/Problem.JPG

    Der Weg über CImage hat auch diese komischen Farben erzeugt. Ich denke das liegt daran, dass das Bild sehr groß ist (2048*1536). Ich hab das Bild mit einem Bearbeitungsprogramm mal kleiner gemacht und dann waren die Farben auch in Ordnung. Leider soll das Programm aber später auch ohne eine manuelle Bearbeitung so große Bilder anzeigen können, was kann man da machen, dass das die Farben wieder "normal" wiedergegeben werden?

    Viele Grüße

    Andreas



  • Oh das sieht ja schrecklich aus, das is winapi was du da gebastelt hast. Hab da mal schnell ne Klasse gebaut

    PictureStatic.cpp

    // PictureStatic.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "PictureStatic.h"
    
    // CPictureStatic
    
    IMPLEMENT_DYNAMIC(CPictureStatic, CStatic)
    
    CPictureStatic::CPictureStatic()
    {
    
    }
    
    CPictureStatic::~CPictureStatic()
    {
    }
    
    BEGIN_MESSAGE_MAP(CPictureStatic, CStatic)
    	ON_WM_PAINT()
    END_MESSAGE_MAP()
    
    // CPictureStatic message handlers
    
    void CPictureStatic::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    	// TODO: Add your message handler code here
    	// Do not call CStatic::OnPaint() for painting messages
    
    	CRect rect;
    	GetClientRect(&rect);
    	dc.SetStretchBltMode(COLORONCOLOR);
    	Image.Draw(dc,rect);
    }
    
    HRESULT CPictureStatic::SetBitmap(LPCTSTR Path)
    {
    	return Image.Load(Path);
    }
    

    PictureStatic.h

    #pragma once
    
    #include <atlimage.h>
    // CPictureStatic
    
    class CPictureStatic : public CStatic
    {
    	DECLARE_DYNAMIC(CPictureStatic)
    
    public:
    	CPictureStatic();
    	virtual ~CPictureStatic();
    	HRESULT SetBitmap(LPCTSTR Path);
    
    protected:
    	CImage Image;
    
    	DECLARE_MESSAGE_MAP()
    public:
    	afx_msg void OnPaint();
    };
    

    jeweils in dein Projekt aufnehmen und dann im Resourceneditor deinem Static ne neue IDC geben und eine Membervariable zuordnen. Die Membervariable änderste von CStatc in CPictureStatic und dann sollte es gehen wie du das willst

    Hoffe ich hab das einergemaßen verständlich rüber gebracht.



  • Hi,

    erstmal vielen, vielen Dank für den Aufwand, hab den Code kopiert und es funktioniert jetzt endlich,

    vielen Dank!!!!

    Viele Grüße

    Andreas



  • aber da hast du jetzt wenigstens gesehen was ich mit überladen gemeint habe 😉 und so viel aufwand war das nicht



  • Hallo kannst du mir sagen was ich daran falsch mache?
    Ich habe dein Klasse eingebunden und mir ein Staticfeld angelegt,
    das ich umbenannt habe. Es hat ebenfalls die Membervariable auf PictureStatic
    bekommen.

    Nun rufe ich doch praktisch SetBitmap über die Membervariable die ich
    angelegt habe auf oder?

    In der Debugversion erhalte ich beim kompilieren keinen Fehler, aber die
    Anwendung stürzt sofort nachdem der Dialog da ist mit "h_bitmap!=0" ab.
    Im Releasemode geht es, aber ich bekomme das Bild von "c:\\bild.bmp" nicht
    angezeigt. 😕



  • Rufst du auch SetBitmap in der InitDialog, oder zumindest beimn erstellen des Dialoges auf, oder Andere das so:

    void CPictureStatic::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    	// TODO: Add your message handler code here
    	// Do not call CStatic::OnPaint() for painting messages
    	if(Image.IsNull() == FALSE)
    	{
    		CRect rect;
    		GetClientRect(&rect);
    		dc.SetStretchBltMode(COLORONCOLOR);
    		Image.Draw(dc,rect);
    	}
    }
    

    ich hab das eigentlich nur schnell zusammen geschrieben 🙄



  • Oh, ich hatte es in einem Button untergebracht und dachte, dass
    die überschriebenen Methoden dann direkt vorrangig gerufen werden?
    Mir war nicht klar, dass es in OnInit gehört und nicht für einen Button gedacht war 😮



  • na änder die OnPaint() wie ich oben beschrieben habe, dann kasste das auch in nen Button verlegen, mit den sachen die du willst CFileDialog oder so



  • Bei der Initialisierung in OnInit wird mein Aufruf ala

    m_var.SetBitmap("c:\\test1.bmp");

    auch genommen und das Bild wunderbar angezeigt. Bei einem erneuten Aufruf
    in meinem Button m_var.SetBitmap("testbild2.bmp"); passiert jedoch nicht
    mehr. Will sagen, das neue Bild wird nicht angezeigt.

    Sorry für meine Laienhaftigkeit bei soetwas 🙄
    Es ist aber sehr interessant. Ich dachte halt, dass die OnPaint deiner
    Klasse automatisch vorrangig gerufen wird, da die Membervariable vom
    Typ deiner Klasse ist. Sowas habe ich bisher noch nie gemacht oder gesehen...



  • Man muss wohl InvalidateRect aufrufen, damit das neue Bild angezeigt wird.
    Vlt. kannst du das ja oben in deinem Code editieren, falls ich damit richtig
    liege? Ich finde deine Klasse eine sehr gute Hilfe!



  • Onkel hat eire Wünsche erhört und hier der nächste teil:

    HRESULT CPictureStatic::SetBitmap(LPCTSTR Path)
    {
    	HRESULT ret;
    	if(Image.IsNull() == FALSE)
    		Image.Destroy();
    	if((ret = Image.Load(Path)) == S_OK)
    		Invalidate();
    	return ret;
    }
    

    einfach tauschen und spass haben


Anmelden zum Antworten