D
,
hab es endlich geschafft. mein cedit kontroll mit nem button das jetzt ne folderauswahl aufruft und danach den pfad im cedit feld schreibt... im nachhinein frag ich mich nur - warun das so lange gedauert hatte bei mir.. es ist eigentlich ganz einfach... Habe auch gleich alles so gemacht das ich die visual styles von XP benutzen kann... das ganze besteht nun aus einer CXPBUTTON Klasse und ner CXPFolderEdit Klasse... beide gut gewürfelt und gezähmt ergeben mein CEditfeld mit browser button für Verzeichnisse... Und das schöne daran ist, dass ich die CXPButton klasse für alle Buttons verwenden kann...
Danke an alle die mir dabei geholfen haben...
Hier nun der Quellcode für alle die es Interessiert:
#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:
void SetIcon(int hIcon, int Icon_Width, int Icon_Hight);
virtual ~CXPBUTTON();
void PrepareImageRect(HWND hButtonWnd, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle,
BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, RECT* rpImage);
void DrawTheIcon(HWND hButtonWnd, HDC* dc, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle,
BOOL bIsPressed, BOOL bIsDisabled);
bool bMouseOverButton;
HICON hIcon;
int Icon_W;
int Icon_H;
private:
CXPTheme* m_pTheme;
// 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_)
// 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;
hIcon = NULL;
}
CXPBUTTON::~CXPBUTTON()
{
delete m_pTheme;
}
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::PrepareImageRect(HWND hButtonWnd, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle,
BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, RECT* rpImage)
{
RECT rBtn;
CopyRect(rpImage, rpItem);
GetClientRect(&rBtn);
if (bHasTitle == FALSE)
{
// Center image horizontally
LONG rpImageWidth = rpImage->right - rpImage->left;
rpImage->left += ((rpImageWidth - (long)dwWidth)/2);
LONG rpImageHeight = rpImage->bottom - rpImage->top;
rpImage->top += ((rpImageHeight - (long)dwHeight)/2);
}
else
{
// Image must be placed just inside the focus rect
LONG rpTitleWidth = rpTitle->right - rpTitle->left;
rpTitle->right = rpTitleWidth - dwWidth - 14;
rpTitle->left = 14;
rpImage->left = rBtn.right - dwWidth - 14;
// Center image vertically
LONG rpImageHeight = rpImage->bottom - rpImage->top;
rpImage->top += ((rpImageHeight - (long)dwHeight)/2);
}
// If button is pressed then press image also
if (bIsPressed && !m_pTheme->IsAppThemed())
OffsetRect(rpImage, 1, 1);
} // End of PrepareImageRect
void CXPBUTTON::DrawTheIcon(HWND hButtonWnd, HDC* dc, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle,
BOOL bIsPressed, BOOL bIsDisabled)
{
RECT rImage;
PrepareImageRect(hButtonWnd, bHasTitle, rpItem, rpTitle, bIsPressed, Icon_W, Icon_H, &rImage);
DrawState( *dc,
NULL,
NULL,
(LPARAM)hIcon,
0,
rImage.left,
rImage.top,
(rImage.right - rImage.left),
(rImage.bottom - rImage.top),
(bIsDisabled ? DSS_DISABLED : DSS_NORMAL) | DST_ICON);
} // End of DrawTheIcon
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;
}
COLORREF crColor = GetSysColor(COLOR_BTNFACE);
HBRUSH brBackground = CreateSolidBrush(crColor);
FillRect(dc, &lpDrawItemStruct->rcItem, brBackground);
DeleteObject(brBackground);
m_pTheme->DrawBackground(lpDrawItemStruct->hDC, BP_PUSHBUTTON, state,
&lpDrawItemStruct->rcItem, 0);
// Read the button's title
char sTitle[100];
sTitle[0] = '\0';
GetWindowText(sTitle, 100);
RECT captionRect = lpDrawItemStruct->rcItem;
// Draw the icon
BOOL bHasTitle = (sTitle[0] != '\0');
if (!hIcon == NULL)
DrawTheIcon(GetSafeHwnd(), &lpDrawItemStruct->hDC, bHasTitle,
&lpDrawItemStruct->rcItem, &captionRect, bIsPressed, bIsDisabled);
// Write the button title (if any)
if (bHasTitle)
{// Draw the button's title
// Center text
RECT centerRect = captionRect;
DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
LONG captionRectWidth = captionRect.right - captionRect.left;
LONG captionRectHeight = captionRect.bottom - captionRect.top;
LONG centerRectWidth = centerRect.right - centerRect.left;
LONG centerRectHeight = centerRect.bottom - centerRect.top;
OffsetRect(&captionRect, (centerRectWidth - captionRectWidth)/2, (centerRectHeight - captionRectHeight)/2);
if(m_pTheme->IsAppThemed())
{
// convert title to UNICODE obviously you don't need to do this if you are a UNICODE app.
int nTextLen = strlen(sTitle);
int mlen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)sTitle, nTextLen + 1, NULL, 0);
WCHAR* output = new WCHAR[mlen];
if(output)
{
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)sTitle, nTextLen + 1, output, mlen);
m_pTheme->DrawText(lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_NORMAL,
output, wcslen(output),
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
0, &captionRect);
delete output;
}
}
}
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 = new 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);
Invalidate(FALSE);
}
CButton::OnMouseMove(nFlags, point);
}
LONG CXPBUTTON::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
bMouseOverButton = FALSE;
Invalidate(FALSE);
return 0;
}
void CXPBUTTON::SetIcon(int hIconID, int Icon_Width, int Icon_Hight)
{
Icon_W = Icon_Width;
Icon_H = Icon_Hight;
hIcon = ( HICON ) ::LoadImage( AfxGetResourceHandle(),
MAKEINTRESOURCE(hIconID),
IMAGE_ICON,
Icon_Width,
Icon_Hight,
LR_LOADTRANSPARENT );
}
#if !defined(AFX_XPFOLDEREDIT_H__3985CDC8_0639_44E0_897D_DBFB1B5C06B2__INCLUDED_)
#define AFX_XPFOLDEREDIT_H__3985CDC8_0639_44E0_897D_DBFB1B5C06B2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "XPBUTTON.h"
#include "shlobj.h"
// XPFolderEdit.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CXPFolderEdit window
class CXPFolderEdit : public CEdit
{
DECLARE_DYNAMIC(CXPFolderEdit)
// Construction
public:
CXPFolderEdit();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CXPFolderEdit)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CXPFolderEdit();
// Generated message map functions
protected:
CXPBUTTON m_Button;
CRect m_ButtonRect;
HCURSOR hCursor;
HICON hIcon;
//{{AFX_MSG(CXPFolderEdit)
afx_msg void OnMyButton();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_XPFOLDEREDIT_H__3985CDC8_0639_44E0_897D_DBFB1B5C06B2__INCLUDED_)
// XPFolderEdit.cpp : implementation file
//
#include "stdafx.h"
#include "XPStyle.h"
#include "XPFolderEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CXPFolderEdit
IMPLEMENT_DYNAMIC(CXPFolderEdit, CEdit)
CXPFolderEdit::CXPFolderEdit()
{
}
CXPFolderEdit::~CXPFolderEdit()
{
}
BEGIN_MESSAGE_MAP(CXPFolderEdit, CEdit)
//{{AFX_MSG_MAP(CXPFolderEdit)
ON_BN_CLICKED(MyButton, OnMyButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXPFolderEdit message handlers
void CXPFolderEdit::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
//Eingabebereich auf der rechten Seite um die Button breite verringern
CRect editRect;
GetRect( &editRect );
editRect.right -= 28;
SetRect( &editRect );
CRect rc;
GetClientRect(&rc);
m_Button.SetIcon(IDI_Ordner2, 11, 11);
m_ButtonRect.bottom = rc.bottom + 1;
m_ButtonRect.left = rc.right - 25;
m_ButtonRect.right = rc.right;
m_ButtonRect.top = rc.top - 1;
// m_Button is of type CXPButton
m_Button.Create ("", WS_VISIBLE | WS_TABSTOP | BS_OWNERDRAW,
CRect (m_ButtonRect.left, m_ButtonRect.top, m_ButtonRect.right,
m_ButtonRect.bottom), this, MyButton);
CEdit::PreSubclassWindow();
}
void CXPFolderEdit::OnMyButton()
{
// TODO: Add your control notification handler code here
//AfxMessageBox("MyButton wurde gedrückt...", MB_OK, 0);
char strOrdner[_MAX_PATH] = "";
BROWSEINFO browseInfo = {0};
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;
browseInfo.pszDisplayName = strOrdner;
browseInfo.hwndOwner = m_Button.m_hWnd;
LPITEMIDLIST ret;
ret = SHBrowseForFolder(&browseInfo);
if(ret != NULL)
{
SHGetPathFromIDList(ret, strOrdner);
SetWindowText(strOrdner);
CoTaskMemFree(ret);
}
}
das einbinden funkioniert eigentlich ziemlich einfach... man erstellt ein edit feld in der Dialog ansicht... danach erstellt man eine Membervariable als control für CXPFolderEdit... der rest sollte selbsterklärend aus dem Code oben folgen - (in m_Button.SetIcon(IDI_Ordner2, 11, 11) den entsprechenden Iconcode eingeben... Für Buttons gilt eigentlich das gleiche...
- Membervariable als control für CXPBUTTON anlegen und mit memberv.SetIcon(...) das Icon festlegen... (muss aber nicht)...
falls jemand fehler oder verbesserungen findet würde ich mich freuen wenn ihr mir bescheid sagt... Bis denni... bin jetzt glaube tot müde...