611 lines
14 KiB
C++
611 lines
14 KiB
C++
/*********************************************************************
|
|
|
|
SAPrefsDialog
|
|
|
|
Copyright (C) 2000 Smaller Animals Software, Inc.
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
http://www.smalleranimals.com
|
|
smallest@smalleranimals.com
|
|
|
|
**********************************************************************/
|
|
|
|
// SAPrefsDialog.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "../resource.h"
|
|
#include "SAPrefsDialog.h"
|
|
|
|
#if defined(_DEBUG) && !defined(MMGR)
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSAPrefsDialog dialog
|
|
|
|
|
|
CSAPrefsDialog::CSAPrefsDialog(UINT nIDTemplate /*=CSAPrefsDialog::IDD*/, CWnd* pParent /*=NULL*/)
|
|
: CDialog(nIDTemplate, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CSAPrefsDialog)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_iCurPage = -1;
|
|
m_pages.clear();
|
|
|
|
m_pStartPage = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CSAPrefsDialog::~CSAPrefsDialog()
|
|
{
|
|
// clean up
|
|
for (unsigned int i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
delete pPS;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CSAPrefsDialog)
|
|
DDX_Control(pDX, IDC_PAGE_TREE, m_pageTree);
|
|
DDX_Control(pDX, IDC_DLG_FRAME, m_boundingFrame);
|
|
//}}AFX_DATA_MAP
|
|
if (GetDlgItem(IDC_CAPTION_BAR))
|
|
{
|
|
DDX_Control(pDX, IDC_CAPTION_BAR, m_captionBar);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CSAPrefsDialog, CDialog)
|
|
//{{AFX_MSG_MAP(CSAPrefsDialog)
|
|
ON_WM_CREATE()
|
|
ON_NOTIFY(TVN_SELCHANGED, IDC_PAGE_TREE, OnSelchangedPageTree)
|
|
ON_NOTIFY(TVN_GETDISPINFO, IDC_PAGE_TREE, OnGetdispinfoPageTree)
|
|
ON_BN_CLICKED(IDC_PHELP, OnPhelp)
|
|
//}}AFX_MSG_MAP
|
|
ON_MESSAGE(WM_CHANGE_PAGE, OnChangePage)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSAPrefsDialog message handlers
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CSAPrefsDialog::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
ASSERT(pMsg != NULL);
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_hWnd != NULL);
|
|
|
|
// Don't let CDialog process the Escape key.
|
|
if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_ESCAPE))
|
|
{
|
|
// return TRUE;
|
|
}
|
|
|
|
if (CWnd::PreTranslateMessage(pMsg))
|
|
return TRUE;
|
|
|
|
// don't translate dialog messages when
|
|
// application is in help mode
|
|
CFrameWnd* pFrameWnd = GetTopLevelFrame();
|
|
if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
|
|
return FALSE;
|
|
|
|
// ensure the dialog messages will not
|
|
// eat frame accelerators
|
|
pFrameWnd = GetParentFrame();
|
|
while (pFrameWnd != NULL)
|
|
{
|
|
if (pFrameWnd->PreTranslateMessage(pMsg))
|
|
return TRUE;
|
|
pFrameWnd = pFrameWnd->GetParentFrame();
|
|
}
|
|
|
|
return PreTranslateInput(pMsg);
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
int CSAPrefsDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CDialog::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CSAPrefsDialog::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
long l = GetWindowLong(m_pageTree.m_hWnd, GWL_STYLE);
|
|
#if (_MSC_VER > 1100)
|
|
l = l | TVS_TRACKSELECT ;
|
|
#else
|
|
//#define TVS_TRACKSELECT 0x0200
|
|
l = l | 0x0200;
|
|
#endif
|
|
SetWindowLong(m_pageTree.m_hWnd, GWL_STYLE, l);
|
|
|
|
// where will the dlgs live?
|
|
m_boundingFrame.GetWindowRect(m_frameRect);
|
|
ScreenToClient(m_frameRect);
|
|
// m_frameRect.DeflateRect(2,2);
|
|
|
|
if (m_csTitle != _T(""))
|
|
SetWindowText(m_csTitle);
|
|
|
|
// set some styles for the pretty page indicator bar
|
|
if (::IsWindow(m_captionBar.m_hWnd))
|
|
{
|
|
m_captionBar.m_textClr = ::GetSysColor(COLOR_3DFACE);
|
|
m_captionBar.m_fontWeight = FW_BOLD;
|
|
m_captionBar.m_fontSize = 14;
|
|
m_captionBar.m_csFontName = _T("Verdana");
|
|
m_captionBar.SetConstantText(m_csConstantText);
|
|
}
|
|
|
|
// fill the tree. we'll create the pages as we need them
|
|
unsigned int i;
|
|
for (i = 0; i <m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS)
|
|
{
|
|
TV_INSERTSTRUCT tvi;
|
|
|
|
// find this node's parent...
|
|
tvi.hParent = FindHTREEItemForDlg(pPS->pDlgParent);
|
|
|
|
tvi.hInsertAfter = TVI_LAST;
|
|
tvi.item.cchTextMax = 0;
|
|
tvi.item.pszText = LPSTR_TEXTCALLBACK;
|
|
tvi.item.lParam = (long)pPS;
|
|
tvi.item.mask = TVIF_PARAM | TVIF_TEXT;
|
|
|
|
HTREEITEM hTree = m_pageTree.InsertItem(&tvi);
|
|
m_pageTree.Expand(tvi.hParent,TVE_EXPAND);
|
|
|
|
// keep track of the dlg's we've added (for parent selection)
|
|
if (hTree)
|
|
{
|
|
DWORD dwTree = (DWORD)hTree;
|
|
m_dlgMap[pPS->pDlg]=dwTree;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < m_pages.size(); i++)
|
|
// if we haven't already, Create the dialog
|
|
if (!::IsWindow(m_pages[i]->pDlg->m_hWnd))
|
|
{
|
|
m_pages[i]->pDlg->Create(m_pages[i]->pDlg->GetID(), this);
|
|
}
|
|
|
|
// start with page 0
|
|
if (m_pStartPage == NULL)
|
|
{
|
|
if (ShowPage(0))
|
|
{
|
|
m_iCurPage = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// find start page
|
|
for (i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg == m_pStartPage)
|
|
{
|
|
ShowPage(i);
|
|
m_iCurPage = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HTREEITEM CSAPrefsDialog::FindHTREEItemForDlg(CSAPrefsSubDlg *pParent)
|
|
{
|
|
// if you didn't specify a parent in AddPage(...) , the
|
|
// dialog becomes a root-level entry
|
|
if (pParent==NULL)
|
|
{
|
|
return TVI_ROOT;
|
|
}
|
|
else
|
|
{
|
|
std::map<CSAPrefsSubDlg *, DWORD>::iterator iter=m_dlgMap.find(pParent);
|
|
if (iter!=m_dlgMap.end())
|
|
return (HTREEITEM)iter->second;
|
|
else
|
|
{
|
|
// you have specified a parent that has not
|
|
// been added to the tree - can't do that.
|
|
ASSERT(FALSE);
|
|
return TVI_ROOT;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
LONG_PTR CSAPrefsDialog::OnChangePage(WPARAM u, LPARAM l)
|
|
{
|
|
if (ShowPage(u))
|
|
{
|
|
m_iCurPage = u;
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool CSAPrefsDialog::AddPage(CSAPrefsSubDlg &dlg, LPCTSTR pCaption, CSAPrefsSubDlg* pDlgParent /*=NULL*/)
|
|
{
|
|
if (m_hWnd)
|
|
{
|
|
// can't add once the window has been created
|
|
ASSERT(0);
|
|
return false;
|
|
}
|
|
|
|
pageStruct *pPS = new pageStruct;
|
|
pPS->pDlg = &dlg;
|
|
pPS->id = dlg.GetID();
|
|
pPS->csCaption = pCaption;
|
|
pPS->pDlgParent = pDlgParent;
|
|
|
|
m_pages.push_back(pPS);
|
|
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CSAPrefsDialog::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if (!CWnd::PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, NULL, NULL, NULL);
|
|
cs.style |= WS_CLIPCHILDREN;
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool CSAPrefsDialog::ShowPage(CSAPrefsSubDlg * pPage)
|
|
{
|
|
// find that page
|
|
for (unsigned int i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg == pPage)
|
|
{
|
|
ShowPage(i);
|
|
m_iCurPage = i;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool CSAPrefsDialog::ShowPage(int iPage)
|
|
{
|
|
if (::IsWindow(m_captionBar.m_hWnd))
|
|
m_captionBar.SetWindowText(_T(""));
|
|
|
|
// turn off the current page
|
|
if ((m_iCurPage >= 0) && (m_iCurPage < (int)m_pages.size()))
|
|
{
|
|
pageStruct *pPS = m_pages[m_iCurPage];
|
|
ASSERT(pPS);
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg)
|
|
{
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
pPS->pDlg->ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// show the new one
|
|
if ((iPage >= 0) && (iPage < (int)m_pages.size()))
|
|
{
|
|
pageStruct *pPS = m_pages[iPage];
|
|
ASSERT(pPS);
|
|
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg)
|
|
{
|
|
|
|
// update caption bar
|
|
if (::IsWindow(m_captionBar.m_hWnd))
|
|
m_captionBar.SetWindowText(pPS->csCaption);
|
|
|
|
// if we haven't already, Create the dialog
|
|
if (!::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
pPS->pDlg->Create(pPS->pDlg->GetID(), this);
|
|
}
|
|
|
|
// move, show, focus
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
pPS->pDlg->MoveWindow(m_frameRect.left, m_frameRect.top, m_frameRect.Width(), m_frameRect.Height());
|
|
pPS->pDlg->ShowWindow(SW_SHOW);
|
|
//pPS->pDlg->SetFocus();
|
|
}
|
|
|
|
// change the tree
|
|
|
|
// find this in our map
|
|
HTREEITEM hItem = FindHTREEItemForDlg(pPS->pDlg);
|
|
if (hItem)
|
|
{
|
|
// select it
|
|
m_pageTree.SelectItem(hItem);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::OnOK()
|
|
{
|
|
// if EndOK returns true, all of the UpdateData(TRUE)'s succeeded
|
|
if (EndOK())
|
|
{
|
|
CDialog::OnOK();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool CSAPrefsDialog::EndOK()
|
|
{
|
|
bool bOK = true;
|
|
|
|
CSAPrefsSubDlg * pPage = NULL;
|
|
|
|
// first, UpdateData...
|
|
unsigned int i;
|
|
for (i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg)
|
|
{
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
if (!pPS->pDlg->UpdateData(TRUE))
|
|
{
|
|
bOK = false;
|
|
pPage = pPS->pDlg;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// were there any UpdateData errors?
|
|
if ((!bOK) && (pPage!=NULL))
|
|
{
|
|
ShowPage(pPage);
|
|
return false;
|
|
}
|
|
|
|
// tell all of the sub-dialogs "OK"
|
|
for ( i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg)
|
|
{
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
pPS->pDlg->OnOK();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::OnCancel()
|
|
{
|
|
// tell all of the sub-dialogs "Cancel"
|
|
for (unsigned int i = 0; i < m_pages.size(); i++)
|
|
{
|
|
pageStruct *pPS = m_pages[i];
|
|
ASSERT(pPS);
|
|
|
|
if (pPS)
|
|
{
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS->pDlg)
|
|
{
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
pPS->pDlg->OnCancel();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CDialog::OnCancel();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::EndSpecial(UINT res, bool bOk)
|
|
{
|
|
if (bOk)
|
|
{
|
|
EndOK();
|
|
}
|
|
|
|
EndDialog(res);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::OnSelchangedPageTree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
|
|
if (pNMTreeView->itemNew.lParam)
|
|
{
|
|
// find out which page was selected
|
|
int iIdx = -1;
|
|
for (unsigned int i = 0; i < m_pages.size(); i++)
|
|
{
|
|
if (m_pages[i]==(pageStruct *)pNMTreeView->itemNew.lParam)
|
|
{
|
|
iIdx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// show that page
|
|
if ((iIdx >= 0) && (iIdx < (int)m_pages.size()))
|
|
{
|
|
if (m_iCurPage!=iIdx)
|
|
{
|
|
PostMessage(WM_CHANGE_PAGE, iIdx);
|
|
}
|
|
}
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::OnGetdispinfoPageTree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
|
|
|
|
// return the caption of the appropriate dialog
|
|
if (pTVDispInfo->item.lParam)
|
|
{
|
|
if (pTVDispInfo->item.mask & TVIF_TEXT)
|
|
{
|
|
pageStruct *pPS = (pageStruct *)pTVDispInfo->item.lParam;
|
|
_tcscpy(pTVDispInfo->item.pszText, pPS->csCaption);
|
|
}
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CSAPrefsDialog::OnPhelp()
|
|
{
|
|
// simulate the property sheet method of sending Help (with WM_NOTIFY)
|
|
if ((m_iCurPage >= 0) && (m_iCurPage < (int)m_pages.size()))
|
|
{
|
|
pageStruct *pPS = m_pages[m_iCurPage];
|
|
ASSERT(pPS);
|
|
ASSERT(pPS->pDlg);
|
|
if (pPS)
|
|
{
|
|
if (pPS->pDlg)
|
|
{
|
|
if (::IsWindow(pPS->pDlg->m_hWnd))
|
|
{
|
|
// help!
|
|
NMHDR nm;
|
|
nm.code=PSN_HELP;
|
|
nm.hwndFrom=m_hWnd;
|
|
nm.idFrom=CSAPrefsDialog::IDD;
|
|
pPS->pDlg->SendMessage(WM_NOTIFY, 0, (long)&nm);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|