应用程序类对象实例初始操作的分析

林嵩弦

林嵩弦

2016-02-19 13:00

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的应用程序类对象实例初始操作的分析教程,一起来看看吧!超容易上手~

BOOL CSomeApp::InitInstance()
{
Enable3dControls();
LoadStdProfileSettings();
AddDocTemplate(...) ...... ShowWindow(...);
m_pMainWnd-DragAcceptFiles();
EnableShellOpen();
RegisterShellFileTypes(TRUE);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;
return TRUE;
}

  下面对InitInstance中的一些操作及其流程进行分析

  1.常规设置

  如:
  SetDialogBkColor()
  Enable3dControls()..
  (如果设置了后者,则前者就不必要了)
  SetRegistryKey(指定注册表键,替代INI文件)

  2.LoadStdProfileSettings()

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  LoadStdProfileSettings 完成最近文件列表功能,在菜单中添加最近的文件作为菜单项过程:

  建立一个CRecentFileList从注册表或INI文件中读入最近文件列表;

  当菜单建立时,文件列表将添加到菜单中ID_FILE_MRU_FILE*位置;

  3.m_pMainWnd-DragAcceptFiles()接收文件拖入

  使主窗口能响应文件拖入消息WM_DROPFILES;

  当有文件拖入时, 框架窗口的OnDropFiles将处理,以打开这些文件。

void CFrameWnd::OnDropFiles(HDROP hDropInfo)
{
SetActiveWindow(); // activate us first !
UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);

CWinApp* pApp = AfxGetApp();
ASSERT(pApp != NULL);
for (UINT iFile = 0; iFile nFiles; iFile++)
{
TCHAR szFileName[_MAX_PATH];
::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH);
//应用程序打开拖入文档
pApp-OpenDocumentFile(szFileName);
}
::DragFinish(hDropInfo);
}

  4.EnableShellOpen();

  为在Windows中使用外壳操作打开文件作准备

void CWinApp::EnableShellOpen()
{
ASSERT(m_atomApp == NULL && m_atomSystemTopic == NULL); // do once

m_atomApp = ::GlobalAddAtom(m_pszExeName);
m_atomSystemTopic = ::GlobalAddAtom(_T("system"));

  5.RegisterShellFileTypes

  向系统注册文件类型,以使用外壳操作。

  将调用m_pDocManager-RegisterShellFileTypes()

  (CDocManager::RegisterShellFileTypes()源码附后)

  要点:将所有文档模板的类型,外壳命令等写入注册表

  包括type ID、shellopenddeexec = [open("%1")]、shellprintddeexec = [print("%1")]、shellprinttoddeexec = [printto("%1","%2","%3","%4")]等等。

  6.ProcessShellCommand

  处理命令行、外壳命令等

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;

  ①先建立CCommandLineInfo对象

  ②再将命令行参数等分解到cmdInfo;

void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
{
for (int i = 1; i __argc; i++)
{
LPCTSTR pszParam = __targv[i];
BOOL bFlag = FALSE;
BOOL bLast = ((i + 1) == __argc);
if (pszParam[0] == '-' || pszParam[0] == '/')
{
// remove flag specifier
bFlag = TRUE;
++pszParam;
}
rCmdInfo.ParseParam(pszParam, bFlag, bLast);
}
}

  通过该操作,命令行被转化为cmdInfo;

  命令行的意义
  app (新建文件)
  app filename(打开文件)
  app /p filename(打印文件)
  app /pt filename printer driver port (用指定的打印机打印)
  app /dde (运行并接收DDE命令)
  app /Automation (启动为自动化服务器)
  app /Embedding (内嵌式运行)

  ParseCommandLine后,操作类型(打开、新建、打印..)存放在m_nShellCommand; 文件名存放在m_strFileName......

  ③处理命令

  主要操作:

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

switch (rCmdInfo.m_nShellCommand)
{
case CCommandLineInf:FileNew:
OnFileNew()....
break;
case CCommandLineInf:FileOpen:
OpenDocumentFile(rCmdInfo.m_strFileName)....
break;
case CCommandLineInf:FilePrint:
case CCommandLineInf:FilePrintT
打开文件,发送ID_FILE_PRINT_DIRECT,返回FALSE值(导致立即程序退出)
case CCommandLineInf: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 CCommandLineInf: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 CCommandLineInf: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 CCommandLineInf:FilePrintT
case CCommandLineInf: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 CCommandLineInf:FileDDE:
m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow;
m_nCmdShow = SW_HIDE;
break;

// If we've been asked to unregister, unregister and then terminate
case CCommandLineInf: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 = CCommandLineInf:AppUnregister;
}
}
break;
}
return bResult;
}

展开更多 50%)
分享

猜你喜欢

应用程序类对象实例初始操作的分析

编程语言 网络编程
应用程序类对象实例初始操作的分析

组件对象开发Web应用的实例分析

ASP
组件对象开发Web应用的实例分析

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

初始化类对象

C语言教程 C语言函数
初始化类对象

体验Vista操作系统应用程序

windows 操作系统
体验Vista操作系统应用程序

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Delphi 应用程序的应用

编程语言 网络编程
Delphi 应用程序的应用

应用程序正常初始化失败的解决方法

电脑入门
应用程序正常初始化失败的解决方法

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

AJAX应用之草稿自动保存

AJAX应用之草稿自动保存

win10升级慢怎么办

win10升级慢怎么办
下拉加载更多内容 ↓