MFC邮递表的中文翻译(转载六)

鬼谷子
交通大学思源BBS -- 文章阅读
--------------------------------------------------------------------------------
发信人: common (只爱陌生人), 信区: Visual
标 题: MFC邮递表的中文翻译(转载六)
发信站: 交大兵马俑BBS站 (Tue Dec 28 16:45:19 1999), 站内信件
MFC邮递表的中文翻译
我是一名mfc程序设计的爱好者,订阅了mfc的maillist,利用业余
时间将它翻译出来,希望能对mfc编程的朋友有所帮助,请朋友们指正.
第三十期目录 杨晓东 1999.3.21
1.改变工具提示框的宽度
2.背景标记
3.关于CString::GetLength()
4.MRU(最近使用的)文件
5.静态成员
6.虚拟(virtual)列表控件
7.关于检查列表框(CCheckListBox)
8.向导生成器的上下文敏感帮助
改变工具提示框的宽度
问:我的工具提示内容很长,当工具提示框显示时并不能完全显示出来,
我知道可以通过 SetTipMaxWidth函数来设置工具提示的宽度,但是要
使用该函数需要取得指向工具条的指针,怎样才能得到它?
答:试一下设置TOOLINFO结构中的uFlags为TTF_TRANSPARENT,然后根据
你所要显示的文本的长度来设置显示的位置就可以了,具体如下:
TOOLINFO ti;
... // Other ti info
ti.uFlags = TTF_TRANSPARENT;
... // rest of the structure field
接着发送下列消息:
m_wndToolTip.SendMessage(TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti);
m_wndToolTip.SendMessage(TTM_TRACKPOSITION, 0, (LPARAM) (DWORD)MAKELONG
(point.x, point.y));
m_wndToolTip.SendMessage(TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
其中point是CPoint类型,用来指出显示工具提示的具体位置.提示文本将会从该点位置起显示,实际值是根据文本
的长度来计算.希望这些能有用.
2)另外一个方法
BOOL CXXX::OnToolTipNotify( UINT id, NMHDR * pNMHDR,
LRESULT * pResult )
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
// UINT nID =pNMHDR->idFrom;
CPoint pt= GetCurrentMessage()->pt; // screen coords
pTTT->hinst= 0;
bool bForThisWindow= ToolTipContents(pt);
// fills in m_szToolTip, returns if for this window
if (bForThisWindow)
{
HWND hTool= pTTT->hdr.hwndFrom;
if (hTool)
{
::SendMessage(hTool, TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
//line breaker
::SetWindowLong(hTool, GWL_STYLE,
::GetWindowLong(hTool, GWL_STYLE)|TTS_NOPREFIX);
}
}
pTTT->lpszText= m_szToolTip;
return(bForThisWindow);
}
回到本期目录
背景标记
问:如何在背景中显示一个图标.
答:你可能已经发现改写OnEraseBkgn()(对应消息WM_ERASEBKGND)可以
满足你的要求. 通过使用该方法可以实现由CView继承类的自定义背景
显示.我通常是用它改变颜色, 但我相信你也可以实现位图的显示.至于
改变背景颜色,只需设置一个静态标志用下面的代码就可以实现.
BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
CRect cClientRect;
// Get client area.
GetClientRect( cClientRect );
if( m_bFlag )
{
// Set background to dark green.
pDC->FillSolidRect( cClientRect, RGB( 0, 128, 0 ) );
}
else
{
// Set background to dark red.
pDC->FillSolidRect( cClientRect, RGB( 128, 0, 0 ) );
}
// Prevent Windows from drawing over our background.
return( TRUE );
// return CScrollView::OnEraseBkgnd(pDC);
} /* end CMyView::OnEraseBkgnd */
回到本期目录
关于CString::GetLength()
问:VC5.0版本帮助文件中指出CString::GetLength()将返回字符串所
占字节的数目对于ASCII,这个描述是正确的,但如果是Unicode则实际
上返回的是字符数而不是字节数,我现在想知道怎样才能知道一个字
符串的字节长度,不管是ASCII还是Unicode.
答:我发现CSting的说明确实如你所说的有些小问题.CSting中的
GetData()方法是保护的,所以如果你继承CString类时碰上问题时,你
必须自己处理nDataLength,虽然我不太清楚nDatalength是不是你想要
的.从MFC例子中我们能看到下列代码.
Void CString::AllocBuffer(int nLen)
{
if (nLen == 0)
Init();
else {
CStringData* pData = (CStringData*) new
BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];
pData->nRefs=1;
pData->data() [nLen] = '\0';
pData->nDataLength = nLen; //nLen is assigned to
nDataLength
pData->nAllocLength = nLen;
m_pchData = pData->data();
}
}
对我来说,好象nDatalength仍然是字符数,而不是字节,如果
sizeof(TCHAR)返回的值是可用的话,可能你要自己计算.
加入代码的中,m_pchData是保护,而不是私有的.也许你能找出字
符串结束符然后自己计算字符串的字节数.
2)我通常使用下面代码来取得字符串的字节数
int nBytes = (csSomeCString.GetLength() + 1) * sizeof(TCHAR);
注意:这字节数的长度还包括文件结束符.
回到本期目录
MRU(最近使用的)文件
问:我想将最近使用过的几个文件名(以及路径)显示出来,该怎么办?
答:一个由向导生成器生成的文档视图结图已经包含MRU列表操作.具体
是放在注册表的 HKEY_CURRENT_USER/Software/Your Company Name
/Your App Name/Recent File List/File1, File2, File3, etc.
你所要做的是用程序中的GetProfileString()读入第一个MRU文件
的位置,剩下的由 CRecentFileList::ReadList()完成所有的工作.
CRecentFileList类包含了所有操作的代码象分析路径,管理MRU文件
等,用不着为此费心.
2)在AFXWIN.H中定义了一个变量CRecentFileList* m_pRecentFileList;
你可以通过使用CRecentFileList的成员变量m_arrNames[n]来取得某个
MRU文件.比如:
#include // needed for access to MRU list
CFile mruFile;
if ( !mruFile.Open( m_pRecentFileList->m_arrNames[index],
CFile::modeRead )
....
3)你不需要建立一个CRecentFileList类,它已经由CWinApp基类完
成了.你只要保证你在 initinstance中调用LoadStdProfileSettings()
函数就可以了. CRecentFileList类中有一个CWinApp保护成员变量
(如m_pRecentFileList) 所以你应该在你的继承类中处理它.下面的代
码在我这儿工作很正常
void CMdiApp::OnFileMruFile1()
{
// TODO: Add your command handler code here
CString vl_name ;
ASSERT( m_pRecentFileList->GetSize() > 0);
vl_name = (*m_pRecentFileList)[0];
CWinApp::OnOpenRecentFile(ID_FILE_MRU_FILE1);
}
OnOpenRecentFile()函数必须要调用缺省处理,其它的就随便了
回到本期目录
静态成员
问:我有个类中有一个静态CBitmap成员变量
CMyClass {...static CBitmap m_MyLogo;...}
在CPP文件中我定义了一个全局变量
CBitmap CMyClass::m_MyLogo;
怎样我才能在其生命周期中调用函数CBitmap::LoadBitmap(nID)就象
是一个位图对象一样
答:这里有一个小小的例子来说明
//@ MyClass.h
CMyClass
{
protected:
static CBitmap& GetMyStaticBitmap();
};
//@ MyClass.cpp
CBitmap&
CMyClass::GetMyStaticBitmap()
throw(CResourceException)
{
static CBitmap ts_rBitmap;
if(NULL == ts_rBitmap.operator HBITMAP())
{
if(!rBitmap.LoadBitmap(IDB_MYBMP))
AfxThrowResourceException();
}
return ts_rBitmap;
}
2)我认为你坚持保持变量m_MyLogo保护属性没有任何机会。唯一
的方法就是(我认为):增加一个静态成员函数,由它返回一个指向
位图对象的指针,就象这样:
CMyClass
{
CMyClass();
protected:
static CBitmap m_MyLogo;
public:
static CBitmap *GetMyLogo() {return m_MyLogo;};
}
如果决定将m_MyLogo公用,那么就不需要该函数,先前的一行就
应变成
CMyClass::m_MyLogo.LoadBitmap(nID);
回到本期目录
虚拟(virtual)列表控件
问:我想从一个虚拟列表控件中取得一个项目,我不能在V5或V6中实现,
但列表控件若是可见的, 则程序一切正常.
答:在带有LVS_OWNERDATA类型列表控件中我也碰上过同样的问题,下面
是我对继承的类的 SetItemState函数的修改.
BOOL CListCtrlEx::SetItemState(int nItem, UINT nState,
UINT nStateMask)
{
LV_ITEM tmpItem;
tmpItem.mask = LVIF_STATE;
tmpItem.iItem = nItem;
tmpItem.iSubItem = 0;
tmpItem.stateMask = nStateMask;
tmpItem.state = nState;
tmpItem.pszText = NULL;
tmpItem.iImage = 0;
tmpItem.lParam = 0;
return (BOOL)(SendMessage(LVM_SETITEMSTATE, nItem,
(LPARAM)(&tmpItem)));
}
问题的原因似乎是消息LVM_SETITEM不能被带有LVS_OWNERDATA类
型列表控件所处理,(在MFC中CListCtrl::SetItemState是使用LVM_SETITEM
消息的)
回到本期目录
于检查列表框(CCheckListBox)
问:使用CCheckListBox时是不是不能调用DeleteString()?
答:我记得是这样的,我从继承类中修改了它,现在它工作很正常.
CPP 文件:
void CMyCheckListBox::PreDrawItem(LPDRAWITEMSTRUCT lpDIS)
{
if((int)lpDIS->itemID < 0 || (long)lpDIS->itemData < 0)
return;
CCheckListBox::PreDrawItem(lpDIS);
}
BOOL CMyCheckListBox::OnChildNotify(UINT message, WPARAM wParam, LPARAM
lParam, LRESULT* pResult)
{
switch (message)
{
case WM_DRAWITEM:
ASSERT(pResult == NULL);
// no return value expected
PreDrawItem((LPDRAWITEMSTRUCT)lParam);
break;
default:
return CCheckListBox::OnChildNotify(message, wParam,
lParam, pResult);
}
return TRUE;
}
头文件
protected:
void PreDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
LRESULT* pResult);
回到本期目录
向导生成器的上下文敏感帮助
问:如何在向导生成器中加入上下文帮助以及关闭按钮,这好象不是缺
省值.
答:你需要处理WS_SYSMENU类型
BOOL CYourPropertySheet::OnInitDialog()
{
if (CPropertySheet::OnInitDialog())
{
ModifyStyle(0, WS_SYSMENU, 0);
ModifyStyleEx(0, WS_EX_CONTEXTHELP, 0);
// The default system menu has several menu items that don't make
// sense for a wizard. Remove them.
CMenu* pSystemMenu = GetSystemMenu(FALSE);
if (pSystemMenu != NULL)
{
// Remove some items
pSystemMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
pSystemMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
pSystemMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
pSystemMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
// Do not remove/hide SC_CLOSE, or the '?' icon won't be
// drawn properly
}
// ... other initialization, like maybe Q143210
return TRUE;
}
else
return FALSE;
}
--
※ 来源:·交大兵马俑BBS站 bbs.xjtu.edu.cn·[FROM: 21_73]
--------------------------------------------------------------------------------
分类讨论区 全部讨论区 上一篇 本讨论区 下一篇 回文章

龙丘居士亦可怜
谈空说有夜不眠
忽闻河东师子吼
拄杖落手心茫然