foobar2000 SDK  2015-08-03
listview_helper.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 
3 #ifdef _WIN32
4 
5 
6 namespace listview_helper {
7 
8  unsigned insert_item(HWND p_listview,unsigned p_index,const char * p_name,LPARAM p_param)
9  {
10  if (p_index == ~0) p_index = ListView_GetItemCount(p_listview);
11  LVITEM item = {};
12 
13  pfc::stringcvt::string_os_from_utf8 os_string_temp(p_name);
14 
15  item.mask = LVIF_TEXT | LVIF_PARAM;
16  item.iItem = p_index;
17  item.lParam = p_param;
18  item.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
19 
20  LRESULT ret = uSendMessage(p_listview,LVM_INSERTITEM,0,(LPARAM)&item);
21  if (ret < 0) return ~0;
22  else return (unsigned) ret;
23  }
24 
25  unsigned insert_item2(HWND p_listview, unsigned p_index, const char * col0, const char * col1, LPARAM p_param) {
26  unsigned i = insert_item( p_listview, p_index, col0, p_param );
27  if (i != ~0) {
28  set_item_text( p_listview, i, 1, col1 );
29  }
30  return i;
31  }
32 
33  unsigned insert_item3(HWND p_listview, unsigned p_index, const char * col0, const char * col1, const char * col2, LPARAM p_param) {
34  unsigned i = insert_item( p_listview, p_index, col0, p_param );
35  if (i != ~0) {
36  set_item_text( p_listview, i, 1, col1 );
37  set_item_text( p_listview, i, 2, col2 );
38  }
39  return i;
40  }
41 
42  unsigned insert_column(HWND p_listview,unsigned p_index,const char * p_name,unsigned p_width_dlu)
43  {
44  pfc::stringcvt::string_os_from_utf8 os_string_temp(p_name);
45 
46  RECT rect = {0,0,p_width_dlu,0};
47  MapDialogRect(GetParent(p_listview),&rect);
48 
49  LVCOLUMN data = {};
50  data.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT;
51  data.fmt = LVCFMT_LEFT;
52  data.cx = rect.right;
53  data.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
54 
55  LRESULT ret = uSendMessage(p_listview,LVM_INSERTCOLUMN,p_index,(LPARAM)&data);
56  if (ret < 0) return ~0;
57  else return (unsigned) ret;
58  }
59 
60  void get_item_text(HWND p_listview,unsigned p_index,unsigned p_column,pfc::string_base & p_out) {
61  enum {buffer_length = 1024*64};
62  pfc::array_t<TCHAR> buffer; buffer.set_size(buffer_length);
63  ListView_GetItemText(p_listview,p_index,p_column,buffer.get_ptr(),buffer_length);
64  p_out = pfc::stringcvt::string_utf8_from_os(buffer.get_ptr(),buffer_length);
65  }
66 
67  bool set_item_text(HWND p_listview,unsigned p_index,unsigned p_column,const char * p_name)
68  {
69  LVITEM item = {};
70 
71  pfc::stringcvt::string_os_from_utf8 os_string_temp(p_name);
72 
73  item.mask = LVIF_TEXT;
74  item.iItem = p_index;
75  item.iSubItem = p_column;
76  item.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
77  return uSendMessage(p_listview,LVM_SETITEM,0,(LPARAM)&item) ? true : false;
78  }
79 
80  bool is_item_selected(HWND p_listview,unsigned p_index)
81  {
82  LVITEM item = {};
83  item.mask = LVIF_STATE;
84  item.iItem = p_index;
85  item.stateMask = LVIS_SELECTED;
86  if (!uSendMessage(p_listview,LVM_GETITEM,0,(LPARAM)&item)) return false;
87  return (item.state & LVIS_SELECTED) ? true : false;
88  }
89 
90  void set_item_selection(HWND p_listview,unsigned p_index,bool p_state)
91  {
92  PFC_ASSERT( ::IsWindow(p_listview) );
93  LVITEM item = {};
94  item.stateMask = LVIS_SELECTED;
95  item.state = p_state ? LVIS_SELECTED : 0;
96  WIN32_OP_D( SendMessage(p_listview,LVM_SETITEMSTATE,(WPARAM)p_index,(LPARAM)&item) );
97  }
98 
99  bool select_single_item(HWND p_listview,unsigned p_index)
100  {
101  LRESULT temp = SendMessage(p_listview,LVM_GETITEMCOUNT,0,0);
102  if (temp < 0) return false;
103  ListView_SetSelectionMark(p_listview,p_index);
104  unsigned n; const unsigned m = pfc::downcast_guarded<unsigned>(temp);
105  for(n=0;n<m;n++) {
106  enum {mask = LVIS_FOCUSED | LVIS_SELECTED};
107  ListView_SetItemState(p_listview,n,n == p_index ? mask : 0, mask);
108  }
109  return ensure_visible(p_listview,p_index);
110  }
111 
112  bool ensure_visible(HWND p_listview,unsigned p_index)
113  {
114  return uSendMessage(p_listview,LVM_ENSUREVISIBLE,p_index,FALSE) ? true : false;
115  }
116 }
117 
118 
119 void ListView_GetContextMenuPoint(HWND p_list,LPARAM p_coords,POINT & p_point,int & p_selection) {
120  POINT pt = {(short)LOWORD(p_coords),(short)HIWORD(p_coords)};
121  ListView_GetContextMenuPoint(p_list, pt, p_point, p_selection);
122 }
123 
124 void ListView_GetContextMenuPoint(HWND p_list,POINT p_coords,POINT & p_point,int & p_selection) {
125  if (p_coords.x == -1 && p_coords.y == -1) {
126  int firstsel = ListView_GetFirstSelection(p_list);
127  if (firstsel >= 0) {
128  ListView_EnsureVisible(p_list, firstsel, FALSE);
129  RECT rect;
130  WIN32_OP_D( ListView_GetItemRect(p_list,firstsel,&rect,LVIR_BOUNDS) );
131  p_point.x = (rect.left + rect.right) / 2;
132  p_point.y = (rect.top + rect.bottom) / 2;
133  WIN32_OP_D( ClientToScreen(p_list,&p_point) );
134  } else {
135  RECT rect;
136  WIN32_OP_D(GetClientRect(p_list,&rect));
137  p_point.x = (rect.left + rect.right) / 2;
138  p_point.y = (rect.top + rect.bottom) / 2;
139  WIN32_OP_D(ClientToScreen(p_list,&p_point));
140  }
141  p_selection = firstsel;
142  } else {
143  POINT pt = p_coords; // {(short)LOWORD(p_coords),(short)HIWORD(p_coords)};
144  p_point = pt;
145  POINT client = pt;
146  WIN32_OP_D( ScreenToClient(p_list,&client) );
147  LVHITTESTINFO info = {};
148  info.pt = client;
149  p_selection = ListView_HitTest(p_list,&info);
150  }
151 }
152 
153 #if 0
154 static bool ProbeColumn(HWND view, int index) {
155  LVCOLUMN col = {LVCF_ORDER};
156  return !! ListView_GetColumn(view, index, &col);
157 }
158 int ListView_GetColumnCount(HWND listView) {
159  if (!ProbeColumn(listView, 0)) return 0;
160  int hi = 1;
161  for(;;) {
162  if (!ProbeColumn(listView, hi)) break;
163  hi <<= 1;
164  if (hi <= 0) {
165  PFC_ASSERT(!"Shouldn't get here!");
166  return -1;
167  }
168  }
169  int lo = hi >> 1;
170  //lo is the highest known valid column, hi is the lowest known invalid, let's bsearch thru
171  while(lo + 1 < hi) {
172  PFC_ASSERT( lo < hi );
173  const int mid = lo + (hi - lo) / 2;
174  PFC_ASSERT( lo < mid && mid < hi );
175  if (ProbeColumn(listView, mid)) {
176  lo = mid;
177  } else {
178  hi = mid;
179  }
180  }
181  return hi;
182 }
183 #else
184 int ListView_GetColumnCount(HWND listView) {
185  HWND header = ListView_GetHeader(listView);
186  PFC_ASSERT(header != NULL);
187  return Header_GetItemCount(header);
188 }
189 #endif
190 
191 #endif // _WIN32
unsigned insert_item2(HWND p_listview, unsigned p_index, const char *col0, const char *col1, LPARAM p_param)
const t_item * get_ptr() const
Definition: array.h:213
unsigned insert_item3(HWND p_listview, unsigned p_index, const char *col0, const char *col1, const char *col2, LPARAM p_param)
bool set_item_text(HWND p_listview, unsigned p_index, unsigned p_column, const char *p_name)
unsigned insert_item(HWND p_listview, unsigned p_index, const char *p_name, LPARAM p_param)
void info(const char *p_message)
Definition: console.cpp:4
bool ensure_visible(HWND p_listview, unsigned p_index)
unsigned insert_column(HWND p_listview, unsigned p_index, const char *p_name, unsigned p_width_dlu)
void get_item_text(HWND p_listview, unsigned p_index, unsigned p_column, pfc::string_base &p_out)
string_utf8_from_wide string_utf8_from_os
Definition: string_conv.h:517
int ListView_GetColumnCount(HWND listView)
void set_size(t_size p_size)
Definition: array.h:104
const wchar_t * get_ptr() const
Definition: string_conv.h:133
bool is_item_selected(HWND p_listview, unsigned p_index)
static int ListView_GetFirstSelection(HWND p_listview)
void set_item_selection(HWND p_listview, unsigned p_index, bool p_state)
void ListView_GetContextMenuPoint(HWND p_list, LPARAM p_coords, POINT &p_point, int &p_selection)
bool select_single_item(HWND p_listview, unsigned p_index)
static bool ProbeColumn(HWND view, int index)