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
);