~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to Windows/W32Util/Misc.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "stdafx.h"
 
2
#include "CommonWindows.h"
 
3
 
 
4
#include <WinUser.h>
 
5
#include <shellapi.h>
 
6
#include <commctrl.h>
 
7
 
 
8
#include "Misc.h"
 
9
#include "util/text/utf8.h"
 
10
 
 
11
bool IsVistaOrHigher() {
 
12
        OSVERSIONINFOEX osvi;
 
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;
 
19
 
 
20
        VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
 
21
        VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
 
22
 
 
23
        return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE;
 
24
}
 
25
 
 
26
namespace W32Util
 
27
{
 
28
        void CenterWindow(HWND hwnd)
 
29
        {
 
30
                HWND hwndParent;
 
31
                RECT rect, rectP;
 
32
                int width, height;      
 
33
                int screenwidth, screenheight;
 
34
                int x, y;
 
35
 
 
36
                //make the window relative to its parent
 
37
                hwndParent = GetParent(hwnd);
 
38
                if (!hwndParent)
 
39
                        return;
 
40
 
 
41
                GetWindowRect(hwnd, &rect);
 
42
                GetWindowRect(hwndParent, &rectP);
 
43
 
 
44
                width  = rect.right  - rect.left;
 
45
                height = rect.bottom - rect.top;
 
46
 
 
47
                x = ((rectP.right-rectP.left) -  width) / 2 + rectP.left;
 
48
                y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top;
 
49
 
 
50
                screenwidth  = GetSystemMetrics(SM_CXSCREEN);
 
51
                screenheight = GetSystemMetrics(SM_CYSCREEN);
 
52
 
 
53
                //make sure that the dialog box never moves outside of
 
54
                //the screen
 
55
                if(x < 0) x = 0;
 
56
                if(y < 0) y = 0;
 
57
                if(x + width  > screenwidth)  x = screenwidth  - width;
 
58
                if(y + height > screenheight) y = screenheight - height;
 
59
 
 
60
                MoveWindow(hwnd, x, y, width, height, FALSE);
 
61
        }
 
62
 
 
63
        void NiceSizeFormat(size_t size, char *out)
 
64
        {
 
65
                char *sizes[] = {"B","KB","MB","GB","TB","PB","EB"};
 
66
                int s = 0;
 
67
                int frac = 0;
 
68
                while (size>=1024)
 
69
                {
 
70
                        s++;
 
71
                        frac = (int)size & 1023;
 
72
                        size /= 1024;
 
73
                }
 
74
                float f = (float)size + ((float)frac / 1024.0f);
 
75
                if (s==0)
 
76
                        sprintf(out, "%d B", (int)size);
 
77
                else
 
78
                        sprintf(out, "%3.1f %s", f, sizes[s]);
 
79
        }
 
80
 
 
81
        BOOL CopyTextToClipboard(HWND hwnd, const char *text) {
 
82
                std::wstring wtext = ConvertUTF8ToWString(text);
 
83
                return CopyTextToClipboard(hwnd, wtext);
 
84
        }
 
85
 
 
86
        BOOL CopyTextToClipboard(HWND hwnd, const std::wstring &wtext) {
 
87
                OpenClipboard(hwnd);
 
88
                EmptyClipboard();
 
89
                HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (wtext.size() + 1) * sizeof(wchar_t));
 
90
                if (hglbCopy == NULL) {
 
91
                        CloseClipboard();
 
92
                        return FALSE;
 
93
                }
 
94
 
 
95
                // Lock the handle and copy the text to the buffer.
 
96
 
 
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);
 
102
                CloseClipboard();
 
103
                return TRUE;
 
104
        }
 
105
 
 
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);
 
110
        }
 
111
 
 
112
        static const wchar_t *RemoveExecutableFromCommandLine(const wchar_t *cmdline) {
 
113
                if (!cmdline) {
 
114
                        return L"";
 
115
                }
 
116
 
 
117
                switch (cmdline[0]) {
 
118
                case '"':
 
119
                        // We don't need to handle escaped quotes, since filenames can't have that.
 
120
                        cmdline = wcschr(cmdline + 1, '"');
 
121
                        if (cmdline) {
 
122
                                ++cmdline;
 
123
                                if (cmdline[0] == ' ') {
 
124
                                        ++cmdline;
 
125
                                }
 
126
                        }
 
127
                        break;
 
128
 
 
129
                default:
 
130
                        cmdline = wcschr(cmdline, ' ');
 
131
                        if (cmdline) {
 
132
                                ++cmdline;
 
133
                        }
 
134
                        break;
 
135
                }
 
136
 
 
137
                return cmdline;
 
138
        }
 
139
 
 
140
        void ExitAndRestart() {
 
141
                // This preserves arguments (for example, config file) and working directory.
 
142
 
 
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);
 
149
 
 
150
                ExitProcess(0);
 
151
        }
 
152
}
 
153
 
 
154
 
 
155
 
 
156
GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def)
 
157
        : handle(hwnd), columns(def.columns),columnCount(def.columnCount),valid(false),
 
158
        inResizeColumns(false),updating(false)
 
159
{
 
160
        DWORD style = GetWindowLong(handle,GWL_STYLE) | LVS_REPORT;
 
161
        SetWindowLong(handle, GWL_STYLE, style);
 
162
 
 
163
        SetWindowLongPtr(handle,GWLP_USERDATA,(LONG_PTR)this);
 
164
        oldProc = (WNDPROC) SetWindowLongPtr(handle,GWLP_WNDPROC,(LONG_PTR)wndProc);
 
165
 
 
166
        auto exStyle = LVS_EX_FULLROWSELECT;
 
167
        if (def.checkbox)
 
168
                exStyle |= LVS_EX_CHECKBOXES;
 
169
        SendMessage(handle, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, exStyle);
 
170
 
 
171
        LVCOLUMN lvc; 
 
172
        lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
 
173
        lvc.iSubItem = 0;
 
174
        
 
175
        RECT rect;
 
176
        GetClientRect(handle,&rect);
 
177
 
 
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;
 
182
 
 
183
                if (columns[i].flags & GLVC_CENTERED)
 
184
                        lvc.fmt = LVCFMT_CENTER;
 
185
                else
 
186
                        lvc.fmt = LVCFMT_LEFT;
 
187
 
 
188
                ListView_InsertColumn(handle, i, &lvc);
 
189
        }
 
190
 
 
191
        if (def.columnOrder != NULL)
 
192
                ListView_SetColumnOrderArray(handle,columnCount,def.columnOrder);
 
193
 
 
194
        SetSendInvalidRows(false);
 
195
        valid = true;
 
196
}
 
197
 
 
198
void GenericListControl::HandleNotify(LPARAM lParam)
 
199
{
 
200
        LPNMHDR mhdr = (LPNMHDR) lParam;
 
201
 
 
202
        if (mhdr->code == NM_DBLCLK)
 
203
        {
 
204
                LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
 
205
                if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
 
206
                        OnDoubleClick(item->iItem,item->iSubItem);
 
207
                return;
 
208
        }
 
209
 
 
210
        if (mhdr->code == NM_RCLICK)
 
211
        {
 
212
                const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
 
213
                if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
 
214
                        OnRightClick(item->iItem,item->iSubItem,item->ptAction);
 
215
                return;
 
216
        }
 
217
 
 
218
        if (mhdr->code == LVN_GETDISPINFO)
 
219
        {
 
220
                NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
 
221
 
 
222
                stringBuffer[0] = 0;
 
223
                GetColumnText(stringBuffer,dispInfo->item.iItem,dispInfo->item.iSubItem);
 
224
                
 
225
                if (stringBuffer[0] == 0)
 
226
                        wcscat(stringBuffer,L"Invalid");
 
227
 
 
228
                dispInfo->item.pszText = stringBuffer;
 
229
                return;
 
230
        }
 
231
         
 
232
        // handle checkboxes
 
233
        if (mhdr->code == LVN_ITEMCHANGED && updating == false)
 
234
        {
 
235
                NMLISTVIEW* item = (NMLISTVIEW*) lParam;
 
236
                if (item->iItem != -1 && (item->uChanged & LVIF_STATE) != 0)
 
237
                {
 
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);
 
243
                }
 
244
 
 
245
                return;
 
246
        }
 
247
}
 
248
 
 
249
void GenericListControl::Update()
 
250
{
 
251
        updating = true;
 
252
        int newRows = GetRowCount();
 
253
 
 
254
        int items = ListView_GetItemCount(handle);
 
255
        while (items < newRows)
 
256
        {
 
257
                LVITEM lvI;
 
258
                lvI.pszText   = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
 
259
                lvI.mask      = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
 
260
                lvI.stateMask = 0;
 
261
                lvI.iSubItem  = 0;
 
262
                lvI.state     = 0;
 
263
                lvI.iItem  = items;
 
264
                lvI.iImage = items;
 
265
 
 
266
                ListView_InsertItem(handle, &lvI);
 
267
                items++;
 
268
        }
 
269
 
 
270
        while (items > newRows)
 
271
        {
 
272
                ListView_DeleteItem(handle,--items);
 
273
        }
 
274
 
 
275
        ResizeColumns();
 
276
 
 
277
        InvalidateRect(handle,NULL,true);
 
278
        UpdateWindow(handle);
 
279
        updating = false;
 
280
}
 
281
 
 
282
 
 
283
void GenericListControl::SetCheckState(int item, bool state)
 
284
{
 
285
        updating = true;
 
286
        ListView_SetCheckState(handle,item,state ? TRUE : FALSE);
 
287
        updating = false;
 
288
}
 
289
 
 
290
void GenericListControl::ResizeColumns()
 
291
{
 
292
        if (inResizeColumns)
 
293
                return;
 
294
        inResizeColumns = true;
 
295
 
 
296
        RECT rect;
 
297
        GetClientRect(handle, &rect);
 
298
 
 
299
        int totalListSize = rect.right - rect.left;
 
300
        for (int i = 0; i < columnCount; i++)
 
301
        {
 
302
                ListView_SetColumnWidth(handle, i, columns[i].size * totalListSize);
 
303
        }
 
304
        inResizeColumns = false;
 
305
}
 
306
 
 
307
LRESULT CALLBACK GenericListControl::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
308
{
 
309
        GenericListControl* list = (GenericListControl*) GetWindowLongPtr(hwnd,GWLP_USERDATA);
 
310
 
 
311
        LRESULT returnValue;
 
312
        if (list->valid && list->WindowMessage(msg,wParam,lParam,returnValue) == true)
 
313
                return returnValue;
 
314
 
 
315
        switch (msg)
 
316
        {
 
317
        case WM_SIZE:
 
318
                list->ResizeColumns();
 
319
                break;
 
320
 
 
321
        case WM_KEYDOWN:
 
322
                switch (wParam)
 
323
                {
 
324
                case VK_INSERT:
 
325
                case 'C':
 
326
                        if (KeyDownAsync(VK_CONTROL))
 
327
                                list->ProcessCopy();
 
328
                        break;
 
329
 
 
330
                case 'A':
 
331
                        if (KeyDownAsync(VK_CONTROL))
 
332
                                list->SelectAll();
 
333
                        break;
 
334
                }
 
335
                break;
 
336
        }
 
337
 
 
338
        return (LRESULT)CallWindowProc((WNDPROC)list->oldProc,hwnd,msg,wParam,lParam);
 
339
}
 
340
 
 
341
void GenericListControl::ProcessCopy()
 
342
{
 
343
        int start = GetSelectedIndex();
 
344
        int size;
 
345
        if (start == -1)
 
346
                size = GetRowCount();
 
347
        else
 
348
                size = ListView_GetSelectedCount(handle);
 
349
 
 
350
        CopyRows(start, size);
 
351
}
 
352
 
 
353
void GenericListControl::CopyRows(int start, int size)
 
354
{
 
355
        std::wstring data;
 
356
 
 
357
        if (start == 0 && size == GetRowCount())
 
358
        {
 
359
                // Let's also copy the header if everything is selected.
 
360
                for (int c = 0; c < columnCount; ++c)
 
361
                {
 
362
                        data.append(columns[c].name);
 
363
                        if (c < columnCount - 1)
 
364
                                data.append(L"\t");
 
365
                        else
 
366
                                data.append(L"\r\n");
 
367
                }
 
368
        }
 
369
 
 
370
        for (int r = start; r < start + size; ++r)
 
371
        {
 
372
                for (int c = 0; c < columnCount; ++c)
 
373
                {
 
374
                        stringBuffer[0] = 0;
 
375
                        GetColumnText(stringBuffer, r, c);
 
376
                        data.append(stringBuffer);
 
377
                        if (c < columnCount - 1)
 
378
                                data.append(L"\t");
 
379
                        else
 
380
                                data.append(L"\r\n");
 
381
                }
 
382
        }
 
383
        W32Util::CopyTextToClipboard(handle, data);
 
384
}
 
385
 
 
386
void GenericListControl::SelectAll()
 
387
{
 
388
        ListView_SetItemState(handle, -1, LVIS_SELECTED, LVIS_SELECTED);
 
389
}
 
390
 
 
391
int GenericListControl::GetSelectedIndex()
 
392
{
 
393
        return ListView_GetNextItem(handle, -1, LVNI_SELECTED);
 
394
}
 
 
b'\\ No newline at end of file'