Since this subject has come up several times lately, I've thrown together a quick example of drawing with GDI calls.
It's based on the Dev GUI app template, I removed all of the normal comments from it, and added the GDI code and comments, so anywhere there are comments is where the changes were made.
It should compile as a C++ GUI app.
I commented the whole thing to preserve the indentation for the forum (hopefully) so after you cut and past, just do a 'select all' and 'ctrl-alt-comma' to remove the first column of //'s
Compile, run, double click on the window, it should draw a rectangle.. pretty basic, but it shows the technique of creating a 'canvas' to buffer your graphics. Once you've got that down it's easy to add various drawing commands to draw lines, circles, text, bitmaps, etc..
Hope it's helpful.
//#include <windows.h>
//
//LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
//
//char szClassName[ ] = "WindowsApp";
//
//int WINAPI WinMain (HINSTANCE hThisInstance,
// HINSTANCE hPrevInstance,
// LPSTR lpszArgument,
// int nFunsterStil)
//{
// HWND hwnd;
// MSG messages;
// WNDCLASSEX wincl;
//
// wincl.hInstance = hThisInstance;
// wincl.lpszClassName = szClassName;
// wincl.lpfnWndProc = WindowProcedure;
// wincl.style = CS_DBLCLKS;
// wincl.cbSize = sizeof (WNDCLASSEX);
//
// wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
// wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
// wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
// wincl.lpszMenuName = NULL;
// wincl.cbClsExtra = 0;
// wincl.cbWndExtra = 0;
// wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
//
// if (!RegisterClassEx (&wincl))
// return 0;
//
// hwnd = CreateWindowEx (
// 0,
// szClassName,
// "Double Click Me!",
// WS_OVERLAPPEDWINDOW,
// CW_USEDEFAULT,
// CW_USEDEFAULT,
// 544,
// 375,
// HWND_DESKTOP,
// NULL,
// hThisInstance,
// NULL
// );
//
// ShowWindow (hwnd, nFunsterStil);
//
// while (GetMessage (&messages, NULL, 0, 0))
// {
// TranslateMessage(&messages);
// DispatchMessage(&messages);
// }
// return messages.wParam;
//}
//
//LRESULT CALLBACK
//WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
//{
// static HDC memdc; // virtual device context handle
// static HBITMAP hbit; // virtual bitmap handle
//
// switch (message)
// {
// case WM_CREATE:
// {
// /* In WM_CREATE we set up the virtual 'canvas' that we will draw on.
// It will consist of a device context and bitmap that are compatible
// with the window dc. We will create a brush to paint the background
// of the 'canvas'
// */
//
// // handle to save current brush
// HGDIOBJ oldBrush;
//
// // get screen coordinates
// int maxX = GetSystemMetrics(SM_CXSCREEN);
// int maxY = GetSystemMetrics(SM_CYSCREEN);
//
// // get handle to window dc
// HDC hdc = GetDC(hwnd);
//
// // create virtual dc and bitmap
// memdc = CreateCompatibleDC(hdc);
// hbit = CreateCompatibleBitmap(hdc, maxX, maxY);
//
// // select bitmap into dc
// SelectObject(memdc, hbit);
//
// // save old brush and select new brush
// oldBrush = SelectObject(memdc, CreateSolidBrush(RGB(255, 255, 240)));
//
// // paint background with brush, delete brush and release dc
// PatBlt(memdc, 0, 0, maxX, maxY, PATCOPY);
// DeleteObject(SelectObject(memdc, oldBrush));
// ReleaseDC(hwnd, hdc);
//
// break;
// }
//
// case WM_PAINT:
// {
// /* In WM_PAINT we update the screen by bitblt'ing the virtual canvas to
// the window.
// */
//
// PAINTSTRUCT ps; // struct to hold screen coordinates
// HDC hdc = BeginPaint(hwnd, &ps); // get window dc and coords.
//
// BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, //copy memdc to hdc
// ps.rcPaint.right-ps.rcPaint.left,
// ps.rcPaint.bottom-ps.rcPaint.top,
// memdc,
// ps.rcPaint.left, ps.rcPaint.top,
// SRCCOPY);
//
// EndPaint(hwnd, &ps); // finished paint
// break;
// }
//
// case WM_LBUTTONDBLCLK:
// {
// /* On double click left button we will save the state of memdc,
// create a pen and a brush, and draw a rectangle. We will call
// InvalidateRect to force Windows to send a WM_PAINT, redrawing
// our window with the updated canvas. Then we will restore the
// state of memdc, and delete the pen and brush we created.
// */
//
// // save the current dc state
// int oldDC = SaveDC(memdc);
//
// // create pen and brush
// HPEN hpRed = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
// HBRUSH hbBlue = CreateSolidBrush(RGB(220, 220, 255));
//
// // select pen and brush into memdc
// SelectObject(memdc, hpRed);
// SelectObject(memdc, hbBlue);
//
// // draw rectangle, uses hpRed pen for border, hbBlue brush for filling
// Rectangle(memdc, 50, 50, 400, 200);
//
// // force repaint
// InvalidateRect(hwnd, NULL, TRUE);
//
// // clean up, restore dc, delete pen and brush
// RestoreDC(memdc, oldDC);
// DeleteObject(hpRed);
// DeleteObject(hbBlue);
//
// break;
// }
//
// case WM_DESTROY:
// PostQuitMessage (0);
// break;
// default:
// return DefWindowProc (hwnd, message, wParam, lParam);
// }
//
// return 0;
//}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You'd think someone could've had a little foresight... "hmm.. we're going to host programming forums, lets use forum software that removes all formatting!!!"
Oh well... c'est la vie
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
However, the spaces are not lost. Simply select to view your the source for the page (view -> source under internet explorer). Cut and paste the code and voila, the leading spaces are there.
Alternatively, get a good editor that can reformat code and cut and paste into it (I use emacs).
rr
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Since this subject has come up several times lately, I've thrown together a quick example of drawing with GDI calls.
It's based on the Dev GUI app template, I removed all of the normal comments from it, and added the GDI code and comments, so anywhere there are comments is where the changes were made.
It should compile as a C++ GUI app.
I commented the whole thing to preserve the indentation for the forum (hopefully) so after you cut and past, just do a 'select all' and 'ctrl-alt-comma' to remove the first column of //'s
Compile, run, double click on the window, it should draw a rectangle.. pretty basic, but it shows the technique of creating a 'canvas' to buffer your graphics. Once you've got that down it's easy to add various drawing commands to draw lines, circles, text, bitmaps, etc..
Hope it's helpful.
//#include <windows.h>
//
//LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
//
//char szClassName[ ] = "WindowsApp";
//
//int WINAPI WinMain (HINSTANCE hThisInstance,
// HINSTANCE hPrevInstance,
// LPSTR lpszArgument,
// int nFunsterStil)
//{
// HWND hwnd;
// MSG messages;
// WNDCLASSEX wincl;
//
// wincl.hInstance = hThisInstance;
// wincl.lpszClassName = szClassName;
// wincl.lpfnWndProc = WindowProcedure;
// wincl.style = CS_DBLCLKS;
// wincl.cbSize = sizeof (WNDCLASSEX);
//
// wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
// wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
// wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
// wincl.lpszMenuName = NULL;
// wincl.cbClsExtra = 0;
// wincl.cbWndExtra = 0;
// wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
//
// if (!RegisterClassEx (&wincl))
// return 0;
//
// hwnd = CreateWindowEx (
// 0,
// szClassName,
// "Double Click Me!",
// WS_OVERLAPPEDWINDOW,
// CW_USEDEFAULT,
// CW_USEDEFAULT,
// 544,
// 375,
// HWND_DESKTOP,
// NULL,
// hThisInstance,
// NULL
// );
//
// ShowWindow (hwnd, nFunsterStil);
//
// while (GetMessage (&messages, NULL, 0, 0))
// {
// TranslateMessage(&messages);
// DispatchMessage(&messages);
// }
// return messages.wParam;
//}
//
//LRESULT CALLBACK
//WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
//{
// static HDC memdc; // virtual device context handle
// static HBITMAP hbit; // virtual bitmap handle
//
// switch (message)
// {
// case WM_CREATE:
// {
// /* In WM_CREATE we set up the virtual 'canvas' that we will draw on.
// It will consist of a device context and bitmap that are compatible
// with the window dc. We will create a brush to paint the background
// of the 'canvas'
// */
//
// // handle to save current brush
// HGDIOBJ oldBrush;
//
// // get screen coordinates
// int maxX = GetSystemMetrics(SM_CXSCREEN);
// int maxY = GetSystemMetrics(SM_CYSCREEN);
//
// // get handle to window dc
// HDC hdc = GetDC(hwnd);
//
// // create virtual dc and bitmap
// memdc = CreateCompatibleDC(hdc);
// hbit = CreateCompatibleBitmap(hdc, maxX, maxY);
//
// // select bitmap into dc
// SelectObject(memdc, hbit);
//
// // save old brush and select new brush
// oldBrush = SelectObject(memdc, CreateSolidBrush(RGB(255, 255, 240)));
//
// // paint background with brush, delete brush and release dc
// PatBlt(memdc, 0, 0, maxX, maxY, PATCOPY);
// DeleteObject(SelectObject(memdc, oldBrush));
// ReleaseDC(hwnd, hdc);
//
// break;
// }
//
// case WM_PAINT:
// {
// /* In WM_PAINT we update the screen by bitblt'ing the virtual canvas to
// the window.
// */
//
// PAINTSTRUCT ps; // struct to hold screen coordinates
// HDC hdc = BeginPaint(hwnd, &ps); // get window dc and coords.
//
// BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, //copy memdc to hdc
// ps.rcPaint.right-ps.rcPaint.left,
// ps.rcPaint.bottom-ps.rcPaint.top,
// memdc,
// ps.rcPaint.left, ps.rcPaint.top,
// SRCCOPY);
//
// EndPaint(hwnd, &ps); // finished paint
// break;
// }
//
// case WM_LBUTTONDBLCLK:
// {
// /* On double click left button we will save the state of memdc,
// create a pen and a brush, and draw a rectangle. We will call
// InvalidateRect to force Windows to send a WM_PAINT, redrawing
// our window with the updated canvas. Then we will restore the
// state of memdc, and delete the pen and brush we created.
// */
//
// // save the current dc state
// int oldDC = SaveDC(memdc);
//
// // create pen and brush
// HPEN hpRed = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
// HBRUSH hbBlue = CreateSolidBrush(RGB(220, 220, 255));
//
// // select pen and brush into memdc
// SelectObject(memdc, hpRed);
// SelectObject(memdc, hbBlue);
//
// // draw rectangle, uses hpRed pen for border, hbBlue brush for filling
// Rectangle(memdc, 50, 50, 400, 200);
//
// // force repaint
// InvalidateRect(hwnd, NULL, TRUE);
//
// // clean up, restore dc, delete pen and brush
// RestoreDC(memdc, oldDC);
// DeleteObject(hpRed);
// DeleteObject(hbBlue);
//
// break;
// }
//
// case WM_DESTROY:
// PostQuitMessage (0);
// break;
// default:
// return DefWindowProc (hwnd, message, wParam, lParam);
// }
//
// return 0;
//}
Ok, crap this forum sucks for posting code!!!!!!
You'd think someone could've had a little foresight... "hmm.. we're going to host programming forums, lets use forum software that removes all formatting!!!"
Oh well... c'est la vie
Yeah, sourceforge suppresses leading spaces.
However, the spaces are not lost. Simply select to view your the source for the page (view -> source under internet explorer). Cut and paste the code and voila, the leading spaces are there.
Alternatively, get a good editor that can reformat code and cut and paste into it (I use emacs).
rr
see my post near the end of the forum FAQ thread
Adrian
so what do you suppose would happen if we just put
<pre>
in our messages
would they display right then?
</pre>
I shall find out in a minute....
duh.. I should have read what it says right below the message input box.. lol!!!
So.. any opinions on the example? Does it look like a good starting place for newbies?