Zeichnung eine jpg in MFC
Ich habe versucht zu zeigen, wird das jpg-Bild im MFC, aber ich kann Sie nicht gezogen. Ich bin ein totaler MFC-Neuling eine alles ich habe bis jetzt meist angepasst von Dingen, die ich im Netz gefunden. Derzeit habe ich dieses:
Bild.h:
#pragma once
#include <afxwin.h>
class Picture
{
public:
Picture();
bool load(LPCTSTR filePath);
bool draw( CDC* deviceContext
, CRect clientRect
, LPCRECT prcMFBounds);
CSize getSize(CDC* pDC);
private:
LPPICTURE m_picture;
};
Picture.cpp:
#include "Picture.h"
Picture::Picture()
: m_picture(0)
{
}
bool Picture::load(LPCTSTR szFile)
{
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return false;
DWORD dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize == (DWORD)-1)
{
CloseHandle(hFile);
return false;
}
LPVOID pvData = NULL;
//alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
if (hGlobal == NULL)
{
CloseHandle(hFile);
return false;
}
pvData = GlobalLock(hGlobal);
if (pvData == NULL)
{
GlobalUnlock(hGlobal);
CloseHandle(hFile);
return false;
}
DWORD dwBytesRead = 0;
//read file and store in global memory
bool bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL) != 0;
GlobalUnlock(hGlobal);
CloseHandle(hFile);
if (!bRead)
return false;
LPSTREAM pstm = NULL;
//create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
if (!(SUCCEEDED(hr)))
{
if (pstm != NULL)
pstm->Release();
return false;
}
else if (pstm == NULL)
return false;
//Create IPicture from image file
if (m_picture)
m_picture->Release();
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&(m_picture));
if (!(SUCCEEDED(hr)))
{
pstm->Release();
return false;
}
else if (m_picture == NULL)
{
pstm->Release();
return false;
}
pstm->Release();
return true;
}
bool Picture::draw(CDC* deviceContext, CRect clientRect, LPCRECT prcMFBounds)
{
if (clientRect.IsRectNull())
{
CSize imageSize = getSize(deviceContext);
clientRect.right = imageSize.cx;
clientRect.bottom = imageSize.cy;
}
long pictureWidth = 0;
long pictureHeigth = 0;
m_picture->get_Width(&pictureWidth);
m_picture->get_Height(&pictureHeigth);
m_picture->Render( *deviceContext
, clientRect.left
, clientRect.top
, clientRect.Width()
, clientRect.Height()
, 0
, pictureHeigth
, pictureWidth
, -pictureHeigth
, prcMFBounds);
return true;
}
CSize Picture::getSize(CDC* deviceContext)
{
if (!m_picture)
return CSize(0,0);
LONG width, height; //HIMETRIC units
m_picture->get_Width(&width);
m_picture->get_Height(&height);
CSize size(width, height);
if (deviceContext==NULL)
{
CWindowDC dc(NULL);
dc.HIMETRICtoDP(&size); //convert to pixels
}
else
{
deviceContext->HIMETRICtoDP(&size);
}
return size;
}
PictureView.h:
#pragma once
#include <afxwin.h>
#include <string>
class Picture;
class PictureView : public CStatic
{
public:
PictureView(std::string path);
protected:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
private:
Picture* m_picture;
};
PictureView.cpp:
#include "PictureView.h"
#include "Picture.h"
PictureView::PictureView(std::string path)
{
m_picture = new Picture();
m_picture->load(path.c_str());
}
void PictureView::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{
CRect rect;
GetClientRect(&rect);
m_picture->draw(GetDC(), rect, rect);
}
Konstruktor-Aufruf:
CWnd* GenericChildWidget::addImage(std::string path, int horizontalPos, int width, int verticalPos, int height, int childId)
{
PictureView* image = new PictureView(path);
image->Create("", SS_OWNERDRAW, CRect(horizontalPos, verticalPos, width + horizontalPos, height + verticalPos), this, childId);
return image;
}
Das problem ist, dass ich kann nicht die DrawItem-Funktion aufgerufen werden. Was mache ich falsch?
Jede Hilfe wird geschätzt.
- Brauchen Sie eine Schaltfläche oder einen Menüpunkt um das Bild zu speichern, und rufen, PictureView::DrawItem?
- Die Idee ist diese: ein anderer Prozess hat eine Kamera und macht Bilder von Dingen. Es speichert diese Bilder als jpg. Wenn ein bestimmter Zustand Eintritt, teilt Sie meinem Prozess und stellt den Pfad zu dem Bild entspricht, dass diese Bedingung. Ich brauche einen dialog anzeigen, um die Benutzer, die das Bild enthält, muss der Benutzer nun entscheiden, wie vorgegangen werden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist eine einfache Möglichkeit zum zeichnen eines Bildes in einer MFC-Dialogfeld:
link mit
gdiplus.dll
Hoffe, es funktioniert!
mit der Hilfe von einem Kollegen von mir, ich habe die Antwort gefunden. Er sagte mir, es ist nicht möglich ein ownerdrawn CStatic. Also, wenn ich jetzt Erben PictureView von CButton und machen es BS_OWNERDRAW mein Bild gerendert wird.
Ich persönlich denke, das ist eine hässliche Lösung, aber ich bin so müde von diesem problem jetzt, dass ich nicht wirklich darauf, dass viel. Dies sind die änderungen, die ich gemacht habe, damit es funktioniert:
Konstruktor-Aufruf:
PictureView.h:
Danke an alle für all die Hilfe.
Ich bin mir nicht sicher, dass die GetDC im Aufruf m_picture->ziehen, wird unbedingt beziehen sich auf den gleichen DC, die in der CREATESTRUCT. Was ich getan habe, ist:
EDIT: Da kann ich nicht kommentieren, hoffentlich ein edit genügt. Ich denke, dein Kollege verwechselt, wie ich gerade vor kurzem eine CStatic control mit SS_OWNERDRAW. Ich vermute, dass die Zugabe von WS_CHILD | WS_VISIBLE auf den Create-Aufruf ist der Schlüssel.
Habe ich noch nie MFC verwendet aber eine schnelle Durchsicht der CStatic::DrawItem-Dokumentation sagt, dass es angelegt werden muss, mit der
SS_OWNERDRAW
Stil fürDrawItem
genannt, bekommen. Sie haben nicht gezeigt, dieCreate
Linie für IhrePictureView
so, vielleicht ist es das?