📄 tabbedmdisave.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// TabbedMDISave.cpp - Classes related to "saving" MDI children in the
// tabbed MDI environment.
//
// Classes:
// CTabbedMDIChildModifiedItem -
// Implements ITabbedMDIChildModifiedItem.
// CTabbedMDIChildModifiedList -
// Implements ITabbedMDIChildModifiedList.
//
// Written by Daniel Bowen (dbowen@es.com)
// Copyright (c) 2004 Daniel Bowen.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever.
//
// If you find bugs, have suggestions for improvements, etc.,
// please contact the author.
//
// History (Date/Author/Description):
// ----------------------------------
//
// 2005/07/13: Daniel Bowen
// - Namespace qualify the use of more ATL and WTL classes.
//
// 2005/04/14: Daniel Bowen
// - CSaveModifiedItemsDialog -
// ImageUtil::CreateCheckboxImage now takes an HWND for the list control
//
// 2005/03/15: Daniel Bowen
// - CSaveModifiedItemsDialog -
// Handle the case when no display name is set for an item - have it show "(New)".
//
// 2005/01/14: Daniel Bowen
// - Fix AutoHideUnusedColumns so that it doesn't try to hide the name column
//
// 2004/08/26: Daniel Bowen
// - Break out checkbox image creation
// - Have CDynamicDialogImpl automatically call ConstructDialogResource
// after the constructor, but before the dialog is created
//
// 2004/06/28: Daniel Bowen
// - Support hiding the description and/or last modified columns
// in the "save modified items" dialog.
// - Clean up warnings on level 4
//
// 2004/04/29: Daniel Bowen
// - Original implementation
#define WTL_TABBED_MDI_SAVE_IMPLEMENTATION
#include "TabbedMDISave.h"
#if (_WIN32_WINNT >= 0x0501)
#include <atltheme.h>
#endif
#if (_ATL_VER < 0x0700)
#error TabbedMDISave.cpp requires ATL 7.0 or higher
#endif
#include <atlcomtime.h>
#include "ImageUtil.h"
/////////////////////////////////////////////////////////////////////////////
// CTabbedMDIChildModifiedList
CTabbedMDIChildModifiedList::CTabbedMDIChildModifiedList() :
m_parentItem(NULL)
{
}
HRESULT CTabbedMDIChildModifiedList::FinalConstruct()
{
return S_OK;
}
void CTabbedMDIChildModifiedList::FinalRelease()
{
this->Clear();
// Don't Release m_parentItem, because
// we only have a weak reference to it
m_parentItem = NULL;
}
STDMETHODIMP CTabbedMDIChildModifiedList::get_Item(long index, ITabbedMDIChildModifiedItem** item)
{
if(item == NULL)
{
return E_POINTER;
}
HRESULT hr = E_INVALIDARG;
*item = NULL;
POSITION pos = this->FindIndex(index);
if(pos != NULL)
{
hr = this->GetAt(pos)->QueryInterface(item);
}
return hr;
}
STDMETHODIMP CTabbedMDIChildModifiedList::get_Index(ITabbedMDIChildModifiedItem* item, long* index)
{
if(item == NULL || index == NULL)
{
return E_POINTER;
}
*index = -1;
ATL::CComPtr<IUnknown> punkItemToFind;
item->QueryInterface(IID_IUnknown, (void**)&punkItemToFind);
// If we tracked items by their identity IUnknown*, we could do
// a "Find". But we don't, so we'll just linearly search the list,
// and depend on the comparing IUnknown* values for identity.
// (It's not expected that this method would be called very frequently).
int currentIndex = 0;
POSITION pos = this->GetHeadPosition();
while(pos != NULL)
{
ATL::CComPtr<IUnknown> punkItem;
this->GetNext(pos)->QueryInterface(IID_IUnknown, (void**)&punkItem);
if(punkItemToFind == punkItem)
{
*index = currentIndex;
pos = NULL;
}
else
{
++currentIndex;
}
}
return ((*index) >= 0) ? S_OK : E_INVALIDARG;
}
STDMETHODIMP CTabbedMDIChildModifiedList::get_Count(long* count)
{
if(count == NULL)
{
return E_POINTER;
}
*count = (long)this->GetCount();
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedList::AddNew(
const wchar_t* name, const wchar_t* displayName, const wchar_t* description,
DATE lastModified, HICON icon,
ITabbedMDIChildModifiedItem** item)
{
HRESULT hr = E_FAIL;
ATL::CComObject<CTabbedMDIChildModifiedItem>* newItem = NULL;
hr = ATL::CComObject<CTabbedMDIChildModifiedItem>::CreateInstance(&newItem);
if(newItem != NULL)
{
newItem->AddRef();
HWND window = NULL;
if(m_parentItem)
{
m_parentItem->get_Window(&window);
}
hr = newItem->InitNew(window, name, displayName, description, lastModified, icon);
if(SUCCEEDED(hr))
{
ATL::CComPtr<ITabbedMDIChildModifiedItem> modifiedItem;
hr = newItem->QueryInterface(&modifiedItem);
this->AddTail(modifiedItem);
// Set the parent list as ourselves, but only after
// we really have added it to our collection of items
modifiedItem->putref_ParentList(this);
if(item != NULL)
{
*item = modifiedItem.Detach();
}
}
newItem->Release();
}
return hr;
}
STDMETHODIMP CTabbedMDIChildModifiedList::Insert(
long index, ITabbedMDIChildModifiedItem* item)
{
HRESULT hr = E_INVALIDARG;
POSITION pos = this->FindIndex(index);
if(pos != NULL)
{
this->InsertBefore(pos, item);
hr = S_OK;
}
else
{
this->AddTail(item);
hr = S_OK;
}
if(SUCCEEDED(hr))
{
// Set the parent list as ourselves, but only after
// we really have added it to our collection of items
item->putref_ParentList(this);
}
return hr;
}
STDMETHODIMP CTabbedMDIChildModifiedList::InsertList(
long index, ITabbedMDIChildModifiedList* list)
{
if(list == NULL)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
long count = 0;
list->get_Count(&count);
if(index < 0)
{
index = count;
}
for(long i=0; i<count; ++i)
{
ATL::CComPtr<ITabbedMDIChildModifiedItem> item;
list->get_Item(i, &item);
this->Insert(index + i, item);
}
return hr;
}
STDMETHODIMP CTabbedMDIChildModifiedList::Remove(
long index, ITabbedMDIChildModifiedItem** item)
{
HRESULT hr = E_INVALIDARG;
POSITION pos = this->FindIndex(index);
if(pos != NULL)
{
ATL::CComPtr<ITabbedMDIChildModifiedItem> oldItem(this->GetAt(pos));
this->RemoveAt(pos);
if(oldItem)
{
oldItem->putref_ParentList(NULL);
if(item != NULL)
{
*item = oldItem.Detach();
}
}
}
return hr;
}
STDMETHODIMP CTabbedMDIChildModifiedList::Clear()
{
POSITION pos = this->GetHeadPosition();
while(pos != NULL)
{
ATL::CComPtr<ITabbedMDIChildModifiedItem> item(this->GetNext(pos));
if(item)
{
item->putref_ParentList(NULL);
}
}
this->RemoveAll();
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedList::get_ParentItem(ITabbedMDIChildModifiedItem** item)
{
ATLASSERT(item != NULL);
if(item == NULL)
{
return E_POINTER;
}
*item = m_parentItem;
if(m_parentItem)
{
m_parentItem->AddRef();
}
return S_OK;
}
// Methods not exposed over iterface:
STDMETHODIMP CTabbedMDIChildModifiedList::putref_ParentItem(ITabbedMDIChildModifiedItem* item)
{
m_parentItem = item;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// CTabbedMDIChildModifiedItem
CTabbedMDIChildModifiedItem::CTabbedMDIChildModifiedItem() :
m_window(NULL),
m_lastModified(0),
m_icon(NULL),
m_parentList(NULL)
{
}
HRESULT CTabbedMDIChildModifiedItem::FinalConstruct()
{
return S_OK;
}
void CTabbedMDIChildModifiedItem::FinalRelease()
{
if(m_icon)
{
::DestroyIcon(m_icon);
m_icon = NULL;
}
// Don't Release m_parentList, because
// we only have a weak reference to it
m_parentList = NULL;
m_window = NULL;
m_name.Empty();
m_displayName.Empty();
m_description.Empty();
m_userData.Release();
m_subItems.Release();
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_Window(
HWND* window)
{
ATLASSERT(window != NULL);
if (window == NULL)
{
return E_POINTER;
}
*window = m_window;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_Window(
HWND window)
{
m_window = window;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_Name(
BSTR* name)
{
return m_name.CopyTo(name);
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_Name(
const wchar_t* name)
{
m_name = name;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_DisplayName(
BSTR* displayName)
{
return m_displayName.CopyTo(displayName);
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_DisplayName(
const wchar_t* displayName)
{
m_displayName = displayName;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_Description(
BSTR* description)
{
return m_description.CopyTo(description);
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_Description(
const wchar_t* description)
{
m_description = description;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_LastModifiedUTC(
DATE* lastModified)
{
ATLASSERT(lastModified != NULL);
if (lastModified == NULL)
{
return E_POINTER;
}
*lastModified = m_lastModified;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_LastModifiedUTC(
DATE lastModified)
{
m_lastModified = lastModified;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_Icon(
HICON* icon)
{
ATLASSERT(icon != NULL);
if (icon == NULL)
{
return E_POINTER;
}
*icon = m_icon;
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::put_Icon(
HICON icon)
{
if(m_icon)
{
::DestroyIcon(m_icon);
m_icon = NULL;
}
m_icon = ::CopyIcon(icon);
return S_OK;
}
STDMETHODIMP CTabbedMDIChildModifiedItem::get_UserData(
IUnknown** userData)
{
return m_userData.CopyTo(userData);
}
STDMETHODIMP CTabbedMDIChildModifiedItem::putref_UserData(
IUnknown* userData)
{
m_userData = userData;
return S_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -