[ Pobierz całość w formacie PDF ]
.Wszystko, co musisz zrobić, aby ich użyć, to zastosować odpowiedni styl (SS_OWNERDRAW) i określić tytuł przycisku.Przyciski tego typu umożliwiają określenie trzech bitmap: bitmapy normalnej, bitmapy określającej wygląd wciśniętego przycisku oraz bitmapy określającej wygląd przycisku wyłączonego.Skojarzeniem odpowiednich bitmap z przyciskiem zajmuje się metoda AutoLoad.W naszym przykładowym programie, kliknięcie normalnego przycisku powoduje wyłączenie przycisku klasy CBitmapButton; dzięki temu będziesz mógł zobaczyć jak wygląda wyłączony przycisk.Możesz zauważyć, że przycisk udostępniany przez MFC nie wygląda tak ładnie, jak przycisk standardowy.Z drugiej jednak strony, przyciski udostępniane przez MFC są bardziej elastyczne od standardowych.Jeśli byś zmodyfikował przyciski MFC tak, aby wykorzystywały one wszystkie efekty przestrzenne, zapewne ich wygląd byłby znacznie bardziej atrakcyjny.Niestety wymaga to trochę pracy.Jednak zaletą przycisków dostępnych w MFC jest to, iż umożliwiają one tworzenie niestandardowych efektów graficznych.Wykorzystanie elementów działających zgodnie i metodą samodzielnego rysowaniaStosowanie elementów kontrolnych, działających zgodnie z zasadami samodzielnego rysowania, jest w MFC stosunkowo proste.Cały problem polega na przesłonięciu w Twojej klasie potomnej odpowiednich metod klasy bazowej (patrz tabela 4.4).Najprostsza jest obsługa przycisków (listing 4.10) i elementów statycznych (listing 4.11), które wymagają przesłonięcia tylko jednej metody - Drawltem.Do metody tej przekazywany jest jeden argument - struktura DRAWITEMSTRUCT (patrz tabela 4.5).W strukturze tej zapisane są wszystkie informacje związane ze sposobem rysowania elementu (oraz z tym, jaki element powinien zostać narysowany - pamiętasz zapewne, że bez pomocy MFC nie jest to takie oczywiste).Tabela 4.4.Implementowanie elementów kontrolnych metodą samodzielnego rysowania.DrawItem MeasureItem CompareItem DeleteItemButton VMenu V VList V V V VCombo Box V V V VStatic VTabela 4.5.Struktura DRAWITEMSTRUCTSkładowa Typ OpisCtlType In Typ elementu kontrolnego (ODT_BUTTON, ODT_MENU, itp.)CtlID In Identyfikator przycisku, pola kombo, listy lub elementu statycznegoitemAction In Polecenie (ODS_DRAWENTIRE, ODA_DRAWFOCUS lub ODA_SELECT)itemState In Stan (ODS_Checked, ODS_GRAYED, itp.)hwndItem In Uchwyt HWND do elementu kontrolnego lub uchwytu HMENU do menuhDC In Kontekst urządzeniarcItem In Prostokąt zawierający element kontrolny (nie dotyczy menu)itemData In Dowolne dane definiowane przez użytkownika (nie może to być łańcuch znaków)Oczywiście, nie jesteś w żaden sposób zobligowany do tego, aby cokolwiek rysować.Elementy kontrolne działające według zasad samodzielnego rysowania, które nie wyświetlają niczego na swojej powierzchni, są bardzo wygodne do tworzenia w oknie obszarów, które można kliknąć, bez konieczności pisania kodu określającego płożenie wskaźnika myszy podczas kliknięcia.Choć nie jest to standardowe zastosowanie elementów kontrolnych samodzielnego rysowania, to jednak doskonale ono pokazuje, że na elementach tych możesz narysować cokolwiek zechcesz lub zgoła nic.Zauważ, że kontekst urządzenia, uchwyt do okna oraz pozostałe dane przekazywane w strukturze DRAWITEMSTRUCT, nie są obiektami MFC, lecz normalnymi uchwytami systemu Windows.Aby użyć tych uchwytów, będziesz musiał je odpowiednio skonwertować (w przypadku kontekstu urządzenia będziesz musiał wywołać metod? CDC:FromHandle).Drawltem a OnDrawItemNiech nie zmylą Cię wywołania metod Drawltem oraz OnDrawItem (lub jakiejkolwiek innej podobnej pary metod).Metoda OnDrawItem jest metodą obsługującą komunikaty WM_DRAWITEM; jest ona zdefiniowana w klasie bazowej elementu kontrolnego rysowanego przez użytkownika.Domyślny kod obsługi zdefiniowany w klasie CWnd wywołuje metodę Drawltem odpowiedniego elementu kontrolnego.Obie te metody robią więc to samo, z tym, że umieszczone są w różnych miejscach: OnDrawItem w oknie rodzicielskim, a Drawltem w oknie potomnym.Tak samo skonstruowane zostały metody OnMeasureltem oraz Measureltem, a także pozostałe pary metod.Listing 4.10.Przycisk działający według metody samodzielnego rysowania.// ODButton.cpp : implementation file//#include "stdafx.h"#include "buttons.h"#include "ODButton.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CODButtonCODButton::CODButton(){}CODButton::~CODButton(){}BEGIN_MESSAGE_MAP(CODButton, CButton)//{{AFX_MSG_MAP(CODButton)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CODButton message handlersvoid CODButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){CDC *dc=CDC::FromHandle(lpDrawItemStruct->hDC);CBrush *btnface;CString caption;GetWindowText(caption);btnface=CBrush::FromHandle(GetSysColorBrush(COLOR_BTNFACE));if (lpDrawItemStruct->itemState&ODS_SELECTED==ODS_SELECTED)btnface=(CBrush *)dc->SelectStockObject(WHITE_BRUSH);elsebtnface=dc->SelectObject(btnface);dc->Ellipse(&lpDrawItemStruct->rcItem);dc->SetBkMode(TRANSPARENT);dc->DrawText(caption,-1,&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_CENTER|DT_VCENTER);dc->SelectObject(btnface);}Listing 4.11.Element statyczny działający według zasad samodzielnego rysowania.// ODStatic.cpp : implementation file//#include "stdafx.h"#include "buttons.h"#include "ODStatic.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CODStaticCODStatic::CODStatic(){}CODStatic::~CODStatic(){}BEGIN_MESSAGE_MAP(CODStatic, CStatic)//{{AFX_MSG_MAP(CODStatic)// ON_WM_DRAWITEM()ON_WM_DRAWITEM_REFLECT()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CODStatic message handlersvoid CODStatic::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){CDC *dc=CDC::FromHandle(lpDrawItemStruct->hDC);dc->Ellipse(&lpDrawItemStruct->rcItem);}Szczególne kłopoty sprawiają elementy statyczne (etykiety).Spowodowane jest to tym, że MFC nie jest w stanie zrozumieć, iż elementy takie mogą być rysowane przez użytkownika (w starszych wersjach systemu Windows nie istniały elementy statyczne rysowane przez użytkownika).Edytor zasobów nie udostępnia nawet opcji pozwalającej na tworzenie statycznych elementów kontrolnych tego typu.Nie jest to jednak wielka przeszkoda gdyż możesz określić styl elementów podczas działania programu (patrz listing 4.9).Chociaż MFC przekazuje komunikaty z powrotem do statycznego elementu kontrolne go rysowanego przez użytkownika, to jednak domyślna implementacja tego elementu obsługuje tych komunikatów.Będziesz więc musiał sam dodać makro ON_WM_D do mapy komunikatów Twojej klasy (będącej klasą potomną klasy CStatic).Przykład takiego postępowania możesz zobaczyć na listingu 4.1 1
[ Pobierz całość w formacie PDF ]