1 // This file has been adapted to the Win32 version of apcctrl
2 // by Kern E. Sibbald. Many thanks to ATT and James Weatherall,
3 // the original author, for providing an excellent template.
4 //
5 // Rewrite/Refactoring by Adam Kropelin
6 //
7 // Copyright (2009) Adam D. Kropelin
8 // Copyright (2000) Kern E. Sibbald
9 //
10
11 // Implementation of the Events dialogue
12
13 #include <windows.h>
14 #include "winevents.h"
15 #include "resource.h"
16 #include "statmgr.h"
17 #include "listview.h"
18 #include "wintray.h"
19
20 // Constructor/destructor
upsEvents(HINSTANCE appinst,upsMenu * menu)21 upsEvents::upsEvents(HINSTANCE appinst, upsMenu *menu) :
22 _appinst(appinst),
23 _hwnd(NULL),
24 _menu(menu)
25 {
26 }
27
~upsEvents()28 upsEvents::~upsEvents()
29 {
30 }
31
32 // Dialog box handling functions
Show()33 void upsEvents::Show()
34 {
35 if (!_hwnd)
36 {
37 DialogBoxParam(_appinst,
38 MAKEINTRESOURCE(IDD_EVENTS),
39 NULL,
40 (DLGPROC)DialogProc,
41 (LONG)this);
42 }
43 }
44
DialogProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)45 BOOL CALLBACK upsEvents::DialogProc(
46 HWND hwnd,
47 UINT uMsg,
48 WPARAM wParam,
49 LPARAM lParam)
50 {
51 upsEvents *_this;
52
53 // Retrieve virtual 'this' pointer. When we come in here the first time for
54 // the WM_INITDIALOG message, the pointer is in lParam. We then store it in
55 // the user data so it can be retrieved on future calls.
56 if (uMsg == WM_INITDIALOG)
57 {
58 // Set dialog user data to our "this" pointer which comes in via lParam.
59 // On subsequent calls, this will be retrieved by the code below.
60 SetWindowLong(hwnd, GWL_USERDATA, lParam);
61 _this = (upsEvents *)lParam;
62 }
63 else
64 {
65 // We've previously been initialized, so retrieve pointer from user data
66 _this = (upsEvents *)GetWindowLong(hwnd, GWL_USERDATA);
67 }
68
69 // Call thru to non-static member function
70 return _this->DialogProcess(hwnd, uMsg, wParam, lParam);
71 }
72
DialogProcess(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)73 BOOL upsEvents::DialogProcess(
74 HWND hwnd,
75 UINT uMsg,
76 WPARAM wParam,
77 LPARAM lParam)
78 {
79 switch (uMsg) {
80 case WM_INITDIALOG:
81 // Silly: Save initial window size for use as minimum size. There's
82 // probably some programmatic way to fetch this from the resource when
83 // we need it, but I can't find it. So we'll save it at runtime.
84 GetWindowRect(hwnd, &_rect);
85
86 // Initialize control wrappers
87 _events = new ListView(hwnd, IDC_LIST, 1);
88
89 // Save a copy of our window handle for later use.
90 // Important to do this AFTER everything needed by Update() is
91 // initialized and ready to go since that function may be called at any
92 // time from the wintray timer thread.
93 _hwnd = hwnd;
94
95 // Show the dialog
96 _menu->Refresh();
97 SetForegroundWindow(hwnd);
98 return TRUE;
99
100 case WM_GETMINMAXINFO:
101 {
102 // Restrict minimum size to initial window size
103 MINMAXINFO *mmi = (MINMAXINFO*)lParam;
104 mmi->ptMinTrackSize.x = _rect.right - _rect.left;
105 mmi->ptMinTrackSize.y = _rect.bottom - _rect.top;
106 return TRUE;
107 }
108
109 case WM_SIZE:
110 {
111 // Fetch new window size (esp client area size)
112 WINDOWINFO wininfo;
113 wininfo.cbSize = sizeof(wininfo);
114 GetWindowInfo(hwnd, &wininfo);
115
116 // Fetch current listview position
117 HWND ctrl = GetDlgItem(hwnd, IDC_LIST);
118 RECT gridrect;
119 GetWindowRect(ctrl, &gridrect);
120
121 // Calculate new position and size of listview
122 int left = gridrect.left - wininfo.rcClient.left;
123 int top = gridrect.top - wininfo.rcClient.top;
124 int width = wininfo.rcClient.right - wininfo.rcClient.left - 2*left;
125 int height = wininfo.rcClient.bottom - wininfo.rcClient.top - top - left;
126
127 // Resize listview
128 SetWindowPos(
129 ctrl, NULL, left, top, width, height, SWP_NOZORDER | SWP_SHOWWINDOW);
130
131 return TRUE;
132 }
133
134 case WM_COMMAND:
135 switch (LOWORD(wParam)) {
136 case IDCANCEL:
137 case IDOK:
138 // Close the dialog
139 EndDialog(hwnd, TRUE);
140 return TRUE;
141 }
142 break;
143
144 case WM_DESTROY:
145 _mutex.lock();
146 _hwnd = NULL;
147 delete _events;
148 _mutex.unlock();
149 return TRUE;
150 }
151
152 return 0;
153 }
154
Update(StatMgr * statmgr)155 void upsEvents::Update(StatMgr *statmgr)
156 {
157 // Bail if window is not open
158 _mutex.lock();
159 if (!_hwnd)
160 {
161 _mutex.unlock();
162 return;
163 }
164
165 // Fetch events from apcctrl
166 alist<astring> events;
167 if (!statmgr->GetEvents(events) || events.empty())
168 {
169 _mutex.unlock();
170 return;
171 }
172
173 // Update listview
174 alist<astring> *data[] = {&events};
175 _events->UpdateAll(data);
176
177 _mutex.unlock();
178 }
179