programming tools for Windows applications development
  Home  |   SwiftForth Archive  |   SwiftX Archive  |

Re: colored buttons

From: <wheath_at_comcast.net>
Date: Sun, 05 Jun 2005 15:28:09 +0000

I have investigated this problem extensively, and as far as I could find out, in windows this is very difficult. The WM_CTLCOLORBTN message sent to the dialog does NOT work as advertised and the button always gets painted back to its original windows default color. I have tried invalidating the button rectangle,
painting over the rectangle etc and all fail.
Possibly one could "subclass" the button and change its color.
The "Official" way is the create your own [DRAWNBUTTON
button. However, then you have to handle ALL of the messages sent to the button, outline it, color it, change the clicked and unclicked appearance, change the focus rectangle, etc yourself.
Enclosed is some trial code with no guarantees.
Warren
wheath at comcast.net
\ owner draw button owndraw.fth
2 Import: DrawFocusRect ( hdc Arect -> 1 )
9 Import: DrawIconEx ( hdc lt top hicon wid ht 0 0 0 -> 1 )
6000 VALUE NEXTID ( NEXT ID FOR ENUMID )
: ENUMID ( NAME -- )
   NEXTID MKID
   1 +to NEXTID ;
  ENUMID IDOWN
DIALOG ODBOX
[MODAL " " 0 0 350 200
   (+STYLE WS_SYSMENU )
        (FONT 8, Fixedsys ) ] ( 800x800 sm font ok )
[DEFPUSHBUTTON " OK" IDOK 50 5 pbwd pbht ]
[DRAWNBUTTON " OWN" IDOWN 150 5 pbwd pbht
   (+STYLE WS_TABSTOP )
   (-STYLE WS_BORDER ) ( need to elim extra sunken border )
     ]
[PUSHBUTTON " Cancel" IDCANCEL 250 5 pbwd pbht ]
END-DIALOG
Rect subclass TRect ( add width etc )
  : Height ( - -> nht ) bottom @ top @ - 0 max ;
  : Width ( - -> nwid ) right @ left @ - 0 max ;
  : Srect ( nl nt nr nb -> - )
      bottom ! right ! top ! left ! ;
  : Rdim ( - -> left top rwid rht \ used by moverect )
      left @ top @ width height ;
  : Pallrect ( - )
      left @ 5 .r top @ 5 .r right @ 5 .r bottom @ 5 .r
      width 5 .r height 5 .r ;
end-class
\ add to reg Trect later
Trect subclass Subrect
  : -Rect ( ndeltax ndeltay -> - \ shrink or expand rect )
      DUP top +!
      NEGATE bottom +!
      DUP left +!
      NEGATE right +! ;
  : >Rect ( ndeltax ndeltay -> - \ move rect )
      dup top +!
          bottom +!
      DUP left +!
          right +! ;
end-class
class tagdrawitem
  VARIABLE ctlType
  VARIABLE ctlID
  VARIABLE itemID
  VARIABLE itemAction
  VARIABLE itemState
  VARIABLE HwndItem
  VARIABLE hDC
  Subrect builds rcItem
  VARIABLE itemData
end-class
tagdrawitem builds Drawitem
Subrect builds FocRect ( focus rect )
Subrect builds FocRectx ( text rect no select )
Subrect builds FocRectx2 ( text rect moved select )
Subrect builds ButRect ( original )
Subrect builds ButRect1 ( smaller for single width edge )
1 VALUE sedge ( single width edge )
sedge 3 + VALUE focedge ( focus rect indent smallest )
\ 4+ cuts top line of text in small button
0 VALUE pdis ( ptr to drawitem sent )
0 VALUE htft ( font height )
16 VALUE iconsz \ 16 = system size
stringn odtext Owner$
: SvFocrect ( - )
    Drawitem rcItem ButRect Subrect sizeof cmove
    ButRect FocRect Subrect sizeof cmove
    ButRect ButRect1 Subrect sizeof cmove
    FOCEDGE DUP Focrect -Rect
    FocRect FocRectx Subrect sizeof cmove
        1 1 FocRectx -Rect \ so foc rect not hit
    FocRectx height TO iconsz
    FocRectx FocRectx2 Subrect sizeof cmove
        1 DUP FocRectx2 >rect
    sedge dup ButRect1 -Rect ;
: W1UL ( - )
         Drawitem hDC @ ButRect
         EDGE_RAISED BF_TOPLEFT BF_SOFT OR
         DrawEdge DROP ;
: BK1UL ( - )
         Drawitem hDC @ ButRect
         EDGE_SUNKEN BF_TOPLEFT BF_SOFT OR
         DrawEdge DROP ;
: BK2UL ( - )
         BK1UL
         Drawitem hDC @ ButRect1
         EDGE_SUNKEN BF_TOPLEFT BF_SOFT OR
         DrawEdge DROP ;
: BK1BR ( - )
         Drawitem hDC @ ButRect
         EDGE_RAISED BF_BOTTOMRIGHT BF_SOFT OR
         DrawEdge DROP ;
: BK2BR ( - )
         BK1BR
         Drawitem hDC @ ButRect1
         EDGE_RAISED BF_BOTTOMRIGHT BF_SOFT OR
         DrawEdge DROP ;
: ?select ( - -> tf \ t=selected )
    Drawitem itemState @ ODS_SELECTED AND 0<> ;
: ?foc ( - -> tf \ t-focus )
    Drawitem itemState @ ODS_FOCUS AND 0<> ;
: Selrect ( - -> Arect ) ?select
        IF FocRectx2
        ELSE FocRectx
        THEN ;
bkcolor VALUE txcolor \ black normal text face
$FF80FF CONSTANT Pink
Pink VALUE bgcolor
      0 VALUE bgbrush
      0 VALUE hodicon
      0 VALUE odctr
      0 VALUE colorctr
IDI_INFORMATION VALUE odicon
stringn iconame c:\consumer.ico$
: chgcolor ( - )
     1 +to colorctr
     colorctr 1 AND 0=
     IF wcolor
     ELSE Pink
     THEN TO bgcolor ;
: GetIcon ( - )
     NULL odicon LoadIcon TO hodicon ;
: GetIconF ( - )
      NULL
      iconame s>z
      IMAGE_ICON
      0 0
      LR_DEFAULTCOLOR LR_LOADFROMFILE OR
\ LR_DEFAULTSIZE OR \ not neded
      LoadImage TO hodicon ;
: DispIcon ( - \ default size )
     Drawitem hDC @
     FocRect left @ FocRect width 6 10 */ +
     ButRect top @ \ large icons
     hodicon DrawIcon DROP ;
: DispIcon2 ( - )
     Drawitem hDC @
     ButRect left @ ButRect width 6 10 */ +
     ?select
     IF FocRectx2 \ so icon moves with select also
     ELSE FocRectx
     THEN top @
     hodicon
     iconsz dup \ any size ok - will clip if too large
     0 NULL
     DI_NORMAL \ reqd or no display
     DrawIconEx DROP ;
\ chg font by chging dialog font
: Dodraw ( - )
    wparam IDOWN <> IF 0 EXIT THEN \ in case more than 1
    lparam TO pdis
    pdis Drawitem tagdrawitem sizeof CMOVE \ copy it
    GetIconF
    SvFocrect
    bgcolor CreateSolidBrush TO bgbrush
    Drawitem hDC @ ButRect
       bgbrush FillRect drop \ whole background
\ if wht background do foc rect here so gray rect
\ before textcolor set
\ foc rect xor'd so if red text - foc comes out green
    ?foc
    IF Drawitem hDC @ FocRect
         DrawFocusRect drop \ ok
       \ keep at focrect pos or disappears at select
    THEN
    Drawitem hDC @
      txcolor SetTextColor DROP \ ok
    Drawitem hDC @
      bgcolor SetBkColor DROP \ ok
\ must match fillrect color
    Drawitem hDC @ odtext
      Selrect \ inside focus rect
\ DT_CENTER \ w/o icon
      DT_LEFT \ icon to right
      DT_VCENTER OR DT_SINGLELINE OR
      DrawText TO htft
    ?select
    IF BK2UL BK2BR
    ELSE ?foc
      IF BK1UL BK2BR
      ELSE W1UL BK1BR
      THEN
    THEN
    bgbrush DeleteObject DROP
    DispIcon2
    ?select
    IF chgcolor \ click or double click
    THEN
    0 ; \ did it

: INITOD ( - )
  ;

: ODCLOSE ( - )
    DLGCLOSE ;

[SWITCH OD-COMMANDS ZERO ( id# -- res )
   IDOK RUN: DLGCLOSE ;
   IDOWN RUN: 1 +to odctr
                  0 ; \ does get here single clicks too
   IDCANCEL RUN: 0 ( ODCLOSE ) ;
     ( no cancel action so can compare to owner button )
SWITCH]

[SWITCH OD-MESSAGES ZERO
   WM_CLOSE RUN: ODCLOSE ;
   WM_INITDIALOG RUN: ( -- res )
       INITOD
      -1 ;
   WM_COMMAND RUN: ( -- res )
         WPARAM loword
         OD-COMMANDS ; ( ctrl id# )
   WM_DRAWITEM RUNS Dodraw
SWITCH]
\ WM_NOTIFY useless
:NONAME ( -- res ) MSG loword OD-MESSAGES ;
                     4 CB: RUNOD
: ODBOXT ( - )
   HINST ODBOX HWND RUNOD
   0 DialogBoxIndirectParam DROP ;

-------------- Original message --------------

> I have a need to change the color of pushbuttons in a dialog box. For
> example, in the following code, is it possible to make the IDYES pushbutton
> green, and the IDNO pushbutton red? How?
>
>
,

----------------------------------------------------------------------
sftalk_at_forth.com The SwiftForth programming discussion email list
To unsubscribe, send subject "unsubscribe" to sftalk-request_at_forth.com
For list command help, send subject "help" to sftalk-request_at_forth.com
Message archives are located at http://www.forth.com/archive/sftalk
----------------------------------------------------------------------
This list is a forum for SwiftForth users. For product support and bug
reports, please send email to support_at_forth.com
----------------------------------------------------------------------
Received on Sun Jun 05 2005 - 08:26:00 PDT

This archive was generated by hypermail 2.2.0 : Thu Dec 04 2008 - 03:04:20 PST