MSDIThread.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:8k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // MSDIThread.cpp
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. /*********************************************************
  21. * Multithreaded SDI Application
  22. * Version: 1.4
  23. * Date: January 3, 2002
  24. * Autor: Michal Mecinski
  25. * E-mail: mimec@mimec.w.pl
  26. * WWW: http://www.mimec.w.pl
  27. *
  28. * Copyright (C) 2002-03 by Michal Mecinski
  29. *********************************************************/
  30. #include "stdafx.h"
  31. #include "MSDI.h"
  32. #include "MSDIThread.h"
  33. #include "MSDIDocManager.h"
  34. #include "MainFrm.h"
  35. #include "SomeDoc.h"
  36. #include "SomeView.h"
  37. #ifdef _DEBUG
  38. #define new DEBUG_NEW
  39. #undef THIS_FILE
  40. static char THIS_FILE[] = __FILE__;
  41. #endif
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CMSDIThread
  44. IMPLEMENT_DYNCREATE(CMSDIThread, CWinThread)
  45. CMSDIThread::CMSDIThread()
  46. {
  47. m_pDocManager = NULL;
  48. m_pWndDlg = NULL;
  49. m_eventTerminate.ResetEvent();
  50. }
  51. CMSDIThread::~CMSDIThread()
  52. {
  53. }
  54. BOOL CMSDIThread::InitInstance()
  55. {
  56. m_pDocManager = new CDocManager();
  57. // moved from CMSDIApp::InitInstance
  58. CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate(
  59. IDR_MAINFRAME,
  60. RUNTIME_CLASS(CSomeDoc),
  61. RUNTIME_CLASS(CMainFrame),
  62. RUNTIME_CLASS(CSomeView));
  63. m_pDocManager->AddDocTemplate(pDocTemplate);
  64. if (m_strFileOpen.IsEmpty())
  65. {
  66. m_pDocManager->OnFileNew();
  67. if (m_pMainWnd)
  68. {
  69. CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
  70. if (pDoc)
  71. {
  72. // append document number like in MDI
  73. CString str;
  74. str.Format(_T("%s%d"), (LPCTSTR)pDoc->GetTitle(), m_nDocCnt);
  75. pDoc->SetTitle(str);
  76. }
  77. }
  78. }
  79. else
  80. m_pDocManager->OpenDocumentFile(m_strFileOpen);
  81. if (!m_pMainWnd)
  82. return FALSE;
  83. m_pMainWnd->BringWindowToTop();
  84. return TRUE;
  85. }
  86. int CMSDIThread::ExitInstance()
  87. {
  88. if (m_pMainWnd)
  89. m_pMainWnd->DestroyWindow();
  90. delete m_pDocManager;
  91. AfxGetApp()->PostThreadMessage(MSDIM_EXIT_THREAD, (WPARAM)this, 0);
  92. // wait for permission to terminate
  93. WaitForSingleObject(m_eventTerminate, INFINITE);
  94. return CWinThread::ExitInstance();
  95. }
  96. BEGIN_MESSAGE_MAP(CMSDIThread, CWinThread)
  97. //{{AFX_MSG_MAP(CMSDIThread)
  98. //}}AFX_MSG_MAP
  99. ON_THREAD_MESSAGE(MSDIM_UPDATE_NOTIFY, OnUpdateNotify)
  100. ON_COMMAND_RANGE(MSDI_ID_FIRST, MSDI_ID_LAST, OnWindowActivate)
  101. ON_COMMAND(MSDI_ID_SELECT, OnWindowSelect)
  102. END_MESSAGE_MAP()
  103. /////////////////////////////////////////////////////////////////////////////
  104. // CWindowDlg dialog used for Window Select
  105. class CWindowDlg : public CDialog
  106. {
  107. // Construction
  108. public:
  109. CWindowDlg(CWnd* pParent = NULL);   // standard constructor
  110. // Dialog Data
  111. //{{AFX_DATA(CWindowDlg)
  112. enum { IDD = IDD_WINDOW };
  113. CListBox    m_lbWndList;
  114. //}}AFX_DATA
  115. int m_nResult;
  116. // Overrides
  117. // ClassWizard generated virtual function overrides
  118. //{{AFX_VIRTUAL(CWindowDlg)
  119. protected:
  120. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  121. //}}AFX_VIRTUAL
  122. // Implementation
  123. protected:
  124. // Generated message map functions
  125. //{{AFX_MSG(CWindowDlg)
  126. virtual void OnOK();
  127. afx_msg void OnDblclkWindowsList();
  128. //}}AFX_MSG
  129. DECLARE_MESSAGE_MAP()
  130. };
  131. /////////////////////////////////////////////////////////////////////////////
  132. // CWindowDlg dialog
  133. CWindowDlg::CWindowDlg(CWnd* pParent /*=NULL*/)
  134. : CDialog(CWindowDlg::IDD, pParent)
  135. {
  136. //{{AFX_DATA_INIT(CWindowDlg)
  137. // NOTE: the ClassWizard will add member initialization here
  138. //}}AFX_DATA_INIT
  139. }
  140. void CWindowDlg::DoDataExchange(CDataExchange* pDX)
  141. {
  142. CDialog::DoDataExchange(pDX);
  143. //{{AFX_DATA_MAP(CWindowDlg)
  144. DDX_Control(pDX, IDC_WINDOW_LIST, m_lbWndList);
  145. //}}AFX_DATA_MAP
  146. }
  147. BEGIN_MESSAGE_MAP(CWindowDlg, CDialog)
  148. //{{AFX_MSG_MAP(CWindowDlg)
  149. ON_LBN_DBLCLK(IDC_WINDOW_LIST, OnDblclkWindowsList)
  150. //}}AFX_MSG_MAP
  151. END_MESSAGE_MAP()
  152. /////////////////////////////////////////////////////////////////////////////
  153. // CWindowDlg message handlers
  154. void CWindowDlg::OnOK()
  155. {
  156. m_nResult = m_lbWndList.GetCurSel();
  157. CDialog::OnOK();
  158. }
  159. void CWindowDlg::OnDblclkWindowsList()
  160. {
  161. OnOK();
  162. }
  163. /////////////////////////////////////////////////////////////////////////////
  164. // CMSDIThread message handlers
  165. void CMSDIThread::OnUpdateNotify(WPARAM nCode, LPARAM /*lParam*/)
  166. {
  167. switch (nCode)
  168. {
  169. // no need to react on MSDIN_NEW_THREAD because
  170. // MSDIN_DOC_TITLE is always sent after it
  171. case MSDIN_EXIT_THREAD:
  172. case MSDIN_DOC_TITLE:
  173. // the window dialog will automatically reopen with updated list
  174. if (m_pWndDlg && m_pWndDlg->m_hWnd && m_pWndDlg->m_lbWndList.m_hWnd)
  175. FillWindowList();
  176. break;
  177. }
  178. }
  179. void CMSDIThread::SetDocumentTitle(LPCTSTR lpszTitle)
  180. {
  181. CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
  182. pDocMgr->Lock();
  183. // change the shared data safely
  184. m_strTitle = lpszTitle;
  185. pDocMgr->Unlock();
  186. // send notification message to all threads
  187. pDocMgr->PostUpdateNotify(MSDIN_DOC_TITLE);
  188. }
  189. void CMSDIThread::OnWindowActivate(UINT uCmdID)
  190. {
  191. CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
  192. pDocMgr->Lock();
  193. POSITION pos = pDocMgr->GetFirstThreadPosition();
  194. int nCnt = uCmdID - MSDI_ID_FIRST;
  195. while (pos)
  196. {
  197. CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
  198. if (nCnt == 0)
  199. {
  200. // restore if it was maximized and switch to foreground
  201. pThread->GetMainWnd()->ShowWindow(SW_RESTORE);
  202. pThread->GetMainWnd()->SetForegroundWindow();
  203. break;
  204. }
  205. nCnt--;
  206. }
  207. pDocMgr->Unlock();
  208. }
  209. void CMSDIThread::OnWindowSelect()
  210. {
  211. CWindowDlg dlg;
  212. m_pWndDlg = &dlg;
  213. // fill the list after the window is created
  214. PostThreadMessage(MSDIM_UPDATE_NOTIFY, MSDIN_DOC_TITLE, 0);
  215. int nRes = (int)dlg.DoModal();
  216. m_pWndDlg = NULL;
  217. if (nRes==IDOK && dlg.m_nResult>=0)
  218. OnWindowActivate(MSDI_ID_FIRST + dlg.m_nResult);
  219. }
  220. void CMSDIThread::FillWindowList()
  221. {
  222. CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
  223. pDocMgr->Lock();
  224. POSITION pos = pDocMgr->GetFirstThreadPosition();
  225. m_pWndDlg->m_lbWndList.ResetContent();
  226. int nCnt = 0;
  227. while (pos)
  228. {
  229. CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
  230. m_pWndDlg->m_lbWndList.AddString(pThread->m_strTitle);
  231. if (pThread == this)
  232. m_pWndDlg->m_lbWndList.SetCurSel(nCnt);
  233. nCnt++;
  234. }
  235. m_pWndDlg->m_lbWndList.SetFocus();
  236. pDocMgr->Unlock();
  237. }
  238. IMPLEMENT_XTP_CONTROL( CControlWindowList, CXTPControlButton)
  239. void CControlWindowList::OnCalcDynamicSize(DWORD /*dwMode*/)
  240. {
  241. ASSERT(m_pControls->GetAt(m_nIndex) == this);
  242. while (m_nIndex + 1 < m_pControls->GetCount())
  243. {
  244. CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
  245. if (pControl->GetID() >= (int)MSDI_ID_FIRST && pControl->GetID() <= (int)MSDI_ID_LAST)
  246. {
  247. m_pControls->Remove(pControl);
  248. }
  249. else break;
  250. }
  251. if (m_pParent->IsCustomizeMode())
  252. {
  253. m_dwHideFlags = 0;
  254. return;
  255. }
  256. m_dwHideFlags |= xtpHideGeneric;
  257. CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
  258. // obtain access to the thread list
  259. pDocMgr->Lock();
  260. POSITION pos = pDocMgr->GetFirstThreadPosition();
  261. int nCnt = 0;
  262. while (pos && nCnt < MSDI_MAX_WINDOWS)
  263. {
  264. CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
  265. CXTPControl* pControl = m_pControls->Add(xtpControlButton, MSDI_ID_FIRST + nCnt, _T(""), m_nIndex + 1 + nCnt, TRUE);
  266. pControl->SetCaption(CXTPControlWindowList::ConstructCaption(pThread->m_strTitle, nCnt+1));
  267. pControl->SetBeginGroup(nCnt == 0);
  268. pControl->SetChecked(pThread == AfxGetThread()? TRUE: FALSE);
  269. pControl->SetFlags(xtpFlagManualUpdate);
  270. nCnt++;
  271. }
  272. pDocMgr->Unlock();
  273. }
  274. BOOL CControlWindowList::IsCustomizeDragOverAvail(CXTPCommandBar* pCommandBar, CPoint /*point*/, DROPEFFECT& dropEffect)
  275. {
  276. if (pCommandBar->GetType() != xtpBarTypePopup)
  277. {
  278. dropEffect = DROPEFFECT_NONE;
  279. return FALSE;
  280. }
  281. return TRUE;
  282. }