switch (rCmdInfo.m_nShellCommand) ...{ case CCommandLineInfo::FileNew: OnFileNew().... break; case CCommandLineInfo::FileOpen: OpenDocumentFile(rCmdInfo.m_strFileName).... break; case CCommandLineInfo::FilePrint: case CCommandLineInfo::FilePrintTo: 打开文件,发送ID_FILE_PRINT_DIRECT,返回FALSE值(导致立即程序退出) case CCommandLineInfo::FileDDE: m_nCmdShow = SW_HIDE;(程序被运行,但被隐藏,m_nCmdShow作为ShowWindow的参数) 等等操作 }
附一:CDocManager::RegisterShellFileTypes
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) ...{ // pathDefaultIcon = 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()) ...{ // pathshellopenddeexec = [open("%1")] strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId, (LPCTSTR)_afxDDEExec); if (!_AfxSetRegKey(strTemp, _afxDDEOpen)) continue; // just skip it if (bCompat) ...{ // pathshellprintddeexec = [print("%1")] strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId, (LPCTSTR)_afxDDEExec); if (!_AfxSetRegKey(strTemp, _afxDDEPrint)) continue; // just skip it // pathshellprinttoddeexec = [printto("%1","%2","%3","%4")] strTemp.Format(_afxShellPrintToFmt, (LPCTSTR)strFileTypeId, (LPCTSTR)_afxDDEExec); if (!_AfxSetRegKey(strTemp, _afxDDEPrintTo)) continue; // just skip it // pathshellopencommand = path /dde // pathshellprintcommand = path /dde // pathshellprinttocommand = path /dde strOpenCommandLine += _afxDDEArg; strPrintCommandLine += _afxDDEArg; strPrintToCommandLine += _afxDDEArg; } else ...{ strOpenCommandLine += _afxOpenArg; } } else ...{ // pathshellopencommand = path filename // pathshellprintcommand = path /p filename // pathshellprinttocommand = path /pt filename printer driver port strOpenCommandLine += _afxOpenArg; if (bCompat) ...{ strPrintCommandLine += _afxPrintArg; strPrintToCommandLine += _afxPrintToArg; } } // pathshellopencommand = path filename strTemp.Format(_afxShellOpenFmt, (LPCTSTR)strFileTypeId, (LPCTSTR)_afxCommand); if (!_AfxSetRegKey(strTemp, strOpenCommandLine)) continue; // just skip it if (bCompat) ...{ // pathshellprintcommand = path /p filename strTemp.Format(_afxShellPrintFmt, (LPCTSTR)strFileTypeId, (LPCTSTR)_afxCommand); if (!_AfxSetRegKey(strTemp, strPrintCommandLine)) continue; // just skip it // pathshellprinttocommand = 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); } } } } } }
附二:CWinApp::ProcessShellCommand
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo) ...{ BOOL bResult = TRUE; switch (rCmdInfo.m_nShellCommand) ...{ case CCommandLineInfo::FileNew: if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)) OnFileNew(); if (m_pMainWnd == NULL) bResult = FALSE; break; // If we've been asked to open a file, call OpenDocumentFile() case CCommandLineInfo::FileOpen: if (!OpenDocumentFile(rCmdInfo.m_strFileName)) bResult = FALSE; break; // If the user wanted to print, hide our main window and // fire a message to ourselves to start the printing case CCommandLineInfo::FilePrintTo: case CCommandLineInfo::FilePrint: m_nCmdShow = SW_HIDE; ASSERT(m_pCmdInfo == NULL); OpenDocumentFile(rCmdInfo.m_strFileName); m_pCmdInfo =&rCmdInfo; m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT); m_pCmdInfo = NULL; bResult = FALSE; break; // If we're doing DDE, hide ourselves case CCommandLineInfo::FileDDE: m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow; m_nCmdShow = SW_HIDE; break; // If we've been asked to unregister, unregister and then terminate case CCommandLineInfo::AppUnregister: ...{ UnregisterShellFileTypes(); BOOL bUnregistered = Unregister(); // if you specify /EMBEDDED, we won't make an success/failure box // this use of /EMBEDDED is not related to OLE if (!rCmdInfo.m_bRunEmbedded) ...{ if (bUnregistered) AfxMessageBox(AFX_IDP_UNREG_DONE); else AfxMessageBox(AFX_IDP_UNREG_FAILURE); } bResult = FALSE; // that's all we do // If nobody is using it already, we can use it. // We'll flag that we're unregistering and not save our state // on the way out. This new object gets deleted by the // app object destructor. if (m_pCmdInfo == NULL) ...{ m_pCmdInfo =new CCommandLineInfo; m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister; } } break; } return bResult; }