Author Topic: Colored Button  (Read 1000 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4486
    • Oxygen Basic
Re: Colored Button
« Reply #15 on: December 16, 2020, 05:44:05 pm »
Hi Nicola,

Demo of toggling owner-drawn button. It's all new to me, and required some google and msdn:

the key points are
    style=WS_CHILD | BS_OWNERDRAW
and
  case WM_CTLCOLORBTN
  ...

Code: [Select]


  '$ filename "t.exe"
  'uses RTL64
  $ EscapeKeyEnd
  uses WinUtil

  MainWindow 640,480,WS_OVERLAPPEDWINDOW



  'STANDARD CHILD WINDOWS STYLES
  ==============================
  '
  'Button button.
  'ComboBox combo box.
  'Edit         edit box.
  'ListBox list box.
  'MDIClient MDI client window.
  'ScrollBar scroll bar.
  'Static static control.



  function WndProc(sys hwnd, uMsg, wParam, lParam) as long callback
  =================================================================
  indexbase 0
  RECT rcClient;
  sys i,id,idmenu,style
  static sys hchw[0x200] 'child windows
  string s,stys
  static int bcolor=0xaabbee
 
  select umsg
 
  case WM_CREATE

    idmenu=0
    '
    SetWindowText hwnd,"Owner Draw Button and Edit Box"


    'https://docs.microsoft.com/en-us/windows/win32/controls/wm-ctlcolorbtn
    style=WS_CHILD | BS_OWNERDRAW
    stys="button"
    hchw[0]=CreateWindowEx(0,stys, null, style, 0,0,0,0, hwnd, 100, inst, null)

    style=WS_CHILD | WS_BORDER | WS_VISIBLE
    stys="edit"
     hchw[1]=CreateWindowEx(0,stys, null, style, 0,0,0,0, hwnd, 101, inst, null)
    ShowWindow(hchw[i], SW_SHOW)



  case WM_CTLCOLORBTN

    sys hdc=wparam
    sys hwn=lparam
    RECT rec
    if hwn=hchw[0]
      GetClientRect  hwn,@rec
      sys hbr=CreateSolidBrush bcolor
      FillRect hdc,@rec,hbr
   
      SetBkColor   hdc,bcolor
      SetTextColor hdc,0x90
      DrawText hDC,"Press",-1,@rec,0x25
      DeleteObject hbr
      return hbr
    endif

  case WM_COMMAND

    int id=loword wparam
    int cmd=hiword wparam
    select id
    case 100
      'print str cmd
      bcolor=1-bcolor 'TOGGLE
      SetWindowText hchw[0],"ok"
    end select



  case WM_SIZE   // main window changed size

    RECT rc
    GetClientRect(hwnd, &rc)
    'child window, position x,y  size x.y, show
    MoveWindow(hchw[0], 10,10, 80, 40, TRUE)
    MoveWindow(hchw[1], 10,60, rc.right-20, rc.bottom-70, TRUE)

  case WM_DESTROY:
 
    PostQuitMessage 0

  case else

    return DefWindowProc(hwnd, uMsg, wParam, lParam)
  end select
  '
  end function
« Last Edit: December 16, 2020, 05:53:06 pm by Charles Pegge »

John

  • Hero Member
  • *****
  • Posts: 3966
Re: Colored Button
« Reply #16 on: December 17, 2020, 11:01:57 am »
Windows API programming is like living on a diet of sushi.

In IUP under Windows the button background color attribute is ignored.  :-\

No problem under VB6.
« Last Edit: December 18, 2020, 04:44:02 am by John »

Nicola

  • Jr. Member
  • **
  • Posts: 73
Re: Colored Button
« Reply #17 on: December 21, 2020, 01:43:58 pm »
Hi Charles,
I applied your example to my test program. It seems to be fine.
The only thing I'd like to implement is that when you click on the button you should see the color change effect to give the feeling of being squashed.
...


Code: OxygenBasic
  1. $ filename "Prova_Button.exe"
  2. $ EscapeKeyEnd
  3.  
  4.   uses WinUtil
  5.  
  6.  
  7.   MainWindow 271,118,WS_SYSMENU|WS_MINIMIZEBOX|WS_EX_TOPMOST
  8.  
  9.  
  10.  % HWND_TOPMOST= -1    
  11.                                                
  12.  % IDD_MAIN = 1000
  13.  % IDC_LBL1 = 1001         ' LABEL
  14. % IDC_BTN1 = 1002
  15.  % IDC_BTN2 = 1003
  16.  
  17. global ac as int
  18.  
  19.  
  20.  
  21. function WndProc(sys hWnd, uMsg, wParam, lParam) as long callback
  22.   ================================================================
  23.   static sys style, Lbl1, hBtn1, hBtn2
  24.   static string s
  25.   static int bcolor=0xaabbee, bcol2=0x00FF0000
  26.   RECT rcClient
  27.    
  28.   select umsg
  29.  
  30.         case WM_CREATE
  31.  
  32.    style=WS_CHILD | WS_VISIBLE | ES_CENTER
  33.    Lbl1=CreateWindowEx(0,"Static", "Hello", style, 0, 5, 264, 50, hWnd, IDC_LBL1, inst, null)
  34.  
  35.    'style=WS_CHILD | BS_TEXT | WS_VISIBLE| BS_OWNERDRAW
  36.   style=WS_CHILD | BS_OWNERDRAW
  37.    hBtn1=CreateWindowEx(0,"Button", "Start", style,8, 58, 79, 24, hWnd, IDC_BTN1, inst, null)
  38.    hBtn2=CreateWindowEx(0,"Button", "Stop", style,178, 58, 79, 24, hWnd, IDC_BTN2, inst, null)
  39.  
  40.         SetWindowText hWnd,"Nicola 12/2020"
  41.         SetWindowPos(hWnd, HWND_TOPMOST,1,1,271,118)
  42.         ShowWindow(hbtn1, SW_SHOW)
  43.         ShowWindow(hbtn2, SW_SHOW)  
  44.    
  45.  
  46.   case WM_CTLCOLORBTN
  47.  
  48.     sys hdc=wparam
  49.     sys hwn=lparam
  50.     RECT rec
  51.     GetClientRect  hwn,@rec
  52.     if hwn=hBtn1
  53.       sys hbr=CreateSolidBrush bcolor
  54.       FillRect hdc,@rec,hbr
  55.       SetBkColor   hdc,bcolor
  56.       SetTextColor hdc,0x90
  57.       DrawText hDC,"Start",-1,@rec,0x25
  58.       DeleteObject hbr
  59.       return hbr
  60.     endif
  61.     if hwn=hBtn2
  62.       sys hbr=CreateSolidBrush bcol2
  63.       FillRect hdc,@rec,hbr
  64.       SetBkColor   hdc,bcol2
  65.       SetTextColor hdc,0x0
  66.       DrawText hDC,"Stop",-1,@rec,0x25
  67.       DeleteObject hbr
  68.       return hbr
  69.     endif
  70.  
  71.  
  72.     case WM_COMMAND
  73.  
  74.         select loword(wParam)
  75.                            
  76.             case IDC_BTN1   'start
  77.                if ac=0 then
  78.                     ac=1
  79.                  else
  80.                     ac=0
  81.                  end if
  82.              
  83.          end select
  84.  
  85.     case WM_CLOSE
  86.                 DestroyWindow(hWnd)
  87.  
  88.     case WM_DESTROY
  89.                 DestroyWindow(hWnd)
  90.       PostQuitMessage 0
  91.  
  92.  
  93.     case else
  94.       return DefWindowProc(hWnd, uMsg, wParam, lParam)
  95.  
  96.     end select
  97.  
  98. end function
  99.  
  100.  
  101.  

Nicola

  • Jr. Member
  • **
  • Posts: 73
Re: Colored Button
« Reply #18 on: December 26, 2020, 06:50:22 am »
Hi Charles,
is it possible to implement the push effect on the button?
thanks.

Arnold

  • Hero Member
  • *****
  • Posts: 977
Re: Colored Button
« Reply #19 on: December 31, 2020, 08:05:16 am »
This is a small example of a Standard and a Color Button. The demo will run in 32-bit and 64-bit mode. In the o2 distribution there is examples\WinDynDialogs\Ownerdrawn.o2bas and examples\WinGui\UniversalButton.o2bas. If you combine the principles of the examples, then a lot is possible.

Std_and_ClrBtn.o2bas
Code: [Select]
// Standard Button and Color (Owner Drawn) Button

$ filename "Std_and_ClrBtn.exe"
'uses rtl32
'uses rtl64

$ EscapeKeyEnd
uses WinUtil

% EDGE_RAISED=5
% EDGE_SUNKEN=10
% BF_RECT=15
% WM_DRAWITEM=43
% ETO_OPAQUE=2
% ETO_CLIPPED=4
% ODS_SELECTED=1
% GWL_HINSTANCE -6

type SIZE
  long cx
  long cy
end type

type DRAWITEMSTRUCT 
    UINT CtlType
    UINT CtlID
    UINT itemID
    UINT itemAction
    UINT itemState
    sys  hwndItem
    sys  hDC
    RECT rcItem
    sys  itemData        'ulong_ptr
end type


% IDB_BUTTON  100
sys hWndStdButton

% IDC_OWNERDRAWN  1000
sys hWndClrButton

MainWindow 240, 120 , WS_OVERLAPPEDWINDOW

function WndProc(sys hwnd, uint MainMsg, sys wParam, lParam) as sys callback
    select case MainMsg

        case WM_CREATE
            SetWindowText(hwnd, "Buttons")

            sys hInstance = GetWindowLongPtr(hWnd, GWL_HINSTANCE)

            hWndStdButton = CreateWindowEx(
            0,
            "BUTTON",
            "Standard Button",
            WS_VISIBLE or WS_CHILD,
            10,  10,
            120, 24,
            hWnd,
            IDB_BUTTON,
            hInstance,
            NULL)

            hWndClrButton = CreateWindowEx(
            0,
            "BUTTON",
            NULL,
            WS_CHILD or BS_OWNERDRAW,
            10,  40,
            120, 24,
            hWnd,
            IDC_OWNERDRAWN,
            GetWindowLongPtr(hWnd, GWL_HINSTANCE),
            NULL)

            if not hWndClrButton then
                MessageBox(NULL, "Button Creation Failed.", "Error", MB_OK or MB_ICONERROR)
                return 0
            end if

            ShowWindow(hWndClrButton, SW_SHOW)

        case WM_DRAWITEM
            select case wParam
                case IDC_OWNERDRAWN

                    'get the pointer to the item-drawing info
                    DRAWITEMSTRUCT *ptDrawItem
                    &ptDrawItem=lParam
                   
                    ' alternative
                    'DRAWITEMSTRUCT ptDrawItem at lParam                   

                    SIZE siz
                    string text
                    text = "Color Button"
                    GetTextExtentPoint32(ptDrawItem.hDC, text, len(text), &siz)
                    SetTextColor(ptDrawItem.hDC, WHITE)
                    SetBkColor(ptDrawItem.hDC, RED)

                    ExtTextOut(ptDrawItem.hDC,
                    ((ptDrawItem.rcItem.right - ptDrawItem.rcItem.left) - siz.cx) \ 2,
                    ((ptDrawItem.rcItem.bottom - ptDrawItem.rcItem.top) - siz.cy) \ 2,
                    ETO_OPAQUE or ETO_CLIPPED, &ptDrawItem.rcItem, text, len(text), NULL)

                    uint edge
                    if ptDrawItem.itemState and ODS_SELECTED then
                      edge = EDGE_SUNKEN
                    else
                      edge = EDGE_RAISED
                    end if   
                    DrawEdge(ptDrawItem.hDC, &ptDrawItem.rcItem,
                    edge, BF_RECT)               
            end select


        case WM_COMMAND
            select case loword(wParam)
                case IDB_BUTTON
                    select case hiword(wParam)
                        case BN_CLICKED
                            MessageBox(NULL, "Selected Standard Button", "Standard Button", MB_OK or MB_ICONINFORMATION)
                    end select
                case IDC_OWNERDRAWN
                    select case hiword(wParam)
                        case BN_CLICKED
                            MessageBox(NULL, "Selected Color Button", "Color Button", MB_OK or MB_ICONINFORMATION)
                    end select
            end select

        case WM_CLOSE
            DestroyWindow(hWnd)

        case WM_DESTROY
            PostQuitMessage(0)

        case else
            return DefWindowProc(hWnd, MainMsg, wParam, lParam)
    end select

    return 0
end function

John

  • Hero Member
  • *****
  • Posts: 3966
Re: Colored Button
« Reply #20 on: December 31, 2020, 08:32:47 am »
Welcome back!

I was worried about you when you didn't respond to the e-mail I sent you seeing if you were okay