vc++.NET调用oracle10g
vc++.NET调用oracle10g
{
CString ConnStr;
ConnStr.Format("Provider=%s;Password=%s;Persist Security Info=True;User ID=%s;Data Source=%s",dbclass,dlg.m_SetDBPWD,dlg.m_SetDBUSER,dlg.m_SetDBNM );
_bstr_t connectstr=ConnStr;
pConn->Open(connectstr,"","",adModeUnknown);
if(hr != S_OK)
{
return ;
}
}catch(_com_error &ex)
{
pRst->Open(sql.AllocSysString(),_variant_t((IDispatch*)pConn,TRUE),adOpenDynamic,adLockOptimistic,adCmdText);
winpcap获取网络设备
{
name.Format("%s",d->name);
if (d->description)
des.Format("%s",d->description);
else
des.Format("(No description available)");
m_AdapterList.InsertItem( LVIF_TEXT|LVIF_STATE, idx-1, "", 0, 0,0, 0); //输出到list 控件 m_AdapterList.SetItem(idx-1,1,LVIF_TEXT,TEXT(name +des),0,0,0,0);
flag = true;
}
VC++.net 2003 捕获局域网组播数据包
VC++.NET2003操作oracle10g
OLE DB是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式和存储方法。
#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","adoEOF")
2.建立connection,recordset指针操作记录:
//打开连接
//
if(FAILED(::CoInitialize(NULL)))
{
::MessageBox(NULL,_T("初始化com失败"),_T("错误"),MB_OK);
exit(-1);
}
CString dbclass="MSDAORA",m_SetDBUSER="tester",m_SetDBPWD="tester",m_SetDBNM="orcl";
if(hr != S_OK)
{
return ;
}
//
//登陆
//
try
{
CString ConnStr;
ConnStr.Format("Provider=%s;User ID=%s;Password=%s;Data Source=%s",dbclass,m_SetDBUSER,m_SetDBPWD,m_SetDBNM); //ConnStr.Format("DRIVER=Microsoft ODBC for Oracle;UID=%s;PWD=%s;SERVER=%s",dlg.m_SetDBUSER,dlg.m_SetDBPWD,dlg.m_SetDBNM);
_bstr_t connectstr=ConnStr;
pConn->Open(connectstr,"","",adModeUnknown);
if(hr != S_OK)
{
return ;
}
}catch(_com_error &ex)
{
AfxMessageBox("捕获得错误原因:/n"+ex.Description());
m_SetDBNM=_T("svorcl");
m_SetDBUSER=_T("tester");
m_SetDBPWD=_T("tester");
}
//验证
//
try
{
_RecordsetPtr pRst;
hr=pRst.CreateInstance("ADODB.Recordset");
_variant_t RecordAffected;
CString sql;
sql.Format( "select user from TB_USER where /"C01/"=/'%s/' and /"C02/"=/'%s/'", m_SetDBUSER, m_SetDBPWD);
pRst->CursorLocation=adUseClient;
pRst->Open(sql.AllocSysString(),_variant_t((IDispatch*)pConn,TRUE),adOpenStatic,adLockOptimistic,adCmdText);
// pRst = pConn->Execute(sql.AllocSysString(),&RecordAffected,adCmdText);
if(pRst->adoEOF)
{
AfxMessageBox("登陆失败!");
if(pRst->State) pRst->Close();
pRst.Release();
if(pConn->State) pConn->Close();
pConn.Release();
m_SetDBUSER.Empty();
m_SetDBPWD.Empty();
}
pRst->Close();
pRst.Release();
}catch(_com_error &e)
{
AfxMessageBox( "捕获得错误原因:/n请检查数据库安装配置!/n"+e.Description());
exit(1);
}
//
//存储
//
HRESULT hrr;
_RecordsetPtr pRst;
hrr=pRst.CreateInstance("ADODB.Recordset");
if(hr !=S_OK)
{
AfxMessageBox("不能建立记录指针实例!");
return;
}
DWORD byteswritten;
char dataBuf[1024*2];
memset(dataBuf,0,sizeof(dataBuf));
CString protocol="TESTUDP";
CString s_address="0.0.0.0";
CString s_port="99";
CString d_address="0.0.0.0";
CString d_port="99";
CString size="88";
CString tdata="''?'";
tdata.Replace("'","|");
CString m_userID="tester";
try
{
CString sql_=NULL;
sql_.Format("insert into TB_PACK(ID,CLASSNAME,SOURCE,SPORT,DES,DPORT,LEN,PDATA,ITIME,OPUSER) values(TB_PACK_IDSEQ.nextval,/'%s/',/'%s/',/'%s/',/'%s/',/'%s/',/'%s/',/' %s /',SYSDATE,/'%s/' )",protocol, s_address, s_port, d_address, d_port, size, tdata,m_userID);
strcpy(dataBuf,sql_);
_bstr_t sql=sql_;
pRst->CursorLocation=adUseClient;
//pRst->Open(sql ,_variant_t((IDispatch*)pConn,TRUE),adOpenDynamic,adLockOptimistic,adCmdText);
pConn->Execute(sql,NULL,adCmdText);
}catch (_com_error &ex)
{
CString filename="errSQLlog.txt";
WIN32_FIND_DATA fd;
HANDLE hd=::FindFirstFile((LPCTSTR)filename,&fd);
if(hd !=INVALID_HANDLE_VALUE )
{
HANDLE handle= CreateFile(
filename, // 要打开的文件名
GENERIC_WRITE, // 文件的操作属性
0, // 文件共享属性
NULL, // 文件安全特性
OPEN_EXISTING, //文件操作 OPEN_EXISTING
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性
);
::SetFilePointer(handle,0,0,FILE_BEGIN);
::WriteFile(handle,dataBuf,sizeof(dataBuf),&num,NULL);
::WriteFile(handle, "/r/n", 2, &byteswritten, NULL);
::ZeroMemory(dataBuf,sizeof(dataBuf));
::CloseHandle(handle);
{
HANDLE handle= CreateFile(
filename, // 要打开的文件名
GENERIC_WRITE, // 文件的操作属性
0, // 文件共享属性
NULL, // 文件安全特性
OPEN_ALWAYS, //文件操作 OPEN_EXISTING
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性
);
::SetFilePointer(handle,0,0,FILE_BEGIN);
::WriteFile(handle,dataBuf,sizeof(dataBuf),&num,NULL);
::WriteFile(handle, "/r/n", 2, &byteswritten, NULL);
::ZeroMemory(dataBuf,sizeof(dataBuf));
//::SetFilePointer(handle,0,0,FILE_BEGIN);
//::ReadFile(handle,Buffer,sizeof(Buffer),&Num,NULL);
::CloseHandle(handle);
}
return;
}
//pRst->Close();
pRst.Release();
数据类型 | 参数 | 描述 |
number(m,n) |
m=1 to 38 n=-84 to 127 |
可变长的数值列,允许0、正值及负值,m是所有有效数字的位数,n是小数点以后的位数。如:number(5,2),则这个字段的最大值是99,999,如果数值超出了位数限制就会被截取多余的位数。如:number(5,2),但在一行数据中的这个字段输入575.316,则真正保存到字段中的数值是575.32。如:number(3,0),输入575.316,真正保存的数据是575。 |
char(n) | n=1 to 2000字节 | 定长字符串,n字节长,如果不指定长度,缺省为1个字节长(一个汉字为2字节) |
long | 无 | 可变长字符列,最大长度限制是2GB,用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型。long是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 |
varchar2(n) | n=1 to 4000字节 | 可变长的字符串,具体定义时指明最大长度n,这种数据类型可以放数字、字母以及ASCII码字符集(或者EBCDIC等数据库系统接受的字符集标准)中的所有符号。如果数据长度没有达到最大值n,Oracle 8i会根据数据大小自动调节字段长度,如果你的数据前后有空格,Oracle 8i会自动将其删去。VARCHAR2是最常用的数据类型。可做索引的最大长度3209。 |
date | 无 | 从公元前4712年1月1日到公元4712年12月31日的所有合法日期,Oracle 8i其实在内部是按7个字节来保存日期数据,在定义中还包括小时、分、秒。缺省格式为DD-MON-YY,如07-11-00 表示2000年11月7日。 |
raw(n) | n=1 to 2000 | 可变长二进制数据,在具体定义字段的时候必须指明最大长度n,Oracle 8i用这种格式来保存较小的图形文件或带格式的文本文件,如Miceosoft Word文档。raw是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 |
long raw | 无 | 可变长二进制数据,最大长度是2GB。Oracle 8i用这种格式来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件。在同一张表中不能同时有long类型和long raw类型,long raw也是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 |
blob clob nclob |
无 |
三种大型对象(LOB),用来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件,最大长度是4GB。 LOB有几种类型,取决于你使用的字节的类型,Oracle 8i实实在在地将这些数据存储在数据库内部保存。可以执行读取、存储、写入等特殊操作。 |
bfile | 无 | 在数据库外部保存的大型二进制对象文件,最大长度是4GB。这种外部的LOB类型,通过数据库记录变化情况,但是数据的具体保存是在数据库外部进行的。Oracle 8i可以读取、查询BFILE,但是不能写入。大小由操作系统决定。 |
名称 | 含义 |
Char | 用于描述定长的字符型数据,长度<= 2000 字节 |
varchar2 | 用于描述变长的字符型数据,长度<= 4000 字节 |
nchar | 用来存储Unicode字符集的定长字符型数据,长度<= 1000 字节 |
nvarchar2 | 用来存储Unicode字符集的变长字符型数据,长度<= 1000 字节 |
number | 用来存储整型或者浮点型数值 |
Date | 用来存储日期数据 |
Long | 用来存储最大长度为2GB的变长字符数据 |
Raw | 用来存储非结构化数据的变长字符数据,长度<= 2000 字节 |
Long raw | 用来存储非结构化数据的变长字符数据,长度<= 2GB |
rowid | 用来存储表中列的物理地址的二进制数据,占用固定的10个字节 |
Blob | 用来存储多达4GB的非结构化的二进制数据 |
Clob | 用来存储多达4GB的字符数据 |
nclob | 用来存储多达4GB的Unicode字符数据 |
Bfile | 用来把非结构化的二进制数据存储在数据库以外的操作系统文件中 |
urowid | 用来存储表示任何类型列地址的二进制数据 |
float | 用来存储浮点数 |
Recordset对象 Recordset对象代表一个表的记录集或者命令
执行的结果,在记录集中,总是有一个当前的记录。记录集是ADO管理
数据的基本对象,所有的Recordset对象都按照行列方式的表状结构进
行管理,每一行对应一个记录(Record),每一列对应一个域(Field)。
Recordset对象也通过游标对记录进行访问,在ADO中,游标分为以下4种
:
静态游标提供对数据集的一个静态拷贝,允许各种移动操作,包括
前移、后移等等,但其他用户所做的操作反映不出来。
动态游标允许各种移动操作,包括前移、后移等等,并且其他用户
所做的操作也可以直接反映出来。
前向游标允许各种前向移动操作,不能向后移动,并且其他用户所
做的操作也可以直接反映出来。
键集(keyset)游标 类似于动态游标,也能够看到其他用户所做的
数据修改,但不能看到其他用户新加的记录,也不能访问其他用户删除
的记录。
Recordset对象的用法如下:
a.利用CursorType属性设置游标类型。
b.通过Open方法打开记录集数据,既可以在Open之前对ActiveCon
nection属性赋值, 指定Recordset对象使用连接对象,也可以直接在O
pen方法中指定连接串参数,ADO将创建一个内部连接,即使连接串与外
部的连接对象相同,它也使用新的连接对象。
c.Recordset对象刚打开时,当前记录被定位在首条记录,并且BOF
和EOF标志属性为F alse,如果当前记录集为空记录集,则BOF和EOF标
志属性为True。
d.通过MoveFirst、MoveLast、MoveNext和MovePrevious方法可
以对记录集的游标进行移动操作。如果OLE DB提供者支持相关功能的
话,可以使用AbsolutePosition、Absol utePage和Filter属性对当前
记录重新定位。
e.ADO提供了两种记录修改方式:立即修改和批修改。在立即修改
方式下,一旦调用U pdate方法,则所有对数据的修改立即被写到底层
的数据源。在批修改方式下,可以对多条记录进行修改,然后调用Upda
teBatch方法把所有的修改递交到底层数据源。递交之后,可以用Stat
us属性检查数据冲突。
Recordset对象是ADO数据操作的核心,它既可以作为Connection
对象或Command对象执行特定方法的结果数据集,也可以独立于这两个
对象而使用,由此可以看出ADO对象在使用上的灵活性。
上面3个对象都包含一个Property对象集合的属性,通过Property
对象可使ADO动态暴露出底层OLE DB提供者的性能。由于并不是所有
的底层提供者都有同样的性能,所以ADO 允许用户动态访问底层提供
者的能力。这样既使得ADO很灵活,又提供了很好的扩展性。
ADO的其他集合对象及其元素对象,都用在特定的上下文环境中,
比如Parameter对象一定要与某个Command对象相联系后,才能真正起
作用。而另外三个对象Field、Error和Property对象只能依附于其父
对象,不能单独创建这些对象。
VC字符串转换
在Visual C++.NET的所有编程方式中,我们常常要用到这样的一些基本字符串类型,如BSTR、LPSTR和LPWSTR等。之所以出现类似上述的这些数据类型,是因为不同编程语言之间的数据交换以及对ANSI、Unicode和多字节字符集(MBCS)的支持。
那么什么是BSTR、LPSTR以及LPWSTR呢?
BSTR(Basic STRing,Basic字符串)是一个OLECHAR*类型的Unicode字符串。它被描述成一个与自动化相兼容的类型。由于操作系统提供相应的API函数(如SysAllocString)来管理它以及一些默认的调度代码,因此BSTR实际上就是一个COM字符串,但它却在自动化技术以外的多种场合下得到广泛使用。图1描述了BSTR的结构,其中DWORD值是字符串中实际所占用的字节数,且它的值是字符串中Unicode字符的两倍。
LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘/0’)结尾的8位ANSI字符数组指针,而LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针。在VC++中,还有类似的字符串类型,如LPTSTR、LPCTSTR等,它们的含义如图2所示。
例如,LPCTSTR是指“long pointer to a constant generic string”,表示“一个指向一般字符串常量的长指针类型”,与C/C++的const char*相映射,而LPTSTR映射为 char*。
一般地,还有下列类型定义:
#ifdef UNICODE
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
#endif
二、CString、CStringA 和 CStringW
Visual C++.NET中将CStringT作为ATL和MFC的共享的“一般”字符串类,它有CString、CStringA和CStringW三种形式,分别操作不同字符类型的字符串。这些字符类型是TCHAR、char和wchar_t。TCHAR在Unicode平台中等同于WCHAR(16位Unicode字符),在ANSI中等价于char。wchar_t通常定义为unsigned short。由于CString在MFC应用程序中经常用到,这里不再重复。
三、VARIANT、COleVariant 和_variant_t
在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:
struct tagVARIANT {
VARTYPE vt;
union {
short iVal; // VT_I2.
long lVal; // VT_I4.
float fltVal; // VT_R4.
double dblVal; // VT_R8.
DATE date; // VT_DATE.
BSTR bstrVal; // VT_BSTR.
…
short * piVal; // VT_BYREF|VT_I2.
long * plVal; // VT_BYREF|VT_I4.
float * pfltVal; // VT_BYREF|VT_R4.
double * pdblVal; // VT_BYREF|VT_R8.
DATE * pdate; // VT_BYREF|VT_DATE.
BSTR * pbstrVal; // VT_BYREF|VT_BSTR.
};
};
显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。例如,如果vt为VT_I2,那么我们可以从iVal中读出VARIANT的值。同样,当给一个VARIANT变量赋值时,也要先指明其类型。例如:
VARIANT va;
:: VariantInit(&va); // 初始化
int a = 2002;
va.vt = VT_I4; // 指明long数据类型
va.lVal = a; // 赋值
为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:
VariantInit —— 将变量初始化为VT_EMPTY;
VariantClear —— 消除并初始化VARIANT;
VariantChangeType —— 改变VARIANT的类型;
VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。
COleVariant类是对VARIANT结构的封装。它的构造函数具有极为强大大的功能,当对象构造时首先调用VariantInit进行初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与VARIANT类型转换中为我们提供极大的方便。例如下面的代码:
COleVariant v1("This is a test"); // 直接构造
COleVariant v2 = "This is a test";
// 结果是VT_BSTR类型,值为"This is a test"
COleVariant v3((long)2002);
COleVariant v4 = (long)2002;
// 结果是VT_I4类型,值为2002
_variant_t是一个用于COM的VARIANT类,它的功能与COleVariant相似。不过在Visual C++.NET的MFC应用程序中使用时需要在代码文件前面添加下列两句:
#include "comutil.h"
#pragma comment( lib, "comsupp.lib" )
四、CComBSTR和_bstr_t
CComBSTR是对BSTR数据类型封装的一个ATL类,它的操作比较方便。例如:
CComBSTR bstr1;
bstr1 = "Bye"; // 直接赋值
OLECHAR* str = OLESTR("ta ta"); // 长度为5的宽字符
CComBSTR bstr2(wcslen(str)); // 定义长度为5
wcscpy(bstr2.m_str, str); // 将宽字符串复制到BSTR中
CComBSTR bstr3(5, OLESTR("Hello World"));
CComBSTR bstr4(5, "Hello World");
CComBSTR bstr5(OLESTR("Hey there"));
CComBSTR bstr6("Hey there");
CComBSTR bstr7(bstr6);
// 构造时复制,内容为"Hey there"
_bstr_t是是C++对BSTR的封装,它的构造和析构函数分别调用SysAllocString和SysFreeString函数,其他操作是借用BSTR API函数。与_variant_t相似,使用时也要添加comutil.h和comsupp.lib。
五、BSTR、char*和CString转换
(1) char*转换成CString
若将char*转换成CString,除了直接赋值外,还可使用CString::Format进行。例如:
char chArray[] = "This is a test";
char * p = "This is a test";
或
LPSTR p = "This is a test";
或在已定义Unicode应的用程序中
TCHAR * p = _T("This is a test");
或
LPTSTR p = _T("This is a test");
CString theString = chArray;
theString.Format(_T("%s"), chArray);
theString = p;
(2) CString转换成char*
若将CString类转换成char*(LPSTR)类型,常常使用下列三种方法:
方法一,使用强制转换。例如:
CString theString( "This is a test" );
LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;
方法二,使用strcpy。例如:
CString theString( "This is a test" );
LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
_tcscpy(lpsz, theString);
需要说明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二个参数是 const wchar_t* (Unicode)或const char* (ANSI),系统编译器将会自动对其进行转换。
方法三,使用CString::GetBuffer。例如:
CString s(_T("This is a test "));
LPTSTR p = s.GetBuffer();
// 在这里添加使用p的代码
if(p != NULL) *p = _T('/0');
s.ReleaseBuffer();
// 使用完后及时释放,以便能使用其它的CString成员函数
(3) BSTR转换成char*
方法一,使用ConvertBSTRToString。例如:
#include
#pragma comment(lib, "comsupp.lib")
int _tmain(int argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L"Test");
char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); // 用完释放
delete[] lpszText2;
return 0;
}
方法二,使用_bstr_t的赋值运算符重载。例如:
_bstr_t b = bstrText;
char* lpszText2 = b;
(4) char*转换成BSTR
方法一,使用SysAllocString等API函数。例如:
BSTR bstrText = ::SysAllocString(L"Test");
BSTR bstrText = ::SysAllocStringLen(L"Test",4);
BSTR bstrText = ::SysAllocStringByteLen("Test",4);
方法二,使用COleVariant或_variant_t。例如:
//COleVariant strVar("This is a test");
_variant_t strVar("This is a test");
BSTR bstrText = strVar.bstrVal;
方法三,使用_bstr_t,这是一种最简单的方法。例如:
BSTR bstrText = _bstr_t("This is a test");
方法四,使用CComBSTR。例如:
BSTR bstrText = CComBSTR("This is a test");
或
CComBSTR bstr("This is a test");
BSTR bstrText = bstr.m_str;
方法五,使用ConvertStringToBSTR。例如:
char* lpszText = "Test";
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
(5) CString转换成BSTR
通常是通过使用CStringT::AllocSysString来实现。例如:
CString str("This is a test");
BSTR bstrText = str.AllocSysString();
…
SysFreeString(bstrText); // 用完释放
(6) BSTR转换成CString
一般可按下列方法进行:
BSTR bstrText = ::SysAllocString(L"Test");
CStringA str;
str.Empty();
str = bstrText;
或
CStringA str(bstrText);
(7) ANSI、Unicode和宽字符之间的转换
方法一,使用MultiByteToWideChar将ANSI字符转换成Unicode字符,使用WideCharToMultiByte将Unicode字符转换成ANSI字符。
方法二,使用“_T”将ANSI转换成“一般”类型字符串,使用“L”将ANSI转换成Unicode,而在托管C++环境中还可使用S将ANSI字符串转换成String*对象。例如:
TCHAR tstr[] = _T("this is a test");
wchar_t wszStr[] = L"This is a test";
String* str = S”This is a test”;
方法三,使用ATL 7.0的转换宏和类。ATL7.0在原有3.0基础上完善和增加了许多字符串转换宏以及提供相应的类,它具有如图3所示的统一形式:
其中,第一个C表示“类”,以便于ATL 3.0宏相区别,第二个C表示常量,2表示“to”,EX表示要开辟一定大小的缓冲。SourceType和DestinationType可以是A、T、W和OLE,其含义分别是ANSI、Unicode、“一般”类型和OLE字符串。例如,CA2CT就是将ANSI转换成一般类型的字符串常量。下面是一些示例代码:
LPTSTR tstr= CA2TEX<16>("this is a test");
LPCTSTR tcstr= CA2CT("this is a test");
wchar_t wszStr[] = L"This is a test";
char* chstr = CW2A(wszStr);
实现树型控件的背景位图
void CMyTreeCtrl::OnPaint()
void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
二、编程步骤
消息响应函数:
afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult);
3、 将树型控件与CmyTreeCtrl类建立关联,在对话框中添加变量CMyTreeCtrl m_CtrlTree;
三、实现代码
/
#if !defined(AFX_TREEDLG_H__D82DB384_F574_44A7_96DA_6EC9068E22B1__INCLUDED_)
#define AFX_TREEDLG_H__D82DB384_F574_44A7_96DA_6EC9068E22B1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/// CTreeDlg dialog
#include "MyTreeCtrl.h"
class CTreeDlg : public CDialog
{
// Construction
public:
CTreeDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CTreeDlg)
enum { IDD = IDD_TREE_DIALOG };
CMyTreeCtrl m_CtrlTree;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTreeDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CTreeDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
// MyTreeCtrl.cpp : implementation file
#include "StdAfx.h"
#include "Tree.h"
#include "MyTreeCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// CMyTreeCtrl
CMyTreeCtrl::CMyTreeCtrl()
{}
CMyTreeCtrl::~CMyTreeCtrl()
{}
BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
//{{AFX_MSG_MAP(CMyTreeCtrl)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CMyTreeCtrl message handlers
BOOL CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource)
{
// if this is not the first call then delete gdi objects
if( m_bitmap.m_hObject != NULL )
m_bitmap.DeleteObject();
HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
LpszResource, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
if( hbmp == NULL )
return FALSE;
m_bitmap.Attach( hbmp );
return TRUE;
}
LRESULT CMyTreeCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
return CTreeCtrl::WindowProc(message, wParam, lParam);
}
void CMyTreeCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rcclient;
GetClientRect(&rcclient);
// create a compatible memory dc
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
memdc.SelectObject( &bitmap );
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);
CDC maskdc;
maskdc.CreateCompatibleDC(&dc);
CBitmap maskbitmap;
maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
maskdc.SelectObject( &maskbitmap );
maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,
rcclient.left, rcclient.top, SRCCOPY);
CBrush brush;
brush.CreatePatternBrush(&m_bitmap);
dc.FillRect(rcclient, &brush);
memdc.SetBkColor(RGB(0,0,0));
memdc.SetTextColor(RGB(255,255,255));
memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
dc.SetBkColor(RGB(255,255,255));
dc.SetTextColor(RGB(0,0,0));
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top,SRCPAINT);
brush.DeleteObject();
}
BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
}
void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
Invalidate();
SetRedraw(TRUE);
*pResult = 0;
}
void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
SetRedraw(FALSE);
*pResult = 0;
}
///
BOOL CTreeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu-> AppendMenu(MF_SEPARATOR);
pSysMenu-> AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
// TODO: Add extra initialization here
m_CtrlTree.SetBKImage("IDB_BITMAP1");
SetIcon(m_hIcon, FALSE); // Set small icon
TVINSERTSTRUCT tvInsert;
tvInsert.hParent = NULL;
tvInsert.hInsertAfter = NULL;
tvInsert.item.mask = TVIF_TEXT;
tvInsert.item.pszText = _T("Visual C++编程实例");
HTREEITEM hCountry = m_CtrlTree.InsertItem(&tvInsert);
HTREEITEM hPA = m_CtrlTree.InsertItem(TVIF_TEXT,
_T("文章中心"), 0, 0, 0, 0, 0, hCountry, NULL);
HTREEITEM hWA = m_CtrlTree.InsertItem(_T("代码中心"),0, 0, hCountry, hPA);
m_CtrlTree.InsertItem(_T("全屏幕程序的实现"), hPA, TVI_SORT);
m_CtrlTree.InsertItem(_T("实现窗口的任意分割"), hPA, TVI_SORT);
m_CtrlTree.InsertItem(_T("实现菜单的自绘"), hPA, TVI_SORT);
m_CtrlTree.InsertItem(_T("实现全屏幕显示的代码"), hWA, TVI_SORT);
m_CtrlTree.InsertItem(_T("窗口任意分割的代码"), hWA, TVI_SORT);
m_CtrlTree.InsertItem(_T("菜单自绘代码"), hWA, TVI_SORT);
m_CtrlTree.Expand(hCountry,TVE_EXPAND);
return TRUE; // return TRUE unless you set the focus to a control
}
四、小结
到此为止,本例通过实现树形控件的背景位图介绍了一些树视图控件编程方法,包括树视图控件的建立、节点值的赋予等。当然,它应用的方面很广,使用方法也很多。这里仅仅是涉及到了构建树视图控件的基本框架,读者朋友们可以在此基础上,可进行扩展,从而完成更强大的功能,感兴趣的读者不妨自己扩展该控件试试。
vc++.NET调用oracle10g相关推荐
- 来总结一下在VC中调用COM组件的方法
来总结一下在VC中调用COM组件的方法(大家来补充) [问题点数:50分,结帖人_foo] http://bbs.csdn.net/topics/50319093 发表于: 2004-04-17 16 ...
- VC输出调用出错信息
VC输出调用出错信息 很多时候要使用GetLastError函数来获取函数调用的出错代码,但仅仅是代码并不够,我们还需要知道错误代码所代表的具体信息.在<Windows核心编程>中提到过一 ...
- C#与VC相互调用之VC调用C#的DLL库
介绍 在之前的博文 C#与VC相互调用之C#调用VC的DLL https://blog.csdn.net/xinxin_2011/article/details/86704660 里面讲了C#程序如何 ...
- VC中调用并获取外部程序输出
VC上调用外部程序的方法大家应该很熟悉,比如ShellExecute,CreateProcess. 例子: system("D://adb.exe devices >c://temp. ...
- VC++ ADO调用存储过程方法
一.调用基本过程 关于ADO调用存储过程一般是按照以下步骤进行: 1.生成并初始化一个_CommandPtr对象:指定CommandType为存储过程. 2.生成调用存储过程需要的参数,这些参数都是_ ...
- vc只能调用matlab子函数,Vc++6.0调用matlab的数学库函数
Vc++6.0调用matlab的数学库函数 前段时间在摸索如何在VC++6.0当中调用Matlab的里的数学库函数.当时弄得我很是郁闷,现在想想,自已走了很多弯路,原来,是如些的简单.所以,与出来和大 ...
- 如何在VC中调用第三方lib库(step by step)
我们以调用Kvaser的库文件为例. 第三方的库一般会提供两个文件,一个是库文件.一个是头文件. Kvaser的库文件为canlib32.lib . 头文件为canlib.h 该库文件里,提供了一个名 ...
- vc只能调用matlab子函数,VC调用matlab函数
最近在学习matlab,先试一个VC调用matlab函数的简单例子 用的是VC++6.0,matlab7.8也就是matlabR2009 首先在matlab下设置环境 >> mbuild ...
- VC如何调用DLL文件
调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载 ...
最新文章
- 使用mybatis-generator-core实现自动创建项目
- NodeJS安装及部署(Linux系统)
- visual studio 2015安装 无法启动程序,因为计算机丢失D3DCOMPILER_47.dll 的解决方法
- 从事人工智能要学计算机什么专业,人工智能专业需要什么学历
- Qt学习之C++基础
- BinaryViewer(二进制查看器)使用教程(附下载)
- 常用模板 UPD12/4
- HJQ巨佬のTwelveFold Way 手稿电子版
- 计算机宏如何设置方法,excel 如何启用宏的方法,以及如何设置excel启用宏
- SQL题目练习---三表联查
- 原创 | DDD领域驱动设计第一话
- 关于流程管理的这些事:项目流程及方法工具
- 中华好诗词大学季第二季(五)
- java利用ffmpeg将amr、caf转mp3格式
- 详细 | 图神经网络从入门到入门
- Android ObjectAnimator类:手把手带你自定义属性动画
- 程序人生--2010年(60)
- 网站加入百度云加速后,出现Error520源站返回未知错误怎么办?
- 微信小程序scroll-into-view实现页面定位
- 细说Java性能测试第一课 Jmeter导读