在Visual Basic 中使用C++ 類 (轉)
在Visual Basic 中使用C++ 類 (轉)[@more@]在 中使用C++ 類
用C++ Builder 建立可重用的OLE Automation
李國興
我在Borland C++ For 環境下編制工程輔肋設計時定義了一個生成AutoCAD DXF 圖形的類,在後來用Visual Basic 編寫另一輔肋設計程式時又需要生成DXF圖形檔案,為了利用已有的程式碼,我在Borland C++ Builder 3.0 中將普通的C++類轉換成Automation 程式內,供Visual basic 使用,成功地實現了不同語言源程式級的重用。現將轉換方法簡單地介紹給大家。供大家參考。
原C++ 類宣告如下: (為節約篇幅,進行了大量簡化只實現基本功能)
class Dxf{
private:
HFILE handle; //DXF 檔案頭
String SecStart; //節頭
String SecEnd; //節尾
String Tables; //表節串
String Blocks; //塊節串
String Entities; //實體節串
protected:
bool WriteTitleSec(); //寫標題節
bool WriteBlockSec(); //寫塊節
bool WriteEntitiesSec(); //寫實體節
public:
Dxf();
bool SaveToFile(char *filename); // 儲存資料到檔案
void Dxf_Line(float x1,float y1,float x2,float y2,int Layer=0); // 畫直線
};
將C++類轉換成程式內伺服器的過程如下:
1. 開啟BorLand C++ Builder 3.0 的整合開發環境,選擇File選單下的new 子選單,C++ Builder 將開啟專案選擇視窗,選擇 頁面,在Active 頁面中選擇Active Library。然後再選擇File選單下的new 子選單,選擇ActiveX 頁面,在Active 頁面中選擇Automation object 開啟Automation Object Wizard 對話方塊,在Class name 框中填入DxfCls 作為在VB中引用Dxf 類的類名,單點Ok 完成。C++ Builder 3.0 將建立型別庫,完成工程的建立。並開啟型別庫編輯視窗。(一點說明,由於BorLand C++ Builder在建立Automation Object 時,預設是建立程式外的自動化伺服器,在此我僅需的是作為DLL的程式內的自動化伺服器,因此要首先創造一外型別庫,再把自動化伺服器加到型別庫中去。
2. 選擇將工程以DxfCls 名存檔,並將unit1以Dxf存檔。
3. 在型別庫編輯窗中的Attributes頁中將Name 中的project1 改為Dxf,將Help組框中的Help string 改為dxf Library,此字串將在的引用選擇窗中顯示。其它不用修改。
4. 將原Dxf 類中的除構造和析構以外的暴露給VB,其方法是選擇Idxfcls節點,單擊工具欄上的Method,然後在Attributes 頁上將name對話方塊中Method1修改為您所需要的函式名,再選擇Parameters 頁設定函式的返回資料型別和型參。在選擇返回資料時,注意下拉選單框中不直接支援bool 作為返回型別,您可以選擇short或者選擇Varian_bool 作為返回型別,在這裡我選擇short來替代bool 作為返回型別。此外型參表中的前兩項對應通常C函式中的資料名和資料型別,資料型別以下拉選單的型式選擇。如果要設定函式的預設形參可雙擊第三個引數,此時將彈出parameters Flags 編輯窗,在編輯窗中選中has default value ,在下面的編輯框中填入預設資料。
5. 單擊工具欄上的Refresh, 編輯器自動在您的Dxf.cpp和dxf.h中新增上您在型別庫中設定的函式宣告。
6. 開啟dxf.cpp檔案,您可在找到SaveToFile等函式的宣告如下:
short STDMETHODCALLTYPE TDxfClsImpl::SaveToFile(LPSTR filename)
{
try
{
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IDxfCls);
}
return S_OK;
};
將原dxf.cpp中的已暴露的函式的實現部分貼上到新的dxf.cpp 中的各函式的try 部分,並修改錯誤處理程式碼和返回資料。其它私有函式直接貼上到新的檔案中,僅修改函式名前的類名。
7. 開啟原dxf.h檔案,將類的宣告部分中除已暴露的函式以外的其它部分貼上到剪粘板,然後再開啟當前工程的dxf.h視窗,將剪貼簿的內容複製到TdxfClsImpl類中間。
8. 選擇project選單中的make dxfcls 將工程編譯成DLL檔案。至此完成了C++中的普通類到自動化伺服器的遷移。
9. 選擇Run 選單下的Register ActiveX server, 對dxf 進行註冊。以後就可以在VB中使用dxf 類了。
10. 在VB5.0中使用,在Visual Basic 專案中,選擇工程|引用,開啟引用視窗,選中dxf library 庫,按確認後返回,然後開啟檢視|物件遊覽器,開啟所有庫下拉選單後選擇dxf,再選擇dxfcls就可以見到以上所暴露的SaveToFile和Dxf_line 函式。VB 工程中可以用Dim dxf as new dxfcls 建立引用了。新的dxf 實現類的宣告和實現如下,標頭檔案中的細體字是C++ Bulr 3.0 自動生成,粗體字是新增的。讀者可與C++ Bulider 3.0 自動生成檔案對照。 為了節約篇幅,自動生成的註釋已去掉。
附一. Dxf.h 標頭檔案
#ifndef dxfH
#define dxfH
#include
#include
//---------------------------------------------------------------------------
#include "Dxf_TLB.h"
#define LIBID_DxfCls LIBID_Dxf
class ATL_NO_VTABLE TDxfClsImpl:
AUTOOBJECT_IMPL(TDxfClsImpl, DxfCls, IDxfCls)
{
public:
TDxfClsImpl();
BEGIN_COM_MAP(TDxfClsImpl)
AUTOOBJECT_COM_INTERFACE_ENTRIES(IDxfCls)
END_COM_MAP()
DECLARE_TYPED_COMSERVER_REGISTRY("Dxf.DxfCls")
private:
HFILE handle;
int Vports;
int LayerNum;
String SecStart;
String SecEnd;
String Tables;
String Blocks;
String Entities;
void WriteTitleSec();
void WriteBlockSec();
void WriteEntitiesSec();
protected:
short STDMETHODCALLTYPE SaveToFile(LPSTR filename);
STDMETHOD(Dxf_Line(float x1, float y1, float x2, float y2, short Layer));
};
#endif
附二. dxf.cpp檔案
#include
#pragma hdrstop
#include
#include
#include "dxf.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TDxfClsImpl::TDxfClsImpl()
{
SecStart=" 0nSECTIONn";
SecEnd=" 0nENDSECn";
Vports=2;
LayerNum=1;
Tables=" 2nTABLESn 0nTABLEn 2nVPORTn 70n";
Blocks=" 2nBLOCKSn";
Entities=" 2nENTITIESn";
}
void TDxfClsImpl::WriteTitleSec()
{
write(handle, SecStart.c_str(), SecStart.Length()); // 寫節頭
write(handle," 2nHEADERn",strlen(" 2nHEADERn"));
write(handle, SecEnd.c_str(),SecEnd.Length()); // 寫節尾
}
void TDxfClsImpl::WriteBlockSec()
{
write(handle,SecStart.c_str(), SecStart.Length()); // 寫節頭
write(handle,Blocks.c_str(),Blocks.Length());
write(handle,SecEnd.c_str(),SecEnd.Length()); // 寫節尾
}
void TDxfClsImpl::WriteEntitiesSec() // 寫實體節
{
write(handle, SecStart.c_str(), SecStart.Length());
write(handle,Entities.c_str(),Entities.Length());
write(handle, SecEnd.c_str(),SecEnd.Length());
}
short STDMETHODCALLTYPE TDxfClsImpl::SaveToFile(LPSTR filename)
{
int i;
try {
if (FileExists(filename)){
i=FileGetAttr(filename);
if (i& faReadOnly)
FileSetAttr(filename,i&0xFE);
DeleteFile(filename); }
handle=open(filename,O_CREAT|O_TEXT|O_RDWR);
if (handle==-1) return false;
WriteTitleSec(); //寫標題節
WriteBlockSec();
WriteEntitiesSec();
write(handle," 0nEOFn",strlen(" 0nEOFn"));
close(handle);
}
catch(Exception &e)
{
return false;
}
return true;
};
//---------------------------------------------------------------------------
STDMETHODIMP TDxfClsImpl::Dxf_Line(float x1, float y1, float x2, float y2,
short Layer)
{
char buffer[16];
try {
Entities+=" 0nLINEn 8n";
Entities+=IntToStr(Layer);
Entities+="n 10n";
sprintf(buffer,"%6.1f",x1);
Entities+=buffer;
Entities+="n 20n";
sprintf(buffer,"%6.1f",y1);
Entities+=buffer;
Entities+="n 30n 0.0n 11n";
sprintf(buffer,"%6.1f",x2);
Entities+=buffer;
Entities+="n 21n";
sprintf(buffer,"%6.1f",y2);
Entities+=buffer;
Entities+="n 31n 0.0n"; }
catch(Exception &e) {
return Error(e.Message.c_str(), IID_IDxfCls);
}
return S_OK;
};
附三 示例:
在VB 5 中建一新視窗,在視窗上放一Commanutton,命名為cmdCreate,然後輸入以下程式碼,執行後,單擊cmdCreate,就可生成基本的AutoCAD下使用的.DXF檔案。
Private Sub cmdCreate_Click()
Dim Dxf As New DxfCls
Dxf.Dxf_Line 100, 100, 500, 100
Dxf.SaveToFile App.Path & "dxftest.dxf"
End Sub
以上程式分別在Borland C++ Builder 3 Server/Client suit 和VB 5.0 專業版下執行透過。生成的dxftest.dxf在AutoCAD for windows 12 下顯示圖形正常。
一點體會:現在各種語言都提供了建立OLE Automation 伺服器的功能,為我們重用以前的程式碼和利用各種語言進行混合提供了方便。我們可利用各種語言的特點,地開發出高效的應用。
參考:Borland C++ Builder 3 Server/Client suit 聯機幫助檔案。
用C++ Builder 建立可重用的OLE Automation
李國興
我在Borland C++ For 環境下編制工程輔肋設計時定義了一個生成AutoCAD DXF 圖形的類,在後來用Visual Basic 編寫另一輔肋設計程式時又需要生成DXF圖形檔案,為了利用已有的程式碼,我在Borland C++ Builder 3.0 中將普通的C++類轉換成Automation 程式內,供Visual basic 使用,成功地實現了不同語言源程式級的重用。現將轉換方法簡單地介紹給大家。供大家參考。
原C++ 類宣告如下: (為節約篇幅,進行了大量簡化只實現基本功能)
class Dxf{
private:
HFILE handle; //DXF 檔案頭
String SecStart; //節頭
String SecEnd; //節尾
String Tables; //表節串
String Blocks; //塊節串
String Entities; //實體節串
protected:
bool WriteTitleSec(); //寫標題節
bool WriteBlockSec(); //寫塊節
bool WriteEntitiesSec(); //寫實體節
public:
Dxf();
bool SaveToFile(char *filename); // 儲存資料到檔案
void Dxf_Line(float x1,float y1,float x2,float y2,int Layer=0); // 畫直線
};
將C++類轉換成程式內伺服器的過程如下:
1. 開啟BorLand C++ Builder 3.0 的整合開發環境,選擇File選單下的new 子選單,C++ Builder 將開啟專案選擇視窗,選擇 頁面,在Active 頁面中選擇Active Library。然後再選擇File選單下的new 子選單,選擇ActiveX 頁面,在Active 頁面中選擇Automation object 開啟Automation Object Wizard 對話方塊,在Class name 框中填入DxfCls 作為在VB中引用Dxf 類的類名,單點Ok 完成。C++ Builder 3.0 將建立型別庫,完成工程的建立。並開啟型別庫編輯視窗。(一點說明,由於BorLand C++ Builder在建立Automation Object 時,預設是建立程式外的自動化伺服器,在此我僅需的是作為DLL的程式內的自動化伺服器,因此要首先創造一外型別庫,再把自動化伺服器加到型別庫中去。
2. 選擇將工程以DxfCls 名存檔,並將unit1以Dxf存檔。
3. 在型別庫編輯窗中的Attributes頁中將Name 中的project1 改為Dxf,將Help組框中的Help string 改為dxf Library,此字串將在的引用選擇窗中顯示。其它不用修改。
4. 將原Dxf 類中的除構造和析構以外的暴露給VB,其方法是選擇Idxfcls節點,單擊工具欄上的Method,然後在Attributes 頁上將name對話方塊中Method1修改為您所需要的函式名,再選擇Parameters 頁設定函式的返回資料型別和型參。在選擇返回資料時,注意下拉選單框中不直接支援bool 作為返回型別,您可以選擇short或者選擇Varian_bool 作為返回型別,在這裡我選擇short來替代bool 作為返回型別。此外型參表中的前兩項對應通常C函式中的資料名和資料型別,資料型別以下拉選單的型式選擇。如果要設定函式的預設形參可雙擊第三個引數,此時將彈出parameters Flags 編輯窗,在編輯窗中選中has default value ,在下面的編輯框中填入預設資料。
5. 單擊工具欄上的Refresh, 編輯器自動在您的Dxf.cpp和dxf.h中新增上您在型別庫中設定的函式宣告。
6. 開啟dxf.cpp檔案,您可在找到SaveToFile等函式的宣告如下:
short STDMETHODCALLTYPE TDxfClsImpl::SaveToFile(LPSTR filename)
{
try
{
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IDxfCls);
}
return S_OK;
};
將原dxf.cpp中的已暴露的函式的實現部分貼上到新的dxf.cpp 中的各函式的try 部分,並修改錯誤處理程式碼和返回資料。其它私有函式直接貼上到新的檔案中,僅修改函式名前的類名。
7. 開啟原dxf.h檔案,將類的宣告部分中除已暴露的函式以外的其它部分貼上到剪粘板,然後再開啟當前工程的dxf.h視窗,將剪貼簿的內容複製到TdxfClsImpl類中間。
8. 選擇project選單中的make dxfcls 將工程編譯成DLL檔案。至此完成了C++中的普通類到自動化伺服器的遷移。
9. 選擇Run 選單下的Register ActiveX server, 對dxf 進行註冊。以後就可以在VB中使用dxf 類了。
10. 在VB5.0中使用,在Visual Basic 專案中,選擇工程|引用,開啟引用視窗,選中dxf library 庫,按確認後返回,然後開啟檢視|物件遊覽器,開啟所有庫下拉選單後選擇dxf,再選擇dxfcls就可以見到以上所暴露的SaveToFile和Dxf_line 函式。VB 工程中可以用Dim dxf as new dxfcls 建立引用了。新的dxf 實現類的宣告和實現如下,標頭檔案中的細體字是C++ Bulr 3.0 自動生成,粗體字是新增的。讀者可與C++ Bulider 3.0 自動生成檔案對照。 為了節約篇幅,自動生成的註釋已去掉。
附一. Dxf.h 標頭檔案
#ifndef dxfH
#define dxfH
#include
#include
//---------------------------------------------------------------------------
#include "Dxf_TLB.h"
#define LIBID_DxfCls LIBID_Dxf
class ATL_NO_VTABLE TDxfClsImpl:
AUTOOBJECT_IMPL(TDxfClsImpl, DxfCls, IDxfCls)
{
public:
TDxfClsImpl();
BEGIN_COM_MAP(TDxfClsImpl)
AUTOOBJECT_COM_INTERFACE_ENTRIES(IDxfCls)
END_COM_MAP()
DECLARE_TYPED_COMSERVER_REGISTRY("Dxf.DxfCls")
private:
HFILE handle;
int Vports;
int LayerNum;
String SecStart;
String SecEnd;
String Tables;
String Blocks;
String Entities;
void WriteTitleSec();
void WriteBlockSec();
void WriteEntitiesSec();
protected:
short STDMETHODCALLTYPE SaveToFile(LPSTR filename);
STDMETHOD(Dxf_Line(float x1, float y1, float x2, float y2, short Layer));
};
#endif
附二. dxf.cpp檔案
#include
#pragma hdrstop
#include
#include
#include "dxf.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TDxfClsImpl::TDxfClsImpl()
{
SecStart=" 0nSECTIONn";
SecEnd=" 0nENDSECn";
Vports=2;
LayerNum=1;
Tables=" 2nTABLESn 0nTABLEn 2nVPORTn 70n";
Blocks=" 2nBLOCKSn";
Entities=" 2nENTITIESn";
}
void TDxfClsImpl::WriteTitleSec()
{
write(handle, SecStart.c_str(), SecStart.Length()); // 寫節頭
write(handle," 2nHEADERn",strlen(" 2nHEADERn"));
write(handle, SecEnd.c_str(),SecEnd.Length()); // 寫節尾
}
void TDxfClsImpl::WriteBlockSec()
{
write(handle,SecStart.c_str(), SecStart.Length()); // 寫節頭
write(handle,Blocks.c_str(),Blocks.Length());
write(handle,SecEnd.c_str(),SecEnd.Length()); // 寫節尾
}
void TDxfClsImpl::WriteEntitiesSec() // 寫實體節
{
write(handle, SecStart.c_str(), SecStart.Length());
write(handle,Entities.c_str(),Entities.Length());
write(handle, SecEnd.c_str(),SecEnd.Length());
}
short STDMETHODCALLTYPE TDxfClsImpl::SaveToFile(LPSTR filename)
{
int i;
try {
if (FileExists(filename)){
i=FileGetAttr(filename);
if (i& faReadOnly)
FileSetAttr(filename,i&0xFE);
DeleteFile(filename); }
handle=open(filename,O_CREAT|O_TEXT|O_RDWR);
if (handle==-1) return false;
WriteTitleSec(); //寫標題節
WriteBlockSec();
WriteEntitiesSec();
write(handle," 0nEOFn",strlen(" 0nEOFn"));
close(handle);
}
catch(Exception &e)
{
return false;
}
return true;
};
//---------------------------------------------------------------------------
STDMETHODIMP TDxfClsImpl::Dxf_Line(float x1, float y1, float x2, float y2,
short Layer)
{
char buffer[16];
try {
Entities+=" 0nLINEn 8n";
Entities+=IntToStr(Layer);
Entities+="n 10n";
sprintf(buffer,"%6.1f",x1);
Entities+=buffer;
Entities+="n 20n";
sprintf(buffer,"%6.1f",y1);
Entities+=buffer;
Entities+="n 30n 0.0n 11n";
sprintf(buffer,"%6.1f",x2);
Entities+=buffer;
Entities+="n 21n";
sprintf(buffer,"%6.1f",y2);
Entities+=buffer;
Entities+="n 31n 0.0n"; }
catch(Exception &e) {
return Error(e.Message.c_str(), IID_IDxfCls);
}
return S_OK;
};
附三 示例:
在VB 5 中建一新視窗,在視窗上放一Commanutton,命名為cmdCreate,然後輸入以下程式碼,執行後,單擊cmdCreate,就可生成基本的AutoCAD下使用的.DXF檔案。
Private Sub cmdCreate_Click()
Dim Dxf As New DxfCls
Dxf.Dxf_Line 100, 100, 500, 100
Dxf.SaveToFile App.Path & "dxftest.dxf"
End Sub
以上程式分別在Borland C++ Builder 3 Server/Client suit 和VB 5.0 專業版下執行透過。生成的dxftest.dxf在AutoCAD for windows 12 下顯示圖形正常。
一點體會:現在各種語言都提供了建立OLE Automation 伺服器的功能,為我們重用以前的程式碼和利用各種語言進行混合提供了方便。我們可利用各種語言的特點,地開發出高效的應用。
參考:Borland C++ Builder 3 Server/Client suit 聯機幫助檔案。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1000361/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在Visual Basic中終止Windows 95 (轉)Windows
- 關於Visual Basic 6.0類開發(下) (轉)
- 關於Visual Basic 6.0類開發(上) (轉)
- Visual Basic的類對於物件導向的支援 (轉)物件
- 在Visual C++中使用內聯彙編 (轉)C++
- 在Visual C++中使用內聯彙編(轉)C++
- 在 Visual C++ 中 建 立 MFC 擴 展 DLL (轉)C++
- Visual Basic.NET 中的語言新變化 (轉)
- 擴 展Visual c++ MFC 類 庫 (轉)C++
- 用Visual Basic設計更好的使用者介面 (轉)
- 用Visual Basic自編小遊戲 (轉)遊戲
- Visual Basic 程式設計標準(1) (轉)程式設計
- Visual Basic for ApplicationAPP
- Visual C++中的圖形特技 (轉)C++
- 在Visual C++中利用UDL檔案建ADO連線(轉)C++
- 在Visual C++中使用fopen()函式來讀寫檔案 (轉)C++函式
- 使用Visual Basic訪問資料庫幾個注意的問題 (轉)資料庫
- 在Visual C++中使用內聯彙編C++
- Visual Basic設計圖形瀏覽器示例 (轉)瀏覽器
- Visual C++中函式呼叫方式淺探 (轉)C++函式
- C++中類及類的定義 (轉)C++
- Visual Basic 14 的 14 大新特性
- visual C++數字影像處理類C++
- 在SDK程式中使用MFC中的輔助類 (轉)
- 理解 Visual C++ Extensions for ADO(轉)C++
- Visual C++應用框架揭密 (轉)C++框架
- 特性(C# 和 Visual Basic) BASIC 快速建模特性的程式語言C#
- 在VBScript中使用類(三) (轉)
- 在VBScript中使用類(四) (轉)
- 開發整合Microsoft Visual Basic for Application的應用系統(一) (轉)ROSAPP
- C#和Visual Basic之匿名型別C#型別
- 在C++ Builder中定義事件 (轉)C++UI事件
- Visual C++/MFC指南(1):幕後 (轉)C++
- Visual C++ 6.0 編 程 經 驗 (轉)C++
- 在Visual C++中用ADO進行資料庫程式設計 (轉)C++資料庫程式設計
- 將資料從 Visual Basic 傳輸到 ExcelExcel
- 利用Visual Basic開發SAP介面程式初探-RFC
- 29.qt quick-在QML中呼叫C++類QTUIC++