1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#include <windows.h>
#include <commctrl.h>
#include "drag.h"
#include "err.h"
#include "listview.h"
#include "win32.h"
#include "window.h"
/* Actual window procedure for all list views, which calls the
* appropriate WndProc member function. */
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ListView::ListView(Window& parent, const HMENU hMenu, const DWORD dwStyle) : parent(parent)
{
extern HFONT g_hfNormal;
if (!(hWnd = CreateWindowExW(
WS_EX_CLIENTEDGE,
WC_LISTVIEW,
L"",
dwStyle|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS,
0, 0, 0, 0,
parent.hWnd, hMenu, GetModuleHandle(nullptr), this)))
throw Err(WINDOWS, L"List view could not be created");
m_proc0 = reinterpret_cast<WNDPROC>(SetWindowLongPtr(
hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(Except<::WndProc>)));
if (!SetPropW(hWnd, L"this", reinterpret_cast<HANDLE>(this)))
throw Err(WINDOWS, L"List view property could not be set");
ListView_SetExtendedListViewStyle(hWnd, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
SendMessageW(hWnd, WM_SETFONT, reinterpret_cast<WPARAM>(g_hfNormal), MAKELPARAM(FALSE, 0));
}
int ListView::Height() noexcept
{
const int cItem = ListView_GetItemCount(hWnd);
return Dpi(4)+cItem*Dpi(19);
}
void ListView::ResizeColumns(int) {}
void ListView::UpdateTheme(const bool bThemeActive)
{
const wchar_t* theme;
WORD action;
extern HRESULT (__stdcall *SetWindowTheme)(HWND, const wchar_t*, const wchar_t*);
if (!SetWindowTheme) return;
if (bThemeActive) {
theme = L"Explorer";
action = UIS_SET;
} else {
theme = nullptr;
action = UIS_CLEAR;
}
/* Use modern "Explorer" theme. */
SetWindowTheme(hWnd, theme, nullptr);
/* Hide focus rectangles. */
SendMessageW(hWnd, WM_UPDATEUISTATE, MAKEWPARAM(action, UISF_HIDEFOCUS), 0);
}
LRESULT CALLBACK ListView::WndProc(const HWND hWnd, const UINT uMsg,
const WPARAM wParam, const LPARAM lParam)
{
switch (uMsg) {
case WM_NOTIFY:
switch (reinterpret_cast<NMHDR*>(lParam)->code) {
case HDN_ENDTRACK:
parent.UpdateLayout();
return TRUE;
}
break;
case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN:
if (parent.dragDlv.HandleLButtonDown())
return 0;
break;
}
return CallWindowProc(m_proc0, hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
const LPARAM lParam)
{
ListView* const lv = reinterpret_cast<ListView*>(GetProp(hWnd, L"this"));
if (uMsg == WM_DESTROY)
RemovePropW(hWnd, L"this");
return lv? lv->WndProc(hWnd, uMsg, wParam, lParam): FALSE;
}
|