XP Style



  • danke dir für den quellcode... Hab da aber mal noch ne frage... es scheint eigentlich zu gehen... eigentlich hem... ich sehe nämlich nichts vom Button außer der schrift "OK" habe eigentlich alles so gemacht wie Du es beschrieben hast... Ich schicke mal ein wenig Quellcode

    // XPBUTTON.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "XPStyle.h"
    #include "XPBUTTON.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON
    IMPLEMENT_DYNAMIC(CXPBUTTON, CButton)
    
    CXPBUTTON::CXPBUTTON(): m_theme(GetSafeHwnd(), L"BUTTON") 
    
    {
    }
    
    CXPBUTTON::~CXPBUTTON()
    {
    }
    
    BEGIN_MESSAGE_MAP(CXPBUTTON, CButton)
    	//{{AFX_MSG_MAP(CXPBUTTON)
    	ON_WM_ERASEBKGND()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON message handlers
    
    void CXPBUTTON::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {
    	// wird aufegrufen vom Framework wegen ownerdraw-style 
        CDC dc; 
        dc.Attach(lpDrawItemStruct->hDC); 
        CString strCaption; 
        GetWindowText(strCaption); 
        m_theme.DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_HOT, &lpDrawItemStruct->rcItem, 0); 
        int nOldBkgnMode = dc.SetBkMode(TRANSPARENT); 
        dc.DrawText(strCaption, &lpDrawItemStruct->rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
        dc.SetBkMode(nOldBkgnMode); 
        dc.Detach(); 
    
    }
    
    BOOL CXPBUTTON::OnEraseBkgnd(CDC* pDC) 
    {
    	// wir zeichnen nichts, weil wir das fenster mit den button 
        // komplett in DrawItem zeichnen 
        // ausserdem verhindern wir dadurch flickern da der standard hintergrund 
        // weiss gezeichnet wird 
        return TRUE;
    }
    
    #if !defined(AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_)
    #define AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // XPBUTTON.h : header file
    //
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON window
    
    class CXPBUTTON : public CButton
    {
    	DECLARE_DYNAMIC(CXPBUTTON)	
    // Construction
    public:
    	CXPBUTTON();
    
    // Attributes
    public:
    
    // Operations
    public:
    
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CXPBUTTON)
    	public:
    	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    	//}}AFX_VIRTUAL
    
    // Implementation
    public:
    	virtual ~CXPBUTTON();
    
    private:
    	CXPTheme m_theme;
    
    	// Generated message map functions
    protected:
    	//{{AFX_MSG(CXPBUTTON)
    	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    	//}}AFX_MSG
    
    	DECLARE_MESSAGE_MAP()
    };
    
    /////////////////////////////////////////////////////////////////////////////
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_)
    
    // stdafx.h : include file for standard system include files,
    //  or project specific include files that are used frequently, but
    //      are changed infrequently
    //
    
    #if !defined(AFX_STDAFX_H__8277A099_2BD2_4DC9_ADFA_572AF7763D2F__INCLUDED_)
    #define AFX_STDAFX_H__8277A099_2BD2_4DC9_ADFA_572AF7763D2F__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
    #define _WIN32_WINNT 0x0501
    #include <afxwin.h>         // MFC core and standard components
    #include <afxext.h>         // MFC extensions
    #include <afxdisp.h>        // MFC Automation classes
    #include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
    #ifndef _AFX_NO_AFXCMN_SUPPORT
    #include <afxcmn.h>			// MFC support for Windows Common Controls
    #endif // _AFX_NO_AFXCMN_SUPPORT
    
    #include "XPTheme.h"
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_STDAFX_H__8277A099_2BD2_4DC9_ADFA_572AF7763D2F__INCLUDED_)
    
    // XPStyleDlg.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "XPStyle.h"
    #include "XPStyleDlg.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    #include "XPBUTTON.h"
    /////////////////////////////////////////////////////////////////////////////
    // CXPStyleDlg dialog
    
    CXPStyleDlg::CXPStyleDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CXPStyleDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CXPStyleDlg)
    	//}}AFX_DATA_INIT
    	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CXPStyleDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CXPStyleDlg)
    	DDX_Control(pDX, IDOK, m_MyXPButton);
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CXPStyleDlg, CDialog)
    	//{{AFX_MSG_MAP(CXPStyleDlg)
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPStyleDlg message handlers
    
    BOOL CXPStyleDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Set the icon for this dialog.  The framework does this automatically
    	//  when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    
    	// TODO: Add extra initialization here
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    // If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.
    
    void CXPStyleDlg::OnPaint() 
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // device context for painting
    
    		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialog::OnPaint();
    	}
    }
    
    // The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CXPStyleDlg::OnQueryDragIcon()
    {
    	return (HCURSOR) m_hIcon;
    }
    
    // XPStyleDlg.h : header file
    //
    
    #if !defined(AFX_XPSTYLEDLG_H__016FCC2C_E80E_4781_B6BE_52B12609424C__INCLUDED_)
    #define AFX_XPSTYLEDLG_H__016FCC2C_E80E_4781_B6BE_52B12609424C__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    #include "XPBUTTON.h"
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPStyleDlg dialog
    
    class CXPStyleDlg : public CDialog
    {
    // Construction
    public:
    	CXPStyleDlg(CWnd* pParent = NULL);	// standard constructor
    
    // Dialog Data
    	//{{AFX_DATA(CXPStyleDlg)
    	enum { IDD = IDD_XPSTYLE_DIALOG };
    	CXPBUTTON	m_MyXPButton;
    	//}}AFX_DATA
    
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CXPStyleDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
    	//}}AFX_VIRTUAL
    
    // Implementation
    protected:
    	HICON m_hIcon;
    
    	// Generated message map functions
    	//{{AFX_MSG(CXPStyleDlg)
    	virtual BOOL OnInitDialog();
    	afx_msg void OnPaint();
    	afx_msg HCURSOR OnQueryDragIcon();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_XPSTYLEDLG_H__016FCC2C_E80E_4781_B6BE_52B12609424C__INCLUDED_)
    

    So das war es denke ich mal... also eigentlich so wie Du es mir geschrieben hattest... Aber wie schon geschrieben bekomme ich keinen Button gezeigt sondern nur den Text. Der Button funktioniert aber wenn ich in den bereich klicke... Seltsam 😮 ...



  • Hi,

    der code funktioniert bei mir so wie er soll. Hast Du vielleicht den Designdienst
    unter XP abgeschaltet?
    Debugge mal die Funktion DrawItem. Was liefert DrawBackground zurück?
    Der Rückgabewert muss S_OK sein, sonst ist da was nicht in Ordnung.

    Gruss
    EB



  • bei:
    m_theme.DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_DEFAULTED, &lpDrawItemStruct->rcItem, 0);

    kommt ein wert von -2147024890 glaube nicht das der richtig ist, also das da irgendetwas falsch läuft... ausgeschaltet dürfte er aber nicht sein, weil der ThemenExplorer con codeguro auch funktioniert... muss ich vieleicht noch wm_themenchange behandeln?



  • bei:
    m_theme.DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_DEFAULTED, &lpDrawItemStruct->rcItem, 0);

    kommt ein wert von -2147024890 glaube nicht das der richtig ist, also das da irgendetwas falsch läuft... ausgeschaltet dürfte er aber nicht sein, weil der ThemenExplorer con codeguro auch funktioniert... muss ich vieleicht noch wm_themenchange behandeln?



  • sorry mein explorer hat grad gesponnen... Deshalb sind die einträge jetzt doppelt!!! 😞



  • habe es nochmal debugt und habe außer das :

    m_theme.DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_DEFAULTED, &lpDrawItemStruct->rcItem, 0);

    einen komischen wert zurückliefert noch festgestellt, das m_hTheme selber NULL :

    - m_theme {...}
    m_hTheme 0x00000000 -> warum null oder ist das so?
    + m_hThemeDll 0x5b0f0000
    m_bLoaded 1
    m_pOpenThemeData 0x5b0f7cb8
    m_pCloseThemeData 0x5b0f4940
    m_pDrawThemeBackground 0x00000000
    m_pDrawThemeText 0x00000000
    m_pGetThemeBackgroundContentRect 0x00000000
    m_pGetThemeBackgroundExtent 0x00000000
    m_pGetThemePartSize 0x00000000
    m_pGetThemeTextExtent 0x00000000
    m_pGetThemeTextMetrics 0x00000000
    m_pGetThemeBackgroundRegion 0x00000000
    m_pHitTestThemeBackground 0x00000000
    m_pDrawThemeEdge 0x00000000
    m_pDrawThemeIcon 0x00000000
    m_pIsThemePartDefined 0x00000000
    m_pIsThemeBackgroundPartiallyTransparent 0x00000000
    m_pGetThemeColor 0x00000000
    m_pGetThemeMetric 0x00000000
    m_pGetThemeString 0x00000000
    m_pGetThemeBool 0x00000000
    m_pGetThemeInt 0x00000000
    m_pGetThemeEnumValue 0x00000000
    m_pGetThemePosition 0x00000000
    m_pGetThemeFont 0x00000000
    m_pGetThemeRect 0x00000000
    m_pGetThemeMargins 0x00000000
    m_pGetThemeIntList 0x00000000
    m_pGetThemePropertyOrigin 0x00000000
    m_pSetWindowTheme 0x00000000
    m_pGetThemeFilename 0x00000000
    m_pGetThemeSysColor 0x00000000
    m_pGetThemeSysColorBrush 0x00000000
    m_pGetThemeSysBool 0x00000000
    m_pGetThemeSysSize 0x00000000
    m_pGetThemeSysFont 0x00000000
    m_pGetThemeSysString 0x00000000
    m_pGetThemeSysInt 0x00000000
    m_pIsThemeActive 0x00000000
    m_pIsAppThemed 0x00000000
    m_pGetWindowTheme 0x00000000
    m_pEnableThemeDialogTexture 0x00000000
    m_pIsThemeDialogTextureEnabled 0x00000000
    m_pGetThemeAppProperties 0x00000000
    m_pSetThemeAppProperties 0x00000000
    m_pGetCurrentThemeName 0x00000000
    m_pGetThemeDocumentationProperty 0x00000000
    m_pDrawThemeParentBackground 0x00000000
    m_pEnableTheming 0x00000000



  • also m_theme darf nicht null sein. bei initialisierung von :

    IMPLEMENT_DYNAMIC(CXPBUTTON, CButton)
    
    CXPBUTTON::CXPBUTTON(): m_theme(GetSafeHwnd(), L"BUTTON") 
    
    {
    }
    

    bekommt m_theme NULL, da GetSafeHwnd() null zurückliefert, da der Button bzw. die Dialogbox noch nicht existiert irgendwie :

    + m_theme {...}
    + this 0x0012fe90 {CXPBUTTON hWnd=0x00000000}
    CButton::CButton returned <void>
    CWnd::GetSafeHwnd returned 0x00000000
    CXPTheme::CXPTheme returned <void>

    Hem.... Habe nun in DrawItem die Zeile:

    CXPTheme m_theme(GetSafeHwnd(), L"BUTTON");
    

    eingefügt. und es funktioniert... Warum das ganze so ist verstehe ich schon... aber wozu schreibe ich denn dann das ganze so:

    IMPLEMENT_DYNAMIC(CXPBUTTON, CButton)
    
    CXPBUTTON::CXPBUTTON(): m_theme(GetSafeHwnd(), L"BUTTON") 
    
    {
    }
    


  • Hi,

    ich habe den code auch mal debugt. GetSafeHwnd liefert natürlich NULL weil
    es im Konstruktor aufgerufen wird und das Fenster dann noch nicht existiert.

    Trotzdem wird bei mir ein gültiges themehandle gesetzt (zumindest im Debug-Mode)
    warum auch immer da ein Unterschied bei dir ist, liegt wohl tiefer im
    Betriebssystem (XP Professionell SP2), aber du hast recht das es so nicht
    richtig ist.

    Da DrawItem im laufe des Programms sehr oft aufgerufen wird, ist es ziemlicher
    Overkill jedesmal ein Objekt vom Typ CXPTheme zu erzeugen, auch wenn das
    auf modernen schnellen Rechnern nicht so auffält.

    Um es dennoch mit der Membervariable zu machen, bleibt dann wohl nichts anderes
    übrig als diese zu Laufzeit dynamisch zu erzeugen.

    Bei einem abgeleiteten Button am besten in PreSubclassWindow

    IMPLEMENT_DYNAMIC(CXPButton, CButton)
    CXPButton::CXPButton()
    : m_pTheme(NULL)
    {
    }
    
    CXPButton::~CXPButton()
    {
    	delete m_pTheme;
    }
    
    void CXPButton::PreSubclassWindow()
    {
    	m_pTheme = new CXPTheme(GetSafeHwnd(), L"BUTTON");
    
    	CButton::PreSubclassWindow();
    }
    

    Gruss
    EB



  • habe es geändert. weil mit dem Overkill hast Du schon recht... Jetzt steht bei m_theme auch etwas drin, also ist nicht mehr NULL. nur leider geht es dann auch nicht. wie gesagt: nur wenn ich die zeile:

    CXPTheme m_theme(GetSafeHwnd(), L"BUTTON");
    

    in die DrawItem function schreibe... ist ganz schön seltsam... 😕



  • habe jetzt in der Function PreSubClassWindow() folgendes geändert:

    void CXPBUTTON::PreSubclassWindow() 
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	 m_pTheme = CXPTheme(GetSafeHwnd(), L"BUTTON"); 
    
    	CButton::PreSubclassWindow();
    }
    

    und das:

    delete m_pTheme;
    

    habe ich gelöscht... Danach ging es auf einmal... 😕

    Noch mal nur so ne andere Frage...

    um den Status des Buttons muss ich mich jetzt selbst kümmern oder gibt es da vieleicht noch ne einfachere Methode? ich wollte es mit wm_mousemove in verbindung mit der drawitem Methode machen und so abfragen ob sich die mause über dem button befindet, um dann das aussehen auf BPS_HOT zu stellen...?



  • darkangel76 schrieb:

    habe jetzt in der Function PreSubClassWindow() folgendes geändert:

    void CXPBUTTON::PreSubclassWindow() 
    {
    	// TODO: Add your specialized code here and/or call the base class
    	
    	 m_pTheme = CXPTheme(GetSafeHwnd(), L"BUTTON"); 
    	
    	CButton::PreSubclassWindow();
    }
    

    und das:

    delete m_pTheme;
    

    Du hast in der Header datei aus CXPTheme m_theme wohl keinen Zeiger
    gemacht!
    Das hatte ich eigentlich als Grundwissen vorausgesetzt...
    Es muss im Heáder folgendes stehen:

    private:
       CXPTheme*  m_pTheme;
    

    Danach klappt die Speicherzuweisung mit new und das freigeben mit delete.

    darkangel76 schrieb:

    um den Status des Buttons muss ich mich jetzt selbst kümmern oder gibt es da vieleicht noch ne einfachere Methode? ich wollte es mit wm_mousemove in verbindung mit der drawitem Methode machen und so abfragen ob sich die mause über dem button befindet, um dann das aussehen auf BPS_HOT zu stellen...?

    Stimmmt, das gehört jetzt alles Dir 😋 und wird alles in DrawItem
    gemacht. Sieh dir dazu die MSDN an was alles in der Struktur lpDrawItemStruct
    drinsteckt, dann kannst Du entscheiden wie und was Du zeichnest in DrawItem.

    Gruss
    EB



  • Hab jetzt soweit alles fertig. auch das der Button auf Mouseleave reagiert u. so... hat nur noch einen kleinen Grafik fehler... der button sieht ein wenig nach mehrmaliegen rüberfahren mit der maus oder beim durchlaufen mit der Tastatur wie ein eingestampf aus - falls du weist was ich meine... wenn ich das fenster minimiere und dann wieder groß mache ist er wieder normal... Na mal schauen ob ich das noch wegbekomme 😕

    Danke Dir aber janz dolle...



  • 😕

    Ich stelle mal meinen Quellcode von meinem CXPButton rein... Vieleicht kann mir ja jemand sagen warum mein Button nachdem ich mit meiner Maus ein paar mal rüber gefahren bin irgendwie so aussieht als ob er tiefergesetzt wurde... Ist schon merkwürdig... man könnte zwar im Hauptprogramm dann über nen wm_mousemove abfragen wo sich der zeiger befindet und dann den kompletten Dialog neu zeichnen, aber ich wollte eigentlich alles in meiner CXPButton Klasse unterbringen. So das man sich beim einbinden keinen Kopf mehr machen muss... erst recht wenn es am ende dann vieleicht 10 Button und noch anderer kram ist... kann man das ganze vieleicht mit nem Sendmessage ans Dialogfenster in "onMouseLeave" erreichen? und wenn ja wie?

    // XPBUTTON.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "XPStyle.h"
    #include "XPBUTTON.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    #define ODS_NOFOCUSRECT     0x0200
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON
    IMPLEMENT_DYNAMIC(CXPBUTTON, CButton)
    
    CXPBUTTON::CXPBUTTON(): m_pTheme(NULL) 
    
    {
    	bMouseOverButton = false;
    }
    
    CXPBUTTON::~CXPBUTTON()
    {
    }
    
    BEGIN_MESSAGE_MAP(CXPBUTTON, CButton)
    	//{{AFX_MSG_MAP(CXPBUTTON)
    	ON_WM_ERASEBKGND()
    	ON_WM_MOUSEMOVE()
    	//}}AFX_MSG_MAP
    	ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON message handlers
    
    void CXPBUTTON::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {
    	// wird aufegrufen vom Framework wegen ownerdraw-style 
    
    	CDC dc; 
        dc.Attach(lpDrawItemStruct->hDC); 
        CString strCaption; 
        GetWindowText(strCaption); 
        if (m_pTheme.IsAppThemed())
    	{			
    		// button state
    		BOOL bIsPressed =	(lpDrawItemStruct->itemState & ODS_SELECTED);
    		BOOL bIsFocused  = (lpDrawItemStruct->itemState & ODS_FOCUS);
    		BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
    		BOOL bDrawFocusRect = !(lpDrawItemStruct->itemState & ODS_NOFOCUSRECT);
    
    		// Prepare draw... paint button background
    
    		DWORD state = (bIsPressed)?PBS_PRESSED:PBS_NORMAL;
    
    		if(state == PBS_NORMAL)
    		{
    			if(bIsFocused)
    				state = PBS_DEFAULTED;
    			if(bMouseOverButton)
    				state = PBS_HOT;
    		}
    
    		m_pTheme.DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, state, &lpDrawItemStruct->rcItem, 0); 
    		int nOldBkgnMode = dc.SetBkMode(TRANSPARENT); 
    		dc.DrawText(strCaption, &lpDrawItemStruct->rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
    		dc.SetBkMode(nOldBkgnMode);	
    
    		if (bIsFocused && bDrawFocusRect)
    		{
    			RECT focusRect =lpDrawItemStruct->rcItem;
    			InflateRect(&focusRect, -3, -3);
    			DrawFocusRect(dc, &focusRect);
    		}
    	}
        dc.Detach(); 	
    }
    
    BOOL CXPBUTTON::OnEraseBkgnd(CDC* pDC) 
    {
    	// wir zeichnen nichts, weil wir das fenster mit den button 
        // komplett in DrawItem zeichnen 
        // ausserdem verhindern wir dadurch flickern da der standard hintergrund 
        // weiss gezeichnet wird 
        return TRUE;
    }
    
    void CXPBUTTON::PreSubclassWindow() 
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	 m_pTheme = CXPTheme(GetSafeHwnd(), L"BUTTON"); 
    
    	CButton::PreSubclassWindow();
    }
    
    void CXPBUTTON::OnMouseMove(UINT nFlags, CPoint point) 
    {
    	// TODO: Add your message handler code here and/or call default
    
    	if(!bMouseOverButton)
    	{
    		bMouseOverButton = TRUE;
    
    		TRACKMOUSEEVENT trackmouseevent;
    		trackmouseevent.cbSize = sizeof(trackmouseevent);
    		trackmouseevent.dwFlags = TME_LEAVE;
    		trackmouseevent.hwndTrack = GetSafeHwnd();
    		trackmouseevent.dwHoverTime = 0;
    		_TrackMouseEvent(&trackmouseevent);
    
    		InvalidateRect(NULL, FALSE);
    	} 
    
    	CButton::OnMouseMove(nFlags, point);
    }
    
    LONG CXPBUTTON::OnMouseLeave(WPARAM wParam, LPARAM lParam) 
    {
    	bMouseOverButton = false;
    
    	InvalidateRect(NULL, FALSE);	
    
    	return 0;
    }
    
    #if !defined(AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_)
    #define AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    // XPBUTTON.h : header file
    //
    
    /////////////////////////////////////////////////////////////////////////////
    // CXPBUTTON window
    
    class CXPBUTTON : public CButton
    {
    	DECLARE_DYNAMIC(CXPBUTTON)	
    // Construction
    public:
    	CXPBUTTON();
    
    // Attributes
    public:
    
    // Operations
    public:
    
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CXPBUTTON)
    	public:
    	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    	protected:
    	virtual void PreSubclassWindow();
    	//}}AFX_VIRTUAL
    
    // Implementation
    public:
    	virtual ~CXPBUTTON();
    
    private:
    	CXPTheme m_pTheme;
    	BOOL	ScreenPointInButtonRect(CPoint point);
    
    	bool bMouseOverButton;
    
    	// Generated message map functions
    protected:
    	//{{AFX_MSG(CXPBUTTON)
    	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    	//}}AFX_MSG
    	LONG OnMouseLeave(WPARAM wParam, LPARAM lParam);
    
    	DECLARE_MESSAGE_MAP()
    };
    
    /////////////////////////////////////////////////////////////////////////////
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_XPBUTTON_H__9AE4DC26_E531_4C94_BF39_F53EE333DF78__INCLUDED_)
    

    ist bestimmt nur kinderkram für die meisten von euch, aber für mich die halbe c++ welt... 😉


Anmelden zum Antworten