Click here to Skip to main content
15,891,423 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using GDI+ to draw png image with transparency.

after sometime I want to draw same image with some rotation. but I am not able to remove The previous image date. So my rendered window is a series of old images.

C++
void CBusyWnd::drawImage	( )
{
	if (mImage)
	{
		Gdiplus::Graphics gdip(mWnd);
		gdip.ResetTransform();
		gdip.TranslateTransform((Gdiplus::REAL)(mImage->GetWidth())/2.0f,(Gdiplus::REAL)(mImage->GetHeight())/2.0f);
		gdip.RotateTransform(mAngle=mAngle>360?0:mAngle+1);
		gdip.TranslateTransform(-1.0f*(Gdiplus::REAL)(mImage->GetWidth())/2.0f,-1.0f*(Gdiplus::REAL)(mImage->GetHeight())/2.0f);
		gdip.DrawImage(mImage, 0, 0, mImage->GetWidth(), mImage->GetHeight());
		gdip.Flush();
	}
	InvalidateRect(mWnd, NULL, FALSE);
}

please find image at http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/825a5243-9441-4abc-be30-e5598ccc9872[^]

my registered window class is:-

C++
outWndClass.style		= CS_HREDRAW | CS_VREDRAW;
outWndClass.lpfnWndProc		= wndProc; 
outWndClass.hInstance		= GetModuleHandle(NULL);
outWndClass.hCursor		= LoadCursor(NULL, IDC_APPSTARTING);
outWndClass.hbrBackground	= (HBRUSH)GetStockObject(HOLLOW_BRUSH);//(HBRUSH)(COLOR_WINDOW + 1);
outWndClass.lpszClassName	= L"BusyWnd";

outWndClass.hIcon		= LoadIcon(outWndClass.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));


if (!RegisterClass(&outWndClass))
{
	if (GetLastError() != 0x00000582) // already registered)
	{
		OutputDebugString(L"Unable to register class BusyWnd\n");
		return false;
	}
}


Can anyone help give me some pointer.

I tried following code for clearing the window before each draw. but Code is too slow and the is no way to set transparency.

C++
HDC hdc = GetDC(mWnd); // Get the DC from that HWND
for( UINT i = 0 ; i < mImage->GetWidth() ; i++ )
	for( UINT j = 0 ; j < mImage->GetHeight() ; j++ )
		SetPixel(hdc, i,j, RGB(255,255,255)); // SetPixel(HDC hdc, int x, int y, COLORREF color)
ReleaseDC(mWnd, hdc); // Release the DC
DeleteDC(hdc); // Delete the DC
Posted
Comments
enhzflep 25-Apr-13 7:42am    
I just handle the WM_ERASEBKG message. Though only do this, so that I can erase the background or not, depending on whether or not the image has an alpha channel. Though, you possibly don't need to go that far. As it stands, your call to InvalidateRect passes false for the 3rd param - if you change this to true, the WM_ERASEBKG message gets sent. I'm not familiar with mfc, so don't know if that will do the trick, or if you'll have to handle it yourself. Also, I noticed a background brush of HOLLOW_BRUSH - think you'll have to set that to a colour for it to work.
saurabh saini 25-Apr-13 8:18am    
Thanks for your reply.
Sending True or False to InvalidateRect doesn't make any difference right now and I have no code in WM_ERASEBKG.
Can u tell me which brush to use for alpha and what code to write in WM_ERASEBKG.
enhzflep 25-Apr-13 8:37am    
No worries.
I use this code in a class that subclasses static controls and draws transparent pngs in em.
So, the background brush is whatever is the default for the control. If it's hollow, then the dialog colour will be shown, I guess.

LRESULT CALLBACK CStaticImg::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RECT myRect;
PAINTSTRUCT ps;
HBRUSH mBrush;
switch (uMsg)
{
case WM_PAINT:
BeginPaint(hWnd, &ps);
displayImage();
EndPaint(hWnd, &ps);
return false;
case WM_ERASEBKGND:
GetClientRect(hWnd, &myRect);
mBrush = (HBRUSH) GetWindowLong(hWnd, GCL_HBRBACKGROUND);
if (isBkgTransparent)
FillRect((HDC)wParam, &myRect, mBrush);
return true;
}
return CallWindowProc(mOldWndProc, hWnd, uMsg, wParam, lParam);
}
saurabh saini 25-Apr-13 9:45am    
I have tried this code, The background is not transparent after the Call of FillRect. moreover it started flickering.
Jochen Arndt 25-Apr-13 8:33am    
To erase rectangular areas, you can use the GDI FillRect() function passing a brush or one of the standard Windows system colors. This will be much faster than using SetPixel() inside a loop.

1 solution

Right now what your code is doing is its not clearing the previous position of .png image. What you need to do is every time you need to reload the background image and then position your .png .
 
Share this answer
 
Comments
saurabh saini 25-Apr-13 9:25am    
thanks for your reply.
Sorry but I am not able to understand what and how to do that. I am bit new to win32 and GDI.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900