用TRUE DBGRID控件时,在COLUMN中的ITEMS里调用函数ADD(LPDISPATCH item);这个LPDISPATCH类型数据如何生成呢?
解决方案 »
- 关于与sqlite3混在一起的内存泄漏问题
- 关于开源Mumble的win32 平台编译问题
- int* &a;是什么语句啊?不懂意思,请指教!
- 出现这种错误怎么办?:LINK : fatal error LNK1104: cannot open file "mfcs42u.lib"
- 在基于对话框的程序中如何将注**册**表中某主键下所有子键逐一读出。
- 各位老兄!请问怎样检测字符串中的字母?
- 是操作系统的问题吗?
- 如何取得本机IP地址(是在Internet上分配的IP地址)
- LPCTSTR 和 BYTE 之间如何相互转换?
- 小人刚学VC,请问高手:new 和 delete是不是要成对出现呢?
- 如何從2個不同的對話框,獲取數據!!
- 关掉主窗体,可是进程还在? 问题出在哪里?谢谢
在无绑定模式下使用DBGrid
作者:Adrian Roman 翻译:白鹤 我花了好长时间来注意这件事情,因为我不能在其他任何文件中找到关于
DBGrid 在无绑定模式下的VC++编程内容(只有VB的)。我想把我的心得与别人
分享会是一个好主意。 首先,尽管连随机文档都说它能接受任何类型的变量作为书签,但是好象并不
是那么回事儿。DaoRecordset把SAFEARRAY作为书签(GetBook返回包含
VT_ARRAY | VT_UI1的变量),但它不能与DBGrid一起工作(DBGrid把变量转变
为VT_BSTR)。 它可能会与VT_I4工作的很好,但据说字符串是最好的,所以我
用他们。当然,我把书签转换成字符串再转换回来。 SchedQ是一个通过查询得
来的动态集(CDaoRecordset),如果关于他你有任何bug或是好想法,请跟我分
享您的发现。 啊,对,我几乎忘了!极其重要!如果你从OCX的类库中继承了
RowBuffer类,请修改构造函数,原构造函数得到LPDISPACH作为参数去调用基类
的构造函数,这时第二个参数要设为FALSE(原来隐性地设置为TRUE)。如果不
这样做,当RowBuffer对象被消除时整个程序会崩溃。 补充技巧:记着使用
BeforeColUpdate 和KeyPress事件去验证一个域的输入及相应地过滤键盘的输入。 请不要给我来e-mails,问我关于如何在绑定模式下使用他们的问题。在加入
DBGrid之前加上一个Microsoft Remote Data Control 的对话框,然后花点时
间调整一下它的属性,你就会弄明白如何使用它。 致那些想在运行时改变列
的人:由DBGrid类生成的GetColumns()成员函数是一个真正的GetColumn函数
(返回一个指向单个列的LPDISPATCH---这样你就可以用这个LPDISPATCH来构造
单个列对象,而不是列集的对象)。如果你想获得指向列集的LPDISPATCH,
把GetColumns()该名为GetColumn,然后象下面这样重新写一个GetColumns():
LPDISPATCH CMsDgridCtrl::GetColumns()
{
LPDISPATCH result;
InvokeHelper(0x8,DISPATCH_PROPERTYGET,VT_DISPATCH,(void*)&result,NULL,NULL);
return result;
}
这样你就可以用返回的LPDISPATCH来构造列集对象。 那么现在,往网格中输
入数据、删除纪录、当网格中写操作发生时从网格中获取数据的代码如下所示:
void CMyView::OnUnboundReadDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* StartLocation, BOOL ReadPriorRows) {
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
long Row,RowsFetched;
VARIANT var;
RowsFetched=0;
if(StartLocation->vt==VT_NULL){
if(ReadPriorRows){
try{
SchedQ->MoveLast();
}catch(CDaoException* e){
e->Delete();
}
}else{
try{
SchedQ->MoveFirst();
}catch(CDaoException* e){
e->Delete();
}
}
}else{
//根据StartLocation书签和ReadPriorRows参数找到开始读数据的位置try{
VectorFromBstr(StartLocation->bstrVal,&varbok.parray);
SchedQ->SetBook(COleVariant(varbok));
if(ReadPriorRows)SchedQ->MovePrev();
else SchedQ->MoveNext();
}catch(CDaoException* e){
e->Delete();
}
}
//把我们的数据集数组转换为DBGrid 用来显示数据的RowBuf对象,
for(Row = 0; Row<buf.GetRowCount() ;Row++){
if(SchedQ->IsEOF() || SchedQ->IsBOF())break;
var.vt=VT_I4;
var.lVal=SchedQ->m_WorkCodeID;
if(buf.GetColumnCount()>0)buf.SetValue(Row, 0,var);
COleVariant olvi(SchedQ->m_TimeIn);
var=*((LPVARIANT)olvi);
if(buf.GetColumnCount()>1)buf.SetValue(Row, 1,var);
COleVariant olvo(SchedQ->m_TimeOut);
var=*((LPVARIANT)olvo);
if(buf.GetColumnCount()>2)buf.SetValue(Row, 2,var);
// Set book using CurRow which is also our
// array index
var.vt=VT_BSTR;
BstrFromVector(((LPVARIANT)SchedQ->GetBook())->parray,&var.bstrVal);
buf.SetBook(Row,var);
RowsFetched++;
if(ReadPriorRows)SchedQ->MovePrev();
else SchedQ->MoveNext();
}
buf.SetRowCount(RowsFetched);
}
void CMyView::OnUnboundWriteDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* WriteLocation)
{
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
COleVariant var;
CString str;
try{
VectorFromBstr(WriteLocation->bstrVal,&varbok.parray);
SchedQ->SetBook(COleVariant(varbok));
}catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
//**********************************************************************
//Here was a portion of code that validated the record
//************************************************//只有被修改过的列更新,否则,值被设置为NULL
try{
SchedQ->Edit();
}
catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
if(buf.GetValue(0L, 0).vt!=VT_NULL){
var=buf.GetValue(0, 0);
str=CString(var.bstrVal);
SchedQ->m_WorkCodeID=atol(str);
}
if(buf.GetValue(0L, 1).vt!=VT_NULL){
var=buf.GetValue(0, 1);
str=CString(var.bstrVal);
SchedQ->m_TimeIn.ParseDateTime(str);
}
if(buf.GetValue(0L, 2).vt!=VT_NULL){
var=buf.GetValue(0, 2);
str=CString(var.bstrVal);
SchedQ->m_TimeOut.ParseDateTime(str);
}
try{
SchedQ->Update();
}catch(CDaoException *e){
SchedQ->CancelUpdate();
e->Delete();
buf.SetRowCount(0);
}
}
void CMyView::OnUnboundAddDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* NewRowBook)
{
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
COleVariant var;
CString str;
NewRowBook->vt=VT_NULL;
//**********************************************************************
//Here was a portion of code that validated the record
//**********************************************************************
try{
SchedQ->AddNew();
SchedQ->Update();
SchedQ->SetBook(SchedQ->GetLastModifiedBook());
SchedQ->Edit();
}catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
SchedQ->m_EmployeeID=m_pSet->m_EmployeeID;
try{
if(buf.GetValue(0L, 0).vt!=VT_NULL){
var=buf.GetValue(0, 0);
}else{
var.vt=VT_I4;
var.lVal=0;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_WorkCodeID=atol(str);
if(buf.GetValue(0L, 1).vt!=VT_NULL){
var=buf.GetValue(0, 1);
}else{
var.vt=VT_I4;
var.lVal=1;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_TimeIn.ParseDateTime(str);
if(buf.GetValue(0L, 2).vt!=VT_NULL){
var=buf.GetValue(0, 2);
}else{
var.vt=VT_I4;
var.lVal=2;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_TimeOut.ParseDateTime(str);
var.vt=VT_I4;
SchedQ->Update();
}catch(CDaoException *e){
e->Delete();
SchedQ->CancelUpdate();
SchedQ->Delete();
buf.SetRowCount(0);
}
NewRowBook->vt=VT_BSTR;
BstrFromVector(((LPVARIANT)SchedQ->GetBook())->parray,&(NewRowBook->bstrVal));
}
void CMyView::OnUnboundDeleteRowDbgridMy(VARIANT FAR* Book)
{
// TODO: Add your control notification handler code here
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
VectorFromBstr(Book->bstrVal,&varbok.parray);
try{
SchedQ->SetBook(COleVariant(varbok));
SchedQ->Delete();
}catch(CDaoException* e){
Book->vt=VT_NULL;
e->Delete();
}
}