/* SetItemlParam() Imposta i dati extra. int nItem indice (base 0) dell'elemento */ void CListCtrlEx::SetItemlParam(int nItem,LPARAM lParam) { CTRL_ROW* ra = GetRowByItem(nItem); if(ra) ra->lParam = lParam; }
/* SetItemwParam() Imposta i dati extra. int nItem indice (base 0) dell'elemento */ void CListCtrlEx::SetItemwParam(int nItem,WPARAM wParam) { CTRL_ROW* ra = GetRowByItem(nItem); if(ra) ra->wParam = wParam; }
/* ResetItemsSelection() Azzera lo status (interno) degli elementi (imposta su non selezionati). */ void CListCtrlEx::ResetItemsSelection(void) { CTRL_ROW* ra; for(int i = 0; i < CListCtrl::GetItemCount(); i++) if((ra = GetRowByItem(i))!=(CTRL_ROW*)NULL) ra->selected = FALSE; }
/* GetItemlParam() Restituisce i dati extra. int nItem indice (base 0) dell'elemento */ LPARAM CListCtrlEx::GetItemlParam(int nItem) { LPARAM lParam = (LPARAM)-1L; CTRL_ROW* ra = GetRowByItem(nItem); if(ra) lParam = ra->lParam; return(lParam); }
/* GetItemwParam() Restituisce i dati extra. int nItem indice (base 0) dell'elemento */ WPARAM CListCtrlEx::GetItemwParam(int nItem) { WPARAM wParam = NULL; CTRL_ROW* ra = GetRowByItem(nItem); if(ra) wParam = ra->wParam; return(wParam); }
/* GetItemSelection() Restituisce lo status (interno) dell'elemento (selezionata o meno). int nItem indice (base 0) dell'elemento */ BOOL CListCtrlEx::GetItemSelection(int nItem) { BOOL bIsSelected = FALSE; CTRL_ROW* ra = GetRowByItem(nItem); if(ra) bIsSelected = ra->selected; return(bIsSelected); }
/* DeleteItem() Elimina l'elemento dal controllo. int nItem indice (base 0) della riga. */ BOOL CListCtrlEx::DeleteItem(int nItem) { ITERATOR iter; CTRL_ROW* ra = NULL; // elimina la riga dal controllo BOOL bDeleted = CListCtrl::DeleteItem(nItem); // cerca la riga relativa all'indice e la elimina dalla lista if((iter = m_RowList.First())!=(ITERATOR)NULL) { do { ra = (CTRL_ROW*)iter->data; if(ra) { if(ra->index==nItem) break; else ra = NULL; } iter = m_RowList.Next(iter); } while(iter!=(ITERATOR)NULL); } if(ra) m_RowList.Remove(iter); // rinumera gli indici delle righe presenti nella lista int tot = m_RowList.Count()+1; for(int n = ++nItem; n < tot; n++) { if((ra = GetRowByItem(n))!=(CTRL_ROW*)NULL) ra->index = n-1; } return(bDeleted); }
int CTimeBarDataViewCtrl::GetRow(const wxDataViewItem & item) { return GetRowByItem(item); }
/* MoveItem() Sposta l'elemento in alto o in basso di una posizione. int nItem indice (base 0) dell'elemento ITEM_SKIP skip flag per tipo spostamento (precedente/successivo) */ int CListCtrlEx::MoveItem(int nItem,ITEM_SKIP skip) { int nCurrentItem = LB_ERR; int nNewItem = (nItem + (skip==PREVIOUS_ITEM ? -1 : (skip==NEXT_ITEM ? +1 : -1))); // controlla l'intervallo if(nNewItem >= 0 && nNewItem < CListCtrl::GetItemCount()) { // riga da spostare CTRL_ROW* ra = GetRowByItem(nItem); // riga precedente/successiva CTRL_ROW* ra_prevnext = GetRowByItem(nNewItem); if(ra && ra_prevnext) { int nSubItem; LV_ITEM lvitem; char szItem[MAX_ITEM_SIZE+1]; // elimina l'elemento dal controllo (chiama la classe base perche' non deve aggiornare il contatore interno) CListCtrl::DeleteItem(nItem); // testo dell'elemento strcpyn(szItem,ra->item,sizeof(szItem)); // rinumera gli indici dei due elementi coinvolti nello spostamento ra->index = nNewItem; ra_prevnext->index = nItem; // colonne dell'elemento for(nSubItem = 0,nCurrentItem = 0; nSubItem < m_nTotColumns && nCurrentItem!=LB_ERR; nSubItem++) { // l'elemento (riga) viene passata in un unico buffer, diviso in colonne dal carattere ';' lvitem.pszText = (LPSTR)GetItemToken(nSubItem,szItem); lvitem.iSubItem = nSubItem; if(nSubItem==0) { lvitem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvitem.iItem = nNewItem; lvitem.iImage = ra->ico; lvitem.lParam = (LPARAM)ra; lvitem.pszText = LPSTR_TEXTCALLBACK; if((nCurrentItem = CListCtrl::InsertItem(&lvitem)) < 0) nCurrentItem = LB_ERR; } else { lvitem.mask = LVIF_TEXT; lvitem.iItem = nCurrentItem; CListCtrl::SetItem(&lvitem); } } // imposta la riga come selezionata nCurrentItem = SelectItem(nNewItem); } } return(nCurrentItem); }
/* AddCol() Aggiunge la colonna al controllo. LPCSTR lpcszColumnText testo per l'intestazione della colonna char cDataType = 'C' carattere per il tipo dei dati contenuti nella colonna: 'C' carattere, 'N' numerico, 'S' dimensione in bytes int nWidth = -1 dimensione della colonna (in pixel) BOOL bDescend = FALSE flag per ordinamento (FALSE=discendente, TRUE=ascendente) */ int CListCtrlEx::AddCol(LPCSTR lpcszColumnText,char cDataType,int nWidth,BOOL bDescend) { int nCurrentCol = LB_ERR; // crea la colonna CTRL_COL* ca = (CTRL_COL*)m_ColList.Add(); if(ca) { memset(ca,'\0',sizeof(CTRL_COL)); int len = strlen(lpcszColumnText)+1; ca->item = new char[len]; memset(ca->item,'\0',len); // aggiunge la colonna alla lista CSize size; LPSTR lpToken; LV_COLUMN lvcolumn; // indice (base 0) della nuova colonna int nCol = m_nTotColumns++; strcpy(ca->item,lpcszColumnText); // ordinamento colonna (default FALSE = discendente) ca->type = cDataType; ca->order = bDescend; // elemento lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH; lvcolumn.fmt = LVCFMT_LEFT; lvcolumn.pszText = ca->item; lvcolumn.iSubItem = nCol; // calcola la dimensione (in pixel) della colonna in base alla dimensione del testo // della colonna e del testo della prima riga (+15 per l'icona) if(nWidth <= 0) { lpToken = ""; if(CListCtrl::GetItemCount() > 0) { CTRL_ROW* ra; if((ra = GetRowByItem(0))!=NULL) lpToken = (LPSTR)GetItemToken(nCol,ra->item); } else { lpToken = ca->item; } int nColSize = CListCtrl::GetStringWidth(lvcolumn.pszText); int nItemSize = CListCtrl::GetStringWidth(lpToken); size.cx = nColSize > nItemSize ? nColSize : nItemSize; lvcolumn.cx = size.cx + 15; } else { lvcolumn.cx = nWidth; } // inserisce la colonna if((nCurrentCol = CListCtrl::InsertColumn(nCol,&lvcolumn)) < 0) nCurrentCol = LB_ERR; } return(nCurrentCol); }
/* OnLButtonDown() Gestore per il click con il bottone sinistro del mouse sull'elemento del controllo. Imposta la riga come selezionata ed invia il messaggio alla finestra principale (in wParam l'indice dell'elemento selezionato ed in lParam le coordinate del click). Per catturare il rilascio del bottone sinistro del mouse con OnLButtonUp() anche quando il cursore del mouse e' stato spostato fuori dall'area client, utilizzare la SetCapture(). */ void CListCtrlEx::OnLButtonDown(UINT nFlags,CPoint point) { // salva le coordinate del click m_Point.x = point.x; m_Point.y = point.y; m_MouseClick.point.x = point.x; m_MouseClick.point.y = point.y; m_MouseClick.flags = nFlags; // chiama il gestore originale CListCtrl::OnLButtonDown(nFlags,point); // per continuare a ricevere i messaggi quando il mouse si sposta fuori dell'area client //::SetCapture(this->m_hWnd); // indice dell'elemento cliccato m_nCurrentItem = CListCtrl::HitTest(point); // imposta il flag relativo alla selezione // se viene cambiato l'ordinamento del controllo l'elemento relativo all'indice non corrisponde a quanto // presente nella lista del chiamante, per cui deve cercare l'elemento relativo prima di impostare il // flag per la selezione // effettua tale ricerca con il primo subitem (indice 0), per cui il valore presente in tale posizione // deve essere unico int nTotItems = CListCtrl::GetItemCount(); if(m_nCurrentItem >= 0 && m_nCurrentItem < nTotItems) { CTRL_ROW* ra = NULL; ITERATOR iter; register int i; char buffer[MAX_ITEM_SIZE+1]; // azzera le selezioni correnti if((iter = m_RowList.First())!=(ITERATOR)NULL) { do { ra = (CTRL_ROW*)iter->data; if(ra) ra->selected = FALSE; iter = m_RowList.Next(iter); } while(iter!=(ITERATOR)NULL); } // per ogni elemento del controllo verifica se e' stato selezionato, ricava il valore relativo al // subitem con indice 0 e lo confronta con l'elemento corrente: se coincidono imposta il flag per // la selezione // deve scorrere il controllo per gestire le selezioni multiple (click sul primo, shift+click // sull'ultimo) for(i = 0; i < nTotItems/*CListCtrl::GetItemCount()*/; i++) { // il cazzo di elemento e' stato cliccato ? // (click sull'elemento o elemento nel mezzo di una selezione click su i, shift+click su i+n) if(CListCtrl::GetItemState(i,LVIS_SELECTED) & LVIS_SELECTED) { memset(buffer,'\0',sizeof(buffer)); LV_ITEM lvitem; lvitem.mask = LVIF_TEXT; lvitem.iItem = i; lvitem.iSubItem = 0; lvitem.pszText = buffer; lvitem.cchTextMax = sizeof(buffer)-1; CListCtrl::GetItem(&lvitem); if((ra = GetRowByItem(i))!=(CTRL_ROW*)NULL) { if(memcmp(ra->item,buffer,strlen(buffer))==0) { ra->selected = TRUE; break; } } if(!m_bMultipleSelection) break; } } } // salva l'indice (base 0) dell'elemento corrente (selezionato), controllando l'intervallo if(m_nCurrentItem < 0) m_nCurrentItem = LB_ERR; else if(m_nCurrentItem >= nTotItems) m_nCurrentItem = nTotItems - 1; // se e' stato specificato un gestore, invia il messaggio relativo // in wParam l'indice dell'elemento ed in lParam le coordinate del click if(m_pWnd!=NULL && m_nLButtonDownMessage!=(UINT)-1L) ::SendMessage(m_pWnd->m_hWnd,m_nLButtonDownMessage,(WPARAM)m_nCurrentItem,(LPARAM)&m_MouseClick); }
/* PopUpMenu() Visualizza il menu popup sul controllo. Il menu visualizzato e' il primo sottomenu (base 0) del menu relativo all'id nel caso in cui venga fatto click su un elemento o il secondo se viene fatto click in una zona del controllo senza elementi. const CPoint& point coordinate del click */ void CListCtrlEx::PopUpMenu(const CPoint& point) { int i; CRect rect; CMenu menu; CMenu* pSubMenu = NULL; CTRL_ROW* ra; // coordinate dell'area client (CWnd, base 0,0) CWnd::GetClientRect(&rect); // trasforma le coordinate in assolute (schermo) // da aggiungere alle coordinate del click del mouse per ottenere le coordinate a cui visualizzare il menu a comparsa CWnd::ClientToScreen(&rect); // click su un elemento del controllo if((i = CListCtrl::HitTest(point)) >= 0) { // carica il menu relativo all'id specificato dall'elemento su cui e' stato fatto click // (primo sottomenu, base 0) if((ra = GetRowByItem(i))!=(CTRL_ROW*)NULL) if(ra->menu > 0) if(menu.LoadMenu(ra->menu)) pSubMenu = menu.GetSubMenu(0); } // click fuori dall'elemento else { // click su una zona del controllo contenente almeno un elemento if((ra = GetRowByItem(0))!=(CTRL_ROW*)NULL) { // carica il menu relativo all'id specificato dal primo elemento della lista // (secondo sottomenu, base 0) if(ra->menu > 0) if(menu.LoadMenu(ra->menu)) pSubMenu = menu.GetSubMenu(1); } // click su una zona del controllo senza nessun elemento else { // carica il menu di default // (primo sottomenu, base 0) if(m_NullRow.menu > 0) if(menu.LoadMenu(m_NullRow.menu)) pSubMenu = menu.GetSubMenu(0); } } // visualizza il menu popup // TrackPopupMenu() does not return until the user selects a menu item or cancels the menu, so EnableMenuItem() is called after the menu has gone if(pSubMenu && m_pWnd) { if(m_nMenuMessage!=(UINT)-1L) ::SendMessage(m_pWnd->m_hWnd,m_nMenuMessage,(WPARAM)m_nCurrentItem,(LPARAM)pSubMenu); CPoint ptCursor; GetCursorPos(&ptCursor); ::TrackPopupMenu(pSubMenu->m_hMenu,0,ptCursor.x,ptCursor.y,0,m_pWnd->m_hWnd,0); ::PostMessage(m_pWnd->m_hWnd,WM_NULL,0,0); } }