Ein CEdit-Control mit nem Button?
-
na ich werd da mal nachkucken... meld mich dann wieder wenn ich etwas gefunden habe...
-
Achja, hast du schon mal bei Codeproject geguckt? Vielleicht gibt es da was ähnliches.
-
Habe es erstmal hinbekommen... habe mir einen Teil des CEdit-Fensters mit create reserviert und dann konnte ich da drinnen rummalen. mit den ereignissen LButtondown und LButtonright kann ich nun den Status ändern und erhalte somit nen Button. ist zwar bestimmt nicht so ganz die feine art denke ich mal, aber es geht erstmal. hem mich würde mal interessieren ob man nicht gleich ein Button in diesen bereich integrieren kann? Hier ein wenig Quelltext:
oid CIconWnd::DrawButton(int ButtonState) { CPaintDC dc( this ); CRect rect; GetClientRect( &rect ); dc.FillSolidRect( rect, GetSysColor(COLOR_WINDOW) ); CRect DrawRect(rect); DrawRect.OffsetRect(0 - rect.left, 0 - rect.top); CWindowDC WndDC(this); // get the DC for drawing CDC MemDC; MemDC.CreateCompatibleDC(&WndDC); int savedDC = MemDC.SaveDC(); CBitmap Bitmap; Bitmap.CreateCompatibleBitmap(&WndDC, rect.Width(), rect.Height()); MemDC.SelectObject(&Bitmap); CBrush theBrush(/*HS_DIAGCROSS,*/ GetSysColor(COLOR_3DFACE)); CPoint BrushOrg; CPoint Origin = WndDC.GetBrushOrg(); BrushOrg.x = (8 - (rect.left - Origin.x) % 8); BrushOrg.y = (8 - (rect.top - Origin.y) % 8); MemDC.SetBrushOrg(BrushOrg); MemDC.SelectObject(&theBrush); MemDC.FillRect(&DrawRect, &theBrush); // Drawing the icon int width = GetSystemMetrics( SM_CXSMICON ); int height = GetSystemMetrics( SM_CYSMICON ); switch(ButtonState) { case 0: { MemDC.DrawEdge(DrawRect, EDGE_RAISED, BF_RECT); WndDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY); MemDC.RestoreDC(savedDC); Bitmap.DeleteObject(); ::DrawIconEx( dc.m_hDC, 2, 1, m_icon, width, height, 0, NULL, DI_NORMAL ); break; } case 1: { CPen thePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); CPen *pOldPen = MemDC.SelectObject(&thePen); MemDC.Rectangle(DrawRect); MemDC.SelectObject(pOldPen); thePen.DeleteObject(); WndDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY); MemDC.RestoreDC(savedDC); Bitmap.DeleteObject(); ::DrawIconEx( dc.m_hDC, 2, 1, m_icon, width, height, 0, NULL, DI_NORMAL); break; } } } void CIconWnd::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CStatic::OnLButtonDown(nFlags, point); ButtonState = 0; if (m_icon) DrawButton(ButtonState); RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW/* | RDW_ERASE*/); } void CIconWnd::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CStatic::OnLButtonDown(nFlags, point); ButtonState = 1; if (m_icon) DrawButton(ButtonState); RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW/* | RDW_ERASE*/); }
-
Du kannst doch jedes Control mit Create erstellen, also auch einen Button.
Ich hab mich da bisher erfolgreich drum gedrückt, deswegen müßte ich auch suchen.Ich würde es so versuchen:
CButton* m_pBtn; pBtn->Create(...); // Musste nachgucken
Verstanden, worauf ich hinaus will? Sonst muss ich mal nen Beitrag mit sowas suchen.
-
jap hab es heute nacht dann auch so probiert. hat auch ganz gut geklappt. Wäre ich mal nur früher darauf gekommen. Hätte mir bestimmt viele nerfen gespart...
Danke ....
-
-
warum setzt du den Button nicht einfach neben das Editfeld ?
-
1. Sieht häßlicher aus
2. Wirkt nur bedingt zusammengehörend
3. Wenn man erstmal was im Kopf hat...
-
4. Ist praktischer da man dann das ganze Control einsetzen kann ohne jedes mal den Button nebendran einzufügen
-
,
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...