|
1
|
1 #include "stdafx.h"
|
|
|
2
|
|
|
3 // Simple CListControl use demo
|
|
|
4 // CListControlSimple
|
|
|
5
|
|
|
6 #include "stdafx.h"
|
|
|
7 #include "resource.h"
|
|
|
8 #include <helpers/atl-misc.h>
|
|
|
9 #include <libPPUI/CListControlSimple.h>
|
|
|
10 #include <string>
|
|
|
11 #include <algorithm>
|
|
|
12 #include <vector>
|
|
|
13
|
|
|
14 #include <helpers/DarkMode.h>
|
|
|
15
|
|
|
16 namespace {
|
|
|
17 struct listData_t {
|
|
|
18 std::string m_key, m_value;
|
|
|
19 };
|
|
|
20 static std::vector<listData_t> makeListData() {
|
|
|
21 std::vector<listData_t> data;
|
|
|
22 data.resize( 10 );
|
|
|
23 for( size_t walk = 0; walk < data.size(); ++ walk ) {
|
|
|
24 auto & rec = data[walk];
|
|
|
25 rec.m_key = (PFC_string_formatter() << "Item #" << (walk+1) ).c_str();
|
|
|
26 rec.m_value = "sample value";
|
|
|
27 }
|
|
|
28 return data;
|
|
|
29 }
|
|
|
30
|
|
|
31
|
|
|
32 class CListControlSimpleDemoDialog : public CDialogImpl<CListControlSimpleDemoDialog> {
|
|
|
33 public:
|
|
|
34
|
|
|
35 enum { IDD = IDD_LISTCONTROL_DEMO };
|
|
|
36
|
|
|
37 BEGIN_MSG_MAP_EX(CListControlOwnerDataDemoDialog)
|
|
|
38 MSG_WM_INITDIALOG(OnInitDialog)
|
|
|
39 COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnCancel)
|
|
|
40 MSG_WM_CONTEXTMENU(OnContextMenu)
|
|
|
41 END_MSG_MAP()
|
|
|
42 private:
|
|
|
43 void OnCancel(UINT, int, CWindow) {
|
|
|
44 DestroyWindow();
|
|
|
45 }
|
|
|
46
|
|
|
47 BOOL OnInitDialog(CWindow, LPARAM) {
|
|
|
48
|
|
|
49 // Create replacing existing windows list control
|
|
|
50 // automatically initialize position, font, etc
|
|
|
51 m_list.CreateInDialog( *this, IDC_LIST1 );
|
|
|
52
|
|
|
53 // Do this AFTER creating CListControl, so dark mode hook talks to new CListControl rather than shortlived IDC_LIST1 placeholder
|
|
|
54 m_dark.AddDialogWithControls(*this);
|
|
|
55
|
|
|
56 // never hardcode values in pixels, always use screen DPI
|
|
|
57 auto DPI = m_list.GetDPI();
|
|
|
58 m_list.AddColumn( "Name", MulDiv(100, DPI.cx, 96 ) );
|
|
|
59 m_list.AddColumn( "Value", MulDiv(150, DPI.cx, 96 ) );
|
|
|
60
|
|
|
61 {
|
|
|
62 auto data = makeListData();
|
|
|
63
|
|
|
64 m_list.SetItemCount( data.size( ) );
|
|
|
65 for( size_t walk = 0; walk < data.size(); ++ walk ) {
|
|
|
66 auto & rec = data[walk];
|
|
|
67 m_list.SetItemText( walk, 0, rec.m_key.c_str() );
|
|
|
68 m_list.SetItemText( walk, 1, rec.m_value.c_str() );
|
|
|
69 }
|
|
|
70 }
|
|
|
71
|
|
|
72 ShowWindow(SW_SHOW);
|
|
|
73
|
|
|
74 return TRUE; // system should set focus
|
|
|
75 }
|
|
|
76
|
|
|
77 // Context menu handler
|
|
|
78 void OnContextMenu(CWindow wnd, CPoint point) {
|
|
|
79 // did we get a (-1,-1) point due to context menu key rather than right click?
|
|
|
80 // GetContextMenuPoint fixes that, returning a proper point at which the menu should be shown
|
|
|
81 point = m_list.GetContextMenuPoint(point);
|
|
|
82
|
|
|
83 CMenu menu;
|
|
|
84 // WIN32_OP_D() : debug build only return value check
|
|
|
85 // Used to check for obscure errors in debug builds, does nothing (ignores errors) in release build
|
|
|
86 WIN32_OP_D(menu.CreatePopupMenu());
|
|
|
87
|
|
|
88 enum { ID_TEST1 = 1, ID_TEST2, ID_SELECTALL, ID_SELECTNONE, ID_INVERTSEL };
|
|
|
89 menu.AppendMenu(MF_STRING, ID_TEST1, L"Test 1");
|
|
|
90 menu.AppendMenu(MF_STRING, ID_TEST2, L"Test 2");
|
|
|
91 menu.AppendMenu(MF_SEPARATOR);
|
|
|
92 // Note: Ctrl+A handled automatically by CListControl, no need for us to catch it
|
|
|
93 menu.AppendMenu(MF_STRING, ID_SELECTALL, L"Select all\tCtrl+A");
|
|
|
94 menu.AppendMenu(MF_STRING, ID_SELECTNONE, L"Select none");
|
|
|
95 menu.AppendMenu(MF_STRING, ID_INVERTSEL, L"Invert selection");
|
|
|
96
|
|
|
97 int cmd;
|
|
|
98 {
|
|
|
99 // Callback object to show menu command descriptions in the status bar.
|
|
|
100 // it's actually a hidden window, needs a parent HWND, where we feed our control's HWND
|
|
|
101 CMenuDescriptionMap descriptions(m_hWnd);
|
|
|
102
|
|
|
103 // Set descriptions of all our items
|
|
|
104 descriptions.Set(ID_TEST1, "This is a test item #1");
|
|
|
105 descriptions.Set(ID_TEST2, "This is a test item #2");
|
|
|
106
|
|
|
107 descriptions.Set(ID_SELECTALL, "Selects all items");
|
|
|
108 descriptions.Set(ID_SELECTNONE, "Deselects all items");
|
|
|
109 descriptions.Set(ID_INVERTSEL, "Invert selection");
|
|
|
110
|
|
|
111 cmd = menu.TrackPopupMenuEx(TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, descriptions, nullptr);
|
|
|
112 }
|
|
|
113 switch(cmd) {
|
|
|
114 case ID_TEST1:
|
|
|
115 {
|
|
|
116 pfc::string_formatter msg;
|
|
|
117 msg << "Test command #1 triggered.\r\n";
|
|
|
118 msg << m_list.GetSelectedCount() << " items selected.";
|
|
|
119 // popup_message : non-blocking MessageBox equivalent
|
|
|
120 popup_message::g_show(msg, "Information");
|
|
|
121 }
|
|
|
122 break;
|
|
|
123 case ID_TEST2:
|
|
|
124 {
|
|
|
125 pfc::string_formatter msg;
|
|
|
126 msg << "Test command #1 triggered.\r\n";
|
|
|
127 msg << "Selected items:\r\n";
|
|
|
128 for( size_t walk = 0; walk < m_list.GetItemCount(); ++ walk) {
|
|
|
129 if ( m_list.IsItemSelected( walk ) ) {
|
|
|
130 msg << "#" << (walk+1) << "\r\n";
|
|
|
131 }
|
|
|
132 }
|
|
|
133 msg << "End selected items.";
|
|
|
134 // popup_message : non-blocking MessageBox equivalent
|
|
|
135 popup_message::g_show(msg, "Information");
|
|
|
136 }
|
|
|
137 break;
|
|
|
138 case ID_SELECTALL:
|
|
|
139 m_list.SelectAll(); // trivial
|
|
|
140 break;
|
|
|
141 case ID_SELECTNONE:
|
|
|
142 m_list.SelectNone(); // trivial
|
|
|
143 break;
|
|
|
144 case ID_INVERTSEL:
|
|
|
145 {
|
|
|
146 auto mask = m_list.GetSelectionMask();
|
|
|
147 m_list.SetSelection(
|
|
|
148 // Items which we alter - all of them
|
|
|
149 pfc::bit_array_true(),
|
|
|
150 // Selection values - NOT'd original selection mask
|
|
|
151 pfc::bit_array_not(mask)
|
|
|
152 );
|
|
|
153 // Exclusion of footer item from selection handled via CanSelectItem()
|
|
|
154 }
|
|
|
155 break;
|
|
|
156 }
|
|
|
157 }
|
|
|
158
|
|
|
159 private:
|
|
|
160
|
|
|
161 CListControlSimple m_list;
|
|
|
162
|
|
|
163 fb2k::CDarkModeHooks m_dark;
|
|
|
164 };
|
|
|
165 }
|
|
|
166
|
|
|
167 // Called from mainmenu.cpp
|
|
|
168 void RunListControlSimpleDemo() {
|
|
|
169 fb2k::newDialog<CListControlSimpleDemoDialog>();
|
|
|
170 }
|