想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的应用程序类对象实例初始操作的分析教程,一起来看看吧!超容易上手~
【 tulaoshi.com - 编程语言 】
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()
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中使用外壳操作打开文件作准备
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)void CWinApp::EnableShellOpen()
{
ASSERT(m_atomApp == NULL && m_atomSystemTopic == NULL); // do once
m_atomApp = ::GlobalAddAtom(m_pszExeName);
m_atomSystemTopic = ::GlobalAddAtom(_T("system"));
}
5.RegisterShellFileTypes
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)向系统注册文件类型,以使用外壳操作。
将调用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......
③处理命令
主要操作:
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;
}
来源:http://www.tulaoshi.com/n/20160219/1602752.html
看过《应用程序类对象实例初始操作的分析》的人还看了以下文章 更多>>