VC++ cdc alpha drawing

Hi Experts,

I'm writing an application in VC++.

I want to create a DC in memory then draw circles and rectangles to the memory DC and then when drawn bring them to the the screen.

Can someone give me a code example on how to draw, circles and rectangles setting the linestyle, width, colour and alpha?  Drawing with Alpha is important.
MOSSPOINTAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ambienceCommented:
GDI does not support Alpha blending so your options are limited to using bitmaps.
See the discussion here
http://www.mofeel.net/36-microsoft-public-win32-programmer-gdi/4356.aspx 
0
ikeworkCommented:
Another option is using DirectX or OpenGL, there you have full control over alpha-blending.

Ike
0
JohnGabyCommented:
You could also use GDI+ which supports alpha blending:

http://msdn.microsoft.com/en-us/library/ms533798%28VS.85%29.aspx
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

pgnatyukCommented:
MSDN. Alpha Blending Lines and Fills
http://msdn.microsoft.com/en-us/library/ms533803(VS.85).aspx
From this article you can find another one:
Drawing Opaque and Semitransparent Lines
http://msdn.microsoft.com/en-us/library/ms533938(v=VS.85).aspx
There is a simple example.
 So you can solve your task with GDI+.
You can do the same with the trivial GDI too. But you will have to implement all functions that draw the primitives.
Same in the managed:
Drawing Transparent Images and Shapes using Alpha Blending
http://www.c-sharpcorner.com/UploadFile/mahesh/DrawTransparentImageUsingAB10102005010514AM/DrawTransparentImageUsingAB.aspx
 
0
MOSSPOINTAuthor Commented:
pgnatyuk,

Thanks for the pointer, sounds like what I need.  I'm currently drawing my circles in a dcmem using GDI, what do I need to do differently to use GDI+ ?
0
pgnatyukCommented:
Short answer:
1. Initialize GDI+ in your application.
2. Obtain the Graphics object and call SetSmoothingMode.
2. Draw the ellipse by calling DrawEllipse method of the Graphics object.

An example:
CRect rect;
GetWindowRect(&rect);
Bitmap bmp(rect.Width(), rect.Height());
Graphics* g = Graphics::FromImage(&bmp);
g->SetSmoothingMode(SmoothingModeAntiAlias);
g->DrawEllipse(&myPen, 100, 50, 160, 80);
//put the image onto your window

Better example in C++ you can find here:
http://msdn.microsoft.com/en-us/library/aa984364(VS.71).aspx

Long answer:

I'd recommend you to make new project (for the learning purpose) and see how you initialize GDI+ and shutdown it in the end. Check the simplest example from MSDN:
GdiplusStartup Function
http://msdn.microsoft.com/en-us/library/ms534077(VS.85).aspx

The real program is in the bottom - you will load an image and detect its size. You will create an empty Win32 project, add new cpp-file and copy the code from the MSDN article. Try to compile. If there is an error, add this line:
#pragma comment(lib, "gdiplus.lib")

That's the first step.

Next step - try to draw an image with GDI+. Make a new project, load an image from the file and draw it on the screen. I attached an example of such program below. It is again the same - make empty Win32 project, add new file and copy the code.

These steps allow you to understand the basic principles.
Then, you can put the code from:
http://msdn.microsoft.com/en-us/library/ms533938(v=VS.85).aspx
to this app and see how it works.

Here you will be ready to modify your own application yourself.

Now your application looks like here:
http://www.functionx.com/visualc/gdi/circles.htm

Read this article in MSDN:
Antialiasing with Lines and Curves
http://msdn.microsoft.com/en-us/library/ms536351

You will see that you can use SetSmoothingMode function:
myGraphics.SetSmoothingMode(SmoothingModeAntiAlias);

and will get antialiased graphics primitives drawn in your app.

myGraphics.DrawLine(&myPen, 0, 0, 12, 8);
myGraphics.DrawEllipse(&myPen, 100, 50, 160, 80);

http://msdn.microsoft.com/en-us/library/ms536362(v=VS.85).aspx

Another (maybe much better) post about it:
Using GDI+ in C++ Win32 programming
http://www.avid-insight.co.uk/2009/05/02/using-gdi-in-c-win32-programming/

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <atlbase.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

Image*  s_pImage = NULL;
LPCWSTR s_szFileName = L"Humpback Whale.jpg";
LPCWSTR s_szWndClassName = L"Load JPG-file";

ATOM RegisterWndClass(HINSTANCE hInstance, LPCWSTR lpszWndClassName);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL DrawPicture(HDC, LPRECT);

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
	LPWSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	HWND hWnd = NULL;
	MSG msg = { 0 };

	s_pImage = Image::FromFile(s_szFileName, FALSE);
	RegisterWndClass(hInstance, s_szWndClassName);

	hWnd = CreateWindow(s_szWndClassName, 
		s_szWndClassName, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, 
		hInstance, NULL);

	if (hWnd != NULL)
	{
		ShowWindow(hWnd, nCmdShow);
		UpdateWindow(hWnd);

		// Main message loop:
		while (GetMessage(&msg, NULL, 0, 0))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}


	delete s_pImage;
	GdiplusShutdown(gdiplusToken);
	return (int)msg.wParam;
}

ATOM RegisterWndClass(HINSTANCE hInstance, LPCWSTR lpszWndClassName)
{
	WNDCLASSEX wcex 		= { 0 };
	wcex.cbSize		= sizeof(WNDCLASSEX);
	wcex.style		= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc		= WndProc;
	wcex.hInstance		= hInstance;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszClassName	= lpszWndClassName;
	return RegisterClassEx(&wcex);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
	WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rect;

	switch (message)
	{
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		::GetClientRect(hWnd, &rect);
		DrawPicture(hdc, &rect);
		EndPaint(hWnd, &ps);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

BOOL DrawPicture(HDC hDC, LPRECT lpRect)
{
	if (s_pImage == NULL)
		return FALSE;
	Graphics graphics(hDC);
	graphics.DrawImage(s_pImage, 
		lpRect->left, lpRect->top,
		lpRect->right - lpRect->left, 
		lpRect->bottom - lpRect->top);
	return TRUE;
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MOSSPOINTAuthor Commented:
Thanks
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.