CFugue
UPDialog.cpp
1 #include "stdafx.h"
2 #include "updialog.h"
3 
4 // Disable the nasty warnings - we know what we are doing !!
5 #pragma warning(disable : 4244) // disable: conversion from 'LONG_PTR' to 'LONG', possible loss of data
6 #pragma warning(disable : 4312) // disable: conversion from 'LONG' to 'CUPDialog *' of greater size
7 #pragma warning(disable : 4996) // disable: 'wcsncpy' was declared deprecated
8 
9 /////////////////////////////////////////////////////////////////////////////////////////////
10 // Built-in Dialog Template.
11 //
12 // Generated using DlgResToDlgTemplate tool (http://www.codeproject.com/dialog/w32inputbox_1.asp). Thanks to its Author.
13 //
14 // #define IDD_PROGRESS_DIALOG 145
15 // #define IDC_PROGRESS_BAR 1018
16 // #define IDC_PROGRESS_TEXT 1026
17 //
18 // IDD_PROGRESS_DIALOG DIALOG 0, 0, 187, 70
19 // STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
20 // CAPTION "Dialog"
21 // FONT 8, "MS Shell Dlg"
22 // BEGIN
23 // PUSHBUTTON "&Cancel",IDCANCEL,129,50,50,14
24 // CONTROL "",IDC_PROGRESS_BAR,"msctls_progress32",WS_BORDER,7,25,172,14
25 // LTEXT "Static",IDC_PROGRESS_TEXT,7,7,172,8,SS_CENTERIMAGE
26 // END
27 //
28 static const unsigned char dlg_145[] =
29 {
30  0xc8,0x08,0xc8,0x82,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xbb,0x00,0x46,
31  0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x69,0x00,0x61,0x00,0x6c,0x00,0x6f,0x00,0x67,
32  0x00,0x00,0x00,0x08,0x00,0x4d,0x00,0x53,0x00,0x20,0x00,0x53,0x00,0x68,0x00,0x65,
33  0x00,0x6c,0x00,0x6c,0x00,0x20,0x00,0x44,0x00,0x6c,0x00,0x67,0x00,0x00,0x00,0x00,
34  0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x81,0x00,0x32,0x00,0x32,0x00,0x0e,0x00,0x02,
35  0x00,0xff,0xff,0x80,0x00,0x26,0x00,0x43,0x00,0x61,0x00,0x6e,0x00,0x63,0x00,0x65,
36  0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x50,0x00,0x00,0x00,0x00,0x07,
37  0x00,0x19,0x00,0xac,0x00,0x0e,0x00,0xfa,0x03,0x6d,0x00,0x73,0x00,0x63,0x00,0x74,
38  0x00,0x6c,0x00,0x73,0x00,0x5f,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x67,0x00,0x72,
39  0x00,0x65,0x00,0x73,0x00,0x73,0x00,0x33,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,
40  0x00,0x00,0x00,0x00,0x02,0x02,0x50,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0xac,
41  0x00,0x08,0x00,0x02,0x04,0xff,0xff,0x82,0x00,0x53,0x00,0x74,0x00,0x61,0x00,0x74,
42  0x00,0x69,0x00,0x63,0x00,0x00,0x00,0x00,0x00
43 };
44 // Do not change these values - they go hand in hand with above template
45 #define CUPDIALOG_TEXTBOX_ID (1026) //Static Control Id
46 #define CUPDIALOG_PROGRESSBAR_ID (1018) //ProgressBar Control Id
47 #define CUPDIALOG_CANCELBUTTON_ID (IDCANCEL) //Cancel Button Control Id
48 #define CUPDIALOG_TERMINATE_DELAY (500) //Amount of time to wait after signaling the termination, in MilliSeconds.
49 
50 CUPDialog::CUPDialog(HWND hParentWnd,LP_CUPDIALOG_USERPROC lpUserProc,LPVOID lpUserProcParam,LPCTSTR lpszDlgTitle/*=_T("Please Wait..")*/,bool bAllowCancel/*=true*/)
51 {
52  m_hThread = NULL; //No Thread Yet !!
53 
54  m_hParentWnd = hParentWnd; //Needed to Create the DialogBox - DlgProc asks this as Parameter
55 
56  m_hInst = NULL;
57 
58  m_lpszTemplateName = NULL; //By default we use the built-in template
59 
60  m_nStaticControlId = CUPDIALOG_TEXTBOX_ID; // Default Static Control Id
61 
62  m_nProgressBarControlId = CUPDIALOG_PROGRESSBAR_ID; // Default Progressbar Control Id
63 
64  m_nCancelButtonId = CUPDIALOG_CANCELBUTTON_ID; // Default Cancel button Control Id
65 
66  m_dwTerminateDelay = CUPDIALOG_TERMINATE_DELAY; //Default Amount of time to wait after signaling the termination, in MilliSeconds.
67 
68  m_bAllowCancel = bAllowCancel; //Is Dialog Terminatable ??
69 
70  m_ThreadData.pUserProcParam = lpUserProcParam; //We send this as Parameter to the UserProc
71 
72  m_ThreadData.m_lpUserProc = lpUserProc; //The actual User Procedure
73 
74  ZeroMemory(m_szDialogCaption,sizeof(m_szDialogCaption));
75 
76  _tcsncpy(m_szDialogCaption,lpszDlgTitle,(sizeof(m_szDialogCaption)/sizeof(m_szDialogCaption[0]))-1);
77 }
78 
79 CUPDialog::~CUPDialog(void)
80 {
81  Cleanup(); //It is possible that the Dialog object can be destroyed while Thread is still running..!!
82 }
83 
84 void CUPDialog::Cleanup()
85 {
86  m_ThreadData.bTerminate = true;
87 
88  if(m_ThreadData.bAlive) //If associated Thread is still alive Terminate It
89  {
90  Sleep(m_dwTerminateDelay);
91  DWORD dwExitCode = 0;
92  if(GetExitCodeThread(m_hThread,&dwExitCode) && dwExitCode == STILL_ACTIVE)
93  TerminateThread(m_hThread, IDCANCEL);
94  }
95 
96  if(m_hThread)
97  {
98  CloseHandle(m_hThread);
99  m_hThread = NULL;
100  }
101 
102  m_ThreadData.bAlive = false;
103  m_ThreadData.bTerminate = false;
104  m_ThreadData.hThreadWnd = NULL;
105 }
106 
107 INT_PTR CUPDialog::DoModal()
108 {
109  Cleanup(); //If this is not first time, we had better Terminate any previous instance Threads !!
110 
111  if(m_lpszTemplateName == NULL) // if no custom dialog template is supplied to us, lets use the built-in one
112  return DialogBoxIndirectParam(NULL, (LPDLGTEMPLATE) dlg_145, m_hParentWnd, (DLGPROC) ProgressDlgProc, (LPARAM)this);
113  else
114  return DialogBoxParam(m_hInst,m_lpszTemplateName,m_hParentWnd,ProgressDlgProc,(LPARAM)this);
115 }
116 
117 static DWORD WINAPI ThreadProc(LPVOID lpThreadParameter) //Calls the User Progress Procedure
118 {
119  LPPROGRESSTHREADDATA pThreadData = (LPPROGRESSTHREADDATA) lpThreadParameter;
120 
121  pThreadData->bAlive = true;
122 
123  INT_PTR nResult = IDCANCEL;
124 
125  if(pThreadData->bTerminate == true)
126  goto TerminateThreadProc;
127 
128  nResult = (true == (*pThreadData->m_lpUserProc)((CUPDUPDATA*)lpThreadParameter)) ? IDOK : IDCANCEL;
129 
130 TerminateThreadProc:
131 
132  pThreadData->bAlive = false;
133 
134  if(pThreadData->bTerminate == false)
135  ::PostMessage(pThreadData->hThreadWnd,PROGRESSTHREADDATA::WM_PROGRESSTHREADCOMPLETED,MAKEWPARAM(nResult,0),0);
136 
137  return 0;
138 }
139 
140 INT_PTR CALLBACK ProgressDlgProc(HWND hDlg,UINT Message,WPARAM wParam,LPARAM lParam)
141 {
142  BOOL bProcessed = FALSE;
143  CUPDialog *pProgressDialog = NULL;
144 
145  switch(Message)
146  {
147  case WM_INITDIALOG:
148  {
149  pProgressDialog = (CUPDialog*) lParam;
150 
151  SetWindowLongPtr(hDlg,GWL_USERDATA,(LONG_PTR)pProgressDialog);
152 
153  if(pProgressDialog->m_bAllowCancel == false)
154  SendMessage(hDlg,PROGRESSTHREADDATA::WM_DISABLECONTROLS,wParam,lParam);
155 
156  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nStaticControlId),WM_SETTEXT,0,(LPARAM)_T(""));
157 
158  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nProgressBarControlId),PBM_SETPOS,0,0);
159 
160  SendMessage(hDlg,WM_SETTEXT,0,(LPARAM)pProgressDialog->m_szDialogCaption);
161 
162  ((LPPROGRESSTHREADDATA)(LPVOID)(&pProgressDialog->m_ThreadData))->hThreadWnd = hDlg;
163 
164  pProgressDialog->OnMessage(hDlg, Message, wParam, lParam, TRUE);
165 
166  DWORD dwThreadId = 0;
167 
168  pProgressDialog->m_hThread = CreateThread(NULL,NULL,ThreadProc,&pProgressDialog->m_ThreadData,0,&dwThreadId);
169 
170  if(pProgressDialog->m_hThread == NULL) EndDialog(hDlg,IDABORT);
171 
172  return TRUE;
173  }
174  case WM_COMMAND:
175  {
176  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
177 
178  if(pProgressDialog->m_nCancelButtonId == LOWORD(wParam))
179  {
180  SendMessage(hDlg,PROGRESSTHREADDATA::WM_CANCELPROGRESSTHREAD,0,0);
181  bProcessed = TRUE;
182  }
183  break;
184  }
185  case WM_SYSCOMMAND:
186  {
187  if(SC_CLOSE == wParam)
188  {
189  SendMessage(hDlg,PROGRESSTHREADDATA::WM_CANCELPROGRESSTHREAD,0,0);
190  bProcessed = TRUE;
191  }
192  break;
193  }
194  case PROGRESSTHREADDATA::WM_DISABLECONTROLS:
195  {
196  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
197  EnableMenuItem(GetSystemMenu(hDlg,false),SC_CLOSE,MF_DISABLED|MF_GRAYED|MF_BYCOMMAND);
198  EnableWindow(GetDlgItem(hDlg, pProgressDialog->m_nCancelButtonId),false);
199  bProcessed = TRUE;
200  break;
201  }
202  case PROGRESSTHREADDATA::WM_ENABLECONTROLS:
203  {
204  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
205  EnableMenuItem(GetSystemMenu(hDlg,false),SC_CLOSE,MF_ENABLED|MF_BYCOMMAND);
206  EnableWindow(GetDlgItem(hDlg, pProgressDialog->m_nCancelButtonId),true);
207  bProcessed = TRUE;
208  break;
209  }
210  case PROGRESSTHREADDATA::WM_PROGRESSTHREADCOMPLETED: //wParam = IDOK or IDCANCEL depending on the Success of Thread
211  {
212  EndDialog(hDlg, wParam);
213  bProcessed = TRUE;
214  break;
215  }
216  case PROGRESSTHREADDATA::WM_PROGRESSTEXTUPDATE: //lParam = ProgressText;
217  {
218  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
219  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nStaticControlId),WM_SETTEXT,0,lParam);
220  bProcessed = TRUE;
221  break;
222  }
223  case PROGRESSTHREADDATA::WM_PROGRESSBARUPDATE: //wParam = % Progress;
224  {
225  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
226  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nProgressBarControlId),PBM_SETPOS,wParam,0);
227  bProcessed = TRUE;
228  break;
229  }
230  case PROGRESSTHREADDATA::WM_CANCELPROGRESSTHREAD: //Enough to Signal the Thread - Actual Handle Would be Closed in the Dialog Destructor
231  {
232  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
233  {
234  LPPROGRESSTHREADDATA pThreadData = (LPPROGRESSTHREADDATA)(LPVOID)(&pProgressDialog->m_ThreadData);
235  pThreadData->bTerminate = true;
236  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nStaticControlId),WM_SETTEXT,0,(LPARAM)(_T("Termination Initiated..")));
237  SendMessage(hDlg,PROGRESSTHREADDATA::WM_DISABLECONTROLS,wParam,lParam);
238  if(pThreadData->bAlive)
239  Sleep(pProgressDialog->m_dwTerminateDelay);
240  if(pThreadData->bAlive)
241  SendMessage(GetDlgItem(hDlg, pProgressDialog->m_nStaticControlId),WM_SETTEXT,0,(LPARAM)(_T("Termination Complete ..Shutting Down !!")));
242  if(pThreadData->bAlive)
243  Sleep(pProgressDialog->m_dwTerminateDelay);
244  EndDialog(hDlg, MAKEWPARAM(IDCANCEL,1));
245  }
246  bProcessed = TRUE;
247  break;
248  }
249  }
250 
251  if(pProgressDialog == NULL) // pProgressDialog could be NULL if we have not processed this message (or initialized the value)
252  pProgressDialog = (CUPDialog*)GetWindowLongPtr(hDlg,GWL_USERDATA);
253 
254  if(pProgressDialog != NULL) // pProgressDialog could be NULL if we have not yet set the GWL_USERDATA
255  {
256  //Pass the message to any one who wants to know about it
257  //An Access violation could occur if SetWindowLongPtr has been used on the Dialog.
258  INT_PTR RetVal = pProgressDialog->OnMessage(hDlg, Message, wParam, lParam, bProcessed);
259 
260  if(bProcessed == FALSE) return RetVal; // if we have not processed the message then return the value we received from OnMessage()
261  }
262 
263  return bProcessed; // We have already processed the message
264 }

CFugue, the C++ Music Programming Library © Copyright 2009 Cenacle Research India Private Limited Gopalakrishna Palem