[win32] - how use the button face?

This is a discussion on [win32] - how use the button face? within the Windows Programming forums, part of the Platform Specific Boards category; when i ownerdraw a button, can i get the button faces? (for then add the image and text)...

  1. #1
    Registered User
    Join Date
    Aug 2013
    Posts
    138

    [win32] - how use the button face?

    when i ownerdraw a button, can i get the button faces?
    (for then add the image and text)

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    419
    The BS_OWNERDRAW style requires that you draw everything, including the button itself.
    The buttons are handled as menu items rather than buttons, but allow you to completely
    design the button yourself. However, this also means that you will have to also draw
    the "button pushed" state yourself when the button is clicked on.

    All drawing should be done in response to a WM_DRAWITEM message:

    WM_DRAWITEM message (Windows)

    The lParam with this message contains a pointer to a DRAWITEMSTRUCT structure:

    DRAWITEMSTRUCT structure (Windows)

    The rcItem member of this structure is a rectangle for the "surface" of the button.

    You have to be careful to not draw outside of the button rectangle. The drawing is not clipped
    as it is with other drawing procedures like drawing in the client area.

    -

  3. #3
    Registered User
    Join Date
    Aug 2013
    Posts
    138
    Quote Originally Posted by megafiddle View Post
    The BS_OWNERDRAW style requires that you draw everything, including the button itself.
    The buttons are handled as menu items rather than buttons, but allow you to completely
    design the button yourself. However, this also means that you will have to also draw
    the "button pushed" state yourself when the button is clicked on.

    All drawing should be done in response to a WM_DRAWITEM message:

    WM_DRAWITEM message (Windows)

    The lParam with this message contains a pointer to a DRAWITEMSTRUCT structure:

    DRAWITEMSTRUCT structure (Windows)

    The rcItem member of this structure is a rectangle for the "surface" of the button.

    You have to be careful to not draw outside of the button rectangle. The drawing is not clipped
    as it is with other drawing procedures like drawing in the client area.

    -
    sorry.. but i continue with the problem: i know draw rectangles and text and bitmaps\icons, my problem is: how can i draw the windows 200(for exemple) button face(with normal states)?
    (my objective is showing the button and then draw the image and text)

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    419
    I'm not sure I understand the question -

    Are you now using a BS_OWNERDRAW style?
    Are you trying to draw on the control and nothing is happenning?

    -

  5. #5
    Registered User
    Join Date
    Aug 2013
    Posts
    138
    Quote Originally Posted by megafiddle View Post
    I'm not sure I understand the question -

    Are you now using a BS_OWNERDRAW style?
    Are you trying to draw on the control and nothing is happenning?

    -
    yes.. i'm using the BS_OWNERDRAW style and i can draw things.
    my problem is: can i draw the windows 2000 button visual style?(for not recreate the button)

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    419
    You would have to draw the entire button yourself. There is no style or other contol parameter
    that you can specify to get a "classic" style OWNERDRAW button, if that is what you you are asking.

    The "classic" button frame uses two different color lines along the left and top edges, and two different
    color lines along the right and bottom edges. (the frame is two pixels thick). So you would have to draw
    these lines yourself.

    -
    Last edited by megafiddle; 05-26-2014 at 03:27 PM.

  7. #7
    Registered User
    Join Date
    Aug 2013
    Posts
    138
    Quote Originally Posted by megafiddle View Post
    You would have to draw the entire button yourself. There is no style or other contol parameter
    that you can specify to get a "classic" style OWNERDRAW button, if that is what you you are asking.

    The "classic" button frame uses two different color lines along the left and top edges, and two different
    color lines along the right and bottom edges. (the frame is two pixels thick). So you would have to draw
    these lines yourself.

    -
    now i can share the code:
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <Uxtheme.h> //for use the theme functions
    #include <Vsstyle.h> //for use the BP_PUSHBUTTON or others const's
    #include "Untitled2.h" //is for resource file
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    static TCHAR szAppName[] = TEXT ("RandRect") ;
    
    HINSTANCE a;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    
        HWND hwnd ;
        MSG msg ;
        a=hInstance;
        WNDCLASS wndclass ;
        wndclass.style = 0 ;
        wndclass.lpfnWndProc = WndProc ;
        wndclass.cbClsExtra = 0 ;
        wndclass.cbWndExtra = 0 ;
        wndclass.hInstance = hInstance ;
        wndclass.hIcon = LoadIcon (NULL, "IDI_ICON");
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName = NULL ;
        wndclass.lpszClassName = szAppName ;
    
        if (!RegisterClass (&wndclass))
        {
            MessageBox (NULL, TEXT ("This program requires Windows NT!"),szAppName, MB_ICONERROR) ;
            return 0 ;
        }
    
        hwnd = CreateWindowEx (WS_EX_CLIENTEDGE,szAppName, TEXT ("Random Rectangles"),
                WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
                CW_USEDEFAULT, CW_USEDEFAULT,
                CW_USEDEFAULT, CW_USEDEFAULT,
                NULL, NULL, hInstance, NULL) ;
    
        ShowWindow (hwnd, iCmdShow) ;
        UpdateWindow (hwnd) ;
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
        }
        return msg.wParam ;
    }
    
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        static HWND hButton;
        static HINSTANCE hInstance = GetModuleHandle(NULL);
        static HICON HandleIcon;
    
        switch (iMsg)
        {
            case WM_DESTROY:
                DestroyIcon(HandleIcon);
                PostQuitMessage (0) ;
                return 0 ;
            //case WM_CTLCOLORBTN:
                //return (LRESULT) GetStockObject (NULL_BRUSH);
            case WM_CREATE:
    
    
                //create the button
                hButton=CreateWindowEx (0,"button", "H&ello \nmy mother",
                WS_CHILD | WS_VISIBLE |  BS_OWNERDRAW | BS_NOTIFY,
                100, 100,100, 50,hwnd,NULL,hInstance, 0) ;
    
                return 0;
    
            case WM_KEYUP:
                //exit the program
                if(wParam==VK_ESCAPE)
                {
                    DestroyWindow(hwnd);
                }
                return 0;
            case WM_DRAWITEM:
                
                //getting the Draw Item structure
                LPDRAWITEMSTRUCT b;
                b = (LPDRAWITEMSTRUCT) lParam;
                
                //Getting the button visual theme(i get the xp style)
                HTHEME hTheme;
                hTheme = OpenThemeData(hButton, L"button");
                
                //translate the LPDRAWITEMSTRUCT->itemState to DrawThemeBackground int id state
                int c=0;
                if(b->itemState & ODS_HOTLIGHT)
                    c=PBS_HOT;
                else if (b->itemState & ODS_DEFAULT)
                    c=PBS_DEFAULTED;
                else if (b->itemState & ODS_DISABLED)
                    c=PBS_DISABLED;
                else if (b->itemState & ODS_SELECTED)
                    c=PBS_PRESSED;
                else
                    c|=PBS_NORMAL;
                
                //draw the button with right state
                //the state is what the button action can draw to us(click,disable and others)
                DrawThemeBackground(hTheme, b->hDC, BP_PUSHBUTTON, c, &b->rcItem, 0);
                
                //getting and draw icon
                HICON hicon;
                hicon=LoadIcon(NULL,IDI_EXCLAMATION);
                DrawIcon(b->hDC,3,0, hicon);
                
                //before show the text, i need put it transparent(hide the text backcolor)
                SetBkMode(b->hDC,TRANSPARENT);
                
                //i can draw the text with prefix('&')
                //the DT_EXPANDTABS is for show us the '\t' and others
                DrawText(b->hDC,"&hello",-1,&b->rcItem,DT_EXPANDTABS| DT_CENTER);
                return 0;
        }
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
    }
    i only see 1 problem: is showed the button face with windows xp visual style, instead windows 2000 visual style
    what you can tell me?
    (you can test my code, just delete the '#include "Untitled2.h"'(5 line) and change these 'wndclass.hIcon = LoadIcon (NULL, "IDI_ICON");'(24 line))

  8. #8
    Registered User
    Join Date
    Mar 2011
    Posts
    419
    I tried running your code, but my compiler (Pelles) does not like two of the functions:

    OpenThemeData
    DrawThemeBackground

    Are you using XP with the theme set to XP?
    If so, that is why you are getting XP button style frames, I believe.
    I don't see anything in your code that explicitly specifies a classic style.
    You can confirm that by changing the desktop theme to classic and running the program again.

    -

  9. #9
    Registered User
    Join Date
    Aug 2013
    Posts
    138
    Quote Originally Posted by megafiddle View Post
    I tried running your code, but my compiler (Pelles) does not like two of the functions:

    OpenThemeData
    DrawThemeBackground

    Are you using XP with the theme set to XP?
    If so, that is why you are getting XP button style frames, I believe.
    I don't see anything in your code that explicitly specifies a classic style.
    You can confirm that by changing the desktop theme to classic and running the program again.

    -
    and how i can convert to the classic them?(i'm totaly new with these code)
    another important thing: if i use the ownerdraw style, why i lose(isn't activated when i click on button) the WM_COMMAND message?

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    419
    You can right click on the desktop to get the display properties dialog. Then you can change the theme
    there in the "Themes" section. Or you can select "Display" in the control panel to get the same dialog.
    This changes the theme for all windows.

    You need an ID value for the window. For example,

    #define ID_MYBUTTON 1

    //create the button
    hButton=CreateWindowEx (0,"button", "H&ello \nmy mother",
    WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | BS_NOTIFY,
    100, 100,100, 50,hwnd, (HMENU) ID_MYBUTTON, hInstance, 0) ;

    Then check for ID_MYBUTTON in the wParam for the WM_COMMAND message.

    -

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic button controls [WIN32 API/c++/VS 2010]
    By William Putnam in forum Windows Programming
    Replies: 3
    Last Post: 09-10-2013, 09:13 PM
  2. Win32 API , Windows XP Button styles
    By Rare177 in forum Windows Programming
    Replies: 12
    Last Post: 06-28-2006, 05:28 PM
  3. making a standard button in win32
    By psychopath in forum Windows Programming
    Replies: 4
    Last Post: 04-16-2004, 07:34 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21