#include "stdafx.h"
#include "resource.h"
#include "aboutdlg.h"
#include "EditorFrame.h"
/////////////////////////////////////////////////////////////////////////////
// Construction
CEditorFrame::CEditorFrame() : m_bAllowTDClose(false)
{
}
CEditorFrame::~CEditorFrame()
{
}
/////////////////////////////////////////////////////////////////////////////
// Message handlers
BOOL CEditorFrame::OnInitDialog ( HWND hwndCtrl, LPARAM lParam )
{
CRect rcTabDisplayArea;
HICON hi = AtlLoadIconImage ( IDI_INFOICON, LR_DEFAULTCOLOR, 16, 16 );
// Init the imagelist for the Rebuild button
if ( NULL != hi && m_iml.Create ( 16, 16, ILC_COLOR8|ILC_MASK, 1, 1 ) )
m_iml.AddIcon ( hi );
// Set up the tabs
m_wndTab = GetDlgItem(IDC_TOOLS_TABS);
m_wndTab.ModifyStyleEx ( 0, WS_EX_CONTROLPARENT );
m_wndTab.InsertItem ( 0, _S(IDS_TEXT_TAB) );
m_wndTab.InsertItem ( 1, _S(IDS_BUTTONS_TAB) );
m_wndTab.InsertItem ( 2, _S(IDS_RADIO_BUTTONS_TAB) );
m_wndTab.InsertItem ( 3, _S(IDS_FLAGS_TAB) );
m_wndTab.GetClientRect ( rcTabDisplayArea );
m_wndTab.AdjustRect ( false, rcTabDisplayArea );
// Create the child dialogs for the tabs.
m_wndTextTools.Create ( m_wndTab );
m_wndButtonsTools.Create ( m_wndTab );
m_wndRadioButtonsTools.Create ( m_wndTab );
m_wndFlagsTools.Create ( m_wndTab );
m_wndTextTools.SetWindowPos ( NULL, rcTabDisplayArea, SWP_NOZORDER );
m_wndButtonsTools.SetWindowPos ( NULL, rcTabDisplayArea, SWP_NOZORDER );
m_wndRadioButtonsTools.SetWindowPos ( NULL, rcTabDisplayArea, SWP_NOZORDER );
m_wndFlagsTools.SetWindowPos ( NULL, rcTabDisplayArea, SWP_NOZORDER );
m_wndCurrPage = m_wndTextTools.m_hWnd;
return TRUE;
}
LRESULT CEditorFrame::OnRebuildTaskDlg ( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
TASKDIALOGCONFIG tdc = { sizeof(TASKDIALOGCONFIG) };
tdc.lpCallbackData = (LONG_PTR) this;
tdc.pfCallback = &CEditorFrame::TDCallback;
// Call each tools dialog so it can store its data in the TDCONFIG struct.
m_wndTextTools.FillInTDConfig ( tdc );
m_wndButtonsTools.FillInTDConfig ( tdc );
m_wndRadioButtonsTools.FillInTDConfig ( tdc );
m_wndFlagsTools.FillInTDConfig ( tdc );
// Show the new task dialog.
m_wndTD.SendMessage ( TDM_NAVIGATE_PAGE, 0, (LPARAM) &tdc );
// Remove the image from the Rebuild button.
BUTTON_IMAGELIST bil = {0};
SendDlgItemMessage ( IDC_REBUILD_DLG, BCM_SETIMAGELIST, 0, (LPARAM) &bil );
return 0;
}
LRESULT CEditorFrame::OnShowApplyFlag ( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
BUTTON_IMAGELIST bil = {0};
// Set an imagelist on the button so it shows the info icon.
bil.himl = m_iml;
bil.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
SendDlgItemMessage ( IDC_REBUILD_DLG, BCM_SETIMAGELIST, 0, (LPARAM) &bil );
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// Command handlers
void CEditorFrame::OnAbout ( UINT uCode, int nID, HWND hwndCtrl )
{
CAboutDlg dlg;
dlg.DoModal ( m_hWnd );
}
void CEditorFrame::OnSaveXML ( UINT uCode, int nID, HWND hwndCtrl )
try
{
IXMLDOMDocumentPtr pDoc ( __uuidof(MSXML::DOMDocument) );
IXMLDOMElementPtr pRoot;
// Set up the root node and the file version number.
pRoot = pDoc->createElement ( "task_dialog" );
pRoot->setAttribute ( "version", 1 );
pDoc->appendChild ( pRoot );
DWORD dwTextFlags = 0, dwButtonsFlags = 0, dwRadioButtonsFlags = 0,
dwFlagsFlags = 0, dwAllFlags = 0;
// Call each page to save its settings to the XML doc.
if ( m_wndTextTools.SaveToXML ( pDoc, dwTextFlags ) &&
m_wndButtonsTools.SaveToXML ( pDoc, dwButtonsFlags ) &&
m_wndRadioButtonsTools.SaveToXML ( pDoc, dwRadioButtonsFlags ) &&
m_wndFlagsTools.SaveToXML ( pDoc, dwFlagsFlags ) )
{
IXMLDOMElementPtr pFlags = pDoc->selectSingleNode ( "/task_dialog/flags" );
if ( NULL == pFlags )
{
pFlags = pDoc->createElement ( "flags" );
pDoc->documentElement->appendChild ( pFlags );
}
dwAllFlags = dwTextFlags | dwButtonsFlags | dwRadioButtonsFlags | dwFlagsFlags;
// Convert the flag values to string tokens & write any leftover flags
// to the "extra" attribute.
if ( WriteFlagTokens ( pFlags, dwAllFlags ) )
{
CString sFilename;
if ( dwAllFlags > 0 )
pFlags->setAttribute ( "extra", dwAllFlags );
if ( PromptForFilename ( sFilename ) )
pDoc->save ( (_bstr_t)(LPCTSTR) sFilename );
}
}
}
catch ( _com_error& e )
{
(void) e;
ATLTRACE(_T("Error while saving XML: %s\n"), e.ErrorMessage());
}
void CEditorFrame::OnRebuild ( UINT uCode, int nID, HWND hwndCtrl )
{
SendMessage ( UWM_REBUILD_DLG );
}
void CEditorFrame::OnCancel ( UINT uCode, int nID, HWND hwndCtrl )
{
// Set this flag so the TDN_BUTTON_CLICKED notification handler will allow
// the task dlg to close.
m_bAllowTDClose = true;
m_wndTD.SendMessage ( TDM_CLICK_BUTTON, IDOK );
}
LRESULT CEditorFrame::OnTabSelchange ( NMHDR* phdr )
{
int nSelTab = m_wndTab.GetCurSel();
// Hide the currently-visible dialog.
m_wndCurrPage.ShowWindow ( SW_HIDE );
// Determine which dlg should be visible.
if ( 0 == nSelTab )
m_wndCurrPage = m_wndTextTools.m_hWnd;
else if ( 1 == nSelTab )
m_wndCurrPage = m_wndButtonsTools.m_hWnd;
else if ( 2 == nSelTab )
m_wndCurrPage = m_wndRadioButtonsTools.m_hWnd;
else if ( 3 == nSelTab )
m_wndCurrPage = m_wndFlagsTools.m_hWnd;
else
ATLASSERT(0);
m_wndCurrPage.ShowWindow ( SW_SHOW );
return 0; // retval ignored
}
bool CEditorFrame::WriteFlagTokens ( IXMLDOMElementPtr& pFlagsElt, DWORD& dwFlags )
try
{
struct { DWORD dwFlag; LPCTSTR szToken; } aszTokens[] = {
{ TDF_USE_COMMAND_LINKS, _T("use_command_links") },
{ TDF_USE_COMMAND_LINKS_NO_ICON, _T("use_command_links_no_icon") },
{ TDF_ENABLE_HYPERLINKS, _T("allow_hyperlinks") },
{ TDF_ALLOW_DIALOG_CANCELLATION, _T("allow_cancellation") },
{ TDF_EXPAND_FOOTER_AREA, _T("expand_footer") },
{ TDF_EXPANDED_BY_DEFAULT, _T("expanded_by_default") },
{ TDF_VERIFICATION_FLAG_CHECKED, _T("checked_by_default") },
{ TDF_SHOW_PROGRESS_BAR, _T("show_progress_bar") },
{ TDF_SHOW_MARQUEE_PROGRESS_BAR, _T("show_marquee") },
{ TDF_POSITION_RELATIVE_TO_WINDOW, _T("position_relative") },
{ 0 }
}, *p;
CString sTokens;
// Convert the flags we know about into their string token equivalents.
for ( p = aszTokens; NULL != p->dwFlag && dwFlags > 0; p++ )
{
if ( dwFlags & p->dwFlag )
{
dwFlags &= ~(p->dwFlag);
if ( !sTokens.IsEmpty() )
sTokens += _T(" ");
sTokens += p->szToken;
}
}
if ( !sTokens.IsEmpty() )
pFlagsElt->text = (_bstr_t)(LPCTSTR) sTokens;
return true;
}
catch ( _com_error& e )
{
(void) e;
ATLTRACE(_T("Exception while building XML: %s\n"), e.ErrorMessage());
return false;
}
bool CEditorFrame::PromptForFilename ( CString& sFilename )
{
HRESULT hr;
CComPtr<IFileSaveDialog> pDlg;
CString sXMLFilter((LPCTSTR) IDS_XML_FILES_FILTERSPEC),
sAllFilesFilter((LPCTSTR) IDS_ALL_FILES_FILTERSPEC),
sDlgTitle((LPCTSTR) IDS_SAVE_FILE_DLG_TITLE);
COMDLG_FILTERSPEC aFileTypes[] = {
{ sXMLFilter, L"*.xml" },
{ sAllFilesFilter, L"*.*" }
};
// Use the new Vista file-save dialog!
hr = pDlg.CoCreateInstance ( __uuidof(FileSaveDialog) );
if ( FAILED(hr) )
return false;
pDlg->SetFileTypes ( _countof(aFileTypes), aFileTypes );
pDlg->SetDefaultExtension ( L"xml" );
pDlg->SetTitle ( sDlgTitle );
hr = pDlg->Show ( m_hWnd );
if ( FAILED(hr) )
return false;
CComPtr<IShellItem> pSelectedItem;
LPOLESTR pwsz = NULL;
hr = pDlg->GetResult ( &pSelectedItem );
if ( FAILED(hr) )
return false;
hr = pSelectedItem->GetDisplayName ( SIGDN_FILESYSPATH, &pwsz );
if ( FAILED(hr) )
return false;
sFilename = pwsz;
CoTaskMemFree ( pwsz );
return true;
}
HRESULT CALLBACK CEditorFrame::TDCallback (
HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData )
{
CEditorFrame* pThis = (CEditorFrame*) dwRefData;
ATLASSERT(NULL != pThis);
#ifdef _DEBUG
// In debug builds, print out a trace message showing which notification we got.
static LPCTSTR aszNotifications[] = {
_T("TDN_CREATED"), _T("TDN_NAVIGATED"), _T("TDN_BUTTON_CLICKED"),
_T("TDN_HYPERLINK_CLICKED"), _T("TDN_TIMER"), _T("TDN_DESTROYED"),
_T("TDN_RADIO_BUTTON_CLICKED"), _T("TDN_DIALOG_CONSTRUCTED"),
_T("TDN_VERIFICATION_CLICKED"), _T("TDN_HELP"),
_T("TDN_EXPANDO_BUTTON_CLICKED")
};
if ( uNotification < _countof(aszNotifications) )
ATLTRACE(_T(">>> TD notification: %s\n"), aszNotifications[uNotification]);
else
ATLTRACE(_T(">>> TD notification: %u\n"), uNotification);
#endif
return pThis->TDCallbackInternal ( hwnd, uNotification, wParam, lParam );
}
HRESULT CEditorFrame::TDCallbackInternal (
HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam )
{
HRESULT hr = 0;
if ( TDN_DIALOG_CONSTRUCTED == uNotification )
{
// Store the task dialog's HWND.
m_wndTD = hwnd;
m_wndTextTools.m_wndTD = hwnd;
m_wndButtonsTools.m_wndTD = hwnd;
m_wndRadioButtonsTools.m_wndTD = hwnd;
m_wndFlagsTools.m_wndTD = hwnd;
}
else if ( TDN_CREATED == uNotification )
{
// Get the window text of the task dialog, which will be the default
// for the Caption option.
m_wndTD.GetWindowText ( m_wndTextTools.m_sDefaultCaption );
if ( NULL != Create(NULL) )
{
RECT rc = {0};
if ( SystemParametersInfo ( SPI_GETWORKAREA, 0, &rc, FALSE ) )
SetWindowPos ( NULL, rc.left+16, rc.top+16, 0, 0, SWP_NOZORDER|SWP_NOSIZE );
ShowWindow(SW_SHOW);
}
}
else if ( TDN_BUTTON_CLICKED == uNotification )
hr = !m_bAllowTDClose; // Return value for this message is a BOOL, true=>don't close
else if ( TDN_NAVIGATED == uNotification )
{
// Notify each page that the task dlg's UI was updated, so they can make
// any necessary changes to UI elements.
m_wndTextTools.OnTDNavigated();
m_wndButtonsTools.OnTDNavigated();
m_wndRadioButtonsTools.OnTDNavigated();
m_wndFlagsTools.OnTDNavigated();
}
else if ( TDN_HYPERLINK_CLICKED == uNotification )
{
// Show a message box to indicate that the link was clicked
TaskDialog ( hwnd, _Module.GetResourceInstance(), MAKEINTRESOURCEW(IDR_MAINFRAME),
MAKEINTRESOURCEW(IDS_LINK_CLICKED_MSG), (LPCWSTR) lParam,
TDCBF_CLOSE_BUTTON, TD_INFORMATION_ICON, NULL );
}
else if ( TDN_DESTROYED == uNotification )
DestroyWindow(); // Destroy the editor window
return hr;
}