Page 1 of 1

Microsoft : Working With Shapes Drawing shapes in a device context Rate Topic: -----

#1 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Posted 19 March 2010 - 05:00 AM

Microsoft : Working With Shapes

Introduction

There are a number of shape routines we can use to spice up the look of the graphical user interface we present to the user. These routines are listed below as links to the appropriate MSDN page.

Chord to produce a partial oval, where the open end is joined by a straight line.
Ellipse to produce a circle or oval.
DrawRect to draw a rectangle.
FrameRect to draw a frame rectangle.
InvertRect to invert the pixel colours in a rectangle.
Pie To produce a section of a circle.
Polygon To produce a polygon.
PolyPolygon to produce a number of polygons that may overlap.
Rectangle To produce a rectangle.
RoundRect To produce a rectangle with rounded edges.

Drawing Shapes

Using these API calls is relatively straight forward, except that they all use the current pen and brush selected into the device context (unlike the FillRect API function).

So, for eaxmple to use the RoundRect routine which draws a green rectangle with rounded edges, we would say:

     HPEN green_pen = CreatePen(PS_SOLID, 1, RGB(0x00, 0xFF, 0x00));
     HBRUSH green_brush = CreateSolidBrush(RGB(0x00, 0xFF, 0x00));
     HGDIOBJ old_pen = SelectObject(paint_dc, green_pen);
     HGDIOBJ old_brush = SelectObject(paint_dc, green_brush);
     RoundRect(paint_dc, 20, 20, 200, 80, 20, 20);
     SelectObject(paint_dc, old_pen);
     SelectObject(paint_dc, old_brush);
     DeleteObject(green_pen);
     DeleteObject(green_brush);



If we wanted to give this rectangle a 3D look, we would quickly realise that it was not possible, unless we have the ability to draw curved lines with a pen. The routine that will draw this curved line is Arc (details found here). The result is not perfect, because the transition between light and dark edging is sudden rather than gradual.

#define OEMRESOURCE
#include <windows.h> 

class frame_window {
    private:    LPWSTR window_class_name;
                HINSTANCE instance_handle;
                RECT client_rectangle; 
    public:     frame_window(LPWSTR window_class_identity) : window_class_name(window_class_identity) { 
                    int screen_width = GetSystemMetrics(SM_CXFULLSCREEN);
                    int screen_height = GetSystemMetrics(SM_CYFULLSCREEN);
                    instance_handle = GetModuleHandle(NULL);
                    HCURSOR cursor_arrow = LoadCursor(instance_handle, IDC_ARROW); 
                    WNDCLASS window_class = { CS_OWNDC, main_window_proc, 0, 0,  
                                              instance_handle, NULL,  
                                              cursor_arrow,  
                                              NULL, NULL,  
                                              window_class_name }; 
                 
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                    // Create a standard frame window 
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                 
                    RegisterClass(&window_class); 
                    HWND window_handle = CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE,  
                                                        window_class_name,  
                                                        L"My Base Window", 
                                                        WS_OVERLAPPEDWINDOW, 100, 
                                                        100, screen_width-200,  
                                                        screen_height-200, NULL, NULL, 
                                                        instance_handle, NULL); 
                 
                    ShowWindow(window_handle, SW_SHOW); 
                    UpdateWindow(window_handle); 
                }
                ~frame_window() {
                    UnregisterClass(window_class_name, instance_handle); 
                }
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                // Windows message processing function 
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                static LRESULT WINAPI main_window_proc(HWND window_handle, UINT message,  
                                                       WPARAM wparam, LPARAM lparam) { 
                    switch ( message ) { 
                        case WM_PAINT: 
                        { 
                            PAINTSTRUCT paint_structure; 
                            RECT client_rect; 
                            HDC paint_device_context, paint_dc; 
                            HBITMAP bitmap; 

                            paint_device_context = BeginPaint(window_handle, &paint_structure); 
                            paint_dc = CreateCompatibleDC(paint_device_context); 
                            GetClientRect(window_handle, &client_rect); 
                            int window_width = client_rect.right - client_rect.left;
                            int window_height = client_rect.bottom - client_rect.top;
                            bitmap = CreateBitmap(window_width, window_height, 1, 32, NULL);
                            HGDIOBJ old_bitmap = SelectObject(paint_dc, bitmap);

                            // Fill the client aread with the user selected face colour
                            HBRUSH fill_brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
                            FillRect(paint_dc, &paint_structure.rcPaint, fill_brush);
                            DeleteObject(fill_brush);
                            
                            // Here is the drawing of the rounded 3D effect.
                            HPEN light_pen = CreatePen(PS_SOLID, 2, GetSysColor(COLOR_3DHIGHLIGHT));
                            HPEN dark_pen = CreatePen(PS_SOLID, 2, GetSysColor(COLOR_3DSHADOW));
                            HGDIOBJ old_pen = SelectObject(paint_dc, light_pen);
                            Arc(paint_dc, 20, 20, 40, 40, 20, 30, 20, 30);
                            MoveToEx(paint_dc, 30, 20, NULL);
                            LineTo(paint_dc, 190, 20);
                            Arc(paint_dc, 180, 20, 200, 40, 200, 70, 190, 80);
                            SelectObject(paint_dc, dark_pen);
                            SetArcDirection(paint_dc, AD_CLOCKWISE);
                            MoveToEx(paint_dc, 200, 30, NULL);
                            LineTo(paint_dc, 200, 70);
                            Arc(paint_dc, 180, 60, 200, 80, 200, 70, 190, 80);
                            MoveToEx(paint_dc, 190, 80, NULL);
                            LineTo(paint_dc, 30, 80);
                            SelectObject(paint_dc, light_pen);
                            Arc(paint_dc, 20, 60, 40, 80, 30, 80, 20, 70);
                            MoveToEx(paint_dc, 20, 70, NULL);
                            LineTo(paint_dc, 20, 30);
                            
                            // Here are is the code for drawing our green rounded rectangle.
                            HPEN green_pen = CreatePen(PS_SOLID, 1, RGB(0x00, 0xFF, 0x00));
                            HBRUSH green_brush = CreateSolidBrush(RGB(0x00, 0xFF, 0x00));
                            SelectObject(paint_dc, green_pen);
                            HGDIOBJ old_brush = SelectObject(paint_dc, green_brush);
                            RoundRect(paint_dc, 21, 21, 199, 79, 20, 20);
                            SelectObject(paint_dc, old_pen);
                            SelectObject(paint_dc, old_brush);
                            DeleteObject(green_pen);
                            DeleteObject(green_brush);
                            DeleteObject(dark_pen);
                            DeleteObject(light_pen);

                            BitBlt(paint_device_context, 0, 0,  
                                   client_rect.right-client_rect.left, 
                                   client_rect.bottom-client_rect.top, 
                                   paint_dc, 0, 0, SRCCOPY); 
                            SelectObject(paint_dc, old_bitmap); 
                            DeleteObject(bitmap); 
                            DeleteDC(paint_dc); 
                            EndPaint(window_handle, &paint_structure); 
                            return 0; 
                        } 
                        case WM_ERASEBKGND: 
                        { 
                            return TRUE; 
                        } 
                        case WM_SIZE: 
                        { 
                            InvalidateRect(window_handle, NULL, TRUE); 
                            return 0; 
                        } 
                        case WM_CLOSE: 
                        { 
                            //++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                            // The user wants to close the window 
                            //++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                 
                            PostQuitMessage(0); 
                            return 0; 
                        } 
                    } 
                    return DefWindowProc(window_handle, message, wparam, lparam); 
                } 
                
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                // Windows message loop 
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                void run() {
                    MSG window_message; 
                    while ( GetMessage(&window_message, NULL, 0, 0) ) { 
                        TranslateMessage(&window_message); 
                        DispatchMessage(&window_message); 
                    } 
                }
};
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
// Windows main entry point 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 
int WINAPI wWinMain(HINSTANCE instance_handle, HINSTANCE, LPWSTR, INT) {
    frame_window mainWindow(L"my base window");
    mainwindow.run();
    return 0; 
}



Is This A Good Question/Topic? 0
  • +

Replies To: Microsoft : Working With Shapes

#2 Huzi94  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 14
  • View blog
  • Posts: 119
  • Joined: 14-November 09

Posted 23 March 2010 - 01:26 AM

Thanks for the tutorial, this was what I was looking for to learn GDI coding. Can you please post a tutorial on progress bars as i am looking forward to learn controls.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1