#define LVN_ODCACHEHINT (-113)
#endif
+#ifndef ListView_GetHeader
+ #define ListView_GetHeader(w) (HWND)SendMessage((w),LVM_GETHEADER,0,0)
+#endif
+
+#ifndef LVM_GETHEADER
+ #define LVM_GETHEADER (LVM_FIRST+31)
+#endif
+
+#ifndef Header_GetItemRect
+ #define Header_GetItemRect(w,i,r) \
+ (BOOL)SendMessage((w),HDM_GETITEMRECT,(WPARAM)(i),(LPARAM)(r))
+#endif
+
+#ifndef HDM_GETITEMRECT
+ #define HDM_GETITEMRECT (HDM_FIRST+7)
+#endif
+
+#ifndef LVCF_IMAGE
+ #define LVCF_IMAGE 0x0010
+#endif
+
+#ifndef LVCFMT_BITMAP_ON_RIGHT
+ #define LVCFMT_BITMAP_ON_RIGHT 0x1000
+#endif
+
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
wxListItem& info,
/* const */ LV_ITEM& lvItem);
+// convert our wxListItem to LV_COLUMN
+static void wxConvertToMSWListCol(int col, const wxListItem& item,
+ LV_COLUMN& lvCol);
+
// ----------------------------------------------------------------------------
// events
// ----------------------------------------------------------------------------
bool wxListCtrl::GetColumn(int col, wxListItem& item) const
{
LV_COLUMN lvCol;
- lvCol.mask = 0;
- lvCol.fmt = 0;
- lvCol.pszText = NULL;
+ wxZeroMemory(lvCol);
if ( item.m_mask & wxLIST_MASK_TEXT )
{
lvCol.cchTextMax = 512;
}
- bool success = (ListView_GetColumn(GetHwnd(), col, & lvCol) != 0);
+ bool success = ListView_GetColumn(GetHwnd(), col, & lvCol) != 0;
// item.m_subItem = lvCol.iSubItem;
item.m_width = lvCol.cx;
bool wxListCtrl::SetColumn(int col, wxListItem& item)
{
LV_COLUMN lvCol;
- lvCol.mask = 0;
- lvCol.fmt = 0;
- lvCol.pszText = NULL;
-
- if ( item.m_mask & wxLIST_MASK_TEXT )
- {
- lvCol.mask |= LVCF_TEXT;
- lvCol.pszText = WXSTRINGCAST item.m_text;
- lvCol.cchTextMax = 0; // Ignored
- }
- if ( item.m_mask & wxLIST_MASK_FORMAT )
- {
- lvCol.mask |= LVCF_FMT;
-
- if ( item.m_format == wxLIST_FORMAT_LEFT )
- lvCol.fmt = LVCFMT_LEFT;
- if ( item.m_format == wxLIST_FORMAT_RIGHT )
- lvCol.fmt = LVCFMT_RIGHT;
- if ( item.m_format == wxLIST_FORMAT_CENTRE )
- lvCol.fmt = LVCFMT_CENTER;
- }
-
- if ( item.m_mask & wxLIST_MASK_WIDTH )
- {
- lvCol.mask |= LVCF_WIDTH;
- lvCol.cx = item.m_width;
+ wxConvertToMSWListCol(col, item, lvCol);
- if ( lvCol.cx == wxLIST_AUTOSIZE)
- lvCol.cx = LVSCW_AUTOSIZE;
- else if ( lvCol.cx == wxLIST_AUTOSIZE_USEHEADER)
- lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
- }
- lvCol.mask |= LVCF_SUBITEM;
- lvCol.iSubItem = col;
- return (ListView_SetColumn(GetHwnd(), col, & lvCol) != 0);
+ return ListView_SetColumn(GetHwnd(), col, &lvCol) != 0;
}
// Gets the column width
else if ( width2 == wxLIST_AUTOSIZE_USEHEADER)
width2 = LVSCW_AUTOSIZE_USEHEADER;
- return (ListView_SetColumnWidth(GetHwnd(), col2, width2) != 0);
+ return ListView_SetColumnWidth(GetHwnd(), col2, width2) != 0;
}
// Gets the number of items that can fit vertically in the
// Deletes an item
bool wxListCtrl::DeleteItem(long item)
{
- return (ListView_DeleteItem(GetHwnd(), (int) item) != 0);
+ if ( !ListView_DeleteItem(GetHwnd(), (int) item) )
+ {
+ wxLogLastError(_T("ListView_DeleteItem"));
+ return FALSE;
+ }
+
+ // the virtual list control doesn't refresh itself correctly, help it
+ if ( IsVirtual() )
+ {
+ // we need to refresh all the lines below the one which was deleted
+ wxRect rectItem;
+ if ( item > 0 && GetItemCount() )
+ {
+ GetItemRect(item - 1, rectItem);
+ }
+ else
+ {
+ rectItem.y =
+ rectItem.height = 0;
+ }
+
+ wxRect rectWin = GetRect();
+ rectWin.height = rectWin.GetBottom() - rectItem.GetBottom();
+ rectWin.y = rectItem.GetBottom();
+
+ RefreshRect(rectWin);
+ }
+
+ return TRUE;
}
// Deletes all items
bool wxListCtrl::DeleteAllItems()
{
- return (ListView_DeleteAllItems(GetHwnd()) != 0);
+ return ListView_DeleteAllItems(GetHwnd()) != 0;
}
// Deletes all items
long wxListCtrl::InsertColumn(long col, wxListItem& item)
{
LV_COLUMN lvCol;
- lvCol.mask = 0;
- lvCol.fmt = 0;
- lvCol.pszText = NULL;
-
- if ( item.m_mask & wxLIST_MASK_TEXT )
- {
- lvCol.mask |= LVCF_TEXT;
- lvCol.pszText = WXSTRINGCAST item.m_text;
- lvCol.cchTextMax = 0; // Ignored
- }
- if ( item.m_mask & wxLIST_MASK_FORMAT )
- {
- lvCol.mask |= LVCF_FMT;
-
- if ( item.m_format == wxLIST_FORMAT_LEFT )
- lvCol.fmt = LVCFMT_LEFT;
- if ( item.m_format == wxLIST_FORMAT_RIGHT )
- lvCol.fmt = LVCFMT_RIGHT;
- if ( item.m_format == wxLIST_FORMAT_CENTRE )
- lvCol.fmt = LVCFMT_CENTER;
- }
+ wxConvertToMSWListCol(col, item, lvCol);
- lvCol.mask |= LVCF_WIDTH;
- if ( item.m_mask & wxLIST_MASK_WIDTH )
- {
- if ( item.m_width == wxLIST_AUTOSIZE)
- lvCol.cx = LVSCW_AUTOSIZE;
- else if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER)
- lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
- else
- lvCol.cx = item.m_width;
- }
- else
+ if ( !(lvCol.mask & LVCF_WIDTH) )
{
// always give some width to the new column: this one is compatible
- // with wxGTK
+ // with the generic version
+ lvCol.mask |= LVCF_WIDTH;
lvCol.cx = 80;
}
- lvCol.mask |= LVCF_SUBITEM;
- lvCol.iSubItem = col;
+ // when we insert a column which can contain an image, we must specify this
+ // flag right now as doing it later in SetColumn() has no effect
+ //
+ // we use LVCFMT_BITMAP_ON_RIGHT by default because without it there is no
+ // way to dynamically set/clear the bitmap as the column without a bitmap
+ // on the left looks ugly (there is a hole)
+ //
+ // unfortunately with my version of comctl32.dll (5.80), the left column
+ // image is always on the left and it seems that it's a "feature" - I
+ // didn't find any way to work around it in any case
+ if ( lvCol.mask & LVCF_IMAGE )
+ {
+ lvCol.mask |= LVCF_FMT;
+ lvCol.fmt |= LVCFMT_BITMAP_ON_RIGHT;
+ }
- bool success = ListView_InsertColumn(GetHwnd(), col, & lvCol) != -1;
+ bool success = ListView_InsertColumn(GetHwnd(), col, &lvCol) != -1;
if ( success )
{
m_colCount++;
{
eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
LV_DISPINFO *info = (LV_DISPINFO *)lParam;
- wxConvertFromMSWListItem(GetHwnd(), event.m_item, info->item);
+ wxConvertFromMSWListItem(NULL, event.m_item, info->item);
if ( info->item.pszText == NULL || info->item.iItem == -1 )
return FALSE;
wxStrncpy(lvi.pszText, text, lvi.cchTextMax);
}
+#if defined(_WIN32_IE) && _WIN32_IE >= 0x300 \
+ && !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 1 ) )
if ( lvi.mask & LVIF_IMAGE )
{
lvi.iImage = OnGetItemImage(item);
}
+#endif
// a little dose of healthy paranoia: as we never use
// LVM_SETCALLBACKMASK we're not supposed to get these ones
lvItem.mask |= LVIF_PARAM;
}
+static void wxConvertToMSWListCol(int col, const wxListItem& item,
+ LV_COLUMN& lvCol)
+{
+ wxZeroMemory(lvCol);
+
+ if ( item.m_mask & wxLIST_MASK_TEXT )
+ {
+ lvCol.mask |= LVCF_TEXT;
+ lvCol.pszText = (wxChar *)item.m_text.c_str(); // cast is safe
+ }
+
+ if ( item.m_mask & wxLIST_MASK_FORMAT )
+ {
+ lvCol.mask |= LVCF_FMT;
+
+ if ( item.m_format == wxLIST_FORMAT_LEFT )
+ lvCol.fmt = LVCFMT_LEFT;
+ else if ( item.m_format == wxLIST_FORMAT_RIGHT )
+ lvCol.fmt = LVCFMT_RIGHT;
+ else if ( item.m_format == wxLIST_FORMAT_CENTRE )
+ lvCol.fmt = LVCFMT_CENTER;
+ }
+
+ if ( item.m_mask & wxLIST_MASK_WIDTH )
+ {
+ lvCol.mask |= LVCF_WIDTH;
+ if ( item.m_width == wxLIST_AUTOSIZE)
+ lvCol.cx = LVSCW_AUTOSIZE;
+ else if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER)
+ lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
+ else
+ lvCol.cx = item.m_width;
+ }
+
+#if defined(_WIN32_IE) && _WIN32_IE >= 0x300 \
+ && !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 1 ) )
+ if ( item.m_mask & wxLIST_MASK_IMAGE )
+ {
+ if ( wxTheApp->GetComCtl32Version() >= 470 )
+ {
+ lvCol.mask |= LVCF_IMAGE;
+ lvCol.iImage = item.m_image;
+ }
+ //else: it doesn't support item images anyhow
+ }
+#endif
+}
+
// ----------------------------------------------------------------------------
// List event
// ----------------------------------------------------------------------------