==================================声明==================================

本文原创,转载在正文中显要的注明作者和出处,并保证文章的完整性。

未经作者同意请勿修改(包括本声明),保留法律追究的权利。

未经作者同意请勿用于出版、印刷或学术引用。

本文不定期修正完善,为保证内容正确,建议移步原文处阅读。

本文链接:http://www.cnblogs.com/wlsandwho/p/4282242.html

=======================================================================

水平太低了,在青岛找个称心的工作,难——真的是不开空调啊,猎头怎么不信我呢!(这个梗请点我点我

这么晚了,还是写个博客看会儿书再睡觉吧,人丑就要多……

=======================================================================

先创建一个MFC程序。

工程创建完后,编译运行一下,看看默认是什么样子。如下图。

点击窗口-新建窗口(N),效果如图:

可以看到,两个窗口都是一样的。

=======================================================================

下面,就要开始魔改了。

=======================================================================

添加一个对话框资源,ID命名为IDD_FORMVIEW1。

给刚添加的资源添加类,CFV1,其基类为CFormView。

添加对IDC_BUTTON1的消息处理函数。

 void CFV1::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(TEXT(""),TEXT("CFV1"),MB_OK);
}

同样的步骤,再添加CFV2和对IDD_FORMVIEW2中IDC_BUTTON1的消息处理函数。

 void CFV2::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(TEXT(""),TEXT("CFV2"),MB_OK);
}

在TestMDIWLS.h中添加头文件

 #include "FV1.h"
#include "FV2.h"

=======================================================================

到这里,让我们暂停一下。下面要进入重点了。

=======================================================================

对模板的注册是在CTestMDIWLSApp::InitInstance中实现的,下面是MFC的MDI中原有的代码。

 // CTestMDIWLSApp 初始化

 BOOL CTestMDIWLSApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls); CWinAppEx::InitInstance(); // 初始化 OLE 库
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
} AfxEnableControlContainer(); EnableTaskbarInteraction(); // 使用 RichEdit 控件需要 AfxInitRichEdit2()
// AfxInitRichEdit2(); // 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
LoadStdProfileSettings(); // 加载标准 INI 文件选项(包括 MRU) InitContextMenuManager(); InitKeyboardManager(); InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams); // 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_TestMDIWLSTYPE,
RUNTIME_CLASS(CTestMDIWLSDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CTestMDIWLSView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); // 创建主 MDI 框架窗口
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame;
// 仅当具有后缀时才调用 DragAcceptFiles
// 在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生 // 分析标准 shell 命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// 主窗口已初始化,因此显示它并对其进行更新
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow(); return TRUE;
}

注意这一块代码:(我手工对齐了一下)

     // 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_TestMDIWLSTYPE,
                    RUNTIME_CLASS(CTestMDIWLSDoc),
                    RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
                    RUNTIME_CLASS(CTestMDIWLSView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);

这里我们需要做的就是new一个自己新建的CFV,然后把它加入文档模板。

所以先再分析下CMultiDocTemplate(...)函数

 CMultiDocTemplate(
UINT nIDResource,
CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass,
CRuntimeClass* pViewClass
);

后三个参数一目了然,形参自注释。

要注意的是第一个参数:UINT nIDResource

MSDN中这样说的:

nIDResource

    Specifies the ID of the resources used with the document type. This may include menu, icon, accelerator table, and string resources.

    The string resource consists of up to seven substrings separated by the '\n' character (the '\n' character is needed as a place holder if a substring is not included; however, trailing '\n' characters are not necessary); these substrings describe the document type. For information on the substrings, see CDocTemplate::GetDocString. This string resource is found in the application's resource file. For example:

    // MYCALC.RC

    STRINGTABLE PRELOAD DISCARDABLE

    BEGIN

    IDR_SHEETTYPE "\nSheet\nWorksheet\nWorksheets (*.myc)\n.myc\n MyCalcSheet\nMyCalc Worksheet"

    END

    Note that the string begins with a '\n' character; this is because the first substring is not used for MDI applications and so is not included. You can edit this string using the string editor; the entire string appears as a single entry in the String Editor, not as seven separate entries.

    For more information about these resource types, see Resource Editors. 

在这里最简单的方式就是在IDE里查找原来的IDR_TestMDIWLSTYPE所对应的字符串,然后模仿着修改。

我尝试了下直接用Sting_Table添加,并修改了一个字符串的部分字段(AAAA和BBBB),另一个未变,以便观察效果。(大晚上的我要是愿意看英文我早就去看美剧了。)

下面是在rc文件中的编码。(新手不要手工编辑,相关资料参见MSDN和罗云彬的汇编书,PS:典藏版亚马逊有售哦!)

 /////////////////////////////////////////////////////////////////////////////
//
// String Table
// STRINGTABLE
BEGIN
IDP_OLE_INIT_FAILED "OLE 初始化失败。请确保 OLE 库是正确的版本。"
IDR_CFV1_TYPE "\nAAAA\nBBBB\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
IDR_CFV2_TYPE "\nTestMDIWLS\nTestMDIWLS\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
END STRINGTABLE
BEGIN
IDR_MAINFRAME "TestMDIWLS"
IDR_TestMDIWLSTYPE "\nTestMDIWLS\nTestMDIWLS\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
ID_WINDOW_MANAGER "窗口(&W)..."
END STRINGTABLE
BEGIN
AFX_IDS_APP_TITLE "TestMDIWLS"
AFX_IDS_IDLEMESSAGE "就绪"
END

可以看到13-18行是MFC自带的,我们手工添加的是7-11中的9、10两行。

根本就没有MSDN上面说的那个PRELOAD DISCARDABLE。看来不预加载也没问题啊。当然这是猜测,可能是资源太小了。

=======================================================================

看完刚才的资料,可以尝试着添加文档模板了。当然要是有闲心情——现在是深夜,不管你有没有,我反正没有——可以看下

https://msdn.microsoft.com/zh-cn/library/2b4xctyw%28v=vs.100%29.aspx和https://msdn.microsoft.com/zh-cn/library/feh4ww6k%28v=vs.100%29.aspx

=======================================================================

现在我们添加模板文档。先添加一个试试。

     // 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_TestMDIWLSTYPE,
RUNTIME_CLASS(CTestMDIWLSDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CTestMDIWLSView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); //////////////////////////////////////////////////////////////////////////
//by wls 20150209 22:17:50
pDocTemplate = new CMultiDocTemplate(IDR_CFV1_TYPE,
RUNTIME_CLASS(CTestMDIWLSDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CFV1));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); //////////////////////////////////////////////////////////////////////////

编译、运行,效果:

注意这里是TestMDIWLS和BBBB。

点击BBBB确定后:

这里是AAAA1。

点击按钮1后:

现在就可以更改String_Table里的东西了。我手工改,毕竟编辑器有点蹩脚。

 /////////////////////////////////////////////////////////////////////////////
//
// String Table
// STRINGTABLE
BEGIN
IDP_OLE_INIT_FAILED "OLE 初始化失败。请确保 OLE 库是正确的版本。"
IDR_CFV1_TYPE "\nCFV1的FormView视图\nCFV1\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
IDR_CFV2_TYPE "\nCFV2的FormView视图\nCFV2\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
END

再添加上CFV2:

     //////////////////////////////////////////////////////////////////////////
//by wls 20150209 22:17:50
pDocTemplate = new CMultiDocTemplate(IDR_CFV1_TYPE,
RUNTIME_CLASS(CTestMDIWLSDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CFV1));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); pDocTemplate = new CMultiDocTemplate(IDR_CFV2_TYPE,
RUNTIME_CLASS(CTestMDIWLSDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CFV2));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); //////////////////////////////////////////////////////////////////////////

编译运行:

点击CFV1后确定:

点击新建,点击CFV2后确定:

发现确实是创建了2个模板。

=======================================================================

现在问题来了,如何让程序一开始运行时,就打开了2个模板?毕竟让用户自己手工点击,99.999%是会有问题的。

=======================================================================

让我们来回忆一下,我们是如何创建模板窗口的?第一个是程序默认给出的选择框。没错。

那第二个呢?第二个是我们手工点击的新建!而且出来的是一模一样的选择框!

现在我们要做的就是先看看这个点击新建的响应函数是怎样的。

=======================================================================

下面是MDI中默认的响应函数的映射宏:

 // CTestMDIWLSApp

 BEGIN_MESSAGE_MAP(CTestMDIWLSApp, CWinAppEx)
ON_COMMAND(ID_APP_ABOUT, &CTestMDIWLSApp::OnAppAbout)
// 基于文件的标准文档命令
ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
// 标准打印设置命令
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
END_MESSAGE_MAP()

可以看到第6行:

     ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)

使用的是CWinAppEx的OnFileNew函数。显然MFC框架的代码是最好不修改的,只能自己模仿CWinAppEx的OnFileNew函数写一个自己的实现,姑且叫OnFileNewWLS吧。

在动手前,先看看OnFileNew是如何实现的:

 /////////////////////////////////////////////////////////////////////////////
// WinApp features for new and open void CWinApp::OnFileNew()
{
if (m_pDocManager != NULL)
m_pDocManager->OnFileNew();
}

那CDocManager的实现呢?如下:

 void CDocManager::OnFileNew()
{
if (m_templateList.IsEmpty())
{
TRACE(traceAppMsg, , "Error: no document templates registered with CWinApp.\n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return;
} CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
if (m_templateList.GetCount() > )
{
// more than one document template to choose from
// bring up dialog prompting user
CNewTypeDlg dlg(&m_templateList);
INT_PTR nID = dlg.DoModal();
if (nID == IDOK)
pTemplate = dlg.m_pSelectedTemplate;
else
return; // none - cancel operation
} ASSERT(pTemplate != NULL);
ASSERT_KINDOF(CDocTemplate, pTemplate); pTemplate->OpenDocumentFile(NULL);
// if returns NULL, the user has already been alerted
}

看完了这些,我们就知道如何实现自己的OnFileNewWLS了,这是我的代码,仅供参考。

 void CTestMDIWLSApp::OnFileNewWLS()
{
CDocTemplate* pTemplate = NULL; POSITION pos = GetFirstDocTemplatePosition();
while(pos)
{
pTemplate = GetNextDocTemplate(pos); ASSERT(pTemplate != NULL);
ASSERT_KINDOF(CDocTemplate, pTemplate); pTemplate->OpenDocumentFile(NULL);
}
}

不要忘了修改映射宏。

 // CTestMDIWLSApp

 BEGIN_MESSAGE_MAP(CTestMDIWLSApp, CWinAppEx)
ON_COMMAND(ID_APP_ABOUT, &CTestMDIWLSApp::OnAppAbout)
// 基于文件的标准文档命令
//ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
ON_COMMAND(ID_FILE_NEW, &CTestMDIWLSApp::OnFileNewWLS)
ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
// 标准打印设置命令
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
END_MESSAGE_MAP()

编译链接看效果:

注意到三个模板都实现了,但是界面有卡顿。

是时候表演真正的记性了!

手工修改String_Table。拆分第一个。添加PRELOAD DISCARDABLE。

 STRINGTABLE
BEGIN
IDP_OLE_INIT_FAILED "OLE 初始化失败。请确保 OLE 库是正确的版本。"
END STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_TestMDIWLSTYPE "\nTestMDIWLS\nTestMDIWLS\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
IDR_CFV1_TYPE "\nCFV1的FormView视图\nCFV1\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
IDR_CFV2_TYPE "\nCFV2的FormView视图\nCFV2\n\n\nTestMDIWLS.Document\nTestMDIWLS.Document"
END STRINGTABLE
BEGIN
IDR_MAINFRAME "TestMDIWLS"
ID_WINDOW_MANAGER "窗口(&W)..."
END

可能是心理效果,我感觉略微快了那么一点点。(处女座请自重。)

=======================================================================

下面屏蔽各种新建按钮,防止创建过多的模板视图。

更改之前的OnFileNewWLS代码,利用局部Static变量。

 void CTestMDIWLSApp::OnFileNewWLS()
{
static BOOL bNew=FALSE; if (bNew==FALSE)
{
bNew=TRUE; CDocTemplate* pTemplate = NULL; POSITION pos = GetFirstDocTemplatePosition();
while(pos)
{
pTemplate = GetNextDocTemplate(pos); ASSERT(pTemplate != NULL);
ASSERT_KINDOF(CDocTemplate, pTemplate); pTemplate->OpenDocumentFile(NULL);
}
}
}

下面要屏蔽新建窗口按钮

在rc文件中有这么一行

 ID_WINDOW_NEW           "为活动文档打开另一个窗口\n新建窗口"

所以需要屏蔽的就是对ID_WINDOW_NEW的响应,所以添加第10行代码,重写自己的响应函数。

 // CMainFrame

 IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWndEx)

 BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_WINDOW_MANAGER, &CMainFrame::OnWindowManager)
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
ON_COMMAND(ID_WINDOW_NEW,&CMainFrame::OnWindowNewWLS)
END_MESSAGE_MAP()

OnWindowsWLS的实现:

 void CMainFrame::OnWindowNewWLS()
{
//no op
}

现在已经能够在运行时一次性创建3个视图,并且不再创建额外的视图。

=======================================================================

既然能且只能创建3个视图,那么就不需要在选项卡上显示表示实例数目的阿拉伯字母了。

 BOOL CTestMDIWLSDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE; // TODO: 在此添加重新初始化代码
// (SDI 文档将重用该文档)
CString strTitle=GetTitle();
strTitle=strTitle.Left(strTitle.GetLength()-);
SetTitle(strTitle); return TRUE;
}

效果:

=======================================================================

下面要做的就是屏蔽彩色选项卡的关闭按钮。

那么这个一直被我称为选项卡/标签页的东西到底是什么呢?使用Spy++查看下。

显示的是TabWnd,那么是一个类似Tab窗口的东西。这些都在CMainFrame::OnCreate里有初始化设置。

先看看MDI原有的代码:

 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -)
return -; BOOL bNameValid;
// 基于持久值设置视觉管理器和样式
OnApplicationLook(theApp.m_nAppLook); CMDITabInfo mdiTabParams;
mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE; // 其他可用样式...
mdiTabParams.m_bActiveTabCloseButton = TRUE; // 设置为 FALSE 会将关闭按钮放置在选项卡区域的右侧
mdiTabParams.m_bTabIcons = FALSE; // 设置为 TRUE 将在 MDI 选项卡上启用文档图标
mdiTabParams.m_bAutoColor = TRUE; // 设置为 FALSE 将禁用 MDI 选项卡的自动着色
mdiTabParams.m_bDocumentMenu = TRUE; // 在选项卡区域的右边缘启用文档菜单
EnableMDITabbedGroups(TRUE, mdiTabParams); m_wndRibbonBar.Create(this);
m_wndRibbonBar.LoadFromResource(IDR_RIBBON); if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -; // 未能创建
} CString strTitlePane1;
CString strTitlePane2;
bNameValid = strTitlePane1.LoadString(IDS_STATUS_PANE1);
ASSERT(bNameValid);
bNameValid = strTitlePane2.LoadString(IDS_STATUS_PANE2);
ASSERT(bNameValid);
m_wndStatusBar.AddElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE1, strTitlePane1, TRUE), strTitlePane1);
m_wndStatusBar.AddExtendedElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE2, strTitlePane2, TRUE), strTitlePane2); // 启用 Visual Studio 2005 样式停靠窗口行为
CDockingManager::SetDockingMode(DT_SMART);
// 启用 Visual Studio 2005 样式停靠窗口自动隐藏行为
EnableAutoHidePanes(CBRS_ALIGN_ANY); // 启用增强的窗口管理对话框
EnableWindowsDialog(ID_WINDOW_MANAGER, ID_WINDOW_MANAGER, TRUE); // 将文档名和应用程序名称在窗口标题栏上的顺序进行交换。这
// 将改进任务栏的可用性,因为显示的文档名带有缩略图。
ModifyStyle(, FWS_PREFIXTITLE); return ;
}

没错,就是CMDITabInfo!找到她了!

10-16是对彩色的选项卡进行的设置。想要屏蔽关闭按钮,要修改为:

     CMDITabInfo mdiTabParams;
mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE; // 其他可用样式...
//mdiTabParams.m_bActiveTabCloseButton = TRUE; // 设置为 FALSE 会将关闭按钮放置在选项卡区域的右侧
mdiTabParams.m_bTabCloseButton=FALSE;
mdiTabParams.m_bTabIcons = FALSE; // 设置为 TRUE 将在 MDI 选项卡上启用文档图标
mdiTabParams.m_bAutoColor = TRUE; // 设置为 FALSE 将禁用 MDI 选项卡的自动着色
mdiTabParams.m_bDocumentMenu = TRUE; // 在选项卡区域的右边缘启用文档菜单
EnableMDITabbedGroups(TRUE, mdiTabParams);

这样,就完成了。

=======================================================================

网上有关禁用MDI选项卡关闭按钮的文章,大多抄袭自MSDN的这篇文档http://support.microsoft.com/kb/201553/zh-cn

但是,不适用于VS2010下使用Office风格的MDI程序——该文档只更新到2006年11月21日。

=======================================================================

本文一步一步的解析实现,故暂不提供示例工程源代码。

魔改——MFC MDI程序 定制 文档模板 运行时全部打开 禁用关闭按钮的更多相关文章

  1. 魔改——MFC SDI程序 转换为 MDI程序

    ==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...

  2. 1、创建MFC应用程序——单个文档

    文件——新建——项目——MFC应用程序 运行即可. [菜单栏单击事件] 视图——其他窗口——资源视图,双击Menu中的IDR_MAINFRAM,打开菜单栏.在主菜单栏输入“显示你好”. “显示你好”处 ...

  3. permission 文档 翻译 运行时权限

    文档位置:API24/guide/topics/security/permissions.html  System Permissions 系统权限 Android is a privilege-se ...

  4. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  5. C++MFC编程笔记day05 文档类-单文档和多文档应用程序

    文档类 1 相关类    CDocument类-父类是CCmdTarget类,所以,文档类也能够处理菜单等               命令消息. 作用保存和管理数据.    注意事项:怎样解决断言错 ...

  6. 微信小程序入门文档

    一 基本介绍 微信专门为小程序开发了一个ide叫做微信开发者工具 最新一版的微信开发者工具,把微信公众号的调试开发工作也集成了进去,可以更换开发模式. https://mp.weixin.qq.com ...

  7. “Word自动更改后的内容保存到通用文档模板上。是否加载该模板?“的解决办法

    在win7系统下,Word2010出现了不能正常关闭.打开一个已有word文档,点击右上角关闭按钮后,先提示"word已停止工作,windows正在检查该问题的解决方案",随后提示 ...

  8. Java中常用到的文件操作那些事(一)——替换doc文档模板,生成真实合同案例

    工作中,我们时常会遇到一些操作文件的操作,比如在线生成合同模板,上传/下载/解析Excel,doc文档转为pdf等操作.本文就已工作中遇到的在线生成合同为例,简要地介绍一种文档替换写法. 本文目的:给 ...

  9. Pycharm文档模板变量

    点击这里查看JetBrains官方英文源文件 本篇Blog只是搬运外加大概翻译一下. File template variables A file template can contain varia ...

随机推荐

  1. android 获取当前位置

    1. Android开发位置感知应用程序方式:1. GPS 定位     精确度高,仅适用于户外,严重消耗电量.如果手机内置GPS接受模块,即使手机处于信号盲区,依然可以获取位置信息. 2. NETW ...

  2. thread_Exchanger数据交换

    Exchanger 是一个同步辅助类,用于两个并发线程之间在一个同步点进行数据交换.  允许两个线程在某一个点进行数据交换. 可以视作双向的同步队列: 可应用于基因算法.流水线设计等场景 Exchan ...

  3. Mysql有没有语法可以在增加列前进行判断该列是否存在

    Mysql没有直接的语法可以在增加列前进行判断该列是否存在,需要写一个存储过程完成同样任务,下面例子是:在sales_order表中增加一列has_sent列 drop procedure if ex ...

  4. asp.net的code-Behind技术

    新建一个VS.NET下的项目..看到ASPX,RESX和CS三个后缀的文件了吗??这个就是代码分离.实现了HTML代码和服务器代码分离.方便代码编写和整理. code-Behind:asp.net中的 ...

  5. 学习笔记(一)——MVC扩展

    1.视图引擎的作用,总结为两点: 查找视图 渲染视图 ViewEngine即视图引擎, 在ASP.NET MVC中将ViewEngine的作用抽象成了 IViewEngine 接口. 默认情况下,AS ...

  6. 互联网产品团队中Web前端工程师的重要性

    国内外各大互联网公司,都有UEx/d|UCD|CDC(Customer Research & User Experience Design Center)团队. 在很多公司会认为,合格的产品经 ...

  7. Java中的Set集合接口实现插入对象不重复的原理

    在java的集合中,判断两个对象是否相等的规则是: 1).判断两个对象的hashCode是否相等 .      如果不相等,认为两个对象也不相等,完毕       如果相等,转入2)(这一点只是为了提 ...

  8. Design Patterns (简单工厂模式)

    文章很长很精彩,如是初学请耐心观看.(大神请绕道!) 简单工厂模式: 1.创建型模式 2.简单工厂模式概述 3.简单工厂模式的结构与实现 4.简单工厂模式的应用实例 5.创建对象与使用对象 6.简单工 ...

  9. HTML 块元素

    分为3类 1. 结构块 只能包含块级元素.它们包含结构含义,但没有语义含义,也就是,不能说明内容是什么,只能说明其组织方式. <ol> <ul> <dl> < ...

  10. js中this的理解

    平常用this很多,对this的理解就是this是对应执行环境,然而很多时候效果并不是想要的,最近看了一些谈到this的笔记和书籍,总结下. 对this的误解: this是指向函数本身 先上个demo ...