用TRUE DBGRID控件时,在COLUMN中的ITEMS里调用函数ADD(LPDISPATCH item);这个LPDISPATCH类型数据如何生成呢?

解决方案 »

  1.   

    LPDISPATCH是一个DISPATH的指针.具体的使用你可以参考:
    在无绑定模式下使用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();

    } 
      

  2.   

    http://www.asp112.com/xxxx/3897/3897347.htm