WQDemoDlg.cpp
上传用户:dfzycw
上传日期:2010-01-10
资源大小:66k
文件大小:7k
源码类别:

进程与线程

开发平台:

Visual C++

  1. // WQDemoDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "WQDemo.h"
  5. #include "WQDemoDlg.h"
  6. #include "WorkQueue.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. class SpecificWorkItem : public WorkItemBase
  13. {
  14. public:
  15. SpecificWorkItem(CXListCtrl* pListCtrl,int nItem){m_pListCtrl = pListCtrl; m_nItem = nItem;}
  16. private:
  17. void   DoWork(void* pThreadContext);
  18.     void   Abort();
  19. int    m_nItem;
  20. CXListCtrl* m_pListCtrl;
  21. };
  22. void SpecificWorkItem::DoWork(void* pThreadContext)
  23. {
  24. m_pListCtrl->EnsureVisible(m_nItem,TRUE);
  25. m_pListCtrl->SetProgress(m_nItem,0);
  26. for(int i = 0 ; i < 100 ; i++)
  27. {
  28. Sleep(100);
  29. m_pListCtrl->UpdateProgress(m_nItem,0,i);
  30. }
  31. m_pListCtrl->DeleteProgress(m_nItem,0);
  32. m_pListCtrl->SetItemText(m_nItem,0,_T("Complete"));
  33. delete this;
  34. }
  35. void SpecificWorkItem::Abort()
  36. {
  37. m_pListCtrl->SetItemText(m_nItem,0,_T("Aborted"));
  38. delete this;
  39. }
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CAboutDlg dialog used for App About
  42. class CAboutDlg : public CDialog
  43. {
  44. public:
  45. CAboutDlg();
  46. // Dialog Data
  47. //{{AFX_DATA(CAboutDlg)
  48. enum { IDD = IDD_ABOUTBOX };
  49. //}}AFX_DATA
  50. // ClassWizard generated virtual function overrides
  51. //{{AFX_VIRTUAL(CAboutDlg)
  52. protected:
  53. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  54. //}}AFX_VIRTUAL
  55. // Implementation
  56. protected:
  57. //{{AFX_MSG(CAboutDlg)
  58. //}}AFX_MSG
  59. DECLARE_MESSAGE_MAP()
  60. };
  61. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  62. {
  63. //{{AFX_DATA_INIT(CAboutDlg)
  64. //}}AFX_DATA_INIT
  65. }
  66. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  67. {
  68. CDialog::DoDataExchange(pDX);
  69. //{{AFX_DATA_MAP(CAboutDlg)
  70. //}}AFX_DATA_MAP
  71. }
  72. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  73. //{{AFX_MSG_MAP(CAboutDlg)
  74. // No message handlers
  75. //}}AFX_MSG_MAP
  76. END_MESSAGE_MAP()
  77. /////////////////////////////////////////////////////////////////////////////
  78. // CWQDemoDlg dialog
  79. unsigned long __stdcall CWQDemoDlg::ThreadFuncDestroy( void*  pParam )
  80. {
  81. CWQDemoDlg* pDlg = (CWQDemoDlg*)pParam;
  82. pDlg->m_WorkQueue.Destroy();
  83. return 1;
  84. }
  85. CWQDemoDlg::CWQDemoDlg(CWnd* pParent /*=NULL*/)
  86. : CDialog(CWQDemoDlg::IDD, pParent)
  87. {
  88. //{{AFX_DATA_INIT(CWQDemoDlg)
  89. m_nNumberOfThreads = 5;
  90. //}}AFX_DATA_INIT
  91. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  92. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  93. }
  94. void CWQDemoDlg::DoDataExchange(CDataExchange* pDX)
  95. {
  96. CDialog::DoDataExchange(pDX);
  97. //{{AFX_DATA_MAP(CWQDemoDlg)
  98. DDX_Control(pDX, IDC_ITEM_QUEUE_LIST, m_ItemsOueueList);
  99. DDX_Text(pDX, IDC_NUMBER_OF_THREADS_EDIT, m_nNumberOfThreads);
  100. DDV_MinMaxUInt(pDX, m_nNumberOfThreads, 0, 64);
  101. //}}AFX_DATA_MAP
  102. }
  103. BEGIN_MESSAGE_MAP(CWQDemoDlg, CDialog)
  104. //{{AFX_MSG_MAP(CWQDemoDlg)
  105. ON_WM_SYSCOMMAND()
  106. ON_WM_PAINT()
  107. ON_WM_QUERYDRAGICON()
  108. ON_BN_CLICKED(IDC_CREATE, OnCreate)
  109. ON_BN_CLICKED(IDC_DESTROY, OnDestroy)
  110. ON_BN_CLICKED(IDC_ADD_ITEM_BTN, OnAddItemBtn)
  111. //}}AFX_MSG_MAP
  112. END_MESSAGE_MAP()
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CWQDemoDlg message handlers
  115. BOOL CWQDemoDlg::OnInitDialog()
  116. {
  117. CDialog::OnInitDialog();
  118. // Add "About..." menu item to system menu.
  119. // IDM_ABOUTBOX must be in the system command range.
  120. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  121. ASSERT(IDM_ABOUTBOX < 0xF000);
  122. CMenu* pSysMenu = GetSystemMenu(FALSE);
  123. if (pSysMenu != NULL)
  124. {
  125. CString strAboutMenu;
  126. strAboutMenu.LoadString(IDS_ABOUTBOX);
  127. if (!strAboutMenu.IsEmpty())
  128. {
  129. pSysMenu->AppendMenu(MF_SEPARATOR);
  130. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  131. }
  132. }
  133. // Set the icon for this dialog.  The framework does this automatically
  134. //  when the application's main window is not a dialog
  135. SetIcon(m_hIcon, TRUE); // Set big icon
  136. SetIcon(m_hIcon, FALSE); // Set small icon
  137. // TODO: Add extra initialization here
  138. m_ItemsOueueList.InsertColumn(0,_T("项目进程"),LVCFMT_LEFT,195);
  139. return TRUE;  // return TRUE  unless you set the focus to a control
  140. }
  141. void CWQDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
  142. {
  143. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  144. {
  145. CAboutDlg dlgAbout;
  146. dlgAbout.DoModal();
  147. }
  148. else
  149. {
  150. CDialog::OnSysCommand(nID, lParam);
  151. }
  152. }
  153. // If you add a minimize button to your dialog, you will need the code below
  154. //  to draw the icon.  For MFC applications using the document/view model,
  155. //  this is automatically done for you by the framework.
  156. void CWQDemoDlg::OnPaint() 
  157. {
  158. if (IsIconic())
  159. {
  160. CPaintDC dc(this); // device context for painting
  161. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  162. // Center icon in client rectangle
  163. int cxIcon = GetSystemMetrics(SM_CXICON);
  164. int cyIcon = GetSystemMetrics(SM_CYICON);
  165. CRect rect;
  166. GetClientRect(&rect);
  167. int x = (rect.Width() - cxIcon + 1) / 2;
  168. int y = (rect.Height() - cyIcon + 1) / 2;
  169. // Draw the icon
  170. dc.DrawIcon(x, y, m_hIcon);
  171. }
  172. else
  173. {
  174. CDialog::OnPaint();
  175. }
  176. }
  177. // The system calls this to obtain the cursor to display while the user drags
  178. //  the minimized window.
  179. HCURSOR CWQDemoDlg::OnQueryDragIcon()
  180. {
  181. return (HCURSOR) m_hIcon;
  182. }
  183. void CWQDemoDlg::OnCreate() 
  184. {
  185.     //界面更新显示
  186. UpdateData();
  187. GetDlgItem(IDC_CREATE)->EnableWindow(FALSE);
  188. GetDlgItem(IDC_NUMBER_OF_THREADS_SPIN_SPIN)->EnableWindow(FALSE);
  189. GetDlgItem(IDC_DESTROY)->EnableWindow(TRUE);
  190. GetDlgItem(IDC_ADD_ITEM_BTN)->EnableWindow(TRUE);
  191. //创建线程
  192. m_WorkQueue.Create(m_nNumberOfThreads);
  193. }
  194. void CWQDemoDlg::OnDestroy() 
  195. {
  196. GetDlgItem(IDC_DESTROY)->EnableWindow(FALSE);
  197. GetDlgItem(IDC_ADD_ITEM_BTN)->EnableWindow(FALSE);
  198. //为了在程序退出时界面不被冻结,这里建立了另一个线程,利用该线程去结束其他的线程
  199. DWORD dwThreadId;
  200. HANDLE hThreade = CreateThread(NULL,
  201. 0,
  202. CWQDemoDlg::ThreadFuncDestroy,
  203. this,
  204. 0,
  205. &dwThreadId);
  206. while (TRUE)
  207. {
  208. DWORD result ; 
  209. MSG msg ; 
  210. // 读取所有的消息 
  211. // 移除读到的所有消息,防止界面锁住
  212. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
  213. if (msg.message == WM_QUIT)  
  214. return; 
  215. DispatchMessage(&msg); 
  216. // 等待任何队列消息或则hThreade线程句柄触发
  217. result = MsgWaitForMultipleObjects(1, &hThreade , 
  218. FALSE, INFINITE, QS_ALLINPUT); 
  219. // 如果是hThreade线程结束,表示所有的线程都已经退出
  220. if (result == WAIT_OBJECT_0)
  221. {
  222. break;
  223. else 
  224. continue;
  225. GetDlgItem(IDC_CREATE)->EnableWindow(TRUE);
  226. GetDlgItem(IDC_NUMBER_OF_THREADS_SPIN_SPIN)->EnableWindow(TRUE);
  227. }
  228. void CWQDemoDlg::OnAddItemBtn() 
  229. {
  230. static i = 0;
  231. i++;
  232. int nItem = m_ItemsOueueList.InsertItem(i, _T("Waiting..."));
  233. m_WorkQueue.InsertWorkItem(new SpecificWorkItem(&m_ItemsOueueList,nItem));
  234. }