2023年3月

出处:http://fiesta.blogbus.com/logs/4429080.html

1. 呼吸:
方法很多,二步一呼二步一吸,口呼鼻吸等不一定。
老赫:
(1)呼吸一定要深,换气效率要高,把肺排空再吸入。
长跑属于有氧运动,氧气吸入不足会加快"极点"的出现,迅速疲劳。
(2)一定要规律的呼吸,呼吸节奏看自己的习惯,但一定要配合步伐规律,
不能上气不接下气地胡乱呼吸,更不能有意憋气。

2.训练量:
老赫:
因人而易,但是不能让你太痛苦以至把它当成包袱。
一般开始隔天2-3K总是能接受的,每月增加1K。
无问题:

过资料,讲运动的最佳脉搏是控制在个人最高心率的60-85%之间,运动效果最好,太底根本没用,过高,加重心脏的负荷,非常有害。如果在有效的心率下连
续运动13分钟,就开始燃烧脂肪,之前的只是水和葡萄糖,而且连续运动的时间越长效果越好。所以连续半个小时的中速跑,比几次间断的快跑,减肥效果更好。
是了,个人的最好心率=210-年龄,25岁的话,就是185,男女有点区别。

3. 喝水
老赫:
中途和结束都可以适度补水,不时地喝一小口,但不能牛饮猛灌。 喝太多会低钠,俗称"水中毒". 不喝会脱水,越跑越慢,直到昏迷。
你经常看马拉就知道了,每隔一定距离都有提供饮水的点。 一直让运动员保持正常的血液浓度。
无问题:
曾经有理论讲,如果在大量运动前,先喝水,到大量运动的时候,刚好补充身体的化学反应,但是,在感到口渴的时候再喝,其实已经晚了。好象马拉松运动员,在中途补充的水分并不多,在跑步前已经补充足够的量。


4. 器材
服装:
KDDD:

身的衣服不能穿棉的,特别是夏天,
棉的衣服在吸透汗水以后会贴在肉上,跑起来很难受。可以去看看现在篮球运动员穿的衣服,偶叫不出那是什么面料,反正是化纤的,看上去好象是网孔编织法,衣
服是两层的。贴身的那层不会吸汗,外面那层吸汗很厉害这样出汗再多也是被外层面料吸附了,这种面料吸透水后,水会迅速的往衣服的下摆渗过去,很快就滴干。
到了冬天就在外面套一件带帽子类似抓绒衣的衣服,又保暖又透气。跑热了可以先拉开拉链,再热就脱下来围在腰上。
回到前面,推荐这个化纤的衣服还有个好处就是经常给汗液浸透后比较容易洗的干净,打上肥皂一搓就可以了,要是棉的时间长了怎么洗都会有股味道。


eXtreme Toolkit是很好的界面库,也有中文资源,但在使用中对中文的支持不好,使用前仍然需要我们做一些工作,才能方便的使用中文。

修改工作包括两个部分,编译动态链接库和修改工程向导。
编译动态链接库:

  1. 在Source\TaskPanel\res文件夹中,复制Resource.rc为Resource_zh_CN.rc,用记事本打开,修改内容:

    #if
    !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)


    #ifdef _WIN32

    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

    #pragma
    code_page(1252)


    #endif

    //
    _WIN32

    替换为:

    #if
    !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)


    #ifdef _WIN32

    LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

    #pragma
    code_page(936)


    #endif

    //
    _WIN32
  2. 修改Source\XTToolkitPro.rc文件,修改内容:

    #define
    LANGUAGE_DEFAULT(ProdName) <##ProdName##\res\Resource.rc>

    替换为:

    #define
    LANGUAGE_DEFAULT(ProdName) <##ProdName##\res\Resource_zh_CN.rc>

修改工程向导:

  1. 修改文件Utils\AppWizard\vc80\vcWizards\XTPAppWizard\html\1033\AppType.htm,搜索PopulateLanguages(),修改内容:

    //
    var strInstalledLangs = window.external.GetInstalledLangs();


    var
    strInstalledLangs
    =

    "
    1033
    "

    替换为:

    var
    strInstalledLangs
    =
    window.external.GetInstalledLangs();

    //
    var strInstalledLangs = "1033"
  2. 在Utils\AppWizard\vc80\vcWizards\XTPAppWizard\templates文件夹下,复制1033文件夹为2052文件夹
  3. 比照2052文件夹与<VS2005安装文件夹>\VC\VCWizards\AppWiz\MFC\Application\templates\2052下的资源文件all.rc、dlgall.rc、root.rc2,将字符串修改为中文。建议使用UltraEdit的对比功能。
  4. 修改2052文件夹中的frame.cpp文件夹,替换_T("Menu Bar")为_T("菜单栏"),替换_T("Standard")为_T("标准")。

在完成以上步骤后,运行Deploy.exe部署即可。

为了方便大家,我把我的修改成果打包,节省大家的时间。解压后直接复制覆盖即可。
eXtreme Toolkit汉化下载

出处:
How to support multiple file extensions with one document type in Visual C++ MFC applications

How to support multiple file extensions with one document type in Visual C++ MFC applications

Article ID : 198538
Last Review : November 21, 2006
Revision : 4.1
This article was previously published under Q198538

SUMMARY

DocMgrEx.exe is a sample that shows how to support multiple
extensions associated with one document type (or template) in MFC's Doc/View
architecture.

This sample implements the code required to allow
registration, unregistration, file open, and file save operations in an
otherwise regular MFC application. The classes touched include the following:

The CWinApp-derived class.
The undocumented CDocManager class.
A custom CFileDialog-derived class that allows transparent
file operations with the newly defined CDocManagerEx.


Back to the top

MORE INFORMATION

The
following files are available for download from the Microsoft Download
Center:

DocMgrEx.exe
(http://download.microsoft.com/download/vc60pro/sample11/1/nt4/en-us/docmgrex.exe)

NOTE
: To Build this project with VS .NET, change the path
in the #include of AfxImpl.h on line 472 of DocManagerEx.cpp:

Change from
:
#include <.."src"afximpl.h>

To
:
#include <.."src"mfc"afximpl.h>


For more information about how to download Microsoft Support files,
click the following article number to view the article in the Microsoft
Knowledge Base:

119591
(http://support.microsoft.com/kb/119591/) How to obtain Microsoft support files from online services

Microsoft scanned this file for viruses. Microsoft used the most
current virus-detection software that was available on the date that
the file was posted. The file is stored on security-enhanced servers
that help prevent any unauthorized changes to the file.
To change the extensions supported by different document
types, or to add new document types, edit the application's string table. In
the string resource associated with the document type resource ID, the fourth
""n" delimited substring should read as follows:

   DocType files (.ex1;.ex2;ex3)

The 5th substring should read as follows:

   .ex1;.ex2;.ex3

NOTE: DocType is the external name of the document type; and ex1,
ex2, ex3 are the extensions you want to associate with your document type.

When testing the application, you will notice its behavior is
similar to DevStudio with regard to file open/save operations. For example,
when trying to open a file, the user specifies only a file name (without an
extension), the application will successively append the extensions from the
currently active filter, trying to build the file name of an existing file. If
this yields no result, the application will either tell the user that the file
does not exist (if the OFN_FILEMUSTEXIST flag was specified) or it will create
a new file with no extension. Saving operations are very similar.


Back to the top

Implementation Details

To implement correct registration code we needed to override
CDocManager::RegisterShellFileTypes().

Unregistration is a bit more
complicated, because the corresponding functions in CWinApp and CDocManager
were not declared virtual. Therefore, we needed to implement the correct code
in an override of CDocManager::UnregisterShellFileTypes(), and copy and paste
the code from CWinApp::UnregisterShellFileTypes() and
CWinApp::ProcessShellCommand() in our own CWinApp-derived class.

To
implement file operations transparently, we overrode
CDocManager::DoPromptFileName() and CDocManager::OpenDocumentFile(). To
minimize the number of changes, the global function MatchDocType() has been
defined to replace the use of CDocTemplate::MatchDocType() member function. The
new function behaves as expected when multiple extensions are provided for one
document template.


Back to the top

REFERENCES

For more information, click the following article number to view the article in the Microsoft Knowledge Base:

141921
(http://support.microsoft.com/kb/141921/)
How to support two file extensions per MFC document type


eXtreme Toolkit(以下简称XTP)的功能强大毋庸置疑,但是虽然号称与MFC完美兼容,很多地方仍然区别很大,当我将原来的MFC程序改用eXtreme Toolkit时,经常出现若干非常奇怪的Bug,非常讨厌!

Toolbar大概是每个应用程序都必不可少的元素。XTP的Toolbar功能比mfc实现要强大的多,实现也比其复杂得多。分析其Command消息的前世今生,追踪CXTPControlButton代码:


void
CXTPControlButton::OnClick(BOOL bKeyboard, CPoint pt)



{

if
(
!
GetEnabled())
return
;


if
(IsCustomizeMode())



{

m_pParent

->
SetPopuped(
-
1
);

m_pParent

->
SetSelected(
-
1
);

CustomizeStartDrag(pt);

return
;

}




if
(
!
bKeyboard)



{

if
(m_pParent
->
GetType()
!=
xtpBarTypePopup)

ClickToolBarButton();

}



else




{

OnExecute();

}



}

这里关键在于ClickToolBarButton()和OnExecute()两个函数。继续查看这两个函数,OnExecute()似乎重点在于处理ToolBarButton支持的一些额外功能,如菜单等。真正产生Command消息的是ClickToolBarButton()函数。继续分析这个函数,这个函数是其基类CXTPControl的成员:


void
CXTPControl::ClickToolBarButton(CRect rcActiveRect)



{



if
(bExecuteOnTimer)



{

m_pParent

->
SetTimer(XTP_TID_CLICKTICK, m_nExecuteOnPressInterval, NULL);

NotifyExecute(

this
, pOwner);

}




while
(::GetCapture()
==
hWndCapture)



{



if
(msg.message
==
WM_LBUTTONUP)



{

bClick

=
m_bSelected
&&
((
!
pt.x
&&

!
pt.y)
||
rcActiveRect.PtInRect(pt));

break
;

}




if
(m_pParent
==
NULL)

break
;


if
(msg.message
==
WM_TIMER
&&
msg.wParam
==
XTP_TID_CLICKTICK)



{

if
(m_bSelected)



{

NotifyExecute(

this
, pOwner);

}



}





}





}

这里没有细致的分析代码,感觉大意是在WM_LBUTTONDOWN后设置timer,然后在WM_LBUTTONUP后产生Click消息,执行NotifyExecute(this, pOwner)。这个函数是CXTPControl的成员,继续追踪这个函数:


AFX_INLINE
void
NotifyExecute(CXTPControl
*
pControl, CWnd
*
pOwner)



{

NMXTPCONTROL tagNMCONTROL;

if
(pControl
->
NotifySite(pOwner, CBN_XTP_EXECUTE,
&
tagNMCONTROL)
==

0
)



{

pOwner

->
SendMessage(WM_COMMAND, pControl
->
GetID());

}



}

至此,心里有个猜想了,敢情先发通知消息,如果未被处理,才发送Command消息。就在当前文件中寻找NotifySite函数:


LRESULT CXTPControl::NotifySite(CWnd
*
pSite, UINT code, NMXTPCONTROL
*
pNM)



{

if
(pSite
==

0
)



{

if
(
!
m_pParent)

return

0
;


pSite

=
m_pParent
->
GetOwnerSite();

}




pNM

->
hdr.code
=
code ;

pNM

->
hdr.idFrom
=
GetID();

pNM

->
hdr.hwndFrom
=

0
;

pNM

->
pControl
=

this
;


LRESULT lResult

=
pSite
->
SendMessage(WM_XTP_COMMAND, GetID(), (LPARAM)pNM);


if
(lResult
||

!
m_pParent)

return
lResult;


AFX_NOTIFY notify;

notify.pResult

=

&
lResult;

notify.pNMHDR

=
(NMHDR
*
)pNM;


if
(pSite
->
OnCmdMsg(GetID(), MAKELONG(code, WM_NOTIFY),
&
notify, NULL))



{

return
lResult;

}




return

0
;

}

这里先发一个用户消息WM_XTP_COMMAND,如果不被处理,调用父窗口OnCmdMsg函数。WM_XTP_COMMAND消息的用途没有找到,只在定义文件的注释里看到文字“ActiveX commands”,莫非用于某种形式的ActiveX交互?不过没关系,调用OnCmdMsg才是重点。注意函数体中的code是传来的参数,值为CBN_XTP_EXECUTE,表达式MAKELONG(code, WM_NOTIFY)的值刚好为5666666908,这个值记住,以后有用处。如果OnCmdMsg没有处理这个消息,则调用链回到函数NotifyExecute处,发送标准的Command消息。
到现在,ToolBar的Command消息处理过程已经清晰了。一般情况下,这种实现与MFC框架实现兼容。但在某些特殊情况下,会出现非常莫名其妙的错误。我在一个程序中使用了CHtmlEditView这个类,并使用了处理标准的html编辑命令的宏,如下例:


DHTMLEDITING_CMD_ENTRY_TYPE(ID_BUTTON_BOLD, IDM_BOLD, AFX_UI_ELEMTYPE_CHECBOX)

奇异的情况发生了,编辑器竟然“不响应”这个加粗命令了!但是同时,编辑器响应左对齐等命令。更奇怪的是,当处理超链接命令时,竟然弹出两个对话框!仔细分析调试并实验发现,并非没有响应命令,而是响应得多了点,每个命令响应了两次。查看CHtmlEditView::OnCmdMsg()函数:


BOOL CHtmlEditView::OnCmdMsg(UINT nID,
int
nCode,
void
*
pExtra, AFX_CMDHANDLERINFO
*
pHandlerInfo)



{

//
if it's not something we're intersted in, let it go to the base



if
(nCode
<
(
int
)CN_UPDATE_COMMAND_UI)

return
CHtmlView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);


//
check for command availability


BOOL bHasExecFunc
=
FALSE;

UINT uiElemType

=
AFX_UI_ELEMTYPE_NORMAL;

UINT dhtmlCmdID

=
GetDHtmlCommandMapping(nID, bHasExecFunc, uiElemType);

if
(dhtmlCmdID
==
AFX_INVALID_DHTML_CMD_ID)



{

//
No mapping for this command. Use normal routing



return
CHtmlView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

}




long
nStatus
=
QueryStatus(dhtmlCmdID);


if
(nCode
==
CN_UPDATE_COMMAND_UI)



{

//
just checking status


CCmdUI
*
pUI
=
static_cast
<
CCmdUI
*>
(pExtra);

if
(pUI)



{

if
(
!
(nStatus
&
OLECMDF_LATCHED
||
nStatus
&
OLECMDF_ENABLED))



{

pUI

->
Enable(FALSE);

if
(uiElemType
&
AFX_UI_ELEMTYPE_CHECBOX)



{

if
(nStatus
&
OLECMDF_LATCHED)

pUI

->
SetCheck(TRUE);

else


pUI

->
SetCheck(FALSE);

}



else

if
(uiElemType
&
AFX_UI_ELEMTYPE_RADIO)



{

if
(nStatus
&
OLECMDF_LATCHED)

pUI

->
SetRadio(TRUE);

else


pUI

->
SetRadio(FALSE);

}




}



else




{

pUI

->
Enable(TRUE);
//
enable

//
check to see if we need to do any other state

//
stuff



if
(uiElemType
&
AFX_UI_ELEMTYPE_CHECBOX)



{

if
(nStatus
&
OLECMDF_LATCHED)

pUI

->
SetCheck(TRUE);

else


pUI

->
SetCheck(FALSE);

}



else

if
(uiElemType
&
AFX_UI_ELEMTYPE_RADIO)



{

if
(nStatus
&
OLECMDF_LATCHED)

pUI

->
SetRadio(TRUE);

else


pUI

->
SetRadio(FALSE);

}



}



return
TRUE;

}



return
FALSE;

}




//
querystatus for this DHTML command to make sure it is enabled



if
(
!
(nStatus
&
OLECMDF_LATCHED
||
nStatus
&
OLECMDF_ENABLED))



{


//
trying to execute a disabled command


TRACE(traceHtml,
0
,
"
Not executing disabled dhtml editing command %d
"
, dhtmlCmdID);

return
TRUE;

}




if
(bHasExecFunc)



{

return
ExecHandler(nID);

}




return
S_OK
==
ExecCommand(dhtmlCmdID, OLECMDEXECOPT_DODEFAULT, NULL, NULL)
?
TRUE : FALSE;

}

结合前面对Command消息的了解并分析函数(这里只是一句话,但是我找出问题足足花了两天时间,包括对Command消息的跟踪),发现了这个函数的一个Bug:它没有判断nCode的值。显然,仅应该在nCode=CN_COMMAND的时候才执行html编辑命令。由于这个Bug,函数会在ToolBar发现通知消息的时候执行一次编辑动作,在确实发送Command消息的时候再执行一次。解决的方法很简单,重载OnCmdMsg函数,剔除掉通知消息即可。
顺便说一下,CXTPMDIFrameWnd竟然不带Menu的,用GetMenu取得的菜单为空!

很精彩的博文
OLE Drag&Drop
,详细描述了ole拖放的相关知识。

枚举IDataObject支持的数据格式:


IEnumFORMATETC
*
pEnum;

if
(SUCCEEDED(pDataObj
->
EnumFormatEtc(DATADIR_GET,
&
pEnum)))



{

ULONG celt

=
1
, celtFetched;

FORMATETC fmt;

while
(SUCCEEDED(pEnum
->
Next(celt,
&
fmt,
&
celtFetched)))



{

if
(celt
!=
celtFetched)



{

break
;

}



TCHAR szFormatName[

100
];

if
(GetClipboardFormatName(fmt.cfFormat, szFormatName,
100
-
1
))

TRACE1(

"
CLIPFORMAT:\t%s\n
"
, szFormatName);

else


TRACE1(

"
CLIPFORMAT:\t%d\n
"
, fmt.cfFormat);

}



}


注册数据格式:


CF_FILEDESCRIPTOR
=
RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);

获得的值为49343。