TB_ADDSTRING

原创 2007年09月20日 08:49:00

 TB_ADDSTRING

在工具栏的数据结构中,有一个字符串列表,在添加或者插入工具栏按钮的时候,可以使用这个列表中的字符串作为按钮文字。TB_ADDSTRING 消息用来向工具栏的字符串列表添加一个或多个新的字符串。

TB_ADDSTRING 
    wParam 
= (WPARAM) (HINSTANCE) hinst; 
    lParam 
= (LPARAM) MAKELONG(idString, 0); 

Parameters

hinst
Handle to the module instance with an executable file that contains the string resource. If idString instead points to a character array with one or more strings, set this parameter to NULL.

idString
Resource identifier for the string resource. If hinst is set to NULL, idString points to a character array with one or more null-terminated strings. The last string in the array must be terminated with two null characters.

Return Values

Returns the index of the first new string if successful, or -1 otherwise.

 

Remarks 

上面的内容 Copy 自 MSDN,尽管我知道大家英语水平都挺不错的,但我还是画蛇添足地给大家解释一下。按照 MSDN 的意思,TB_ADDSTRING 的参数存在以下两种组合方式:
 
方式一:
    wParam = (HINSTANCE)hinst;            // 包含字符串资源的模块句柄
    lParam = (MAKELONG)(idString, 0);   // 一个字符串资源的资源 ID
 
在 MFC 的 CToolBarCtrl 中,我们可以找到与之对应的封装函数 CToolBarCtrl::AddString(),其实现如下:
 
int CToolBarCtrl::AddString(UINT nStringID)
{
 ASSERT(::IsWindow(m_hWnd));
 HINSTANCE hInst 
= AfxFindResourceHandle(MAKEINTRESOURCE((nStringID>>4)+1),
  RT_STRING);
 ASSERT(hInst 
!= NULL);
 
return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)hInst, nStringID);
}
 
    然而实践证明,在 WindowsXP 下,使用这种方式来添加字符串是无效的。于是我大胆假设,有可能是因为 Windows 的升级换代,新的操作系统已经不再兼容此种方式了。我以 TB_ADDSTRING 为关键字在 MSDN 以及一些知名搜索引擎网站做过检索,没有找到相关可运行的代码来推翻我以上的假设,所以亲爱的同僚们,如果你也在为 CToolBarCtrl::AddString() 的调用异常而苦闷的话,就别再钻牛角尖,浪费时间了,你可以试一下方式二中介绍的方法。
 
方式二:
    wParam = NULL;
    lParam = (LPCTSTR)lpszStrings;   // 一个字符串缓冲区
 
在 MFC 的 CToolBarCtrl 中,与之对应的封装函数是 CToolBarCtrl::AddStrings(),这里需要强调的是,系统对字符串缓冲区的格式是有要求的:
(1) 各个字符串之间需以 '/0' 字符作为间隔符;
(2) 最后一个字符串必须以两个 '/0' 字符结尾。
 
以上的规则可以用以下的代码进行诠释:
 
// Code1
 m_tbCtrl.AddStrings(_T("剪切(&T)/0"));
 m_tbCtrl.AddStrings(_T(
"复制(&C)/0"));
 m_tbCtrl.AddStrings(_T(
"粘贴(&P)/0"));
 
// Code2
m_tbCtrl.AddStrings(_T("剪切(&T)/0复制(&C)/0粘贴(&P)/0"));
 
因为字符串总是以 '/0' 结尾的,所以 _T("剪切(&T)/0") 实际上已经满足“最后一个字符串必须以两个 '/0' 字符结尾”要求。

Example Code

以下代码在对话框中创建了一个工具栏,并添加了三个带文字的工具栏按钮。方法一和方法二是两种常用指定工具栏文字的方法。使用方法一时要注意,你必须确认字符串缓冲区有足够的长度,以避免发生写内存越界的情况。


代码中所使用到的字符串资源定义如下:
IDS_CUT 剪切(&T)
IDS_COPY 复制(&C)
IDS_PASTE 粘贴(&P)
 
#define IDR_TOOLBAR1 131
BOOL CTest_ToolbarCtrlDlg::CreateAToolBar()
{
 
if (!m_tbCtrl.Create(WS_CHILD, CRect(0000), this, IDR_TOOLBAR1))
 {
  ASSERT(FALSE);
  
return FALSE;
 } 
 
 
// 方法一
 
//  CString strText(_T(""));
 
//  TCHAR szBuf[16]; // 字符串缓冲区
 
//  
 
//  strText.LoadString(IDS_CUT);
 
//  lstrcpy(szBuf, strText);
 
//  szBuf[lstrlen(szBuf) + 1] = _T('/0');  // 以两个'/0'字符结尾
 
//  int iCut = m_tbCtrl.AddStrings(szBuf);
 
//  
 
//  strText.LoadString(IDS_COPY);
 
//  lstrcpy(szBuf, strText);
 
//  szBuf[lstrlen(szBuf) + 1] = _T('/0');  // 以两个'/0'字符结尾
 
//  int iCopy = m_tbCtrl.AddStrings(szBuf);
 
//  
 
//  strText.LoadString(IDS_PASTE);
 
//  lstrcpy(szBuf, strText);
 
//  szBuf[lstrlen(szBuf) + 1] = _T('/0');  // 以两个'/0'字符结尾
 
//  int iPaste = m_tbCtrl.AddStrings(szBuf);
 
 
// 方法二 
 CString strText(_T(""));
 
 strText.LoadString(IDS_CUT);
 CString strCut(strText, strText.GetLength()
+1);
 
int iCut = m_tbCtrl.AddStrings(strCut);
 
 strText.LoadString(IDS_COPY);
 CString strCopy(strText, strText.GetLength()
+1);
 
int iCopy = m_tbCtrl.AddStrings(strCopy);
 
 strText.LoadString(IDS_PASTE);
 CString strPaste(strText, strText.GetLength()
+1);
 
int iPaste = m_tbCtrl.AddStrings(strPaste);
 
 
 
// Fill the TBBUTTON array with button information, and add the 
 
// buttons to the toolbar. The buttons on this toolbar have text 
 
// but do not have bitmap images. 
 TBBUTTON tbb[3]; 
 tbb[
0].iBitmap = -1
 tbb[
0].idCommand = IDS_CUT; 
 tbb[
0].fsState = TBSTATE_ENABLED; 
 tbb[
0].fsStyle = TBSTYLE_BUTTON; 
 tbb[
0].dwData = 0
 tbb[
0].iString = iCut;
 
 tbb[
1].iBitmap = -1
 tbb[
1].idCommand = IDS_COPY; 
 tbb[
1].fsState = TBSTATE_ENABLED; 
 tbb[
1].fsStyle = TBSTYLE_BUTTON; 
 tbb[
1].dwData = 0
 tbb[
1].iString = iCopy; 
 
 tbb[
2].iBitmap = -1
 tbb[
2].idCommand = IDS_PASTE; 
 tbb[
2].fsState = TBSTATE_ENABLED; 
 tbb[
2].fsStyle = TBSTYLE_BUTTON; 
 tbb[
2].dwData = 0
 tbb[
2].iString = iPaste; 
 
 m_tbCtrl.AddButtons(
sizeof(tbb)/sizeof(tbb[0]), tbb);
 m_tbCtrl.AutoSize();
 
 m_tbCtrl.ShowWindow(SW_SHOW);
 
 
return TRUE;

error C2664: “CListBox::AddString”: 不能将参数 从“const char [5]”转换为“LPCTSTR”

往列表框中添加信息的时候出现错误:error C2664: “CListBox::AddString”: 不能将参数 从“const char [5]”转换为“LPCTSTR”;代码如下: ((CLi...

网盘不靠谱 那就自己搭建256TB的网盘呗 — Nextcloud搭建过程

2016年 网盘的日子不好过啊 一家家的over了 百度云也已经早早的限速了。隐私问题也经常曝光。 既然现在网盘这么不靠谱,那就自己搭建一个Nextcloud呗~~~ 他能上传 能下载(不废话)...
  • zhywbp
  • zhywbp
  • 2017年06月15日 00:44
  • 1624

分享MSP430用TB捕获脉宽问题与解决心得

原帖: http://bbs.21ic.com/icview-293369-1-1.html ====================================================...

arduino UNO 用TB6560驱动42步进电机

arduino UNO 用TB6560驱动42步进电机

Python篇----多线程1TB数据生成脚本

0 前言 Sorry,我骗了你!!! “多线程”,在Python中就是鸡肋,我只是想得到很多份1TB数据文件而已。 “1TB数据”,这个大小是可以改的,生成1G,1M的数据随便都行。数据,目前只是随机...

【翻译自mos文章】使用asm来部署 超大数据库(10TB到PB 范围)--针对oracle 10G

使用asm来部署 超大数据库(10TB到PB 范围)--针对oracle 10G

格式化大于16TB的分区为ext4遇到的挫折

假如想对>2T磁盘进行分区操作,请使用parted fdisk 是基于MBR的分区工具,假如fdisk -l检查到了gpt磁盘,那么会报错 Disk /dev/sdb: 19998.4...
  • dsc1245
  • dsc1245
  • 2017年05月27日 16:18
  • 419

我的Android进阶之旅------>Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换)

Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换) 有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写。下面是一个Jav...

交易开拓者TB夜盘编程技术集

一、夜盘交易的基本情况 目前期货市场上,越来越多的品种都加入了夜盘交易大军。截止7月23日,目前已经确定在夜盘交易的有: 上海期货交易所:白银ag,铜cu,金au,锌zu 大连商品交...

海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?

1、外排序   传统的排序算法一般指内排序算法,针对的是数据可以一次全部载入内存中的情况。但是面对海量数据,即数据不可能一次全部载入内存,需要用到外排序的方法。外排序采用分块的方法(分而治之),首...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:TB_ADDSTRING
举报原因:
原因补充:

(最多只允许输入30个字)