Hi, I am dabbling in PPC coding, and want to know how the hell one displays alpha transparency PNGs in Win32 Native code (ie not managed, no MFC, no .NET etc)
Is this possible using the PPC 2003 SDK? Or should I move from eVC to VS 2005 and use the WM5 SDK?
Help please !!
You can use the Imaging API. It is available with PPC 2003 SDK.
Here is some sample code on how to load a png file and display it:
// init it
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IImagingFactory,
(void **) & m_pImgFactory)))
{
}
else
{
err(( TEXT("CoCreateInstance failed!") ));
return false;
}
// load it
if( SUCCEEDED(m_pImgFactory->CreateImageFromFile( lpstrPngImageFileName, &m_pImage )) )
{
ImageInfo info = {0};
m_pImage->GetImageInfo( &info );
m_nWidth = info.Width;
m_nHeight = info.Height;
log(( TEXT("Image loaded <%d> <%d>"), m_nWidth, m_nHeight ));
}
else
{
err(( TEXT("CreateImageFromFile failed!") ));
return false;
}
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( m_hDC, &rc, NULL );
// release
if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
Thanks for the post.
What framework is that?
If I drop the sample code into a test project and try to build I get:
Code:
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : error C2065: 'IImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : error C2065: 'm_pImgFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : warning C4552: '*' : operator has no effect; expected operator with side-effect
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(211) : error C2065: 'CLSID_ImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(211) : error C2065: 'IID_IImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2227: left of '->CreateImageFromFile' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2065: 'lpstrPngImageFileName' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2065: 'm_pImage' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2065: 'ImageInfo' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2146: syntax error : missing ';' before identifier 'info'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2065: 'info' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2059: syntax error : '{'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2143: syntax error : missing ';' before '{'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2143: syntax error : missing ';' before '}'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(225) : error C2227: left of '->GetImageInfo' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2065: 'm_nWidth' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2228: left of '.Width' must have class/struct/union type
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2065: 'm_nHeight' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2228: left of '.Height' must have class/struct/union type
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(232) : error C2065: 'err' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(237) : error C2065: 'm_nPosX' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(238) : error C2065: 'm_nPosY' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(241) : error C2227: left of '->Draw' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(241) : error C2065: 'm_hDC' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(243) : error C2227: left of '->Release' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(244) : error C2227: left of '->Release' must point to class/struct/union
Error executing cl.exe.
Adding #include <imaging.h> to the top brings this error list down to:
Code:
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(212) : error C2065: 'm_pImgFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2227: left of '->CreateImageFromFile' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2065: 'lpstrPngImageFileName' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2065: 'm_pImage' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2227: left of '->GetImageInfo' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2065: 'm_nWidth' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(228) : error C2065: 'm_nHeight' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(233) : error C2065: 'err' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(238) : error C2065: 'm_nPosX' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(239) : error C2065: 'm_nPosY' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(242) : error C2227: left of '->Draw' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(242) : error C2065: 'm_hDC' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(244) : error C2227: left of '->Release' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(245) : error C2227: left of '->Release' must point to class/struct/union
Error executing cl.exe.
bump, still no joy here.
I managed to get code using AlphaBlend to compile, but I can't seem to get it to work, I just get nothing.
Does anyone have an example of usage of AlphaBlend in native code? Does it do per-pixel alpha? I just want to be able to overlay PNG icons that have semitransparent pixels on a background...
What exactly happens when you run your code?
I've successfully used AlphaBlend in managed code with P/Invoke so it should certainly work in unmanaged code. What parameters are you passing? The CE version of AlphaBlend doesn't support all of the flags that the desktop version supports. Could you paste the line of code where you call AlphaBlend?
To achieve alpha blending, first I create a DC (device context), then create a DIB section and select it into the DC... this is the only way I know to directly edit a bitmap in memory:
Code:
BITMAPINFO bi;
DWORD *pimg;
HBITMAP bitmap;
HDC hdcout = CreateCompatibleDC(NULL);
ZeroMemory(&bi.bmiColors, 4);
bi.bmiHeader.biClrImportant=bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biXPelsPerMeter = bi.bmiHeader.biYPelsPerMeter = 3780;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biHeight = YourVerticalSize;
bi.bmiHeader.biWidth = YourHorizontalSize;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmap = CreateDIBSection(hdcout, &bi, DIB_RGB_COLORS, (void**)&pimg, NULL, NULL);
SelectObject(hdcout, bitmap);
Then I have the pointer to the raw pixels in pimg, and I copy the pixels there in a 0xAABBGGRR ordering (or the inverse, I don't remember very well).
Then I use that DC with AlphaBlend, specifying the last parameter as follows:
Code:
BLENDFUNCTION alphaNormal = {AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA};
thjis always worked for me, and doesn't require all that COM boilerplate floating around
Dont know if this helps, but RLtoday can show transparent pngs in your today screen.
:/
Add this:
#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
IImagingFactory* m_pImgFactory;
IImage* m_pImage;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
err() is my logging function. You can delete this line.
Hope that helps.
Houser
evilc said:
Thanks for the post.
What framework is that?
If I drop the sample code into a test project and try to build I get:
Code:
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : error C2065: 'IImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : error C2065: 'm_pImgFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(207) : warning C4552: '*' : operator has no effect; expected operator with side-effect
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(211) : error C2065: 'CLSID_ImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(211) : error C2065: 'IID_IImagingFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2227: left of '->CreateImageFromFile' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2065: 'lpstrPngImageFileName' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(222) : error C2065: 'm_pImage' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2065: 'ImageInfo' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2146: syntax error : missing ';' before identifier 'info'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2065: 'info' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2059: syntax error : '{'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2143: syntax error : missing ';' before '{'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(224) : error C2143: syntax error : missing ';' before '}'
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(225) : error C2227: left of '->GetImageInfo' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2065: 'm_nWidth' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2228: left of '.Width' must have class/struct/union type
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2065: 'm_nHeight' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2228: left of '.Height' must have class/struct/union type
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(232) : error C2065: 'err' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(237) : error C2065: 'm_nPosX' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(238) : error C2065: 'm_nPosY' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(241) : error C2227: left of '->Draw' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(241) : error C2065: 'm_hDC' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(243) : error C2227: left of '->Release' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(244) : error C2227: left of '->Release' must point to class/struct/union
Error executing cl.exe.
Adding #include <imaging.h> to the top brings this error list down to:
Code:
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(212) : error C2065: 'm_pImgFactory' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2227: left of '->CreateImageFromFile' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2065: 'lpstrPngImageFileName' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(223) : error C2065: 'm_pImage' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(226) : error C2227: left of '->GetImageInfo' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(227) : error C2065: 'm_nWidth' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(228) : error C2065: 'm_nHeight' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(233) : error C2065: 'err' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(238) : error C2065: 'm_nPosX' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(239) : error C2065: 'm_nPosY' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(242) : error C2227: left of '->Draw' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(242) : error C2065: 'm_hDC' : undeclared identifier
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(244) : error C2227: left of '->Release' must point to class/struct/union
C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\test1\test1.cpp(245) : error C2227: left of '->Release' must point to class/struct/union
Error executing cl.exe.
Click to expand...
Click to collapse
twolf said:
Dont know if this helps, but RLtoday can show transparent pngs in your today screen.
:/
Click to expand...
Click to collapse
Yeah, I used rlToday to model what I want (see "SaFF" theme in my sig) but I am trying to write the same thing in C++ as an exercise for learning WM programming....
Houser said:
Add this:
#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
IImagingFactory* m_pImgFactory;
IImage* m_pImage;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
err() is my logging function. You can delete this line.
Hope that helps.
Houser
Click to expand...
Click to collapse
Thanks for that, it now seems to compile fine...
However, I just get a blank white screen when I run it.
Here is my code:
Code:
case WM_PAINT:
IImagingFactory* m_pImgFactory;
IImage* m_pImage;
HDC m_hDC;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
m_nPosX = 0;
m_nPosY = 0;
hdc = BeginPaint(hWnd, &ps);
m_hDC = CreateCompatibleDC (hdc);
// init it
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) & m_pImgFactory)))
{
}
else
{
//err(( TEXT("CoCreateInstance failed!") ));
return false;
}
// load it
if( SUCCEEDED(m_pImgFactory->CreateImageFromFile( TEXT("\\Storage Card\\shared\\test.png"), &m_pImage )) )
{
ImageInfo info = {0};
m_pImage->GetImageInfo( &info );
m_nWidth = info.Width;
m_nHeight = info.Height;
log(( TEXT("Image loaded <%d> <%d>"), m_nWidth, m_nHeight ));
}
else
{
//err(( TEXT("CreateImageFromFile failed!") ));
return false;
}
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( m_hDC, &rc, NULL );
// release
if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
break;
Attached is the PNG I am using.
I only get one warning when I compile:
Code:
1>LIBCMTD.lib(gshandler.obj) : warning LNK4099: PDB 'libbmtd.pdb' was not found with 'C:\Program Files\Microsoft Visual Studio 8\VC\ce\lib\ARMV4I\LIBCMTD.lib' or at 's:\Prj\test1\test1\Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\Debug\libbmtd.pdb'; linking object as if no debug info
I set breakpoints and it is definately loading the image OK and getting as far as the drawing code, it's just that I see nothing but a blank white background...
You can delete this line: m_hDC = CreateCompatibleDC (hdc);
Change m_pImage->Draw( m_hDC, &rc, NULL ); to m_pImage->Draw( hdc, &rc, NULL );
You must call EndPaint() after m_pImage->Draw( hdc, &rc, NULL );
Houser
Thank You Houser, it all works now!!
Final code:
Code:
case WM_PAINT:
IImagingFactory* m_pImgFactory;
IImage* m_pImage;
HDC m_hDC;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
m_nPosX = 0;
m_nPosY = 0;
hdc = BeginPaint(hWnd, &ps);
// init it
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) & m_pImgFactory)))
{
}
else
{
//err(( TEXT("CoCreateInstance failed!") ));
return false;
}
// load it
if( SUCCEEDED(m_pImgFactory->CreateImageFromFile( TEXT("\\Storage Card\\shared\\test.png"), &m_pImage )) )
{
ImageInfo info = {0};
m_pImage->GetImageInfo( &info );
m_nWidth = info.Width;
m_nHeight = info.Height;
log(( TEXT("Image loaded <%d> <%d>"), m_nWidth, m_nHeight ));
}
else
{
//err(( TEXT("CreateImageFromFile failed!") ));
return false;
}
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( hdc, &rc, NULL );
EndPaint(hWnd, &ps);
// release
if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
break;
In your WM_PAINT block it would be the best to only
call m_pImage->Draw( m_hDC, &rc, NULL );
The image API initialization and image loading should only be done once
for performance reasons, because your WM_PAINT block is called every time
your window is repainted.
Call if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
when your app is closed.
Houser
Houser said:
In your WM_PAINT block it would be the best to only
call m_pImage->Draw( m_hDC, &rc, NULL );
Click to expand...
Click to collapse
You mean like this?
Code:
case WM_PAINT:
HDC m_hDC;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
m_nPosX = 0;
m_nPosY = 0;
m_hDC = BeginPaint(hWnd, &ps);
// init it
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) & m_pImgFactory)))
{
}
else
{
//err(( TEXT("CoCreateInstance failed!") ));
return false;
}
// load it
if( SUCCEEDED(m_pImgFactory->CreateImageFromFile( TEXT("\\Storage Card\\shared\\test.png"), &m_pImage )) )
{
ImageInfo info = {0};
m_pImage->GetImageInfo( &info );
m_nWidth = info.Width;
m_nHeight = info.Height;
log(( TEXT("Image loaded <%d> <%d>"), m_nWidth, m_nHeight ));
}
else
{
//err(( TEXT("CreateImageFromFile failed!") ));
return false;
}
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( m_hDC, &rc, NULL );
EndPaint(hWnd, &ps);
The image API initialization and image loading should only be done once
for performance reasons, because your WM_PAINT block is called every time
your window is repainted.
Call if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
when your app is closed.
Click to expand...
Click to collapse
So I put this code before PostQuitMessage(0); in WM_DESTROY ?
I did this and it appears to work, but I had to move the declaration for m_pImage and m_pImgFactory to the top of the code else the line in WM_DESTROY moaned warning C4700: uninitialized local variable 'm_pImage' used. My limited knowledge thus far tells me that the m_ prefix is denoting scope and it shouldn't be a global, so I guess this is wrong.
I mean so:
Code:
case WM_PAINT:
HDC m_hDC;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
m_nPosX = 0;
m_nPosY = 0;
m_hDC = BeginPaint(hWnd, &ps);
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( m_hDC, &rc, NULL );
EndPaint(hWnd, &ps);
Put the image loading and init in your main function when your app starts.
WM_DESTROY is a good place for the deinit aof imaging API.
Houser
Thanks for yet another speedy reply, this is really appreciated!
I think I have it now. I had to move the definitions for m_nWidth, m_nHeight, m_nPosX and m_nPosY out to where I put the loading and init code too, as it is needed for that.
So, I have now:
At the top of code in the includes section:
Code:
#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
At the start of WndProc:
Code:
PAINTSTRUCT ps;
int m_nWidth, m_nHeight, m_nPosX, m_nPosY;
m_nPosX = 0;
m_nPosY = 0;
IImagingFactory* m_pImgFactory;
IImage* m_pImage;
// init it
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) & m_pImgFactory)))
{
}
else
{
//err(( TEXT("CoCreateInstance failed!") ));
return false;
}
// load it
if( SUCCEEDED(m_pImgFactory->CreateImageFromFile( TEXT("\\Storage Card\\shared\\test.png"), &m_pImage )) )
{
ImageInfo info = {0};
m_pImage->GetImageInfo( &info );
m_nWidth = info.Width;
m_nHeight = info.Height;
log(( TEXT("Image loaded <%d> <%d>"), m_nWidth, m_nHeight ));
}
else
{
//err(( TEXT("CreateImageFromFile failed!") ));
return false;
}
Contents of WM_PAINT:
Code:
HDC m_hDC;
m_hDC = BeginPaint(hWnd, &ps);
// draw it
RECT rc;
rc.left = m_nPosX;
rc.top = m_nPosY;
rc.right = m_nWidth + m_nPosX;
rc.bottom = m_nHeight + m_nPosY;
m_pImage->Draw( m_hDC, &rc, NULL );
EndPaint(hWnd, &ps);
break;
Contents of WM_DESTROY:
Code:
if( m_pImage ) m_pImage->Release();
if( m_pImgFactory ) m_pImgFactory->Release();
CoUninitialize();
PostQuitMessage(0);
break;
I had been using VS2005 prior to now. I tried to go back and do this in eVC++ 4.0, as I wanted to use free tools if poss, but it refused to build:
Code:
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoUninitialize referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoCreateInstance referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoInitializeEx referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
ARMV4Dbg/AlphaPNGDemo.exe : fatal error LNK1120: 3 unresolved externals
Is this code compatible with eVC++ 4.0 and the PPC 2003 SDK, or do I need the WM5 SDK ? (And so VS2005)
Add Ole32.lib to your linker settings.
Houser
evilc said:
I had been using VS2005 prior to now. I tried to go back and do this in eVC++ 4.0, as I wanted to use free tools if poss, but it refused to build:
Code:
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoUninitialize referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoCreateInstance referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
AlphaPNGDemo.obj : error LNK2019: unresolved external symbol CoInitializeEx referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]@[email protected]@[email protected])
ARMV4Dbg/AlphaPNGDemo.exe : fatal error LNK1120: 3 unresolved externals
Is this code compatible with eVC++ 4.0 and the PPC 2003 SDK, or do I need the WM5 SDK ? (And so VS2005)
Click to expand...
Click to collapse
That allows it to build, but when I run it, the app does nothing. I see "AlphaPNGDemo" in the status bar, as if the app is running, but it is still on the today screen - it doesn't even blank the screen out white or anything.
Obviously I neglected to sacrifice a chicken over the keyboard to appease the gods of MicroSoft.
Here is a .cpp file giving a full demonstration of Per-Pixel Alpha PNGs.
Plus it detects screen orientation and loads a different PNG for portrait or landscape, thought I would post it up for anyone else who should follow.
The code is very clear as to where I have modified the base file, so you can see which code is mine and which is just normal WM stuff.
Also included are the sample semitransparent PNGs, one 240x40 and one 320x40. Put them on your hard disk and set the "Shared Folder" for the emulator to that disk so that the PNGs appear as \Storage Card\shared\<file>.png on the device.
[Please note, code may be really crappy, it's literally my first cpp prog, and my book still hasn't arrived yet...]