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
14 #include <afs/param.h>
18 #include <WINNT/al_progress.h>
23 * DEFINITIONS ________________________________________________________________
27 #define WM_UPDATE_PROGRESS WM_TIMER
31 * PROTOTYPES _________________________________________________________________
37 * ROUTINES ___________________________________________________________________
41 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hWnd)
47 PROGRESSDISPLAY::PROGRESSDISPLAY (HWND hParent, int iddTemplate, DLGPROC dlgproc)
50 dlgproc = (DLGPROC)PROGRESSDISPLAY::ProgressDisplay_StubProc;
51 HWND hWnd = ModelessDialogParam (iddTemplate, hParent, dlgproc, (LPARAM)this);
53 m_fCreatedWindow = TRUE;
57 PROGRESSDISPLAY::~PROGRESSDISPLAY (void)
60 SetWindowLongPtr (m_hWnd, DWLP_USER, (LONG)0);
61 DeleteCriticalSection (&m_cs);
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);
75 InitializeCriticalSection (&m_cs);
77 m_fCreatedWindow = FALSE;
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);
91 HWND PROGRESSDISPLAY::GetWindow (void)
96 void PROGRESSDISPLAY::GetProgressRange (int *piStart, int *piFinish)
98 EnterCriticalSection (&m_cs);
101 *piStart = m_iProgressStart;
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);
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;
170 if ((ppd = (LPPROGRESSDISPLAY)(GetWindowLongPtr (hWnd, DWLP_USER))) != NULL) {
171 if (ppd->m_hWnd != hWnd)
182 HRESULT CALLBACK PROGRESSDISPLAY::ProgressDisplay_StubProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
188 HRESULT CALLBACK PROGRESSDISPLAY::ProgressDisplay_HookProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
190 PVOID oldproc = Subclass_FindNextHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
194 case WM_UPDATE_PROGRESS:
197 LPPROGRESSDISPLAY ppd;
198 if ((ppd = PROGRESSDISPLAY::GetProgressDisplay (hWnd)) != NULL)
205 Subclass_RemoveHook (hWnd, PROGRESSDISPLAY::ProgressDisplay_HookProc);
210 return CallWindowProc ((WNDPROC)oldproc, hWnd, msg, wp, lp);
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)
227 InterlockedIncrement (&m_cRef);
229 ShowWindow (m_hWnd, SW_SHOW);
232 HANDLE hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)(PROGRESSDISPLAY::ThreadProc), this, 0, &dwThreadID);
234 if (m_msgFinish == 0)
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);
255 void PROGRESSDISPLAY::Finish (DWORD dwStatus)
257 EnterCriticalSection (&m_cs);
260 m_dwStatus = dwStatus;
262 PostMessage (m_hWnd, m_msgFinish, 0, 0);
264 PostMessage (m_hWnd, WM_UPDATE_PROGRESS, 0, 0);
266 LeaveCriticalSection (&m_cs);
268 if (InterlockedDecrement (&m_cRef) == 0)
273 DWORD PROGRESSDISPLAY::GetStatus (void)
275 EnterCriticalSection (&m_cs);
276 DWORD dwStatus = (m_fFinished) ? m_dwStatus : ERROR_BUSY;
277 LeaveCriticalSection (&m_cs);
282 void PROGRESSDISPLAY::Close (void)
284 EnterCriticalSection (&m_cs);
286 if (m_fCreatedWindow)
288 DestroyWindow (m_hWnd);
292 LeaveCriticalSection (&m_cs);
294 if (InterlockedDecrement (&m_cRef) == 0)
299 void PROGRESSDISPLAY::OnUpdate (void)
301 EnterCriticalSection (&m_cs);
304 if (m_iProgressFinish <= m_iProgressStart)
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) {
328 dwStatus = (*(ppd->m_pfnUser))(ppd, ppd->m_lpUser);
330 dwStatus = ERROR_PROCESS_ABORTED;
333 ppd->Finish (dwStatus);