`
Jack Wu
  • 浏览: 887480 次
  • 来自: ...
社区版块
存档分类
最新评论

VC--操作HTML的TABLE的样例代码

阅读更多

#include "stdafx.h"
#include "sreport.h"
#include "SHTMLReport.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSHTMLReport::CSHTMLReport()
{
 m_pHtmlDoc2=NULL;
 m_iHeadLines=1;
}

CSHTMLReport::~CSHTMLReport()
{

}

//***********************************************
// 指定HTML文档接口
//**********************************************
void CSHTMLReport::SetHtmlDocPtr(IHTMLDocument2 *pDoc)
{
 m_pHtmlDoc2=pDoc;
}

//***********************************************
// 指定操作的表的名称,表名称在HTML模板中指定
//*********************************************
void CSHTMLReport::SetTableName(CString name)
{
 m_strTableName=name;
}

//**************************************************
// 获取HTML表格COM接口,内部接口
//**************************************************
IHTMLTable * CSHTMLReport::GetTableDispatch()
{
 ASSERT(m_pHtmlDoc2);
 IHTMLElementCollection *all;
 m_pHtmlDoc2->get_all(&all);
 IDispatch *distable;
 all->item(COleVariant(m_strTableName),COleVariant(short(0)),&distable);
 IHTMLTable *pITable=NULL;
 HRESULT hr=distable->QueryInterface(IID_IHTMLTable, (void**)&pITable);//get table dispatch
 ASSERT(hr==S_OK);
 return pITable;
}

//*******************************************************
// 在指定位置插入一行,index==-1表示append
//*******************************************************
BOOL CSHTMLReport::InsertRow(int index)
{
 IHTMLTable *pITable=GetTableDispatch();
 IDispatch *disrow;
 HRESULT hr=pITable->insertRow(index,&disrow);//insert a  row at 1 position
 if(hr!=S_OK) return FALSE;

 IHTMLTableRow *pIRow;
 hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
 ASSERT(hr==S_OK);
 
 long cols;
 hr=pITable->get_cols(&cols);
 ASSERT(hr==S_OK&&cols!=0);
 
 IDispatch *discell;
 IHTMLElement *cell;

 CString str= " ";
 BSTR bsStr = str.AllocSysString();
 for(int i=0;i<cols;i++)
 {
  pIRow->insertCell(i,&discell);
  discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
  cell->put_innerHTML(bsStr);
  cell->Release();
  discell->Release();
 }
 SysFreeString(bsStr);
 pIRow->Release();

 if(!m_strIndexFormat.IsEmpty())
 {
  IHTMLElementCollection *irows;
  hr=pITable->get_rows(&irows);
  ASSERT(hr==S_OK);
  long rows;
  hr=irows->get_length(&rows);
  ASSERT(hr==S_OK);
  CString strHead="";
  if(index==-1) index=rows-1;
  for(long i=index;i<rows;i++)
  {
   strHead.Format(m_strIndexFormat,i);
   BSTR bsStrHead=strHead.AllocSysString();
   hr=irows->item(COleVariant(long(i)),COleVariant(long(0)),&disrow);
   ASSERT(hr==S_OK);
   //get row interface
   hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
   ASSERT(hr==S_OK);
   IHTMLElementCollection *icells;
   hr=pIRow->get_cells(&icells);
   ASSERT(hr==S_OK);
   hr=icells->item(COleVariant(long(0)),COleVariant(long(0)),&discell);
   ASSERT(hr==S_OK);
   discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
   ASSERT(hr==S_OK);
   cell->put_innerText(bsStrHead);
   SysFreeString(bsStrHead);
   cell->Release();
   pIRow->Release();
   disrow->Release();
  }
  irows->Release();
 }

 pIRow->Release();
 disrow->Release();
 pITable->Release();
 return TRUE;
}

//***************************************************************
// 修改单元格的内容:可以使用html语法
//***************************************************************
BOOL CSHTMLReport::SetItemHTML(int iRow, int iCol, CString html)
{
 IHTMLTable *pITable=GetTableDispatch();
 //get row collect
 IHTMLElementCollection *pIRows;
 HRESULT hr=pITable->get_rows(&pIRows);
 ASSERT(hr==S_OK);
 //get specisfied row
 IDispatch *disrow;
 hr=pIRows->item(COleVariant(long(iRow)),COleVariant(short(0)),&disrow);//iRow row
 if(hr!=S_OK||disrow==NULL) return FALSE;

 IHTMLTableRow *pIRow;
 hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
 ASSERT(hr==S_OK);
 //get cell collect
 IHTMLElementCollection *rowcells;
 pIRow->get_cells(&rowcells);
 //get cell
 IDispatch *discell;
 IHTMLElement *cell;
 hr=rowcells->item(COleVariant(long(iCol)),COleVariant(short(0)),&discell);//iCol col
 if(hr!=S_OK||discell==NULL) return FALSE;
 hr=discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
 ASSERT(hr==S_OK);

 BSTR bsStr = html.AllocSysString();
 cell->put_innerHTML(bsStr);
 SysFreeString(bsStr);
 
 cell->Release();
 pIRow->Release();
 pITable->Release();
 return TRUE;
}

//************************************************
// 删除指定行
//************************************************
BOOL CSHTMLReport::DeleteRow(int index)
{
 IHTMLTable *pITable=GetTableDispatch();
 HRESULT hr=pITable->deleteRow(index);
 pITable->Release();
 return hr==S_OK;
}

//************************************************
// 将指定行数据相同的单元格合并
//************************************************
BOOL CSHTMLReport::MergeRow(int iRow)
{
 IHTMLTable *pITable=GetTableDispatch();
 //get row collect
 IHTMLElementCollection *pIRows;
 HRESULT hr=pITable->get_rows(&pIRows);
 ASSERT(hr==S_OK);
 //get specisfied row
 IDispatch *disrow;
 hr=pIRows->item(COleVariant(long(iRow)),COleVariant(short(0)),&disrow);//iRow row
 if(hr!=S_OK||disrow==NULL) return FALSE;

 IHTMLTableRow *pIRow;
 hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
 ASSERT(hr==S_OK);
 //get cell collect
 IHTMLElementCollection *rowcells;
 pIRow->get_cells(&rowcells);
 long cells;
 hr=rowcells->get_length(&cells);

 IDispatch *discell;
 IHTMLElement *icellElement;
 long begin=-1,end=-1;
 CString beginStr;
 CString cellStr;
 long    beginRowSpan=0,rowSpan;
 for(long i=m_strIndexFormat.IsEmpty()?0:1;i<cells;i++)
 {
  //get cell
  hr=rowcells->item(COleVariant(long(i)),COleVariant(short(0)),&discell);
  ASSERT(hr==S_OK&&discell!=NULL);
  hr=discell->QueryInterface(IID_IHTMLElement,(void **)&icellElement);
  ASSERT(hr==S_OK&&icellElement!=NULL);
  
  cellStr=GetElementText(icellElement,inner_text);
  IHTMLTableCell *icell;
  hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
  ASSERT(hr==S_OK&&icell!=NULL);
  icell->get_rowSpan(&rowSpan);
  if(cellStr!=beginStr||rowSpan!=beginRowSpan)
  {
   if(end-begin+1>1&&begin!=-1)
   {
    ASSERT(beginRowSpan!=0);
    MergeRowPrivate(pIRow,begin,end);
    cells-=end-begin;
    i-=end-begin;
   }
   begin=end=i;
   beginStr=cellStr;
   beginRowSpan=rowSpan;
  }else
   end=i;
  icell->Release();
  icellElement->Release();
 }

 if(begin!=end)
  MergeRowPrivate(pIRow,begin,end);
 pIRow->Release();
 pITable->Release();
 return TRUE;
}

//************************************************
// 将指定列数据相同的单元格合并
//************************************************
BOOL CSHTMLReport::MergeCol(int iCol)
{
 IHTMLTable *pITable=GetTableDispatch();
 //get row collect
 IHTMLElementCollection *pIRows;
 HRESULT hr=pITable->get_rows(&pIRows);
 ASSERT(hr==S_OK);
 CSArray<COLCELLINFO> colArray;
 if(!MakeColDispatchCollection(pIRows,iCol,colArray)) return FALSE;
 int colCells=colArray.GetSize();
 COLCELLINFO cci;
 CString beginStr,cellStr;
 long beginColSpan=0,colSpan;
 int  begin=-1,end;
 for(int i=0;i<colCells;i++)
 {
  cci=colArray.GetAt(i);
  if(cci.pDisCell==NULL)
   continue;
  IHTMLElement *icellElement;
  hr=cci.pDisCell->QueryInterface(IID_IHTMLElement,(void **)&icellElement);
  ASSERT(hr==S_OK&&icellElement!=NULL);
  cellStr=GetElementText(icellElement,inner_text);
  IHTMLTableCell *icell;
  hr=cci.pDisCell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
  ASSERT(hr==S_OK&&icell!=NULL);
  hr=icell->get_colSpan(&colSpan);
  if(cellStr!=beginStr||colSpan!=beginColSpan)
  {
   if(begin!=-1&&end-begin+1>1)
   {
    ASSERT(beginColSpan!=0);
    MergeColPrivate(pIRows,colArray,begin,end);
   }
   begin=end=i;
   beginStr=cellStr;
   beginColSpan=colSpan;
  }else
   end=i;
  icell->Release();
  icellElement->Release();
 }
 if(begin!=end)
  MergeColPrivate(pIRows,colArray,begin,end);
 pITable->Release();
 return TRUE;
}

//***********************************************
// 设置索引列的显示格式:遵循sprintf函数的规则
//***********************************************
void CSHTMLReport::SetIndexFormat(CString strIndexFormat)
{
 m_strIndexFormat=strIndexFormat;
}

//*************************************************
// 获取元素的字符
//*************************************************
CString CSHTMLReport::GetElementText(IHTMLElement *pElement, int type)
{
 CString str= "";
 BSTR bsStr = str.AllocSysString();
 switch(type)
 {
 case inner_text:
  pElement->get_innerText(&bsStr);
  break;
 case inner_html:
  pElement->get_innerHTML(&bsStr);
  break;
 case outer_text:
  pElement->get_outerText(&bsStr);
  break;
 case outer_html:
  pElement->get_outerHTML(&bsStr);
  break;
 default:
  ASSERT(0);
  break;
 }
 _bstr_t bstStr;
 bstStr = bsStr;
 str.Format("%s",(LPCTSTR)bstStr);
 SysFreeString(bsStr);
 return str;
}

//********************************************************
// 设置元素字符
//*******************************************************
BOOL CSHTMLReport::SetElementText(IHTMLElement *pElement, int type,CString str)
{
 BSTR bsStr = str.AllocSysString();
 HRESULT hr;
 switch(type)
 {
 case inner_text:
  hr=pElement->put_innerText(bsStr);
  break;
 case inner_html:
  hr=pElement->put_innerHTML(bsStr);
  break;
 case outer_text:
  hr=pElement->put_outerText(bsStr);
  break;
 case outer_html:
  hr=pElement->put_outerHTML(bsStr);
  break;
 default:
  ASSERT(0);
  break;
 }
 SysFreeString(bsStr);
 return (hr==S_OK);
}

//******************************************************************
// 在指定的行中从指定的起始及终止位置进行合并:内部函数
//******************************************************************
void CSHTMLReport::MergeRowPrivate(IHTMLTableRow *pIRow, long begincol, long endcol)
{
 long   colSpan=0;
 IHTMLElementCollection *picells;
 HRESULT hr=pIRow->get_cells(&picells);
 for(long i=endcol;i>=begincol;i--)
 {
  IDispatch *discell;
  hr=picells->item(COleVariant(i),COleVariant(short(0)),&discell);
  ASSERT(hr==S_OK&&discell!=NULL);
  IHTMLTableCell *picell;
  hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&picell);
  ASSERT(hr==S_OK&&picell!=NULL);
  long tmpColSpan;
  picell->get_colSpan(&tmpColSpan);
  colSpan+=tmpColSpan;
  if(i==begincol)
   picell->put_colSpan(colSpan);
  else
   pIRow->deleteCell(i);
  picell->Release();
 }
}

//******************************************************************
// 在指定的行集中对指定列从指定的起始及终止位置进行合并:内部函数
//******************************************************************
void CSHTMLReport::MergeColPrivate(IHTMLElementCollection *pIRowArray,CSArray<COLCELLINFO> &colArray,long beginrow, long endrow)
{
 IHTMLTableCell *ibegincell=NULL;
 long   rowSpan=0;
 for(int i=beginrow;i<=endrow;i++)
 {
  IHTMLTableCell *icell;
  COLCELLINFO cci=colArray.GetAt(i);
  ASSERT(cci.iIndexInRow!=-1);
  IDispatch *disrow;
  HRESULT hr=pIRowArray->item(COleVariant(cci.iRow),COleVariant(short(0)),&disrow);//iRow row
  if(hr!=S_OK||disrow==NULL) return ;
  IHTMLTableRow *pIRow;
  hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
  ASSERT(hr==S_OK);
  //get cell collection
  IHTMLElementCollection *rowcells;
  pIRow->get_cells(&rowcells);
  //get cell element
  IDispatch *discell;
  hr=rowcells->item(COleVariant(cci.iIndexInRow),COleVariant(short(0)),&discell);
  ASSERT(hr==S_OK&&discell!=NULL);
  
  hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
  ASSERT(hr==S_OK&&icell!=NULL);
  long       tmpRowSpan;
  hr=icell->get_rowSpan(&tmpRowSpan);
  ASSERT(hr==S_OK);
  rowSpan+=tmpRowSpan;
  if(i==beginrow)
  {
   ibegincell=icell;
  }else{
   icell->Release();          
   if(cci.iIndexInRow!=-1)
    pIRow->deleteCell(cci.iIndexInRow);
  }
  pIRow->Release();
 }
 ibegincell->put_rowSpan(rowSpan);
 ibegincell->Release();
}

//******************************************************************
// 构造指定列的集合:内部函数
//******************************************************************
BOOL CSHTMLReport::MakeColDispatchCollection(
 IHTMLElementCollection *pIRowArray/*in*/,
 long iCol/*in*/,
 CSArray<COLCELLINFO> &colArray/*out*/)
{
 long rows;
 HRESULT hr=pIRowArray->get_length(&rows);
 ASSERT(hr==S_OK);
 IHTMLElementCollection **rowcellsarray =new IHTMLElementCollection *[rows];

 //get cell collect array
 for(int j=0;j<rows;j++)
 {
  //get specisfied row
  IDispatch *disrow;
  hr=pIRowArray->item(COleVariant(long(j)),COleVariant(short(0)),&disrow);//iRow row
  if(hr!=S_OK||disrow==NULL) return FALSE;
  IHTMLTableRow *pIRow;
  hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
  ASSERT(hr==S_OK);
  //get cell collection
  pIRow->get_cells(&rowcellsarray[j]);
  pIRow->Release();
 }
 
 struct colindexinfo{
  long index; //在行中的索引
  long iCol; //在列中的索引
  long colSpan;//列跨越
 };
 struct colindexinfo *ciis=new struct colindexinfo[rows];
 memset(ciis,0,rows*sizeof(struct colindexinfo));

 for(j=1;j<=iCol;j++)//追踪到第iCol列:初始化的数据即为第一列的数据,不需要计算
 {
  for(int k=0;k<rows;k++)
  {
   if(ciis[k].iCol+ciis[k].colSpan>j) continue;
   IDispatch *discell;
   hr=rowcellsarray[k]->item(COleVariant(ciis[k].index),COleVariant(short(0)),&discell);
   ASSERT(hr==S_OK&&discell!=NULL);
   IHTMLTableCell *icell;
   hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
   ASSERT(hr==S_OK&&icell!=NULL);
   long colSpan,rowSpan;
   hr=icell->get_colSpan(&colSpan);
   ASSERT(hr==S_OK);
   hr=icell->get_rowSpan(&rowSpan);
   icell->Release();

   ciis[k].index++;
   ciis[k].iCol+=colSpan;
   ciis[k].colSpan=colSpan-1;
   for(int kk=k+1;kk<k+rowSpan;kk++)
   {
    if(ciis[kk].iCol+ciis[kk].colSpan>j){
     delete []ciis;
     delete []rowcellsarray;
     return FALSE;
    }
    ciis[kk].iCol++;
    ciis[kk].colSpan=0;
   }
   k+=rowSpan-1;
  }
 }
 for(int i=0;i<rows;i++)
 {
  if(ciis[i].colSpan){
   COLCELLINFO cci={i,NULL,-1};
   colArray.Add(cci);
   continue;
  }
  IDispatch *discell;
  hr=rowcellsarray[i]->item(COleVariant(ciis[i].index),COleVariant(short(0)),&discell);
  ASSERT(hr==S_OK&&discell!=NULL);
  IHTMLTableCell *icell;
  hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
  ASSERT(hr==S_OK&&icell!=NULL);
  long rowSpan;
  hr=icell->get_rowSpan(&rowSpan);
  icell->Release();

  COLCELLINFO cci;
  cci.iRow=i;
  cci.iIndexInRow=ciis[i].index;
  cci.pDisCell=discell;
  colArray.Add(cci);
  i+=rowSpan-1;
 }
 delete []ciis;
 delete []rowcellsarray;
 return TRUE;
}

 
分享到:
评论

相关推荐

    VC代码 fterm-smth (实用代码源)

    VC代码 fterm-smth (实用代码源)VC代码 fterm-smth (实用代码源)VC代码 fterm-smth (实用代码源)VC代码 fterm-smth (实用代码源)VC代码 fterm-smth (实用代码源)VC代码 fterm-smth (实用代码源)VC代码 fterm-smth ...

    VC代码 文件夹监视--FileWatcherTest (实用代码源)

    VC代码 文件夹监视--FileWatcherTest (实用代码源)VC代码 文件夹监视--FileWatcherTest (实用代码源)VC代码 文件夹监视--FileWatcherTest (实用代码源)VC代码 文件夹监视--FileWatcherTest (实用代码源)VC代码 ...

    VC代码 camfr-1.2 (实用代码源)

    VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码源)VC代码 camfr-1.2 (实用代码...

    RTL8214FC-VC-CG规格书

    RTL8214FC-VC-CG是一款高性能的芯片,可以集成设计24*GE+4 SPF千兆交换机

    VC-MFC编程实例

    [VC-MFC编程实例].01 [VC-MFC编程实例].02 [VC-MFC编程实例].03 [VC-MFC编程实例].04 [VC-MFC编程实例].05 [VC-MFC编程实例].06 [VC-MFC编程实例].07 [VC-MFC编程实例].08 [VC-MFC编程实例].09 [VC-MFC编程实例].10 ...

    VC代码 QuantLib-0.3.14.tar (实用代码源)

    VC代码 QuantLib-0.3.14.tar (实用代码源)VC代码 QuantLib-0.3.14.tar (实用代码源)VC代码 QuantLib-0.3.14.tar (实用代码源)VC代码 QuantLib-0.3.14.tar (实用代码源)VC代码 QuantLib-0.3.14.tar (实用代码源)VC...

    VC代码 mozilla-19980728.tar (实用代码源)

    VC代码 mozilla-19980728.tar (实用代码源)VC代码 mozilla-19980728.tar (实用代码源)VC代码 mozilla-19980728.tar (实用代码源)VC代码 mozilla-19980728.tar (实用代码源)VC代码 mozilla-19980728.tar (实用代码源)...

    vc-common-src v2.3.1 -> HP-Socket 和 VC-Logger 的公共库代码

    ========================================================================================== v2.3.1 更新: ========================================================================================== ...

    VC代码 boost-1_20_2 (实用代码源)

    VC代码 boost-1_20_2 (实用代码源)VC代码 boost-1_20_2 (实用代码源)VC代码 boost-1_20_2 (实用代码源)VC代码 boost-1_20_2 (实用代码源)VC代码 boost-1_20_2 (实用代码源)VC代码 boost-1_20_2 (实用代码源)VC代码 ...

    VC-自由拼音输入法源代码

    《VC-自由拼音输入法源代码》是一款基于Visual C++(简称VC)开发的开源拼音输入法项目。这个项目的源代码提供了对自由拼音输入法的实现细节,为开发者提供了深入理解输入法工作原理以及如何利用VC进行编程的宝贵...

    ffmpeg-0.8.11-vc-sdk

    ffmpeg-0.8.11-vc-sdk,是使用ffmpeg 转换vc项目工具生成VC工程编译的 release 版本的sdk。因为编译器的问题导致sse开启的时候会导致程序崩溃,所以屏蔽了sse优化.其他的优化还是有了,config.h里面看到我屏蔽了其他...

    VC-LTL-4.0.1.10-Binary-VS2019.7z

    VC-LTL是一个基于微软VC修改的开源运行时,有效减少应用程序体积并摆脱微软运行时DLL,比如msvcr120.dll、api-ms-win-crt-time-l1-1-0.dll等依赖。 VC-LTL最初是Dism++专用运行时。2017年3月6号从Dism++源代码中...

    Visual Studio 2015-2022 VC-redist运行库

    如果你遇到了“在VS开发的exe应用程序在他人的电脑无法运行”的问题,那么你就需要在该电脑上安装这个VC redistribution 运行库。这样就可以在其他电脑上运行之前无法运行的应用程序啦! 联系作者 邮箱:QSQ...

    VC6.0的四种清屏函数代码-程序员SUMER

    VC6.0的四种清屏函数代码--程序员SUMER VC6.0的四种清屏函数代码--程序员SUMER VC6.0的四种清屏函数代码--程序员SUMER VC6.0的四种清屏函数代码--程序员SUMER VC6.0的四种清屏函数代码--程序员SUMER VC6.0的四种清屏...

    策略为王源代码无删减版本-vc++6.0-可以升级到vc2024-64位

    策略为王源代码无删减版本------vc++6.0-------可以升级到vc2024-----64位---- 策略为王源代码无删减版本------vc++6.0-------可以升级到vc2024-----64位---- 策略为王源代码无删减版本------vc++6.0-------可以升级...

    VC-Excel多文件操作源代码

    首先,"VC-Excel多文件操作源代码"的核心在于利用MFC对Excel的自动化接口进行编程。MFC是微软提供的一套面向对象的C++库,它为Windows API提供了一种封装,使得开发者可以更加方便地编写Windows应用程序。在这个项目...

    VC发送邮件完整样例代码

    这个“VC发送邮件完整样例代码”提供了一个完整的示例,帮助开发者理解如何利用C++编程语言和Microsoft Visual C++集成开发环境(IDE)来实现邮件的发送功能。下面我们将详细探讨这个过程中的关键知识点。 首先,要...

    php-7.3.0-Win32-VC15-x64.zip+VC环境

    标题中的"php-7.3.0-Win32-VC15-x64.zip"表明这是一款针对Windows操作系统,基于Visual C++ 15编译器(VC15)构建的64位PHP 7.3.0版本。这个版本的PHP在2018年发布,带来了性能提升和一些新特性,比如对箭头函数的...

    VC代码 mtl-2.1.2-21 (实用代码源).rar

    VC代码 mtl-2.1.2-21 (实用代码源).rarVC代码 mtl-2.1.2-21 (实用代码源).rarVC代码 mtl-2.1.2-21 (实用代码源).rarVC代码 mtl-2.1.2-21 (实用代码源).rarVC代码 mtl-2.1.2-21 (实用代码源).rarVC代码 mtl-2.1.2-21 ...

Global site tag (gtag.js) - Google Analytics