Page 1 of 1

Microsoft : Working with Buttons Part I - Pushbuttons The first part of a three part tutorial on button controls 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 23 March 2010 - 04:15 AM

Microsoft : Working with Buttons Part I - Pushbuttons

Introduction

Buttons covers quite a few of the windows controls we have in our control arsenal. Too many for a single tutorial, as each have their own oddities that require attention.

Pushbuttons are raised areas of the screen containing text and possibly images. These buttons when pressed, appear to sink into the screen, and normally pop back out when you release the mouse button.

Creating a pushbuton

To create a pushbutton in our frame window, we use the "Button" window class. You can also add the BS_PUSHBUTTON window style as I have done below, but this is not nessesary as it is the default window style.

The code snippet below is taken from the code example found at the end of this tutorial. It creates a simple pushbutton with the text 'Press Me!' in the middle of the button.

            window_handle = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,    
                                           window_class_name,    
                                           L"Pushbutton Example",   
                                           WS_OVERLAPPEDWINDOW | 
                                           WS_CLIPCHILDREN | WS_CLIPSIBLINGS,   
                                           100, 100, screen_width-200,    
                                           screen_height-200, NULL, NULL,   
                                           instance_handle, NULL);
            RECT client_rectangle;
            GetClientRect(window_handle, &client_rectangle);
            int width = client_rectangle.right - client_rectangle.left;
            int height = client_rectangle.bottom - client_rectangle.top;
            pushbutton_handle = CreateWindowEx(0, L"Button", L"Press Me!",
                                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,   
                                               (width-180)/2, ((height-15)/2), 180,
                                               30, window_handle, (HMENU)11,   
                                               instance_handle, NULL);



When do we know when the button has been pressed?

The window management system will inform you when the button has been pressed by sending the parent window a WM_COMMAND message. This message can be sent for a variety of controls, so I have checked that the ID in the control message is what I am expecting (even though we only have the one control).

Code Example

The code example below creates a push button in the middle of the frame window. It contains the text 'Press Me!. When you press the button, the WM_COMMAND message is received, and the ID of the command message used to ensure that it is this button we are dealing with (as there could be others!). Depending on the state of an internal boolean flag, the text of the button is changed from 'Press Me!' to 'Press Me Again!".

#include <windows.h>  
#include <CommCtrl.h> 
#include <ctime>  
#include <cstdlib>  
using namespace std;

#pragma comment(lib, "comctl32.lib")
class frame_window {  
    private:
        LPWSTR window_class_name;  
        HINSTANCE instance_handle;  
        HCURSOR cursor_arrow;  
        HWND window_handle;
        HWND pushbutton_handle;
        RECT client_rectangle;
        bool pressed;
    public:
        frame_window(LPWSTR window_class_identity) : window_class_name(window_class_identity), pressed(false) {  
            int screen_width = GetSystemMetrics(SM_CXFULLSCREEN);  
            int screen_height = GetSystemMetrics(SM_CYFULLSCREEN);  
            instance_handle = GetModuleHandle(NULL);  
               
            WNDCLASS window_class = { CS_OWNDC, main_window_proc, 0, 0,    
                                      instance_handle, NULL,    
                                      NULL, NULL, NULL,    
                                      window_class_name };   
            
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
            // Create a standard frame window   
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
            
            RegisterClass(&window_class);   
            window_handle = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,    
                                           window_class_name,    
                                           L"Pushbutton Example",   
                                           WS_OVERLAPPEDWINDOW | 
                                           WS_CLIPCHILDREN | WS_CLIPSIBLINGS,   
                                           100, 100, screen_width-200,    
                                           screen_height-200, NULL, NULL,   
                                           instance_handle, NULL);
            RECT client_rectangle;
            GetClientRect(window_handle, &client_rectangle);
            int width = client_rectangle.right - client_rectangle.left;
            int height = client_rectangle.bottom - client_rectangle.top;
            pushbutton_handle = CreateWindowEx(0, L"Button", L"Press Me!",
                                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,   
                                               (width-180)/2, ((height-15)/2), 180,
                                               30, window_handle, (HMENU)11,   
                                               instance_handle, NULL);
            SetCursor(LoadCursor(NULL, IDC_ARROW)); 
            SetWindowLongPtr(window_handle, GWL_USERDATA, (LONG)this);  
            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) {  
            frame_window *This = (frame_window *)GetWindowLongPtr(window_handle, 
                GWL_USERDATA);  
            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 light_brush = CreateSolidBrush(RGB(255, 255, 238));  
                    FillRect(paint_dc, &paint_structure.rcPaint, light_brush);  
                    DeleteObject(light_brush);  
                                                                            
                    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:   
                {
                    RECT client_rectangle;
                    GetClientRect(window_handle, &client_rectangle);
                    int width = client_rectangle.right - client_rectangle.left;
                    int height = client_rectangle.bottom - client_rectangle.top;
                    SetWindowPos(This->pushbutton_handle, NULL, 
                                 (width-100)/2, ((height-15)/2), 0,
                                 0, SWP_NOSIZE|SWP_NOZORDER);
                    InvalidateRect(window_handle, NULL, TRUE);   
                    return 0;   
                }
                case WM_COMMAND:
                {
                    if ( LOWORD(wparam) == 11 ) {
                        if ( This->pressed == false ) {
                            SetWindowText(This->pushbutton_handle, L"Press Me Again!");
                            This->pressed = true;
                        }
                        else {
                            SetWindowText(This->pushbutton_handle, L"Press Me!");
                            This->pressed = false;
                        }
                    }
                    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 main_window(L"my base window");  
    main_window.run();  
    return 0;   
}



The next part of the tutorial may be found here.

This post has been edited by Martyn.Rae: 23 March 2010 - 05:08 AM


Is This A Good Question/Topic? 1
  • +

Page 1 of 1