2 * Copyright 2000, International Business Machines Corporation and others.
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
11 #include <afs/param.h>
15 #include <WINNT/al_progress.h>
20 * DEFINITIONS ________________________________________________________________
24 #define WM_UPDATE_PROGRESS WM_TIMER
28 * PROTOTYPES _________________________________________________________________
34 * ROUTINES ___________________________________________________________________
38 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hWnd)
44 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hParent, int iddTemplate, DLGPROC dlgproc)
47 dlgproc = (DLGPROC)PROGRESSDISPLAY::ProgressDisplay_StubProc;
48 HWND hWnd = ModelessDialogParam (iddTemplate, hParent, dlgproc, (LPARAM)this);
50 m_fCreatedWindow = TRUE;
54 PROGRESSDISPLAY::~PROGRESSDISPLAY (void)
57 SetWindowLong (m_hWnd, DWL_USER, (LONG)0);
58 DeleteCriticalSection (&m_cs);
60 DestroyWindow (m_hWnd);
64 void PROGRESSDISPLAY::Init (HWND hWnd)
66 SetWindowLong (hWnd, DWL_USER, (LONG)this);
67 Subclass_AddHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
72 InitializeCriticalSection (&m_cs);
74 m_fCreatedWindow = FALSE;
80 GetDlgItemText (m_hWnd, IDC_OPERATION, m_szOperation, cchRESOURCE);
81 GetDlgItemText (m_hWnd, IDC_PROGRESSTEXT, m_szProgressText, cchRESOURCE);
82 SendDlgItemMessage (m_hWnd, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0,100));
83 SetProgressRange (0, 100);
88 HWND PROGRESSDISPLAY::GetWindow (void)
93 void PROGRESSDISPLAY::GetProgressRange (int *piStart, int *piFinish)
95 EnterCriticalSection (&m_cs);
98 *piStart = m_iProgressStart;
100 *piFinish = m_iProgressFinish;
102 LeaveCriticalSection (&m_cs);
106 void PROGRESSDISPLAY::SetProgressRange (int iStart, int iFinish)
108 EnterCriticalSection (&m_cs);
110 m_iProgressStart = iStart;
111 m_iProgressFinish = iFinish;
112 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
114 LeaveCriticalSection (&m_cs);
118 int PROGRESSDISPLAY::GetProgress (void)
120 EnterCriticalSection (&m_cs);
122 int iProgress = m_iProgress;
124 LeaveCriticalSection (&m_cs);
129 void PROGRESSDISPLAY::SetProgress (int iProgress)
131 EnterCriticalSection (&m_cs);
133 m_iProgress = max( m_iProgress, iProgress );
134 m_iProgress = min( max( m_iProgress, m_iProgressStart ), m_iProgressFinish );
135 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
137 LeaveCriticalSection (&m_cs);
141 void PROGRESSDISPLAY::GetOperation (LPTSTR pszOperation)
143 EnterCriticalSection (&m_cs);
145 lstrcpy (pszOperation, m_szOperation);
147 LeaveCriticalSection (&m_cs);
151 void PROGRESSDISPLAY::SetOperation (LPCTSTR pszOperation)
153 EnterCriticalSection (&m_cs);
155 lstrcpy (m_szOperation, pszOperation);
156 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
158 LeaveCriticalSection (&m_cs);
162 LPPROGRESSDISPLAY PROGRESSDISPLAY::GetProgressDisplay (HWND hWnd)
164 LPPROGRESSDISPLAY ppd = NULL;
167 if ((ppd = (LPPROGRESSDISPLAY)(GetWindowLong (hWnd, DWL_USER))) != NULL) {
168 if (ppd->m_hWnd != hWnd)
179 BOOL CALLBACK PROGRESSDISPLAY::ProgressDisplay_StubProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
185 BOOL CALLBACK PROGRESSDISPLAY::ProgressDisplay_HookProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
187 PVOID oldproc = Subclass_FindNextHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
191 case WM_UPDATE_PROGRESS:
194 LPPROGRESSDISPLAY ppd;
195 if ((ppd = PROGRESSDISPLAY::GetProgressDisplay (hWnd)) != NULL)
202 Subclass_RemoveHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
207 return CallWindowProc ((WNDPROC)oldproc, hWnd, msg, wp, lp);
209 return DefWindowProc (hWnd, msg, wp, lp);
213 void PROGRESSDISPLAY::SetFinishMessage (int msgFinish)
215 m_msgFinish = msgFinish;
219 void PROGRESSDISPLAY::Show (DWORD (CALLBACK *pfn)(LPPROGRESSDISPLAY ppd, LPARAM lp), LPARAM lp)
224 InterlockedIncrement (&m_cRef);
226 ShowWindow (m_hWnd, SW_SHOW);
229 HANDLE hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)(PROGRESSDISPLAY::ThreadProc), this, 0, &dwThreadID);
231 if (m_msgFinish == 0)
234 while (GetMessage (&msg, 0, 0, NULL))
236 if (!IsDialogMessage (m_hWnd, &msg))
238 TranslateMessage (&msg);
239 DispatchMessage (&msg);
242 EnterCriticalSection (&m_cs);
243 BOOL fBreak = m_fFinished;
244 LeaveCriticalSection (&m_cs);
252 void PROGRESSDISPLAY::Finish (DWORD dwStatus)
254 EnterCriticalSection (&m_cs);
257 m_dwStatus = dwStatus;
259 PostMessage (m_hWnd, m_msgFinish, 0, 0);
261 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
263 LeaveCriticalSection (&m_cs);
265 if (InterlockedDecrement (&m_cRef) == 0)
270 DWORD PROGRESSDISPLAY::GetStatus (void)
272 EnterCriticalSection (&m_cs);
273 DWORD dwStatus = (m_fFinished) ? m_dwStatus : ERROR_BUSY;
274 LeaveCriticalSection (&m_cs);
279 void PROGRESSDISPLAY::Close (void)
281 EnterCriticalSection (&m_cs);
283 if (m_fCreatedWindow)
285 DestroyWindow (m_hWnd);
289 LeaveCriticalSection (&m_cs);
291 if (InterlockedDecrement (&m_cRef) == 0)
296 void PROGRESSDISPLAY::OnUpdate (void)
298 EnterCriticalSection (&m_cs);
301 if (m_iProgressFinish <= m_iProgressStart)
304 perComplete = 100 * (m_iProgress - m_iProgressStart) / (m_iProgressFinish - m_iProgressStart);
306 SendDlgItemMessage (m_hWnd, IDC_PROGRESS, PBM_SETPOS, (WPARAM)perComplete, 0);
308 LPTSTR pszProgressText = FormatString (m_szProgressText, TEXT("%lu"), perComplete);
309 SetDlgItemText (m_hWnd, IDC_PROGRESSTEXT, pszProgressText);
310 FreeString (pszProgressText);
312 SetDlgItemText (m_hWnd, IDC_OPERATION, m_szOperation);
314 LeaveCriticalSection (&m_cs);
318 DWORD WINAPI PROGRESSDISPLAY::ThreadProc (PVOID lp)
320 LPPROGRESSDISPLAY ppd;
321 if ((ppd = (LPPROGRESSDISPLAY)lp) != NULL) {
325 dwStatus = (*(ppd->m_pfnUser))(ppd, ppd->m_lpUser);
327 dwStatus = ERROR_PROCESS_ABORTED;
330 ppd->Finish (dwStatus);