377 lines
8.1 KiB
C++
377 lines
8.1 KiB
C++
|
|
// MSDIThread.cpp
|
||
|
|
//
|
||
|
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
||
|
|
// (c)1998-2008 Codejock Software, All Rights Reserved.
|
||
|
|
//
|
||
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
|
//
|
||
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
|
// SINGLE COMPUTER.
|
||
|
|
//
|
||
|
|
// CONTACT INFORMATION:
|
||
|
|
// support@codejock.com
|
||
|
|
// http://www.codejock.com
|
||
|
|
//
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/*********************************************************
|
||
|
|
* Multithreaded SDI Application
|
||
|
|
* Version: 1.4
|
||
|
|
* Date: January 3, 2002
|
||
|
|
* Autor: Michal Mecinski
|
||
|
|
* E-mail: mimec@mimec.w.pl
|
||
|
|
* WWW: http://www.mimec.w.pl
|
||
|
|
*
|
||
|
|
* Copyright (C) 2002-03 by Michal Mecinski
|
||
|
|
*********************************************************/
|
||
|
|
|
||
|
|
#include "stdafx.h"
|
||
|
|
#include "MSDI.h"
|
||
|
|
#include "MSDIThread.h"
|
||
|
|
#include "MSDIDocManager.h"
|
||
|
|
|
||
|
|
#include "MainFrm.h"
|
||
|
|
#include "SomeDoc.h"
|
||
|
|
#include "SomeView.h"
|
||
|
|
|
||
|
|
#ifdef _DEBUG
|
||
|
|
#define new DEBUG_NEW
|
||
|
|
#undef THIS_FILE
|
||
|
|
static char THIS_FILE[] = __FILE__;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CMSDIThread
|
||
|
|
|
||
|
|
IMPLEMENT_DYNCREATE(CMSDIThread, CWinThread)
|
||
|
|
|
||
|
|
CMSDIThread::CMSDIThread()
|
||
|
|
{
|
||
|
|
m_pDocManager = NULL;
|
||
|
|
m_pWndDlg = NULL;
|
||
|
|
|
||
|
|
m_eventTerminate.ResetEvent();
|
||
|
|
}
|
||
|
|
|
||
|
|
CMSDIThread::~CMSDIThread()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
BOOL CMSDIThread::InitInstance()
|
||
|
|
{
|
||
|
|
m_pDocManager = new CDocManager();
|
||
|
|
|
||
|
|
// moved from CMSDIApp::InitInstance
|
||
|
|
|
||
|
|
CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate(
|
||
|
|
IDR_MAINFRAME,
|
||
|
|
RUNTIME_CLASS(CSomeDoc),
|
||
|
|
RUNTIME_CLASS(CMainFrame),
|
||
|
|
RUNTIME_CLASS(CSomeView));
|
||
|
|
|
||
|
|
m_pDocManager->AddDocTemplate(pDocTemplate);
|
||
|
|
|
||
|
|
if (m_strFileOpen.IsEmpty())
|
||
|
|
{
|
||
|
|
m_pDocManager->OnFileNew();
|
||
|
|
|
||
|
|
if (m_pMainWnd)
|
||
|
|
{
|
||
|
|
CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
|
||
|
|
if (pDoc)
|
||
|
|
{
|
||
|
|
// append document number like in MDI
|
||
|
|
CString str;
|
||
|
|
str.Format(_T("%s%d"), (LPCTSTR)pDoc->GetTitle(), m_nDocCnt);
|
||
|
|
pDoc->SetTitle(str);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
m_pDocManager->OpenDocumentFile(m_strFileOpen);
|
||
|
|
|
||
|
|
if (!m_pMainWnd)
|
||
|
|
return FALSE;
|
||
|
|
|
||
|
|
m_pMainWnd->BringWindowToTop();
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
int CMSDIThread::ExitInstance()
|
||
|
|
{
|
||
|
|
if (m_pMainWnd)
|
||
|
|
m_pMainWnd->DestroyWindow();
|
||
|
|
|
||
|
|
delete m_pDocManager;
|
||
|
|
|
||
|
|
AfxGetApp()->PostThreadMessage(MSDIM_EXIT_THREAD, (WPARAM)this, 0);
|
||
|
|
|
||
|
|
// wait for permission to terminate
|
||
|
|
WaitForSingleObject(m_eventTerminate, INFINITE);
|
||
|
|
|
||
|
|
return CWinThread::ExitInstance();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
BEGIN_MESSAGE_MAP(CMSDIThread, CWinThread)
|
||
|
|
//{{AFX_MSG_MAP(CMSDIThread)
|
||
|
|
//}}AFX_MSG_MAP
|
||
|
|
ON_THREAD_MESSAGE(MSDIM_UPDATE_NOTIFY, OnUpdateNotify)
|
||
|
|
ON_COMMAND_RANGE(MSDI_ID_FIRST, MSDI_ID_LAST, OnWindowActivate)
|
||
|
|
ON_COMMAND(MSDI_ID_SELECT, OnWindowSelect)
|
||
|
|
END_MESSAGE_MAP()
|
||
|
|
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CWindowDlg dialog used for Window Select
|
||
|
|
|
||
|
|
class CWindowDlg : public CDialog
|
||
|
|
{
|
||
|
|
// Construction
|
||
|
|
public:
|
||
|
|
CWindowDlg(CWnd* pParent = NULL); // standard constructor
|
||
|
|
|
||
|
|
// Dialog Data
|
||
|
|
//{{AFX_DATA(CWindowDlg)
|
||
|
|
enum { IDD = IDD_WINDOW };
|
||
|
|
CListBox m_lbWndList;
|
||
|
|
//}}AFX_DATA
|
||
|
|
|
||
|
|
int m_nResult;
|
||
|
|
|
||
|
|
// Overrides
|
||
|
|
// ClassWizard generated virtual function overrides
|
||
|
|
//{{AFX_VIRTUAL(CWindowDlg)
|
||
|
|
protected:
|
||
|
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||
|
|
//}}AFX_VIRTUAL
|
||
|
|
|
||
|
|
// Implementation
|
||
|
|
protected:
|
||
|
|
// Generated message map functions
|
||
|
|
//{{AFX_MSG(CWindowDlg)
|
||
|
|
virtual void OnOK();
|
||
|
|
afx_msg void OnDblclkWindowsList();
|
||
|
|
//}}AFX_MSG
|
||
|
|
DECLARE_MESSAGE_MAP()
|
||
|
|
};
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CWindowDlg dialog
|
||
|
|
|
||
|
|
CWindowDlg::CWindowDlg(CWnd* pParent /*=NULL*/)
|
||
|
|
: CDialog(CWindowDlg::IDD, pParent)
|
||
|
|
{
|
||
|
|
//{{AFX_DATA_INIT(CWindowDlg)
|
||
|
|
// NOTE: the ClassWizard will add member initialization here
|
||
|
|
//}}AFX_DATA_INIT
|
||
|
|
}
|
||
|
|
|
||
|
|
void CWindowDlg::DoDataExchange(CDataExchange* pDX)
|
||
|
|
{
|
||
|
|
CDialog::DoDataExchange(pDX);
|
||
|
|
//{{AFX_DATA_MAP(CWindowDlg)
|
||
|
|
DDX_Control(pDX, IDC_WINDOW_LIST, m_lbWndList);
|
||
|
|
//}}AFX_DATA_MAP
|
||
|
|
}
|
||
|
|
|
||
|
|
BEGIN_MESSAGE_MAP(CWindowDlg, CDialog)
|
||
|
|
//{{AFX_MSG_MAP(CWindowDlg)
|
||
|
|
ON_LBN_DBLCLK(IDC_WINDOW_LIST, OnDblclkWindowsList)
|
||
|
|
//}}AFX_MSG_MAP
|
||
|
|
END_MESSAGE_MAP()
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CWindowDlg message handlers
|
||
|
|
|
||
|
|
void CWindowDlg::OnOK()
|
||
|
|
{
|
||
|
|
m_nResult = m_lbWndList.GetCurSel();
|
||
|
|
|
||
|
|
CDialog::OnOK();
|
||
|
|
}
|
||
|
|
|
||
|
|
void CWindowDlg::OnDblclkWindowsList()
|
||
|
|
{
|
||
|
|
OnOK();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CMSDIThread message handlers
|
||
|
|
|
||
|
|
void CMSDIThread::OnUpdateNotify(WPARAM nCode, LPARAM /*lParam*/)
|
||
|
|
{
|
||
|
|
switch (nCode)
|
||
|
|
{
|
||
|
|
// no need to react on MSDIN_NEW_THREAD because
|
||
|
|
// MSDIN_DOC_TITLE is always sent after it
|
||
|
|
case MSDIN_EXIT_THREAD:
|
||
|
|
case MSDIN_DOC_TITLE:
|
||
|
|
// the window dialog will automatically reopen with updated list
|
||
|
|
if (m_pWndDlg && m_pWndDlg->m_hWnd && m_pWndDlg->m_lbWndList.m_hWnd)
|
||
|
|
FillWindowList();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CMSDIThread::SetDocumentTitle(LPCTSTR lpszTitle)
|
||
|
|
{
|
||
|
|
CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
|
||
|
|
|
||
|
|
pDocMgr->Lock();
|
||
|
|
|
||
|
|
// change the shared data safely
|
||
|
|
m_strTitle = lpszTitle;
|
||
|
|
|
||
|
|
pDocMgr->Unlock();
|
||
|
|
|
||
|
|
// send notification message to all threads
|
||
|
|
pDocMgr->PostUpdateNotify(MSDIN_DOC_TITLE);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CMSDIThread::OnWindowActivate(UINT uCmdID)
|
||
|
|
{
|
||
|
|
CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
|
||
|
|
|
||
|
|
pDocMgr->Lock();
|
||
|
|
|
||
|
|
POSITION pos = pDocMgr->GetFirstThreadPosition();
|
||
|
|
|
||
|
|
int nCnt = uCmdID - MSDI_ID_FIRST;
|
||
|
|
|
||
|
|
while (pos)
|
||
|
|
{
|
||
|
|
CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
|
||
|
|
|
||
|
|
if (nCnt == 0)
|
||
|
|
{
|
||
|
|
// restore if it was maximized and switch to foreground
|
||
|
|
pThread->GetMainWnd()->ShowWindow(SW_RESTORE);
|
||
|
|
pThread->GetMainWnd()->SetForegroundWindow();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
nCnt--;
|
||
|
|
}
|
||
|
|
|
||
|
|
pDocMgr->Unlock();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CMSDIThread::OnWindowSelect()
|
||
|
|
{
|
||
|
|
CWindowDlg dlg;
|
||
|
|
|
||
|
|
m_pWndDlg = &dlg;
|
||
|
|
|
||
|
|
// fill the list after the window is created
|
||
|
|
PostThreadMessage(MSDIM_UPDATE_NOTIFY, MSDIN_DOC_TITLE, 0);
|
||
|
|
|
||
|
|
int nRes = (int)dlg.DoModal();
|
||
|
|
|
||
|
|
m_pWndDlg = NULL;
|
||
|
|
|
||
|
|
if (nRes==IDOK && dlg.m_nResult>=0)
|
||
|
|
OnWindowActivate(MSDI_ID_FIRST + dlg.m_nResult);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CMSDIThread::FillWindowList()
|
||
|
|
{
|
||
|
|
CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
|
||
|
|
|
||
|
|
pDocMgr->Lock();
|
||
|
|
|
||
|
|
POSITION pos = pDocMgr->GetFirstThreadPosition();
|
||
|
|
|
||
|
|
m_pWndDlg->m_lbWndList.ResetContent();
|
||
|
|
|
||
|
|
int nCnt = 0;
|
||
|
|
|
||
|
|
while (pos)
|
||
|
|
{
|
||
|
|
CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
|
||
|
|
|
||
|
|
m_pWndDlg->m_lbWndList.AddString(pThread->m_strTitle);
|
||
|
|
|
||
|
|
if (pThread == this)
|
||
|
|
m_pWndDlg->m_lbWndList.SetCurSel(nCnt);
|
||
|
|
|
||
|
|
nCnt++;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_pWndDlg->m_lbWndList.SetFocus();
|
||
|
|
|
||
|
|
pDocMgr->Unlock();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
IMPLEMENT_XTP_CONTROL( CControlWindowList, CXTPControlButton)
|
||
|
|
|
||
|
|
void CControlWindowList::OnCalcDynamicSize(DWORD /*dwMode*/)
|
||
|
|
{
|
||
|
|
ASSERT(m_pControls->GetAt(m_nIndex) == this);
|
||
|
|
|
||
|
|
while (m_nIndex + 1 < m_pControls->GetCount())
|
||
|
|
{
|
||
|
|
CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
|
||
|
|
if (pControl->GetID() >= (int)MSDI_ID_FIRST && pControl->GetID() <= (int)MSDI_ID_LAST)
|
||
|
|
{
|
||
|
|
m_pControls->Remove(pControl);
|
||
|
|
}
|
||
|
|
else break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_pParent->IsCustomizeMode())
|
||
|
|
{
|
||
|
|
m_dwHideFlags = 0;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_dwHideFlags |= xtpHideGeneric;
|
||
|
|
|
||
|
|
CMSDIDocManager* pDocMgr = (CMSDIDocManager*)AfxGetApp()->m_pDocManager;
|
||
|
|
|
||
|
|
// obtain access to the thread list
|
||
|
|
pDocMgr->Lock();
|
||
|
|
|
||
|
|
POSITION pos = pDocMgr->GetFirstThreadPosition();
|
||
|
|
int nCnt = 0;
|
||
|
|
|
||
|
|
while (pos && nCnt < MSDI_MAX_WINDOWS)
|
||
|
|
{
|
||
|
|
CMSDIThread* pThread = pDocMgr->GetNextThread(pos);
|
||
|
|
|
||
|
|
CXTPControl* pControl = m_pControls->Add(xtpControlButton, MSDI_ID_FIRST + nCnt, _T(""), m_nIndex + 1 + nCnt, TRUE);
|
||
|
|
|
||
|
|
pControl->SetCaption(CXTPControlWindowList::ConstructCaption(pThread->m_strTitle, nCnt+1));
|
||
|
|
pControl->SetBeginGroup(nCnt == 0);
|
||
|
|
pControl->SetChecked(pThread == AfxGetThread()? TRUE: FALSE);
|
||
|
|
|
||
|
|
pControl->SetFlags(xtpFlagManualUpdate);
|
||
|
|
|
||
|
|
nCnt++;
|
||
|
|
}
|
||
|
|
|
||
|
|
pDocMgr->Unlock();
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CControlWindowList::IsCustomizeDragOverAvail(CXTPCommandBar* pCommandBar, CPoint /*point*/, DROPEFFECT& dropEffect)
|
||
|
|
{
|
||
|
|
if (pCommandBar->GetType() != xtpBarTypePopup)
|
||
|
|
{
|
||
|
|
dropEffect = DROPEFFECT_NONE;
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
return TRUE;
|
||
|
|
}
|