Page 1 of 1

BTNBMP with windows style

Posted: Thu Mar 19, 2015 9:21 am
by AntoninoP
Hello,
looking around the fivewin code I found the wrapper for use of theme data of windows, I used it some time ago for a my project in C++.
So I think it would be great if the btnbmp uses this procedures (and DrawFrameControl) to paint itself.
Here an example of result:
Image

here an example of use:

Code: Select all

#include "fivewin.ch"

function main()

   local oDlg, theme
   

   DEFINE WINDOW oDlg FROM  0,0 TO 300,300 PIXEL TITLE "Test"
   @ 10,10 SAY "custom" PIXEL
   TThemed():New(30,10,oDlg)
   @ 10,110 SAY "Button" PIXEL
   @ 30,110 BUTTON "" SIZE 64,64 OF oDlg PIXEL
   @ 110,10 SAY "BTNBMP" PIXEL
   @ 130,10 BTNBMP SIZE 64,64 OF oDlg PIXEL
   @ 110,110 SAY "BTNBMP 2007" PIXEL
   @ 130,110 BTNBMP SIZE 64,64 OF oDlg PIXEL 2007

   ACTIVATE WINDOW oDlg CENTERED

return nil

//----------------------------------------------------------------------------//

CLASS TThemed FROM TControl
   DATA theme
   DATA lMOver AS LOGICAL
   DATA lMDown AS LOGICAL
   CLASSDATA lRegistered AS LOGICAL
   METHOD New( nRow, nCol, oWnd, nWidth, nHeight ) CONSTRUCTOR
   METHOD End() INLINE ::Destroy()
   METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0

   METHOD Destroy()
   METHOD Paint()
   
   METHOD MouseLeave( nRow, nCol, nFlags )
   METHOD MouseMove( nRow, nCol, nKeyFlags )
   METHOD LButtonDown( nRow, nCol )
   METHOD LButtonUp( nRow, nCol )
   
   METHOD HandleEvent( nMsg, nWParam, nLParam )
   
ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( nRow, nCol, oWnd, nWidth, nHeight ) CLASS TThemed
   DEFAULT nRow := 10, nCol := 10, oWnd := GetWndDefault(), nWidth := 64, nHeight := 64
   ::oWnd    = oWnd
   ::nId     = ::GetNewId()
   ::nStyle  = nOR( WS_CHILD, WS_VISIBLE, WS_TABSTOP )
   ::nTop    = nRow
   ::nLeft   = nCol
   ::nBottom = ::nTop + nHeight - 1
   ::nRight  = ::nLeft + nWidth
   ::lDrag   = .F.                
   ::lMOver  = .F.
   ::lMDown  = .F.
   
   ::theme   = C5_OpenThemeData(oWnd:hWnd,"BUTTON")
   ::Register( nOR( CS_VREDRAW, CS_HREDRAW ) )
   ::Create()
   oWnd:AddControl( Self )

return Self

METHOD Destroy() CLASS TThemed
   if ::theme!=0
      C5_CloseThemeData(::theme)
   endif
return ::Super:Destroy()

METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TThemed
   if ! ::lMOver
      ::lMOver = .T.
      ::Refresh()
   endif
   TrackMouseEvent( ::hWnd, /*TME_LEAVE*/2 )
return 0

METHOD MouseLeave( nRow, nCol, nFlags ) CLASS TThemed
   ::lMOver = .F.
   ::Refresh()
return nil

METHOD LButtonDown( nRow, nCol ) CLASS TThemed
   ::lMDown = .T.
   ::Refresh()
return nil
METHOD LButtonUp( nRow, nCol ) CLASS TThemed
   ::lMDown = .F.
   ::Refresh()
return nil

// DrawThemeBackground constants
#define BP_PUSHBUTTON 1
#define PBS_NORMAL 1
#define PBS_HOT 2
#define PBS_PRESSED 3
// DrawFrameControl constants
#define DFC_BUTTON 4
#define DFCS_HOT 0x1000
#define DFCS_PUSHED 0x0200
#define DFCS_BUTTONPUSH 0x0010

METHOD Paint() CLASS TThemed
   local oBrush
   //local aInfo := ::DispBegin()
   local nState
   //FillRect( ::hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush )
   ::PaintBack(::hDC)

   if ::theme!=0
      if ::lMOver
         if ::lMDown
            C5_DrawThemeBackground(::theme,::hDC, BP_PUSHBUTTON,PBS_PRESSED,GetClientRect( ::hWnd ),)
         else
            C5_DrawThemeBackground(::theme,::hDC, BP_PUSHBUTTON,PBS_HOT,GetClientRect( ::hWnd ),)
         endif
      else
         C5_DrawThemeBackground(::theme,::hDC, BP_PUSHBUTTON,PBS_NORMAL,GetClientRect( ::hWnd ),)
      endif
   else
      nState := DFCS_BUTTONPUSH
      if ::lMOver
         if ::lMDown
            nState := nOR( nState, DFCS_PUSHED)
         else
            nState := nOR( nState, DFCS_HOT)
         endif
      endif
      DrawFrameControl(::hDC,GetClientRect( ::hWnd ), DFC_BUTTON, nState)
   endif
   //::DispEnd( aInfo )
return


METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TThemed

   if nMsg == 794//WM_THEMECHANGED
      if ::theme!=0
         C5_CloseThemeData(::theme)
      endif
      ::theme   = C5_OpenThemeData(::oWnd:hWnd,"BUTTON")
      ::Refresh()
   endif

   if nMsg == 675//WM_MOUSELEAVE
      ::MouseLeave( nHiWord( nLParam ), nLoWord( nLParam ), nWParam )
   endif

return ::Super:HandleEvent( nMsg, nWParam, nLParam )
anyone agree with me?
Antonino Perricone

Re: BTNBMP with windows style

Posted: Thu Mar 19, 2015 1:07 pm
by Antonio Linares
Antonino,

They look very nice, congratulations! a great work

Do you think that you could include your code in Class TBtnBmp ? I appreciate if you review it yourself.

If you don't have the most recent btnbmp.prg I will send it to you, many thanks! :-)

Re: BTNBMP with windows style

Posted: Fri Jun 05, 2015 11:47 am
by Silvio.Falconi
I think it can be use d also to create CHECKBOX on xbrowse ( no use bitmaps instead)
with the paramter BP_CHECKBOX

#define CBS_CHECKEDDISABLED 8
#define CBS_CHECKEDHOT 6
#define CBS_CHECKEDNORMAL 5
#define CBS_CHECKEDPRESSED 7
#define CBS_MIXEDDISABLED 12
#define CBS_MIXEDHOT 10
#define CBS_MIXEDNORMAL 9
#define CBS_MIXEDPRESSED 11
#define CBS_UNCHECKEDDISABLED 4
#define CBS_UNCHECKEDHOT 2
#define CBS_UNCHECKEDNORMAL 1
#define CBS_UNCHECKEDPRESSED 3
#define DFCS_BUTTONCHECK 0
#define DFCS_CHECKED 1024
#define DFCS_FLAT 16384



C5_DrawThemeBackground( hTheme, hDC, BP_CHECKBOX, if( n==0,CBS_UNCHECKEDNORMAL,CBS_CHECKEDNORMAL) , GetClientRect( ::hWnd ) )

thii is my cent...

Re: BTNBMP with windows style

Posted: Fri Jun 05, 2015 11:48 am
by Antonio Linares
Antonino's enhancements have been included in FWH 15.05 :-)

* Enhancement TBTNBMP. Now btnbmp also can use the selected Desktop theme.
Themes are applied only to btnbmps not defined with 2007 or 2010 or FlatStyles.
Changing desktop theme when the application is running repaints the
themed buttons using the current theme selected.

Usage:
Global Setting: TBtnBmp():lDefaultTheme := lOnOff // default .f.
From the time this class data is set to true, all BtnBmp created (without
200? or flat style) are painted using the selected theme.

Individual buttons can also be set as themed or not themed by setting
oBtn:SetThemed( lOnOff ), overriding the global setting.

Thanks to Mr Antonio Perricone.
http://forums.fivetechsupport.com/viewt ... 22&t=30403

Many thanks Antonino! :-)

Re: BTNBMP with windows style

Posted: Mon Jun 08, 2015 2:20 pm
by AntoninoP
Silvio.Falconi wrote:I think it can be use d also to create CHECKBOX on xbrowse ( no use bitmaps instead)
with the paramter BP_CHECKBOX
Hi,
for xBrowse the modification is very complex.
Here a work-around:

Code: Select all

#include <fivewin.ch>

function main()

   local oDlg, oList, nSel, aBtm
   
   DEFINE WINDOW oDlg FROM  0,0 TO 300,300 PIXEL TITLE "Test"
   aBtm := GetCheckBoxes(oDlg)
   @ 10,10 LISTBOX oList VAR nSel MULTISEL OF oDlg ;
      SIZE 200,200 PIXEL;
      ITEMS {"Item 1","Item 2","Item 3","Item 4","Item 5","Item 6","Item 7","Item 8"};
      BITMAPS aBtm ;
        ON DRAWITEM ( IIF(aScan(oList:GetSelItems(),nItem)>0, 2, 1) )
   ACTIVATE WINDOW oDlg CENTERED

return nil

#define DFC_BUTTON 4
#define DFCS_BUTTONCHECK        0x0000
#define DFCS_CHECKED            0x0400
#define BP_CHECKBOX 3
#define CBS_UNCHECKEDNORMAL 1
#define CBS_CHECKEDNORMAL 5

function GetCheckBoxes(oWnd)
   LOCAL hDCMem, hBmpMem := {Nil,Nil},i, tmp
   LOCAL FCStates := {DFCS_BUTTONCHECK,nOr(DFCS_BUTTONCHECK,DFCS_CHECKED)}
   LOCAL TMStates := {CBS_UNCHECKEDNORMAL,CBS_CHECKEDNORMAL}
   LOCAL oTheme := 0
   if IsAppThemed()
      oTheme   = C5_OpenThemeData(oWnd:hWnd,"BUTTON")
   endif
      
   for i:=1 to 2 
      hDCMem := CreateCompatibleDC( oWnd:GetDC() )
      hBmpMem[i] := CreateCompatibleBitmap( oWnd:GetDC(), 16, 16 )
      tmp := SelectObject( hDCMem, hBmpMem[i] )
      
      FillRect( hDCMem,{0,0,16,16}, GetStockObject( 0 ) )
      if oTheme != 0
         C5_DrawThemeBackground(oTheme, hDCMem, BP_CHECKBOX,TMStates[i],{1,1,15,15})
      else
         DrawFrameControl(hDCMem,{1,1,15,15}, DFC_BUTTON,FCStates[i])
      endif
      SelectObject( hDCMem, tmp )
      DeleteDC( hDCMem )
   next
   
   if oTheme!=0
      C5_CloseThemeData(oTheme)
   endif
   
return hBmpMem
It consists to create the bitmaps using C5_DrawThemeBackground and DrawFrameControl.
Here a screen shot
Image

regards,
Antonino

Re: BTNBMP with windows style

Posted: Thu Jun 11, 2015 10:42 am
by Silvio.Falconi
yes
I thinked it could be made....
you're a big

Re: BTNBMP with windows style

Posted: Thu Jun 11, 2015 10:57 am
by Silvio.Falconi
Antonino,
to move an item -> change the position Up and Down

Code: Select all

function SwapUpArray( aArray, nPos )

   local uTmp

   DEFAULT nPos   := len( aArray )

   if nPos <= len( aArray ) .and. nPos > 1
      uTmp              := aArray[nPos]
      aArray[nPos]      := aArray[nPos - 1 ]
      aArray[nPos - 1 ] := uTmp
   end if

return nil

/*_____________________________________________________________________________*/

function SwapDwArray( aArray, nPos )

   local uTmp

   DEFAULT nPos   := len( aArray )

   if nPos < len( aArray ) .and. nPos > 0
      uTmp              := aArray[nPos]
      aArray[nPos]      := aArray[nPos + 1 ]
      aArray[nPos + 1 ] := uTmp
   end if

return nil