2
#include "CommonWindows.h"
9
#include "util/text/utf8.h"
11
bool IsVistaOrHigher() {
13
DWORDLONG dwlConditionMask = 0;
14
int op = VER_GREATER_EQUAL;
15
ZeroMemory(&osvi, sizeof(osvi));
16
osvi.dwOSVersionInfoSize = sizeof(osvi);
17
osvi.dwMajorVersion = 6; // Vista is 6.0
18
osvi.dwMinorVersion = 0;
20
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
21
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
23
return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE;
28
void CenterWindow(HWND hwnd)
33
int screenwidth, screenheight;
36
//make the window relative to its parent
37
hwndParent = GetParent(hwnd);
41
GetWindowRect(hwnd, &rect);
42
GetWindowRect(hwndParent, &rectP);
44
width = rect.right - rect.left;
45
height = rect.bottom - rect.top;
47
x = ((rectP.right-rectP.left) - width) / 2 + rectP.left;
48
y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top;
50
screenwidth = GetSystemMetrics(SM_CXSCREEN);
51
screenheight = GetSystemMetrics(SM_CYSCREEN);
53
//make sure that the dialog box never moves outside of
57
if(x + width > screenwidth) x = screenwidth - width;
58
if(y + height > screenheight) y = screenheight - height;
60
MoveWindow(hwnd, x, y, width, height, FALSE);
63
void NiceSizeFormat(size_t size, char *out)
65
char *sizes[] = {"B","KB","MB","GB","TB","PB","EB"};
71
frac = (int)size & 1023;
74
float f = (float)size + ((float)frac / 1024.0f);
76
sprintf(out, "%d B", (int)size);
78
sprintf(out, "%3.1f %s", f, sizes[s]);
81
BOOL CopyTextToClipboard(HWND hwnd, const char *text) {
82
std::wstring wtext = ConvertUTF8ToWString(text);
83
return CopyTextToClipboard(hwnd, wtext);
86
BOOL CopyTextToClipboard(HWND hwnd, const std::wstring &wtext) {
89
HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (wtext.size() + 1) * sizeof(wchar_t));
90
if (hglbCopy == NULL) {
95
// Lock the handle and copy the text to the buffer.
97
wchar_t *lptstrCopy = (wchar_t *)GlobalLock(hglbCopy);
98
wcscpy(lptstrCopy, wtext.c_str());
99
lptstrCopy[wtext.size()] = (wchar_t) 0; // null character
100
GlobalUnlock(hglbCopy);
101
SetClipboardData(CF_UNICODETEXT, hglbCopy);
106
void MakeTopMost(HWND hwnd, bool topMost) {
107
HWND style = HWND_NOTOPMOST;
108
if (topMost) style = HWND_TOPMOST;
109
SetWindowPos(hwnd, style, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
112
static const wchar_t *RemoveExecutableFromCommandLine(const wchar_t *cmdline) {
117
switch (cmdline[0]) {
119
// We don't need to handle escaped quotes, since filenames can't have that.
120
cmdline = wcschr(cmdline + 1, '"');
123
if (cmdline[0] == ' ') {
130
cmdline = wcschr(cmdline, ' ');
140
void ExitAndRestart() {
141
// This preserves arguments (for example, config file) and working directory.
143
wchar_t moduleFilename[MAX_PATH];
144
wchar_t workingDirectory[MAX_PATH];
145
GetCurrentDirectoryW(MAX_PATH, workingDirectory);
146
const wchar_t *cmdline = RemoveExecutableFromCommandLine(GetCommandLineW());
147
GetModuleFileName(GetModuleHandle(NULL), moduleFilename, MAX_PATH);
148
ShellExecute(NULL, NULL, moduleFilename, cmdline, workingDirectory, SW_SHOW);
156
GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def)
157
: handle(hwnd), columns(def.columns),columnCount(def.columnCount),valid(false),
158
inResizeColumns(false),updating(false)
160
DWORD style = GetWindowLong(handle,GWL_STYLE) | LVS_REPORT;
161
SetWindowLong(handle, GWL_STYLE, style);
163
SetWindowLongPtr(handle,GWLP_USERDATA,(LONG_PTR)this);
164
oldProc = (WNDPROC) SetWindowLongPtr(handle,GWLP_WNDPROC,(LONG_PTR)wndProc);
166
auto exStyle = LVS_EX_FULLROWSELECT;
168
exStyle |= LVS_EX_CHECKBOXES;
169
SendMessage(handle, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, exStyle);
172
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
176
GetClientRect(handle,&rect);
178
int totalListSize = rect.right-rect.left;
179
for (int i = 0; i < columnCount; i++) {
180
lvc.cx = columns[i].size * totalListSize;
181
lvc.pszText = columns[i].name;
183
if (columns[i].flags & GLVC_CENTERED)
184
lvc.fmt = LVCFMT_CENTER;
186
lvc.fmt = LVCFMT_LEFT;
188
ListView_InsertColumn(handle, i, &lvc);
191
if (def.columnOrder != NULL)
192
ListView_SetColumnOrderArray(handle,columnCount,def.columnOrder);
194
SetSendInvalidRows(false);
198
void GenericListControl::HandleNotify(LPARAM lParam)
200
LPNMHDR mhdr = (LPNMHDR) lParam;
202
if (mhdr->code == NM_DBLCLK)
204
LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
205
if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
206
OnDoubleClick(item->iItem,item->iSubItem);
210
if (mhdr->code == NM_RCLICK)
212
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
213
if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
214
OnRightClick(item->iItem,item->iSubItem,item->ptAction);
218
if (mhdr->code == LVN_GETDISPINFO)
220
NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
223
GetColumnText(stringBuffer,dispInfo->item.iItem,dispInfo->item.iSubItem);
225
if (stringBuffer[0] == 0)
226
wcscat(stringBuffer,L"Invalid");
228
dispInfo->item.pszText = stringBuffer;
233
if (mhdr->code == LVN_ITEMCHANGED && updating == false)
235
NMLISTVIEW* item = (NMLISTVIEW*) lParam;
236
if (item->iItem != -1 && (item->uChanged & LVIF_STATE) != 0)
238
// image is 1 if unchcked, 2 if checked
239
int oldImage = (item->uOldState & LVIS_STATEIMAGEMASK) >> 12;
240
int newImage = (item->uNewState & LVIS_STATEIMAGEMASK) >> 12;
241
if (oldImage != newImage)
242
OnToggle(item->iItem,newImage == 2);
249
void GenericListControl::Update()
252
int newRows = GetRowCount();
254
int items = ListView_GetItemCount(handle);
255
while (items < newRows)
258
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
259
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
266
ListView_InsertItem(handle, &lvI);
270
while (items > newRows)
272
ListView_DeleteItem(handle,--items);
277
InvalidateRect(handle,NULL,true);
278
UpdateWindow(handle);
283
void GenericListControl::SetCheckState(int item, bool state)
286
ListView_SetCheckState(handle,item,state ? TRUE : FALSE);
290
void GenericListControl::ResizeColumns()
294
inResizeColumns = true;
297
GetClientRect(handle, &rect);
299
int totalListSize = rect.right - rect.left;
300
for (int i = 0; i < columnCount; i++)
302
ListView_SetColumnWidth(handle, i, columns[i].size * totalListSize);
304
inResizeColumns = false;
307
LRESULT CALLBACK GenericListControl::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
309
GenericListControl* list = (GenericListControl*) GetWindowLongPtr(hwnd,GWLP_USERDATA);
312
if (list->valid && list->WindowMessage(msg,wParam,lParam,returnValue) == true)
318
list->ResizeColumns();
326
if (KeyDownAsync(VK_CONTROL))
331
if (KeyDownAsync(VK_CONTROL))
338
return (LRESULT)CallWindowProc((WNDPROC)list->oldProc,hwnd,msg,wParam,lParam);
341
void GenericListControl::ProcessCopy()
343
int start = GetSelectedIndex();
346
size = GetRowCount();
348
size = ListView_GetSelectedCount(handle);
350
CopyRows(start, size);
353
void GenericListControl::CopyRows(int start, int size)
357
if (start == 0 && size == GetRowCount())
359
// Let's also copy the header if everything is selected.
360
for (int c = 0; c < columnCount; ++c)
362
data.append(columns[c].name);
363
if (c < columnCount - 1)
366
data.append(L"\r\n");
370
for (int r = start; r < start + size; ++r)
372
for (int c = 0; c < columnCount; ++c)
375
GetColumnText(stringBuffer, r, c);
376
data.append(stringBuffer);
377
if (c < columnCount - 1)
380
data.append(L"\r\n");
383
W32Util::CopyTextToClipboard(handle, data);
386
void GenericListControl::SelectAll()
388
ListView_SetItemState(handle, -1, LVIS_SELECTED, LVIS_SELECTED);
391
int GenericListControl::GetSelectedIndex()
393
return ListView_GetNextItem(handle, -1, LVNI_SELECTED);
b'\\ No newline at end of file'