📄 docmgr.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
AFX_STATIC_DATA const TCHAR _afxShellOpenFmt[] = _T("%s\\shell\\open\\%s");
AFX_STATIC_DATA const TCHAR _afxShellPrintFmt[] = _T("%s\\shell\\print\\%s");
AFX_STATIC_DATA const TCHAR _afxShellPrintToFmt[] = _T("%s\\shell\\printto\\%s");
AFX_STATIC_DATA const TCHAR _afxDefaultIconFmt[] = _T("%s\\DefaultIcon");
AFX_STATIC_DATA const TCHAR _afxShellNewFmt[] = _T("%s\\ShellNew");
#define DEFAULT_ICON_INDEX 0
AFX_STATIC_DATA const TCHAR _afxIconIndexFmt[] = _T(",%d");
AFX_STATIC_DATA const TCHAR _afxCommand[] = _T("command");
AFX_STATIC_DATA const TCHAR _afxOpenArg[] = _T(" \"%1\"");
AFX_STATIC_DATA const TCHAR _afxPrintArg[] = _T(" /p \"%1\"");
AFX_STATIC_DATA const TCHAR _afxPrintToArg[] = _T(" /pt \"%1\" \"%2\" \"%3\" \"%4\"");
AFX_STATIC_DATA const TCHAR _afxDDEArg[] = _T(" /dde");
AFX_STATIC_DATA const TCHAR _afxDDEExec[] = _T("ddeexec");
AFX_STATIC_DATA const TCHAR _afxDDEOpen[] = _T("[open(\"%1\")]");
AFX_STATIC_DATA const TCHAR _afxDDEPrint[] = _T("[print(\"%1\")]");
AFX_STATIC_DATA const TCHAR _afxDDEPrintTo[] = _T("[printto(\"%1\",\"%2\",\"%3\",\"%4\")]");
AFX_STATIC_DATA const TCHAR _afxShellNewValueName[] = _T("NullFile");
AFX_STATIC_DATA const TCHAR _afxShellNewValue[] = _T("");
// recursively remove a registry key if and only if it has no subkeys
BOOL AFXAPI _AfxDeleteRegKey(LPCTSTR lpszKey)
{
// copy the string
LPTSTR lpszKeyCopy = _tcsdup(lpszKey);
LPTSTR lpszLast = lpszKeyCopy + lstrlen(lpszKeyCopy);
// work until the end of the string
while (lpszLast != NULL)
{
*lpszLast = '\0';
lpszLast = _tcsdec(lpszKeyCopy, lpszLast);
// try to open that key
HKEY hKey;
if (::RegOpenKey(HKEY_CLASSES_ROOT, lpszKeyCopy, &hKey) != ERROR_SUCCESS)
break;
// enumerate the keys underneath
TCHAR szScrap[_MAX_PATH+1];
DWORD dwLen = _countof(szScrap);
BOOL bItExists = FALSE;
if (::RegEnumKey(hKey, 0, szScrap, dwLen) == ERROR_SUCCESS)
bItExists = TRUE;
::RegCloseKey(hKey);
// found one? quit looping
if (bItExists)
break;
// otherwise, delete and find the previous backwhack
::RegDeleteKey(HKEY_CLASSES_ROOT, lpszKeyCopy);
lpszLast = _tcsrchr(lpszKeyCopy, '\\');
}
// release the string and return
free(lpszKeyCopy);
return TRUE;
}
AFX_STATIC BOOL AFXAPI
_AfxSetRegKey(LPCTSTR lpszKey, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL)
{
if (lpszValueName == NULL)
{
if (::RegSetValue(HKEY_CLASSES_ROOT, lpszKey, REG_SZ,
lpszValue, lstrlen(lpszValue) * sizeof(TCHAR)) != ERROR_SUCCESS)
{
TRACE1("Warning: registration database update failed for key '%s'.\n",
lpszKey);
return FALSE;
}
return TRUE;
}
else
{
HKEY hKey;
if(::RegCreateKey(HKEY_CLASSES_ROOT, lpszKey, &hKey) == ERROR_SUCCESS)
{
LONG lResult = ::RegSetValueEx(hKey, lpszValueName, 0, REG_SZ,
(CONST BYTE*)lpszValue, (lstrlen(lpszValue) + 1) * sizeof(TCHAR));
if(::RegCloseKey(hKey) == ERROR_SUCCESS && lResult == ERROR_SUCCESS)
return TRUE;
}
TRACE1("Warning: registration database update failed for key '%s'.\n", lpszKey);
return FALSE;
}
}
CDocManager::CDocManager()
{
}
void CDocManager::UnregisterShellFileTypes()
{
ASSERT(!m_templateList.IsEmpty()); // must have some doc templates
CString strPathName, strTemp;
AfxGetModuleShortFileName(AfxGetInstanceHandle(), strPathName);
POSITION pos = m_templateList.GetHeadPosition();
for (int nTemplateIndex = 1; pos != NULL; nTemplateIndex++)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
CString strFilterExt, strFileTypeId, strFileTypeName;
if (pTemplate->GetDocString(strFileTypeId,
CDocTemplate::regFileTypeId) && !strFileTypeId.IsEmpty())
{
// enough info to register it
if (!pTemplate->GetDocString(strFileTypeName,
CDocTemplate::regFileTypeName))
strFileTypeName = strFileTypeId; // use id name
ASSERT(strFileTypeId.Find(' ') == -1); // no spaces allowed
strTemp.Format(_afxDefaultIconFmt, (LPCTSTR)strFileTypeId);
_AfxDeleteRegKey(strTemp);
// If MDI Application
if (!pTemplate->GetDocString(strTemp, CDocTemplate::windowTitle) ||
strTemp.IsEmpty())
{
// path\shell\open\ddeexec = [open("%1")]
strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
_AfxDeleteRegKey(strTemp);
// path\shell\print\ddeexec = [print("%1")]
strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
_AfxDeleteRegKey(strTemp);
// path\shell\printto\ddeexec = [printto("%1","%2","%3","%4")]
strTemp.Format(_afxShellPrintToFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
_AfxDeleteRegKey(strTemp);
}
// path\shell\open\command = path filename
strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
_AfxDeleteRegKey(strTemp);
// path\shell\print\command = path /p filename
strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
_AfxDeleteRegKey(strTemp);
// path\shell\printto\command = path /pt filename printer driver port
strTemp.Format(_afxShellPrintToFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
_AfxDeleteRegKey(strTemp);
pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt);
if (!strFilterExt.IsEmpty())
{
ASSERT(strFilterExt[0] == '.');
LONG lSize = _MAX_PATH * 2;
LONG lResult = ::RegQueryValue(HKEY_CLASSES_ROOT, strFilterExt,
strTemp.GetBuffer(lSize), &lSize);
strTemp.ReleaseBuffer();
if (lResult != ERROR_SUCCESS || strTemp.IsEmpty() ||
strTemp == strFileTypeId)
{
strTemp.Format(_afxShellNewFmt, (LPCTSTR)strFilterExt);
_AfxDeleteRegKey(strTemp);
// no association for that suffix
_AfxDeleteRegKey(strFilterExt);
}
}
}
}
}
void CDocManager::RegisterShellFileTypes(BOOL bCompat)
{
ASSERT(!m_templateList.IsEmpty()); // must have some doc templates
CString strPathName, strTemp;
AfxGetModuleShortFileName(AfxGetInstanceHandle(), strPathName);
POSITION pos = m_templateList.GetHeadPosition();
for (int nTemplateIndex = 1; pos != NULL; nTemplateIndex++)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
CString strOpenCommandLine = strPathName;
CString strPrintCommandLine = strPathName;
CString strPrintToCommandLine = strPathName;
CString strDefaultIconCommandLine = strPathName;
if (bCompat)
{
CString strIconIndex;
HICON hIcon = ::ExtractIcon(AfxGetInstanceHandle(), strPathName, nTemplateIndex);
if (hIcon != NULL)
{
strIconIndex.Format(_afxIconIndexFmt, nTemplateIndex);
DestroyIcon(hIcon);
}
else
{
strIconIndex.Format(_afxIconIndexFmt, DEFAULT_ICON_INDEX);
}
strDefaultIconCommandLine += strIconIndex;
}
CString strFilterExt, strFileTypeId, strFileTypeName;
if (pTemplate->GetDocString(strFileTypeId,
CDocTemplate::regFileTypeId) && !strFileTypeId.IsEmpty())
{
// enough info to register it
if (!pTemplate->GetDocString(strFileTypeName,
CDocTemplate::regFileTypeName))
strFileTypeName = strFileTypeId; // use id name
ASSERT(strFileTypeId.Find(' ') == -1); // no spaces allowed
// first register the type ID of our server
if (!_AfxSetRegKey(strFileTypeId, strFileTypeName))
continue; // just skip it
if (bCompat)
{
// path\DefaultIcon = path,1
strTemp.Format(_afxDefaultIconFmt, (LPCTSTR)strFileTypeId);
if (!_AfxSetRegKey(strTemp, strDefaultIconCommandLine))
continue; // just skip it
}
// If MDI Application
if (!pTemplate->GetDocString(strTemp, CDocTemplate::windowTitle) ||
strTemp.IsEmpty())
{
// path\shell\open\ddeexec = [open("%1")]
strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
if (!_AfxSetRegKey(strTemp, _afxDDEOpen))
continue; // just skip it
if (bCompat)
{
// path\shell\print\ddeexec = [print("%1")]
strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
if (!_AfxSetRegKey(strTemp, _afxDDEPrint))
continue; // just skip it
// path\shell\printto\ddeexec = [printto("%1","%2","%3","%4")]
strTemp.Format(_afxShellPrintToFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxDDEExec);
if (!_AfxSetRegKey(strTemp, _afxDDEPrintTo))
continue; // just skip it
// path\shell\open\command = path /dde
// path\shell\print\command = path /dde
// path\shell\printto\command = path /dde
strOpenCommandLine += _afxDDEArg;
strPrintCommandLine += _afxDDEArg;
strPrintToCommandLine += _afxDDEArg;
}
else
{
strOpenCommandLine += _afxOpenArg;
}
}
else
{
// path\shell\open\command = path filename
// path\shell\print\command = path /p filename
// path\shell\printto\command = path /pt filename printer driver port
strOpenCommandLine += _afxOpenArg;
if (bCompat)
{
strPrintCommandLine += _afxPrintArg;
strPrintToCommandLine += _afxPrintToArg;
}
}
// path\shell\open\command = path filename
strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
if (!_AfxSetRegKey(strTemp, strOpenCommandLine))
continue; // just skip it
if (bCompat)
{
// path\shell\print\command = path /p filename
strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
if (!_AfxSetRegKey(strTemp, strPrintCommandLine))
continue; // just skip it
// path\shell\printto\command = path /pt filename printer driver port
strTemp.Format(_afxShellPrintToFmt, (LPCTSTR)strFileTypeId,
(LPCTSTR)_afxCommand);
if (!_AfxSetRegKey(strTemp, strPrintToCommandLine))
continue; // just skip it
}
pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt);
if (!strFilterExt.IsEmpty())
{
ASSERT(strFilterExt[0] == '.');
LONG lSize = _MAX_PATH * 2;
LONG lResult = ::RegQueryValue(HKEY_CLASSES_ROOT, strFilterExt,
strTemp.GetBuffer(lSize), &lSize);
strTemp.ReleaseBuffer();
if (lResult != ERROR_SUCCESS || strTemp.IsEmpty() ||
strTemp == strFileTypeId)
{
// no association for that suffix
if (!_AfxSetRegKey(strFilterExt, strFileTypeId))
continue;
if (bCompat)
{
strTemp.Format(_afxShellNewFmt, (LPCTSTR)strFilterExt);
(void)_AfxSetRegKey(strTemp, _afxShellNewValue, _afxShellNewValueName);
}
}
}
}
}
}
#ifdef AFX_CORE3_SEG
#pragma code_seg(AFX_CORE3_SEG)
#endif
AFX_STATIC void AFXAPI _AfxAppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
CDocTemplate* pTemplate, CString* pstrDefaultExt)
{
ASSERT_VALID(pTemplate);
ASSERT_KINDOF(CDocTemplate, pTemplate);
CString strFilterExt, strFilterName;
if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&
!strFilterExt.IsEmpty() &&
pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&
!strFilterName.IsEmpty())
{
// a file based document template - add to filter list
ASSERT(strFilterExt[0] == '.');
if (pstrDefaultExt != NULL)
{
// set the default extension
*pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1; // skip the '.'
ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);
ofn.nFilterIndex = ofn.nMaxCustFilter + 1; // 1 based number
}
// add to filter
filter += strFilterName;
ASSERT(!filter.IsEmpty()); // must have a file type name
filter += (TCHAR)'\0'; // next string please
filter += (TCHAR)'*';
filter += strFilterExt;
filter += (TCHAR)'\0'; // next string please
ofn.nMaxCustFilter++;
}
}
// Get the best document template for the named file
class CNewTypeDlg : public CDialog
{
protected:
CPtrList* m_pList; // actually a list of doc templates
public:
CDocTemplate* m_pSelectedTemplate;
public:
//{{AFX_DATA(CNewTypeDlg)
enum { IDD = AFX_IDD_NEWTYPEDLG };
//}}AFX_DATA
CNewTypeDlg(CPtrList* pList) : CDialog(CNewTypeDlg::IDD)
{
m_pList = pList;
m_pSelectedTemplate = NULL;
}
~CNewTypeDlg() { }
protected:
BOOL OnInitDialog();
void OnOK();
//{{AFX_MSG(CNewTypeDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CNewTypeDlg, CDialog)
//{{AFX_MSG_MAP(CNewTypeDlg)
ON_LBN_DBLCLK(AFX_IDC_LISTBOX, OnOK)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CNewTypeDlg::OnInitDialog()
{
CListBox* pListBox = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX);
ASSERT(pListBox != NULL);
// fill with document templates in list
pListBox->ResetContent();
POSITION pos = m_pList->GetHeadPosition();
// add all the CDocTemplates in the list by name
while (pos != NULL)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_pList->GetNext(pos);
ASSERT_KINDOF(CDocTemplate, pTemplate);
CString strTypeName;
if (pTemplate->GetDocString(strTypeName, CDocTemplate::fileNewName) &&
!strTypeName.IsEmpty())
{
// add it to the listbox
int nIndex = pListBox->AddString(strTypeName);
if (nIndex == -1)
{
EndDialog(-1);
return FALSE;
}
pListBox->SetItemDataPtr(nIndex, pTemplate);
}
}
int nTemplates = pListBox->GetCount();
if (nTemplates == 0)
{
TRACE0("Error: no document templates to select from!\n");
EndDialog(-1); // abort
}
else if (nTemplates == 1)
{
// get the first/only item
m_pSelectedTemplate = (CDocTemplate*)pListBox->GetItemDataPtr(0);
ASSERT_VALID(m_pSelectedTemplate);
ASSERT_KINDOF(CDocTemplate, m_pSelectedTemplate);
EndDialog(IDOK); // done
}
else
{
// set selection to the first one (NOT SORTED)
pListBox->SetCurSel(0);
}
return CDialog::OnInitDialog();
}
void CNewTypeDlg::OnOK()
{
CListBox* pListBox = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX);
ASSERT(pListBox != NULL);
// if listbox has selection, set the selected template
int nIndex;
if ((nIndex = pListBox->GetCurSel()) == -1)
{
// no selection
m_pSelectedTemplate = NULL;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -