|
And, as usual, the problem was caused by not reading documentation. nafxcwd.lib is the debug, static link, non-Unicode version of the MFC library. There are many options you can pursue. You can try to do a static link release build which will require nafxcw.lib or you can try a dynamic link build, debug or release.
Incidentally, the project is compiling but it is not linking. Those are two different things.
|
|
|
|
|
Hello Anonymous. Can you be a little more specific about what documentation i should be reading? I tried what you said and it still wont link. Thanks for your help.
|
|
|
|
|
When drawing a animated gif, only the first frame is drawn. How to draw
animated gifs?.
The code works great for regular gifs!.
Thanks
Srinivas.
|
|
|
|
|
I am having the same problem here. Does anyone have any idea?
|
|
|
|
|
I use GDI plus finish it.
|
|
|
|
|
I use GDI plus finished it.
|
|
|
|
|
Can some one pleez show uz how to use thiz or any other thing, to draw gif's (or png's) and jpeg's!
And... pleez not.. "use bla with bla..." and example of the code would be nice!
i've looked everywhere.... so pleez?
thanx!
|
|
|
|
|
void CAboutDlg::OnPaint()
{
m_cPicture->Load("1.JPG");
CWnd* pWnd = GetDlgItem(IDC_STATICPAINT);
CDC* pDC = pWnd->GetDC();
CMemDC cDC(pDC);
pWnd->Invalidate();
pWnd->UpdateWindow();
m_cPicture->Draw(&cDC,CPoint(0,0),1);
CPaintDC dc(this); // device context for painting
}
The above example draws the picture "1.JPG" i the aboutbox! IDC_STATICPAINT
is just a normel statictext placed i the dialog just as you would any other static text.
Jesper )
PS Can you help me with a dialogbox with scrollbars so that the above example kan be scrolled? I´ve desigend the aboutbox with scrollbars i resource editor but can´t seem to connect it to the picture...
|
|
|
|
|
void CAboutDlg::OnPaint()
{
m_cPicture->Load("1.JPG");
CPaintDC dc(this); // device context for painting
//CWnd* pWnd = GetDlgItem(IDC_STATICDRAW);
//CDC* pDC = pWnd->GetDC();
CDC* pDC = GetDC();
CMemDC cDC(pDC);
m_cPicture->Draw(&cDC,CPoint(10,10),1);
}
I´ve modified my last reply so that you draw directly in the dialog
Jesper )
|
|
|
|
|
I found this on Microsoft website (see below), as an example how to save pictures. The SaveAsFile function sets the Length to the right amount. But the file seems to be corrupted (About twice the size as the original) Did anyone find a solution to this?
void CPicture::SaveThePicture()
{
IPicture* pPicture = 0;
HRESULT hr = m_pPicture->QueryInterface(IID_IPicture,(void **)&pPicture);
if(SUCCEEDED(hr))
{
IStorage* pStg = 0;
hr = ::StgCreateDocfile(L"E:\\pictures\\mypicture.jpg",
STGM_SHARE_EXCLUSIVE |
STGM_CREATE |
STGM_READWRITE,
0, &pStg);
if(SUCCEEDED(hr))
{
IStream* pStream = 0;
hr = pStg->CreateStream(L"PICTURE",
STGM_SHARE_EXCLUSIVE |
STGM_CREATE |
STGM_READWRITE,
0, 0, &pStream);
if(SUCCEEDED(hr))
{
LONG Length;
hr = pPicture->SaveAsFile(pStream,
FALSE,
&Length);
pStream->Release();
}
pStg->Release();
}
pPicture->Release();
}
}
|
|
|
|
|
This appears to fail because an IStorage file is like a file-system within a file - you actually need to copy the IStream file data to a "normal" file. Here is how I do it (it's long winded but it works fine):
// Create the IStorage needed
IStorage* pStorage = NULL;
// Convert the name
WCHAR wName[MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCTSTR)"TEST.TMP", -1, wName, MAX_PATH);
// Create the storage
if (::StgCreateDocfile(wName, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE,
0, &pStorage) != ERROR_SUCCESS)
{
return false;
}
// Use the COleStreamFile class
COleStreamFile file;
// Create
if (!file.CreateStream(pStorage, "PICTURE"))
{
pStorage->Release();
return false;
}
// Save
LONG lSize = 0;
// Save the data
HRESULT hResult = m_pPicture->SaveAsFile(file.GetStream(), FALSE, &lSize);
// Success?
if (!SUCCEEDED(hResult))
{
pStorage->Release();
return false;
}
// Create the final output file
CFile fileOut;
// Open
if (!fileOut.Open("PICTURE.JPG", CFile::modeCreate|CFile::modeWrite))
{
pStorage->Release();
return false;
}
// Allocate a read buffer
BYTE* pBuffer = new BYTE [PIC_BUFSIZE];
// Be defensive
if (pBuffer == NULL)
{
pStorage->Release();
return false;
}
// Write to a real file
file.SeekToBegin();
// Loop
while (true)
{
// Read...
UINT nBytesRead = file.Read(pBuffer, PIC_BUFSIZE);
// Write...
fileOut.Write(pBuffer, nBytesRead);
// Are we done?
if (nBytesRead < PIC_BUFSIZE)
break;
}
// Release
pStorage->Release();
// Done
return true;
|
|
|
|
|
Great piece of work, does its job fine in a CFormView!
But I could not manage to get it working in a CDialog (there is no WM_DRAW Message in Dialogs)
and I got a bit confused with DCs ...
Has anyone a hint?
Guenter
|
|
|
|
|
It's a wonderful and useful class. But I encountered a problem when using the class.
The class seems to support MM_TEXT mapping mode only. When I change the dc mapping mode to MM_LOGICAL, the picture can not be drawed on the dc properly. I tried to pass parameters [CPoint(100, -100), CSize(100, -100)] to method Draw(...) instead of [CPoint(100, 100), CSize(100, 100)], but it didn't work, too.
I hope someone could help me. Thanks.
|
|
|
|
|
Yes, I am noticing the same thing. My application uses MM_LOMETRIC and CPicture does not work with this map mode either. You are correct, CPicture ONLY works with MM_TEXT. Additionally, after much massaging, when the image is finally displayed, it is upside down.
Does anyone have any suggestions, or do we need to look at another application? Your help is much appreciated. MK
|
|
|
|
|
I have solved the problem by a compromise way. I change the mapping mode to MM_TEXT when drawing pictures. I rewrote the CPicture::Draw(..) method. With this new method, I can now draw pictures in all type of mapping mode. The new code is as followed. I hope it may be useful to someone.
// rect -- the area on which to draw the picture, the data in rect are just the original
// data in your mapping mode. For example, if you are using MM_LOMETRIC mapping mode, the rect
// may be something like this : top=-100, bottom=-300, left=100, right=200.
BOOL CPicture::Draw(CDC *pDC, CRect rect)
{
BOOL bResult = FALSE;
if (m_pPicture != NULL)
{
CRect rectI = rect;
CPoint startPoint(rect.TopLeft());
CPoint endPoint(rect.BottomRight());
// calculate dp
pDC->LPtoDP(rectI);
// set mapping mode to MM_TEXT
int nOldMode = pDC->SetMapMode(MM_TEXT);
// calculate lp in MM_TEXT mapping mode
pDC->DPtoLP(rectI);
long hmWidth;
long hmHeight;
m_pPicture->get_Width(&hmWidth);
m_pPicture->get_Height(&hmHeight);
int nWidth = rectI.Width();
int nHeight = rectI.Height();
bResult = Draw(pDC, rectI.left, rectI.top, nWidth, nHeight);
// reset mapping mode
pDC->SetMapMode(nOldMode);
}
return bResult;
}
|
|
|
|
|
|
Very good code, but i have a problem with some of bitmaps (jpg, bmp) which are not well rendered with this method, like low quality jpeg images.
Can anyone help me ?
thks
|
|
|
|
|
Ok pb solved. My high-quality jpeg which was rendered like low-quality images. This pb seems to be linked to color depth of windows (16 bits) and the rendering is normal with a color depth of 24 or 32 bits.
|
|
|
|
|
Perhaps that is a little stupid, but please help me!
I see how to load a picture from file, but how can I create a new CPicture with a new drawing (not from a file) or modify an existing one? Is there any way to insert a windows bitmap (CBitmap or DIBSection) into a CPicture object?
Thanks in advance.
Jessie.
|
|
|
|
|
I appreciate your class but saving image is also important. I search for a class that do reading, drawing and saving in different format for a complete package.
Jean-Yves Garneau
|
|
|
|
|
IPicture has method "SaveAsFile" it saves the picture's data into a stream in the same format that it would save itself into a file.
|
|
|
|
|
It will be more easyer:
int PImage::Load(LPCTSTR szFileName) {
...
HRESULT hr = ::OleLoadPicturePath(const_cast<lpolestr>(T2COLE(m_FileName)),
NULL, 0, 0, IID_IPicture, reinterpret_cast<lpvoid *="">(&m_pPicture));
...
}
|
|
|
|
|
Needed a quick and dirty way of loading and display any type of picture, well this is just cool.
5/5
Norm
|
|
|
|
|
Hi Peter,
Excellent class. I was looking for something just like that! It made my life a lot easier.
I added some code to one of the Draw()-functions, so the clients of this class don't need to calculate the ratio if the picture is bigger than the size of the device context. Hope you like it.
In the header file, add a default parameter to the draw function:
bool Draw(CDC* pDC, BOOL bUseDCExtends = FALSE );
In the cpp file, add the following code (and also the default parameter):
bool CPicture::Draw(CDC* pDC, BOOL bUseDCExtends )
{
if (m_pPicture != NULL)
{
long hmWidth;
long hmHeight;
m_pPicture->get_Width(&hmWidth);
m_pPicture->get_Height(&hmHeight);
int nWidth = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH);
if( bUseDCExtends != FALSE )
{
CRect rect;
double dMinRatio;
double dWidthRatio;
double dHeightRatio;
pDC->GetWindow()->GetWindowRect( &rect );
dWidthRatio = (double)rect.Width() / nWidth;
dHeightRatio = (double)rect.Height() / nHeight;
dMinRatio = ( dWidthRatio < dHeightRatio )? dWidthRatio: dHeightRatio;
if( dMinRatio < 1 )
{
return Draw( pDC, dMinRatio );
}
}
return Draw(pDC, 0, 0, nWidth, nHeight);
}
return false;
}
Of course you can also add the same code in the function Draw( CDC *pDC, CPoint Pos),
but then you should adjust the calculation of dWidthRatio and dHeightRatio, by extracting the CPoint-values from the width and height of the WindowRect.
Have Fun!
|
|
|
|
|
I have been unable to use this class with TIF files.
It seems to work for JPEG,GIF,BMP,ICO,WMF.
Any other formats with which it should work ? I tried PNG as
well and that doesn't seem to work either.
Thanks,
Bruno
|
|
|
|
|