Icon für Button wechseln
-
Hi, ich bin ein absoluter Anfänger in der MFC-Welt.
Ich benutze OwnDraw-Buttons. Für die beiden Zustände (Button gedrückt und Button nicht gedrückt) sind zwei Icons vorhanden.
Notwendig weil man ja eine physikalische Rückkopplung nachahmen möchte. Also zeichnet man Icons mit entsprechenden Schattenwurf.
Je nach Zustand des Buttons werden die zugehörigen Icons auch dargestellt. Leider liegen allerdings beide Icons übereinander.Wie bekomme ich je nach Zustand das alte Icon wieder gelöscht?
Hier mein Konstruktor:
CIconCreate::CIconCreate() { m_myIconUp=AfxGetApp()->LoadIcon(IDI_BUTTONUP); }und hier meine DrawItem-Behandlung:
void CIconCreate::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if(lpDrawItemStruct->itemState & ODS_SELECTED) { // entferne m_myIconDown muss noch m_myIconDown=AfxGetApp()->LoadIcon(IDI_BUTTONDOWN); DrawIcon(lpDrawItemStruct->hDC,0,0,m_myIconDown); } else { // entferne m_myIconUp muss noch m_myIconUp=AfxGetApp()->LoadIcon(IDI_BUTTONUP); DrawIcon(lpDrawItemStruct->hDC,0,0,m_myIconUp); } }Vielen Dank schon mal !
-
Verwende bitte demnächst Code Tags!
Du musst auch den Hintergrund löschen, denn sonst werden die Icons nicht alles löschen, denn Du hast diese offensichtlich teilweise transparent gestalltet.
-
Danke für die Antwort. Bin auch in solchen Foren Neuling und gelobe Besserung!
Genau das ist es ja, ich möchte das Hintergrundicon löschen, verzweifle nur daran. Mit SetButtonStyle(BS_OWNERDRAW) führe ich einen Redraw aus, wie ich nun schon ermittelt habe. Und zwar immer dann, wenn der Button gedrückt, also das Bit ODA_SELECT aktiv ist. Damit unterbinde ich zwar übernanderliegende Icons, dafür flakkert mein Button allerdings, weil bei gedrückter linker Maustaste ständig ein Redraw ausgelöst wird. Leider funktioniert auch keine Überprüfung welches Icon gerade auf dem Button liegt ( mit GetIcon() z.B.). Obwohl ich die SetIcon-Methode ausführe, bekomme ich jedes mal über GetIcon NULL zurück geliefert.
Was mache ich bloß noch falsch?
-
1. Lösche bitte den Hintergrund in Deiner OnDraw Routine!
2. Beachte bitte für SetIcon/GetIcon haben nichts mit den Button Icons zu tun!
Gar nichts. Das sind die allgemienen Fenster Icons, für Popups!
-
Erstmal vielen Dank für die Hilfe. Ich habe nun eine Lösung gefunden mit der ich leben kann. Über löschen des DC-Handle mit DeleteDC(lpDrawItemStruct->hDC) bin ich nicht zum Ziel gekommen.
Ich übermale nun einfach den Hintergrund mit der Farbe meines Dialoges in der OnItemDraw-Routine.Da ich ja noch viel lernen muss bin ich auch für andere Lösungsvorschläge offen.
Hier meine Variante:
void CIconCreate::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if(lpDrawItemStruct->itemState & ODS_SELECTED) // Button gedrückt { OnDrawItem(IDC_DEMOBUTTON,lpDrawItemStruct); m_myIconDown=AfxGetApp()->LoadIcon(IDI_BUTTONDOWN); DrawIcon(lpDrawItemStruct->hDC,0,0,m_myIconDown); } else { OnDrawItem(IDC_DEMOBUTTON,lpDrawItemStruct); m_myIconUp=AfxGetApp()->LoadIcon(IDI_BUTTONUP); DrawIcon(lpDrawItemStruct->hDC,0,0,m_myIconUp); } } void CIconCreate::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDrawItemStruct) { // zeichne Hintergrund neu FillRect(lpDrawItemStruct->hDC,&lpDrawItemStruct->rcItem,(HBRUSH)CreateSolidBrush(BACKGROUNDCOLOR)); }
-
Rainer Wahnsinn schrieb:
Ich habe nun eine Lösung gefunden mit der ich leben kann. Über löschen des DC-Handle mit DeleteDC(lpDrawItemStruct->hDC) bin ich nicht zum Ziel gekommen.
Hat auch keiner behauptet das es so geht (oder habe ich mich verlesen).
Rainer Wahnsinn schrieb:
Ich übermale nun einfach den Hintergrund mit der Farbe meines Dialoges in der OnItemDraw-Routine.
War auch so gemeint.
Und hier meine Variante:
void CIconCreate::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // zeichne Hintergrund neu FillRect(lpDrawItemStruct->hDC,&lpDrawItemStruct->rcItem,(HBRUSH)CreateSolidBrush(BACKGROUNDCOLOR)); if(lpDrawItemStruct->itemState & ODS_SELECTED) // Button gedrückt { m_myIconDown=AfxGetApp()->LoadIcon(IDI_BUTTONDOWN); } else { m_myIconUp=AfxGetApp()->LoadIcon(IDI_BUTTONUP); } DrawIcon(lpDrawItemStruct->hDC,0,0,m_myIconUp); }Gruß Matthias
-
Hab ich dann vielleicht falsch verstanden mit dem löschen. Nach der Variante gehts natürlich auch wenn man nur eine statt zwei Variablen benutzt. Danke!
Ich hab nun noch eine Frage. Ist die Größe von Icons auf 32x32 Pixel begrenzt?
Möchte noch einen großen Button einfügen 48x48 Pixel (Stop-Button mit Aufschrift STOP). Verwende den gleichen Code nur wird er nicht gezeichnet mit DrawIcon(...).
Irgend eine Idee? Danke schon mal!
Gruß Rainer
-
LoadIcon und DrawIcon, machen nur einen auf Standard-Icon Größe
Du musst LoadImage und DrawIconEx nutzen.
http://blog.m-ri.de/index.php/2008/03/15/loadicon-macht-es-nicht-richtig/
-
Hello again,
ich versuche mich jetzt schon wieder viel zu lange an meinem großen Icon und verzweifle an meinem NICHTWISSEN.
Warum klappt es nicht nach dieser Variante?void CStopButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //Modulhandel geladenes Programm HINSTANCE hInstance=GetModuleHandle(NULL); HICON myIcon=(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_STOPICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR); DrawIconEx(lpDrawItemStruct->hDC,0,0,myIcon,0,0,0,NULL,DI_DEFAULTSIZE); }Gruß Rainer
-
Dann musst Du auch schon die Größe angeben, die Du möchtest.
-
OK danke!
Jetzt bekomme ich folgende Fehlermeldung: "resource file res\stop.ico is not in 3.00 format".
Gibt es eine Möglichkeit die Datei in das geforderte Format umzuwandeln? Ich programiere mit VS 2008.
Gruß
-
Und wie hast Du die Datei erzeugt. Doch nicht einfach nur umgenannt?
In VS-2008 kann man auch Icon Dateien erzeugen.