#include #include #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(SetWindowLongPtr( hWnd, GWLP_WNDPROC, reinterpret_cast(Except<::WndProc>))); if (!SetPropW(hWnd, L"this", reinterpret_cast(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(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(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(GetProp(hWnd, L"this")); if (uMsg == WM_DESTROY) RemovePropW(hWnd, L"this"); return lv? lv->WndProc(hWnd, uMsg, wParam, lParam): FALSE; }