Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsapplib / al_progress.cpp
blobbd88cbbc218f1556c5afc5613cd253c95fd7f1ce
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
18 #include <WINNT/al_progress.h>
19 #include <commctrl.h>
23 * DEFINITIONS ________________________________________________________________
27 #define WM_UPDATE_PROGRESS WM_TIMER
31 * PROTOTYPES _________________________________________________________________
37 * ROUTINES ___________________________________________________________________
41 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hWnd)
43 Init (hWnd);
47 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hParent, int iddTemplate, DLGPROC dlgproc)
49 if (dlgproc == 0)
50 dlgproc = (DLGPROC)PROGRESSDISPLAY::ProgressDisplay_StubProc;
51 HWND hWnd = ModelessDialogParam (iddTemplate, hParent, dlgproc, (LPARAM)this);
52 Init (hWnd);
53 m_fCreatedWindow = TRUE;
57 PROGRESSDISPLAY::~PROGRESSDISPLAY (void)
59 m_fFinished = TRUE;
60 SetWindowLongPtr (m_hWnd, DWLP_USER, (LONG)0);
61 DeleteCriticalSection (&m_cs);
62 if (m_fCreatedWindow)
63 DestroyWindow (m_hWnd);
67 void PROGRESSDISPLAY::Init (HWND hWnd)
69 SetWindowLongPtr (hWnd, DWLP_USER, (LONG_PTR)this);
70 Subclass_AddHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
72 m_msgFinish = 0;
73 m_fFinished = FALSE;
74 m_dwStatus = 0;
75 InitializeCriticalSection (&m_cs);
76 m_hWnd = hWnd;
77 m_fCreatedWindow = FALSE;
78 m_pfnUser = NULL;
79 m_lpUser = 0;
80 m_iProgress = 0;
81 m_cRef = 1;
83 GetDlgItemText (m_hWnd, IDC_OPERATION, m_szOperation, cchRESOURCE);
84 GetDlgItemText (m_hWnd, IDC_PROGRESSTEXT, m_szProgressText, cchRESOURCE);
85 SendDlgItemMessage (m_hWnd, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0,100));
86 SetProgressRange (0, 100);
87 SetProgress (0);
91 HWND PROGRESSDISPLAY::GetWindow (void)
93 return m_hWnd;
96 void PROGRESSDISPLAY::GetProgressRange (int *piStart, int *piFinish)
98 EnterCriticalSection (&m_cs);
100 if (piStart)
101 *piStart = m_iProgressStart;
102 if (piFinish)
103 *piFinish = m_iProgressFinish;
105 LeaveCriticalSection (&m_cs);
109 void PROGRESSDISPLAY::SetProgressRange (int iStart, int iFinish)
111 EnterCriticalSection (&m_cs);
113 m_iProgressStart = iStart;
114 m_iProgressFinish = iFinish;
115 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
117 LeaveCriticalSection (&m_cs);
121 int PROGRESSDISPLAY::GetProgress (void)
123 EnterCriticalSection (&m_cs);
125 int iProgress = m_iProgress;
127 LeaveCriticalSection (&m_cs);
128 return iProgress;
132 void PROGRESSDISPLAY::SetProgress (int iProgress)
134 EnterCriticalSection (&m_cs);
136 m_iProgress = max( m_iProgress, iProgress );
137 m_iProgress = min( max( m_iProgress, m_iProgressStart ), m_iProgressFinish );
138 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
140 LeaveCriticalSection (&m_cs);
144 void PROGRESSDISPLAY::GetOperation (LPTSTR pszOperation)
146 EnterCriticalSection (&m_cs);
148 lstrcpy (pszOperation, m_szOperation);
150 LeaveCriticalSection (&m_cs);
154 void PROGRESSDISPLAY::SetOperation (LPCTSTR pszOperation)
156 EnterCriticalSection (&m_cs);
158 lstrcpy (m_szOperation, pszOperation);
159 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
161 LeaveCriticalSection (&m_cs);
165 LPPROGRESSDISPLAY PROGRESSDISPLAY::GetProgressDisplay (HWND hWnd)
167 LPPROGRESSDISPLAY ppd = NULL;
169 try {
170 if ((ppd = (LPPROGRESSDISPLAY)(GetWindowLongPtr (hWnd, DWLP_USER))) != NULL) {
171 if (ppd->m_hWnd != hWnd)
172 ppd = NULL;
174 } catch(...) {
175 ppd = NULL;
178 return ppd;
182 HRESULT CALLBACK PROGRESSDISPLAY::ProgressDisplay_StubProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
184 return FALSE;
188 HRESULT CALLBACK PROGRESSDISPLAY::ProgressDisplay_HookProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
190 PVOID oldproc = Subclass_FindNextHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
192 switch (msg)
194 case WM_UPDATE_PROGRESS:
195 if (!wp && !lp)
197 LPPROGRESSDISPLAY ppd;
198 if ((ppd = PROGRESSDISPLAY::GetProgressDisplay (hWnd)) != NULL)
199 ppd->OnUpdate();
200 return TRUE;
202 break;
204 case WM_DESTROY:
205 Subclass_RemoveHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
206 break;
209 if (oldproc)
210 return CallWindowProc ((WNDPROC)oldproc, hWnd, msg, wp, lp);
211 else
212 return DefWindowProc (hWnd, msg, wp, lp);
216 void PROGRESSDISPLAY::SetFinishMessage (int msgFinish)
218 m_msgFinish = msgFinish;
222 void PROGRESSDISPLAY::Show (DWORD (CALLBACK *pfn)(LPPROGRESSDISPLAY ppd, LPARAM lp), LPARAM lp)
224 m_pfnUser = pfn;
225 m_lpUser = lp;
227 InterlockedIncrement (&m_cRef);
229 ShowWindow (m_hWnd, SW_SHOW);
231 DWORD dwThreadID;
232 HANDLE hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)(PROGRESSDISPLAY::ThreadProc), this, 0, &dwThreadID);
234 if (m_msgFinish == 0)
236 MSG msg;
237 while (GetMessage (&msg, 0, 0, NULL))
239 if (!IsDialogMessage (m_hWnd, &msg))
241 TranslateMessage (&msg);
242 DispatchMessage (&msg);
245 EnterCriticalSection (&m_cs);
246 BOOL fBreak = m_fFinished;
247 LeaveCriticalSection (&m_cs);
248 if (fBreak)
249 break;
255 void PROGRESSDISPLAY::Finish (DWORD dwStatus)
257 EnterCriticalSection (&m_cs);
259 m_fFinished = TRUE;
260 m_dwStatus = dwStatus;
261 if (m_msgFinish)
262 PostMessage (m_hWnd, m_msgFinish, 0, 0);
263 else
264 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
266 LeaveCriticalSection (&m_cs);
268 if (InterlockedDecrement (&m_cRef) == 0)
269 Delete (this);
273 DWORD PROGRESSDISPLAY::GetStatus (void)
275 EnterCriticalSection (&m_cs);
276 DWORD dwStatus = (m_fFinished) ? m_dwStatus : ERROR_BUSY;
277 LeaveCriticalSection (&m_cs);
278 return dwStatus;
282 void PROGRESSDISPLAY::Close (void)
284 EnterCriticalSection (&m_cs);
286 if (m_fCreatedWindow)
288 DestroyWindow (m_hWnd);
289 m_hWnd = NULL;
292 LeaveCriticalSection (&m_cs);
294 if (InterlockedDecrement (&m_cRef) == 0)
295 Delete (this);
299 void PROGRESSDISPLAY::OnUpdate (void)
301 EnterCriticalSection (&m_cs);
303 int perComplete;
304 if (m_iProgressFinish <= m_iProgressStart)
305 perComplete = 100;
306 else
307 perComplete = 100 * (m_iProgress - m_iProgressStart) / (m_iProgressFinish - m_iProgressStart);
309 SendDlgItemMessage (m_hWnd, IDC_PROGRESS, PBM_SETPOS, (WPARAM)perComplete, 0);
311 LPTSTR pszProgressText = FormatString (m_szProgressText, TEXT("%lu"), perComplete);
312 SetDlgItemText (m_hWnd, IDC_PROGRESSTEXT, pszProgressText);
313 FreeString (pszProgressText);
315 SetDlgItemText (m_hWnd, IDC_OPERATION, m_szOperation);
317 LeaveCriticalSection (&m_cs);
321 DWORD WINAPI PROGRESSDISPLAY::ThreadProc (PVOID lp)
323 LPPROGRESSDISPLAY ppd;
324 if ((ppd = (LPPROGRESSDISPLAY)lp) != NULL) {
325 DWORD dwStatus;
327 try {
328 dwStatus = (*(ppd->m_pfnUser))(ppd, ppd->m_lpUser);
329 } catch(...) {
330 dwStatus = ERROR_PROCESS_ABORTED;
333 ppd->Finish (dwStatus);
335 return 0;