1、界面域定义,包含域成员变量:用于保存对应的数据,通过UpdateData方法进行成员变量与界面值之间的动态交换,
UpdateData(true)是从界面值交换到成员变量
UpdateData(false)是从成员变量交换到界面值
所有需要交换的控件,都在方法DoDataExchange中注册。
域控制变量:用于控制对应的界面控件
2、域消息事件处理:
Killfocus
Onchanged
3、页、对话框消息事件处理:
Onsetactive
OnApply
OnCancel
OnOk
4、Sheet消息事件处理
OnApply
OnCancel
5、字符处理类CString
时间类COleDateTime
OLE字符串
作者:冯明德
一、概述
32位宽字符串,前面32位为长度,尾部以0结束
二、相关定义
BSTR (又称Basic 类型字符串)
LPOLESTR
相关宏定义:
typedef unsigned short wchar_t; (unsigned short为两字节)
typedef wchar_t WCHAR;
typedef WCHAR OLECHAR; (Win32)
typedef OLECHAR* BSTR;
typedef /* [string] */ OLECHAR __RPC_FAR *LPOLESTR;
三、使用
1.分配
// Create BSTR containing "Text"
bs = SysAllocString(L"Text")
// Create BSTR containing "Te"
bs = SysAllocStringLen(L"Text", 2)
// Create BSTR containing "Text" followed by \0 and a junk character
bs = SysAllocStringLen(L"Text", 6)
// Reallocate BSTR bs as "NewText" 重新赋值
f = SysReAllocString(&bs, "NewText");
2.长度
// Get character length of string.
cch = SysStringLen(bs);
3.释放
// Deallocate a string.
SysFreeString(bs);
四、转换问题
1 使用_bstr_t
BSTR tmpBStr;
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr(tmpBStr, FALSE); //将得到的BSTR作为构造函数参数
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);
注意: 直接赋值转换,会引发内存泄漏
BSTR tmpBStr;
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr;
tmpbstr= tmpBStr; //Caution: 内存泄漏参数
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);
2 使用T2COLE、T2OLE等
#include <afxpriv.h>
在转换前需要添加宏
USES_CONVERSION
#define USES_CONVERSION int _convert = 0; \
_convert;\
UINT _acp = GetACP();\
_acp;\
LPCWSTR _lpw = NULL;\
_lpw;\
LPCSTR _lpa = NULL;\
_lpa
这个宏提供了一些临时变量供转化用
看一下其在单字节字符集时的宏定义
#define T2COLE(lpa) A2CW(lpa)
#define T2OLE(lpa) A2W(lpa)
#define OLE2CT(lpo) W2CA(lpo)
#define OLE2T(lpo) W2A(lpo)
#define A2CW(lpa) ((LPCWSTR)A2W(lpa))
#define W2CA(lpw) ((LPCSTR)W2A(lpw))
#define A2W(lpa) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert)))
#define W2A(lpw) (\
((_lpw = lpw) == NULL) ? NULL : (\
_convert = (lstrlenW(_lpw)+1)*2,\
ATLW2AHELPER((LPSTR) alloca(_convert), _lpw, _convert)))
LPSTR AFXAPI AfxW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
{
if (lpw == NULL)
return NULL;
ASSERT(lpa != NULL);
// verify that no illegal character present
// since lpa was allocated based on the size of lpw
// don''t worry about the number of chars
lpa[0] = ''\0'';
VERIFY(WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL));
return lpa;
}
LPWSTR AFXAPI AfxA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
{
if (lpa == NULL)
return NULL;
ASSERT(lpw != NULL);
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don''t worry about the number of chars
lpw[0] = ''\0'';
VERIFY(MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars));
return lpw;
}
3 .CString 对转化的支持
//m_cstrCaption是一个CString 对象。
BSTR bstrCaption =m_cstrCaption.AllocSysString();
FireChange(&bstrCaption,&m_lAlignment);
::SysFreeString(bstrCaption);
冯明德,你好!
>>
>> 我在VC知识库上看到了你的《OLE字符串》,读后有些问题,希望能和你交流。
>> 文章标题给我的感觉应该是讲OLECHAR这种字符串类型,但是阅读过整篇文章后发现是在讲BSTR这种类型(除了在文章开头列出的相关定义)。我不知道你本意是否就是在讲BSTR。
>> 根据我以前的了解OLECHAR和BSTR还是不同的,最主要的区别就在于BSTR前面有4个字节用于保留字符串的长度,而OLESTR没有,但BSTR所指向的位置是从第五个字节,也就是真正的OLECHAR串的开始处。由于这个区别所以对于BSTR要通过一系列专门的函数来进行管理,如:SysAllocString等。同样在声明的时候可以让OLESTR等于一个宽字符串常量,而BSTR确需要调用SysAllocString进行分配。
>> 我觉得OLESTR和BSTR这两种类型是很容易让人混淆的,从相关的宏定义来看似乎是一样的,但是实际上并不相同,不知你的看法如何?如果你本意是讲BSTR,那么我建议你修改一下你文章的题目。
>> 廖志柏
公开回复如下:
谢谢您的来信提醒。实际上,对于以上问题,本人是一知半解,只是凭一时的理解,做了以上笔记。
两三年前,自己初学小有收获,就开始轻狂浮躁,将笔记放之于网络,如今,自己已经很少编程实践了。即使发现纰漏,也无暇顾及。看到自己的文字在网络中流传,所感不是成就,而是对自己浮躁轻狂的抱歉。
由于是转载,本人无法修改此文,见谅。
再谢。
望学习者,读而思之。广泛查取资料,去芜存精。
若有误导,深表抱歉。
( FMD 发表于 2003-4-1 0:41:00)
VC++学习:字符串黑箱的背后
去年的时候,由于某种原因,我需要将一个文件的二进制形式以文本的格式输出到一个文本文件中,类似下面这个样子:
4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 D0 00 00 00
0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68
69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F
74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20
6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00
......
我想的很简单:打开文件,读取文件,用一个循环,对每个字节使用wsprintf,然后用lstrcat连接起来,写文件,搞定。于是我很容易地得到了以下这段毫无语法错误的代码:
// 注1:你可以将其中的几个未定义变量理解为全局变量。
// 注2:NEW是我定义的一个宏函数,仿照了C++ 的operator new。
// #define NEW(type, count) (type *)(malloc(sizeof(type) * (count)))
void Save(void)
{
DWORD dwSize, dwReaded, i;
TCHAR szByte[5];
// 读取源文件
hFileSrc = CreateFile(szFileSrc, GENERIC_READ, 0, NULL, OPEN_ALWAYS, 0, NULL);
dwSize = GetFileSize(hFileSrc, NULL);
lpbySrc = NEW(BYTE, dwSize);
ReadFile(hFileSrc, (LPVOID)lpbySrc, dwSize, &dwReaded, NULL);
// 下面的MYSIZE是一个指示缓冲区大小的宏,由于计算大小较为繁琐且与本文无关,所以此处略去
lpDst = NEW(TCHAR, MYSIZE);
*lpDst = '\0';
for (i = 0; i < dwSize - 1; i++)
{
if (i % 16 == 15) // 处理换行
wsprintf(szByte, "%02X\r\n", lpbySrc[i]);
else
wsprintf(szByte, "%02X ", lpbySrc[i]);

浙公网安备 33010602011771号