相信大家在開發項目時一般都會用到數據庫,以前開發web時,大部份的時間就是用代碼來處理數據,現在搞協同CAD系統的開發也要處理數據庫中的數據,(我的web和CAD是一個系統,協同嘛!)不同的是以前用C#,而現在要用c++,沒辦法,項目的第一步都是搞什麽密碼啊,權限管理之類的好,還有就是要存入文件什麽的!因為文件的數據量比較大,存取比其他類型的數據類型麻煩多了!
目標:用MFC(DLL)對Pro/E進行二次開發,對做好的模型(.prt文件)可以在服務器的數據庫中存取,我用的數據庫是SQL Server 2000
好先掛上我運行成功后的代碼:
View Code
1
void
CPartToDBDlg::OnOK()
2 {
3 // TODO: Add extra validation here
4 ::CoInitialize(NULL);
5 // 定义变量
6 _RecordsetPtr pRs = NULL;
7 _ConnectionPtr pConnection = NULL;
8 _variant_t varChunk;
9 HRESULT hr;
10 HLOCAL hMem;
11 BYTE * pbyte;
12 CString strHint; // 提示信息
13 CFile strFileR; // 定义读文件对象
14
15 LPTSTR pstrBack = _tcsrchr(m_sourcePath, ' \\ ' ); // 取得文件名称,只含文件名和最后一个'\'
16 strFileR.Open(m_sourcePath,CFile::modeRead);
17 long nLength = strFileR.GetLength();
18 hMem = LocalAlloc(LHND, nLength + 1 ); // 分配内存,将读出的数据放入其中
19 if (hMem == NULL)
20 {
21 return ; // 分配内存失败
22 }
23 pbyte = (BYTE * )LocalLock(hMem); // 锁定内存
24 memset(pbyte, (BYTE) 0 , strFileR.GetLength() + 1 ); // 初始化新分配的内存,设定初始值为0
25 strHint.Format( " 开始读取文件%s " ,m_sourcePath); // 提示信息
26 AfxMessageBox(strHint); // 读取文件到内存,注意这里是ReadHuge而非Read
27 strFileR.ReadHuge(pbyte,nLength);
28
29 BYTE * pBufEx;
30 pBufEx = pbyte;
31
32 SAFEARRAY * psa;
33 SAFEARRAYBOUND rgsabound[ 1 ];
34 rgsabound[ 0 ].lLbound = 0 ;
35 rgsabound[ 0 ].cElements = nLength;
36 psa = SafeArrayCreate(VT_UI1, 1 ,rgsabound);
37 for ( long i = 0 ;i < nLength;i ++ )
38 {
39 SafeArrayPutElement(psa, & i,pBufEx ++ ); // Stores the data element at a given location in the array.
40 }
41 VARIANT varBLOB;
42 varBLOB.vt = VT_ARRAY | VT_UI1;
43 varBLOB.parray = psa;
44
45 _bstr_t strCnn( " Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=; " );
46 try
47 {
48 pConnection.CreateInstance(__uuidof(Connection)); // Open a connection
49 hr = pConnection -> Open(strCnn, "" , "" ,NULL); // Connect a DataBase
50 pRs.CreateInstance(__uuidof(Recordset));
51 pRs -> Open( " select * from PartsClass where id=1 " ,_variant_t((IDispatch * )pConnection, true ),adOpenKeyset,adLockOptimistic,adCmdText); // Open a Table
52 pRs -> Fields -> GetItem( " Image " ) -> AppendChunk(varBLOB);
53 pRs -> Update();
54 // 給出提示信息顯示成功
55 CString sMsg;
56 sMsg.Format( " 數據字段長度為:%d " ,pRs -> Fields -> GetItem( " Image " ) -> ActualSize);
57 pRs -> Close();
58 pConnection -> Close();
59 AfxMessageBox(sMsg);
60 }
61 catch (_com_error & e)
62 {
63 // Notify the user of errors if any.
64 _bstr_t bstrSource(e.Source());
65 _bstr_t bstrDescription(e.Description());
66 CString sError;
67 sError.Format( " Source : %s \n Description : %s\n " ,(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
68 AfxMessageBox(sError);
69 }
70 // 释放内存
71 LocalUnlock(pbyte);
72 LocalFree(hMem);
73 // 关闭文件
74 strFileR.Close();
75 }
76
77 void CPartToDBDlg::OnCancel()
78 {
79 // TODO: Add extra cleanup here
80 // 2. VC把数据库中IMAGE字段取出存为文件
81 ::CoInitialize(NULL);
82 _RecordsetPtr pRs = NULL;
83 _ConnectionPtr pConnection = NULL;
84 HRESULT hr;
85 _bstr_t strCnn( " Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=; " );
86 try
87 {
88 pConnection.CreateInstance(__uuidof(Connection)); // Open a connection
89 hr = pConnection -> Open(strCnn, "" , "" ,NULL); // Connect a DataBase
90 pRs.CreateInstance(__uuidof(Recordset));
91 pRs -> Open( " select * from PartsClass where id=1 " ,_variant_t((IDispatch * )pConnection, true ),adOpenKeyset,adLockOptimistic,adCmdText);
92 long lDataSize = pRs -> GetFields() -> GetItem( " Image " ) -> ActualSize;
93 char * m_pBuffer; // 定义缓冲变量
94 if (lDataSize > 0 )
95 {
96
97 _variant_t varBLOB; // 从image字段中读取数据到varBLOB中
98 varBLOB = pRs -> GetFields() -> GetItem( " Image " ) -> GetChunk(lDataSize);
99 if (varBLOB.vt == (VT_ARRAY | VT_UI1))
100 {
101 if (m_pBuffer = new char [lDataSize + 1 ]) // 分配必要的存储空间
102 {
103 char * pBuf = NULL;
104 SafeArrayAccessData(varBLOB.parray,( void ** ) & pBuf);
105 memcpy(m_pBuffer,pBuf,lDataSize); /// 复制数据到缓冲区m_pBuffer
106 SafeArrayUnaccessData (varBLOB.parray);
107 }
108 }
109 }
110 CFile file( " d:\\user\\sweep_blend_5.prt " ,CFile::modeCreate | CFile::modeWrite);
111 file.Write(m_pBuffer,lDataSize);
112 file.Flush();
113 file.Close();
114 // 給出提示信息顯示成功
115 CString sMsg;
116 sMsg.Format( " 數據字段長度為:%d " ,lDataSize);
117 pRs -> Close();
118 pConnection -> Close();
119 AfxMessageBox(sMsg);
120
121 }
122 catch (_com_error & e)
123 {
124 // Notify the user of errors if any.
125 _bstr_t bstrSource(e.Source());
126 _bstr_t bstrDescription(e.Description());
127 CString sError;
128 sError.Format( " Source : %s \n Description : %s\n " ,(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
129 AfxMessageBox(sError);
130 }
131
132 CDialog::OnCancel();
133 }
134
135 void CPartToDBDlg::OnButton1()
136 {
137 // TODO: Add your control notification handler code here
138 CString strFilter;
139 strFilter = " All Files(*.*)|*.*|| " ;
140 CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER | OFN_HIDEREADONLY |
141 OFN_ENABLESIZING | OFN_FILEMUSTEXIST,strFilter);
142
143 dlg.m_ofn.lStructSize = sizeof (OPENFILENAME);
144 if (dlg.DoModal() == IDOK )
145 {
146 m_sourcePath = dlg.GetPathName(); // Edit控件
147 }
148 UpdateData(FALSE);
149 }
2 {
3 // TODO: Add extra validation here
4 ::CoInitialize(NULL);
5 // 定义变量
6 _RecordsetPtr pRs = NULL;
7 _ConnectionPtr pConnection = NULL;
8 _variant_t varChunk;
9 HRESULT hr;
10 HLOCAL hMem;
11 BYTE * pbyte;
12 CString strHint; // 提示信息
13 CFile strFileR; // 定义读文件对象
14
15 LPTSTR pstrBack = _tcsrchr(m_sourcePath, ' \\ ' ); // 取得文件名称,只含文件名和最后一个'\'
16 strFileR.Open(m_sourcePath,CFile::modeRead);
17 long nLength = strFileR.GetLength();
18 hMem = LocalAlloc(LHND, nLength + 1 ); // 分配内存,将读出的数据放入其中
19 if (hMem == NULL)
20 {
21 return ; // 分配内存失败
22 }
23 pbyte = (BYTE * )LocalLock(hMem); // 锁定内存
24 memset(pbyte, (BYTE) 0 , strFileR.GetLength() + 1 ); // 初始化新分配的内存,设定初始值为0
25 strHint.Format( " 开始读取文件%s " ,m_sourcePath); // 提示信息
26 AfxMessageBox(strHint); // 读取文件到内存,注意这里是ReadHuge而非Read
27 strFileR.ReadHuge(pbyte,nLength);
28
29 BYTE * pBufEx;
30 pBufEx = pbyte;
31
32 SAFEARRAY * psa;
33 SAFEARRAYBOUND rgsabound[ 1 ];
34 rgsabound[ 0 ].lLbound = 0 ;
35 rgsabound[ 0 ].cElements = nLength;
36 psa = SafeArrayCreate(VT_UI1, 1 ,rgsabound);
37 for ( long i = 0 ;i < nLength;i ++ )
38 {
39 SafeArrayPutElement(psa, & i,pBufEx ++ ); // Stores the data element at a given location in the array.
40 }
41 VARIANT varBLOB;
42 varBLOB.vt = VT_ARRAY | VT_UI1;
43 varBLOB.parray = psa;
44
45 _bstr_t strCnn( " Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=; " );
46 try
47 {
48 pConnection.CreateInstance(__uuidof(Connection)); // Open a connection
49 hr = pConnection -> Open(strCnn, "" , "" ,NULL); // Connect a DataBase
50 pRs.CreateInstance(__uuidof(Recordset));
51 pRs -> Open( " select * from PartsClass where id=1 " ,_variant_t((IDispatch * )pConnection, true ),adOpenKeyset,adLockOptimistic,adCmdText); // Open a Table
52 pRs -> Fields -> GetItem( " Image " ) -> AppendChunk(varBLOB);
53 pRs -> Update();
54 // 給出提示信息顯示成功
55 CString sMsg;
56 sMsg.Format( " 數據字段長度為:%d " ,pRs -> Fields -> GetItem( " Image " ) -> ActualSize);
57 pRs -> Close();
58 pConnection -> Close();
59 AfxMessageBox(sMsg);
60 }
61 catch (_com_error & e)
62 {
63 // Notify the user of errors if any.
64 _bstr_t bstrSource(e.Source());
65 _bstr_t bstrDescription(e.Description());
66 CString sError;
67 sError.Format( " Source : %s \n Description : %s\n " ,(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
68 AfxMessageBox(sError);
69 }
70 // 释放内存
71 LocalUnlock(pbyte);
72 LocalFree(hMem);
73 // 关闭文件
74 strFileR.Close();
75 }
76
77 void CPartToDBDlg::OnCancel()
78 {
79 // TODO: Add extra cleanup here
80 // 2. VC把数据库中IMAGE字段取出存为文件
81 ::CoInitialize(NULL);
82 _RecordsetPtr pRs = NULL;
83 _ConnectionPtr pConnection = NULL;
84 HRESULT hr;
85 _bstr_t strCnn( " Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=; " );
86 try
87 {
88 pConnection.CreateInstance(__uuidof(Connection)); // Open a connection
89 hr = pConnection -> Open(strCnn, "" , "" ,NULL); // Connect a DataBase
90 pRs.CreateInstance(__uuidof(Recordset));
91 pRs -> Open( " select * from PartsClass where id=1 " ,_variant_t((IDispatch * )pConnection, true ),adOpenKeyset,adLockOptimistic,adCmdText);
92 long lDataSize = pRs -> GetFields() -> GetItem( " Image " ) -> ActualSize;
93 char * m_pBuffer; // 定义缓冲变量
94 if (lDataSize > 0 )
95 {
96
97 _variant_t varBLOB; // 从image字段中读取数据到varBLOB中
98 varBLOB = pRs -> GetFields() -> GetItem( " Image " ) -> GetChunk(lDataSize);
99 if (varBLOB.vt == (VT_ARRAY | VT_UI1))
100 {
101 if (m_pBuffer = new char [lDataSize + 1 ]) // 分配必要的存储空间
102 {
103 char * pBuf = NULL;
104 SafeArrayAccessData(varBLOB.parray,( void ** ) & pBuf);
105 memcpy(m_pBuffer,pBuf,lDataSize); /// 复制数据到缓冲区m_pBuffer
106 SafeArrayUnaccessData (varBLOB.parray);
107 }
108 }
109 }
110 CFile file( " d:\\user\\sweep_blend_5.prt " ,CFile::modeCreate | CFile::modeWrite);
111 file.Write(m_pBuffer,lDataSize);
112 file.Flush();
113 file.Close();
114 // 給出提示信息顯示成功
115 CString sMsg;
116 sMsg.Format( " 數據字段長度為:%d " ,lDataSize);
117 pRs -> Close();
118 pConnection -> Close();
119 AfxMessageBox(sMsg);
120
121 }
122 catch (_com_error & e)
123 {
124 // Notify the user of errors if any.
125 _bstr_t bstrSource(e.Source());
126 _bstr_t bstrDescription(e.Description());
127 CString sError;
128 sError.Format( " Source : %s \n Description : %s\n " ,(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
129 AfxMessageBox(sError);
130 }
131
132 CDialog::OnCancel();
133 }
134
135 void CPartToDBDlg::OnButton1()
136 {
137 // TODO: Add your control notification handler code here
138 CString strFilter;
139 strFilter = " All Files(*.*)|*.*|| " ;
140 CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER | OFN_HIDEREADONLY |
141 OFN_ENABLESIZING | OFN_FILEMUSTEXIST,strFilter);
142
143 dlg.m_ofn.lStructSize = sizeof (OPENFILENAME);
144 if (dlg.DoModal() == IDOK )
145 {
146 m_sourcePath = dlg.GetPathName(); // Edit控件
147 }
148 UpdateData(FALSE);
149 }
說明:
當然了,在工程中要先導入msado15.dll是必須的,其他的就看上面的代碼吧!在數據庫中對應的數據類型可以是image,text,ntext三種,我只對image的做了,
其他兩個沒做!還有就是這段程序是可以存取任何類型的文件數據的!
總結:
要注意做事的方法!我開始在網上找了很久都沒有找到,我想原因主要是因為我現在對VC,MFC還處於入門階段,很多函數都不認識,
上網看了很多,但就是達不到我的目的,畢竟代碼都是要完成個人所需的功能的,很是浪費時間,所以啊,還是應該從最簡單的功能做起,確定自己想要的東西,
多利用圖書館的資源,學校就是圖書館好,資源相當豐富,這個我是要肯定的…