Kurz5 - Kapitola5

17. června 2007 v 11:13 | http://www.sweb.cz/kurz_evt/ |  Programování pro WinCE

7.5 Pohled ListView

Funguje nám menu, tlačítka, ukládá se nastavení, ale doposud jsme se nezabývali největší plochou na obrazovce - tzv. pohledem, kde se budou zobrazovat data. Při zakládání programu jsme AppWizard požádali, aby nám vytvořil v aplikaci pohled založený na třídě CListView.
Nejprve si zkusíme, zda pohled pracuje tak, jak má. Vytvoříme si v pohledu 3 sloupce pro zobrazení odesílatele, předmětu a adresy, odkud bylo odesláno. Abychom si graficky rozlišili řádky, které vybereme, použijeme na začátku řádku ikonu pro rozlišení vybraného a nevybraného řádku. Musíme si obě ikony připravit.
Do třídy CClrMailView si pomocí Add Member Variable doplňte členskou proměnnou m_ImageList, která bude typu CImageList. Také si v resources přidejte 2 ikony. Jejich ID budou: IDI_ICON1 a IDI_ICON2. Jejich grafické znázornění je na vaší volbě. Jako vzor může posloužit toto:
obr. 81 Ikony pro třídu pohledu
Ikony vypadají divně, ale jsou přizpůsobeny velikosti standardního řádku. V profesionálním programu by tato část chtěla ještě vylepšit.
Najděte členskou funkci OnInitialUpdate třídy CClrMailView a změňte ji na:
void CClrMailView::OnInitialUpdate()
{
// Promenne pro vytvoreni seznamu ikon
BOOL bRetValue;
HICON hIcon;

// Puvodni prikaz - zustava zachovano
CListView::OnInitialUpdate();

// Nastavime oznacovani celeho radku pri vyberu
ListView_SetExtendedListViewStyle(m_hWnd,LVS_EX_FULLROWSELECT);
// Vlozime 3 sloupce
GetListCtrl().InsertColumn(0,_T("From:"),LVCFMT_LEFT,100);
GetListCtrl().InsertColumn(1,_T("Subject:"),LVCFMT_LEFT,100);
GetListCtrl().InsertColumn(2,_T("Address:"),LVCFMT_LEFT,100);

// Vytvorime Image List v clenske promenne
bRetValue = m_ImageList.Create(16, 16, ILC_COLOR, 0, 1);
ASSERT(bRetValue == TRUE);
// Pridame dve jiz vlozene ikony
hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
m_ImageList.Add(hIcon);
hIcon = AfxGetApp()->LoadIcon(IDI_ICON2);
m_ImageList.Add(hIcon);
// A priradime seznam ikon nasemu pohledu
GetListCtrl().SetImageList(&m_ImageList,LVSIL_SMALL);
}
Šířku sloupců jsem nastavil na 100, vy si je můžete upravit podle svého vkusu. Takto připravená třída pohledu by vám ovšem ještě nefungovala. Aby bylo možné používat sloupce, musí mít okno pohledu styl LVS_REPORT. To lze jednoduše nastavit přidáním řádku
  
cs.style |= LVS_REPORT;
v členské funkci CClrMailView::PreCreateWindow.
Opět provedeme jednoduchý test funkčnosti programu. Do obsluhy příkazu "Connect" ve funkci CMainFrame::OnConnect() doplňte na konci tyto řádky.
  
// Ukazatel na pohled
CClrMailView* pView;
pView = (CClrMailView*)GetActiveView();
// Vlozim si zkusebne 20 polozek
for(int i=0; i<20; i++)
{
// Naplnim tri sloupce s E-maily odesilatelem, predmetem a adresou s ikonou nevybrano
pView->GetListCtrl().InsertItem(i,_T("Odesilatel"),0);
pView->GetListCtrl().SetItemText(i,1,_T("Predmet"));
pView->GetListCtrl().SetItemText(i,2,_T("Adresa"));
}
Budete muset také vložit hlavičku třídy CClrMailView do souboru MainFrame.cpp. Je pravděpodobné, že také do souboru ClrMailView.h budete muset doplnit hlavičku ClrMailDoc.h i když dokument v tomto příkladu vůbec nepoužíváme :-)
Mužete nyní vyzkoušet vzhled programu po spuštění příkazu "Connect". Pohled nám již zobrazuje jednotlivé řádky, my si však doplníme jejich označování tj. volbu ikony na začátku řádku pomocí klávesy enter a kliknutí stylusem. Tak nejprve vezmeme třeba stylus.
Otevřete si Class Wizard a zvolte třídu CClrMailView a v ní zprávu WM_LBUTTONDOWN. Vložte pro ni členskou funkci a po přenesení do jejího těla ji upravte na:
  
void CClrMailView::OnLButtonDown(UINT nFlags, CPoint point)
{
// Nejdulezitejsi promenna, ktera umoznuje pristup k polozkam ListView
LVITEM item;
// Priznak, zda jsou nektere polozky vybrany
BOOL nastav=FALSE;
int kolik,i;

// Zajima mne obrazek v prvni podpolozce u polozky
item.mask = LVIF_IMAGE;
item.iSubItem = 0;
// Prevedu kliknuti na odpovidajici polozku,
if((i = GetListCtrl().HitTest(point))!= -1) {
item.iItem = i;
// zjistim v jakem je stavu,
GetListCtrl().GetItem(&item);
// a podle toho invertuju obrazek.
if(item.iImage == 0) item.iImage = 1; else item.iImage = 0;
GetListCtrl().SetItem(&item);
// A ted povolim/zakazu operace s vybranymi/nevybranymi polozkami
kolik=GetListCtrl().GetItemCount();
for(i=kolik;i>=0;i--) {
item.iItem = i;
GetListCtrl().GetItem(&item);
// Prochazim polozky a pokud je zatrzeno, povolim s nimi praci v programu
if(item.iImage==1) {
nastav=TRUE;
break;
}
}
((CMainFrame *)GetParentFrame())->m_bSelected=nastav;
}

CListView::OnLButtonDown(nFlags, point);
}
Kód je okomentován a měl by být čitelný. Důležité je vědět, že s položkami v CListView pracujeme pomocí struktury LVITEM (nastudujte v Helpu) a řady členských funkcí přístupných přes GetListCtrl. Nezapomeňte na doplnění hlavičky v tomto souboru pro třídu CMainFrame, která je ve funkci použita!
Pokud program nyní pustíte, již byste měli být schopni vybírat řádky (měnit ikony) pomocí stylusu (příp. myši). Podobným způsobem doplníme i obsluhu klávesy enter. V Class Wizardu ve třídě CClrMailView tentokrát vyberte PreTranslateMessage a doplňte kód aby funkce vypadala takto:
  
BOOL CClrMailView::PreTranslateMessage(MSG* pMsg)
{
// Obsluha je velmi podobna obsluze kliknuti
LVITEM item;
BOOL nastav=FALSE;
int kolik,i;

if((pMsg->message == WM_KEYDOWN) & (pMsg->wParam == VK_RETURN)) {
GetListCtrl().GetFirstSelectedItemPosition();
item.mask = LVIF_IMAGE;
item.iSubItem = 0;
item.iItem = GetListCtrl().GetSelectionMark();
GetListCtrl().GetItem(&item);
if(item.iImage == 0) item.iImage = 1; else item.iImage = 0;
GetListCtrl().SetItem(&item);
// Nyni povolim nebo zakazu praci s polozkami (stejne jako OnClick)
kolik=GetListCtrl().GetItemCount();
for(i=kolik;i>=0;i--) {
item.iItem = i;
GetListCtrl().GetItem(&item);
if(item.iImage==1) {
nastav=TRUE;
break;
}
}
((CMainFrame *)GetParentFrame())->m_bSelected=nastav;
}

return CListView::PreTranslateMessage(pMsg);
}
A tím dnes končíme. Naše třída pohledu již přijímá jednotlivé položky a umíme s nimi pracovat - měnit jejich příznak vybraná/nevybraná.
A za odměnu ještě ukázka dosavadního výsledku práce:
obr. 82 Dokončený pohled programu

Co bychom si měli z této lekce zapamatovat?

  • I standardní třídy si můžeme díky dědičnosti upravit podle svých představ.
 

Buď první, kdo ohodnotí tento článek.

Nový komentář

Přihlásit se
  Ještě nemáte vlastní web? Můžete si jej zdarma založit na Blog.cz.