Drawing custom themed buttons
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Drawing custom themed buttons
Hi,
Apps like Windows Media player add a button to the title bar, that removes the outside frame of its window. Other apps draw a button to minimize to tray. All these are coloured according to the current xp colour theme
I don't want to put one in the title bar. I'd just like a button like the combobox to put next to a get control, which has a browse attached to it.
Has anyone done something like this, or stumbled across a way of doing this?
I don't want to keep a copy of the combo box button as a bmp, because the colours can change.
Alex
Apps like Windows Media player add a button to the title bar, that removes the outside frame of its window. Other apps draw a button to minimize to tray. All these are coloured according to the current xp colour theme
I don't want to put one in the title bar. I'd just like a button like the combobox to put next to a get control, which has a browse attached to it.
Has anyone done something like this, or stumbled across a way of doing this?
I don't want to keep a copy of the combo box button as a bmp, because the colours can change.
Alex
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
XP Button bitmaps
Hi,
I know about those, but I want a button drawn that looks like the xp combobox arrow button. It must also use the colours of the current xp theme (like blue, silver and olive green defaults)
Alex
I know about those, but I want a button drawn that looks like the xp combobox arrow button. It must also use the colours of the current xp theme (like blue, silver and olive green defaults)
Alex
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Themed button
Hi,
Below is some cpp code that does it:
Below is some cpp code that does it:
Code: Select all
TEMPLATE void CDialogMinTrayBtn<BASE>::MinTrayBtnDraw()
{
if (!MinTrayBtnIsVisible())
return;
CDC *pDC= GetWindowDC();
if (!pDC)
return; // panic!
if (IsWindowsClassicStyle())
{
CBrush black(GetSysColor(COLOR_BTNTEXT));
CBrush gray(GetSysColor(COLOR_GRAYTEXT));
CBrush gray2(GetSysColor(COLOR_BTNHILIGHT));
// button
if (m_bMinTrayBtnUp)
pDC->DrawFrameControl(MinTrayBtnGetRect(), DFC_BUTTON, DFCS_BUTTONPUSH);
else
pDC->DrawFrameControl(MinTrayBtnGetRect(), DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED);
// dot
CRect btn = MinTrayBtnGetRect();
btn.DeflateRect(2,2);
UINT caption = MinTrayBtnGetSize().cy + (CAPTION_BUTTONSPACE * 2);
UINT pixratio = (caption >= 14) ? ((caption >= 20) ? 2 + ((caption - 20) / 8) : 2) : 1;
UINT pixratio2 = (caption >= 12) ? 1 + (caption - 12) / 8: 0;
UINT dotwidth = (1 + pixratio * 3) >> 1;
UINT dotheight = pixratio;
CRect dot(CPoint(0,0), CPoint(dotwidth, dotheight));
CSize spc((1 + pixratio2 * 3) >> 1, pixratio2);
dot -= dot.Size();
dot += btn.BottomRight();
dot -= spc;
if (!m_bMinTrayBtnUp)
dot += CPoint(1,1);
if (m_bMinTrayBtnEnabled)
{
pDC->FillRect(dot, &black);
}
else
{
pDC->FillRect(dot + CPoint(1,1), &gray2);
pDC->FillRect(dot, &gray);
}
}
else
{
// VisualStylesXP
CRect btn = MinTrayBtnGetRect();
int iState;
if (!m_bMinTrayBtnEnabled)
iState = TRAYBS_DISABLED;
else if (GetStyle() & WS_DISABLED)
iState = MINBS_NORMAL;
else if (m_bMinTrayBtnHitTest)
iState = (m_bMinTrayBtnCapture) ? MINBS_PUSHED : MINBS_HOT;
else
iState = MINBS_NORMAL;
// inactive
if (!m_bMinTrayBtnActive)
iState += 4; // inactive state TRAYBS_Ixxx
if (m_bmMinTrayBtnBitmap.m_hObject && _TransparentBlt)
{
// known theme (bitmap)
CBitmap *pBmpOld;
CDC dcMem;
if (dcMem.CreateCompatibleDC(pDC) && (pBmpOld = dcMem.SelectObject(&m_bmMinTrayBtnBitmap)) != NULL)
{
_TransparentBlt(pDC->m_hDC, btn.left, btn.top, btn.Width(), btn.Height(), dcMem.m_hDC, 0, BMP_TRAYBTN_HEIGHT * (iState - 1), BMP_TRAYBTN_WIDTH, BMP_TRAYBTN_HEIGHT, BMP_TRAYBTN_TRANSCOLOR);
dcMem.SelectObject(pBmpOld);
}
}
else
{
// unknown theme (ThemeData)
HTHEME hTheme = g_xpStyle.OpenThemeData(m_hWnd, L"Window");
if (hTheme)
{
btn.top += btn.Height() / 8;
g_xpStyle.DrawThemeBackground(hTheme, pDC->m_hDC, WP_TRAYBUTTON, iState, &btn, NULL);
g_xpStyle.CloseThemeData(hTheme);
}
}
}
ReleaseDC(pDC);
}
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
New class help
Hi,
I created a new class based on tpanel, in which the paint event becomes:
DrawQBBackground comes from:
Unfortunately, I don't see anything
Is there a C wizard which can help me out here
I created a new class based on tpanel, in which the paint event becomes:
Code: Select all
METHOD Paint() CLASS QButton
DrawQBBackground(::hWnd, ::hDc)
RETURN NIL
Code: Select all
#include <WinTen.h>
#include <Windows.h>
#include <ClipApi.h>
#ifdef __FLAT__
#include <ShellApi.h>
#endif
#ifdef __HARBOUR__
#include <hbapiitm.h>
#include <hbdate.h>
#include <hbset.h>
#endif
#include "uxtheme.h"
HB_FUNC( DRAWQBBACKGROUND )
{
HTHEME hTheme;
HDC hDc;
HWND hWnd;
RECT rcWnd;
int iStateId = 1;
hWnd = ( HWND ) _parnl( 1 );
hDc = ( HDC ) _parl(2);
GetClientRect( hWnd, &rcWnd );
hTheme = OpenThemeData(hWnd, L"BUTTON");
if ( hTheme)
{
DrawThemeBackground(hTheme,
hDc,
0,
0,
&rcWnd,
NULL);
_retni(1);
}
else
{
_retni(0);
}
}
Is there a C wizard which can help me out here
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: New class help
TryAlexSchaft wrote:Code: Select all
hDc = ( HDC ) _parl(2);
Code: Select all
hDc = ( HDC ) _parnl(2);
EMG
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Themed button working
Thanks, that change works, along with changing the first zero to 1 in the DrawThemeBackground call, and the second parameter is 1 for normal 2 for "hot", 3 for down, and 4 for disabled.
Only problem now is detecting when mouse leaves the control. I've copied the basics from btnbmp:mousemove but no luck so far. What am I missing?
Only problem now is detecting when mouse leaves the control. I've copied the basics from btnbmp:mousemove but no luck so far. What am I missing?
Code: Select all
METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS QButton
// Super:MouseMove( nRow, nCol, nKeyFlags )
if IsOverWnd( ::hWnd, nRow, nCol )
::nState := 2
else
::nState := 1
endif
::Refresh()
return nil
//---------------------------------------------------------------------------------------------//
METHOD Paint() CLASS QButton
// 1 Regular
// 2 Mouse over
// 3 Down
// 4 Disabled
DrawQBBackground(::hWnd, ::hDc, ::nState)
RETURN NIL
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Themed button working
Try adding hb prefix to all the _par* and _ret* functions.
EMG
EMG
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Themed button working
I don't have a problem in my C code anymore. It links and works perfectly. I now need to detect in my control events when the mouse leaves my control.
I suppose you receive mousemove while in the control, but what do you receive when the mouse moves out of the control?
Alex
I suppose you receive mousemove while in the control, but what do you receive when the mouse moves out of the control?
Alex
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Themed button working
Have a look at how tooltips are managed. Or TBtnBmp states.
EMG
EMG
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Got it
Hi,
It's working now, thanks.
It's working now, thanks.
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
- AlexSchaft
- Posts: 172
- Joined: Fri Oct 07, 2005 1:29 pm
- Location: Edenvale, Gauteng, South Africa
Working button
I copied the whole btnbmp mousemove event, and removed everything I didn't need
C Code:
Code: Select all
METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS QButton
if ::lDrag .or. ! Empty( ::oDragCursor )
return Super:MouseMove( nRow, nCol, nKeyFlags )
endif
Super:MouseMove( nRow, nCol, nKeyFlags )
if IsOverWnd( ::hWnd, nRow, nCol )
if !::lCaptured
::Capture()
if ::nState != 2
::nState := 2
::Refresh()
endif
else
::Refresh()
endif
else
if !::lCaptured
ReleaseCapture()
if ::nState != 1
::nState := 1
::Refresh()
endif
else
::Refresh()
endif
endif
::oWnd:SetMsg( ::cMsg )
return 0
//---------------------------------------------------------------------------------------------//
METHOD Paint() CLASS QButton
// 1 Regular
// 2 Mouse over
// 3 Down
// 4 Disabled
DrawQBBackground(::hWnd, ::hDc, ::nState)
RETURN NIL
Code: Select all
#include <WinTen.h>
#include <Windows.h>
#include <ClipApi.h>
#ifdef __FLAT__
#include <ShellApi.h>
#endif
#ifdef __HARBOUR__
#include <hbapiitm.h>
#include <hbdate.h>
#include <hbset.h>
#endif
#include "uxtheme.h"
HB_FUNC( DRAWQBBACKGROUND )
{
HTHEME hTheme;
HDC hDc;
HWND hWnd;
RECT rcWnd;
int iStateId = 1;
hWnd = ( HWND ) _parnl( 1 );
hDc = ( HDC ) _parnl(2);
GetClientRect( hWnd, &rcWnd );
hTheme = OpenThemeData(hWnd, L"COMBOBOX");
if ( hTheme)
{
DrawThemeBackground(hTheme,
hDc,
1,
( ISNUM(3) ? _parni( 3 ) : 1 ),
&rcWnd,
NULL);
CloseThemeData(hTheme);
_retni(1);
}
else
{
_retni(0);
}
}
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact: