📄 dictionary.cpp
字号:
// Dictionary.cpp : Implementation of CDictionary
#include "stdafx.h"
#include "Dictionary.h"
// CDictionary
inline DWORD ROUND_UP(DWORD dwSize, DWORD dwAmount) { return ((dwSize + (dwAmount-1)) & ~(dwAmount-1));}
STDMETHODIMP CDictionary::InitialDict(BSTR bStrDict)
{
// TODO: Add your implementation code here
TCHAR szDictName[128] = _T("");
HRESULT hr = NOERROR;
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
if (FAILED(ConvertBstrToChar(bStrDict, szDictName)))
return E_FAIL;
ObjectLock Dict_Lock(this);
if (m_lchange != 0)
SyncDictLib();
_tcscpy(m_dictname, szDictName);
hFind = FindFirstFile((LPCWSTR) szDictName, &FindFileData);
if (INVALID_HANDLE_VALUE != hFind)
{
FindClose(hFind);
hr = OpenDatabase();
}
else
{
hr = CreateDatabase();
}
if (hr == S_OK) InitDictWord();
return S_OK;
}
STDMETHODIMP CDictionary::AddWord(BSTR SrcWord, BSTR DestWord)
{
// TODO: Add your implementation code here
ObjectLock Dict_Lock(this);
if (m_wordcount < MaxWordCount)
{
ConvertBstrToChar(SrcWord, m_pData[ m_wordcount ].wordFromLang);
ConvertBstrToChar(DestWord, m_pData[ m_wordcount ].wordToLang);
m_wordcount++;
m_lchange ++;
}
else
{
return E_FAIL;
}
//判断是否需要做同步
return S_OK;
}
STDMETHODIMP CDictionary::ModifyWord(BSTR SrcWord, BSTR DestWord)
{
// TODO: Add your implementation code here
long lIndex = 0;
TCHAR szToLang[MaxWordLength] = _T("");
if (FAILED(ConvertBstrToChar(DestWord, szToLang)))
return E_FAIL;
ObjectLock Dict_Lock(this);
if ( FAILED( GetIndexOfWord( SrcWord, &lIndex ))) return E_FAIL;
_tcscpy(m_pData[ lIndex ].wordToLang, DestWord );
m_lchange ++;
//判断是否需要做同步
return S_OK;
}
STDMETHODIMP CDictionary::DeleteWord(BSTR bStrWord)
{
// TODO: Add your implementation code here
long lIndex = 0;
TCHAR *pchToLang = NULL;
ObjectLock Dict_Lock(this);
if ( FAILED( GetIndexOfWord( bStrWord, &lIndex ))) return E_FAIL;
m_wordcount --;
for(int i = lIndex; i<m_wordcount; i++)
{
_tcscpy(m_pData[ i ].wordFromLang, m_pData[ i+1 ].wordFromLang);
_tcscpy(m_pData[ i ].wordToLang, m_pData[ i+1 ].wordToLang);
}
m_lchange ++;
//判断是否需要做同步
return S_OK;
}
STDMETHODIMP CDictionary::QueryWord(BSTR bStrWord, BSTR* bStrDest)
{
// TODO: Add your implementation code here
long lIndex = 0;
ObjectLock Dict_Lock(this);
if ( FAILED( GetIndexOfWord( bStrWord, &lIndex ))) return E_FAIL;
if (bStrDest != NULL) SysFreeString( *bStrDest);
*bStrDest = SysAllocString(m_pData[ lIndex ].wordToLang);
return S_OK;
}
// 从BSTR字符串转换到CHAR型
STDMETHODIMP CDictionary::ConvertBstrToChar(BSTR pbStrFrom, TCHAR * pcTo)
{
//char szStrTemp[100];
TCHAR * tToLang = NULL;
int i = 0;
i = SysStringLen(pbStrFrom);
if (SysStringLen(pbStrFrom) > MaxWordLength/2)
return E_FAIL;
tToLang = OLE2T( pbStrFrom );
_tcscpy( pcTo, tToLang );
return S_OK;
}
// //根据单词查找字典顺序
STDMETHODIMP CDictionary::GetIndexOfWord(BSTR bStrWordFnd, long * lIndex)
{
TCHAR szWordFnd[MaxWordLength] = _T("");
long i = 0;
if (FAILED(ConvertBstrToChar(bStrWordFnd, szWordFnd)))
return E_FAIL;
ObjectLock Dict_Lock(this);
for (i = 0; i < m_wordcount; i++)
if (_tcscmp(szWordFnd, m_pData[ i ].wordFromLang) == 0)
break;
if ( i < m_wordcount)
{
*lIndex = i;
return S_OK;
}
return E_FAIL;
}
STDMETHODIMP CDictionary::SyncDictLib(void)
{
HRESULT hr;
ULONG iPropSet = 0;
ULONG iProp = 0;
ICommandText * pICmdText = NULL;
IDBCreateCommand * pIDBCrtCmd = NULL;
ICommandPrepare * pICmdPrepare = NULL;
ICommandWithParameters * pICmdWParams = NULL;
IAccessor * pIAcc = NULL;
ULONG cParams;
DBPARAMINFO * rgParamInfo = NULL;
OLECHAR * pNamesBuffer = NULL;
ULONG cBindings;
DBBINDING rgBindings[3];
ULONG cbRowSize;
HACCESSOR hAcc;
BYTE * pData = NULL;
DBPARAMS params;
LONG cRowsAffected;
ObjectLock Dict_Lock(this);
if (m_lchange == 0)
return S_OK;
hr = m_pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pIDBCrtCmd);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Create the new command that uses parameters.
hr = pIDBCrtCmd->CreateCommand(NULL, IID_ICommandWithParameters,
(IUnknown**) &pICmdWParams);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
hr = pICmdWParams->QueryInterface(IID_ICommandText, (void**) &pICmdText);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
hr = pICmdWParams->QueryInterface(IID_ICommandPrepare, (void**) &pICmdPrepare);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Specify the command text using parameter markers in the query syntax.
hr = ExecuteSQL(pICmdText, (LPWSTR)L"DELETE FROM YF_DICT");
if(FAILED(hr))
{
goto Exit;
}
// Specify the command text using parameter markers in the query syntax.
hr = pICmdText->SetCommandText(DBGUID_DBSQL, L"INSERT INTO YF_DICT(Nick, Word) VALUES (?, ?)");
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Prepare the current command.
hr = pICmdPrepare->Prepare(m_wordcount);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Retrieving parameter information
hr = pICmdWParams->GetParameterInfo(&cParams, &rgParamInfo, &pNamesBuffer);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Create the acessor object and column specific bindings.
hr = pICmdText->QueryInterface(IID_IAccessor, (void**) &pIAcc);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Create the bindings for the two columns.
cBindings = 2;
rgBindings[0].iOrdinal = 1;
rgBindings[0].obStatus = 0;
rgBindings[0].obLength = rgBindings[0].obStatus + sizeof(DBSTATUS);
rgBindings[0].obValue = rgBindings[0].obLength + sizeof(ULONG);
rgBindings[0].pTypeInfo = NULL;
rgBindings[0].pObject = NULL;
rgBindings[0].pBindExt = NULL;
rgBindings[0].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
rgBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
rgBindings[0].eParamIO = DBPARAMIO_INPUT;
rgBindings[0].cbMaxLen = 30 * sizeof(WCHAR); //From language is nvachar(30)
rgBindings[0].dwFlags = 0;
rgBindings[0].wType = DBTYPE_WSTR;
rgBindings[0].bPrecision = 0;
rgBindings[0].bScale = 0;
rgBindings[1].iOrdinal = 2;
rgBindings[1].obStatus = rgBindings[0].obValue + rgBindings[0].cbMaxLen;
rgBindings[1].obLength = rgBindings[1].obStatus + sizeof(DBSTATUS);
rgBindings[1].obValue = rgBindings[1].obLength + sizeof(ULONG);
rgBindings[1].pTypeInfo = NULL;
rgBindings[1].pObject = NULL;
rgBindings[1].pBindExt = NULL;
rgBindings[1].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
rgBindings[1].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
rgBindings[1].eParamIO = DBPARAMIO_INPUT;
rgBindings[1].cbMaxLen = 30 * sizeof(WCHAR); //CompanyName is nvarchar(40)
rgBindings[1].dwFlags = 0;
rgBindings[1].wType = DBTYPE_WSTR;
rgBindings[1].bPrecision = 0;
rgBindings[1].bScale = 0;
// Calculate the total memory needed for the input buffer.
cbRowSize = rgBindings[1].obValue + rgBindings[1].cbMaxLen;
// Create the accessor for the parameter data.
hr = pIAcc->CreateAccessor(DBACCESSOR_PARAMETERDATA, cBindings,
rgBindings, cbRowSize, &hAcc, NULL);
if (FAILED(hr))
{
//Send an error-specific message and do error handling.
goto Exit;
}
// Allocate memory for the parameter data.
pData = (BYTE*) malloc(cbRowSize);
if(!(pData))
{
hr = E_OUTOFMEMORY;
goto Exit;
}
for(int i = 0; i < m_wordcount; i++)
{
//Clear out the buffer.
memset(pData, 0, cbRowSize);
// CompanyName
* (DBSTATUS*) (pData + rgBindings[0].obStatus) = DBSTATUS_S_OK;
wcscpy((WCHAR*) (pData + rgBindings[0].obValue), T2W(m_pData[ i ].wordFromLang));
* (int*) (pData + rgBindings[0].obLength) = wcslen(T2W(m_pData[ i ].wordFromLang)) * sizeof(WCHAR);
// Phone
* (DBSTATUS*) (pData + rgBindings[1].obStatus) = DBSTATUS_S_OK;
wcscpy((WCHAR*) (pData + rgBindings[1].obValue), T2W(m_pData[ i ].wordToLang));
* (int*) (pData + rgBindings[1].obLength) = wcslen(T2W(m_pData[ i ].wordToLang)) * sizeof(WCHAR);
// Define the DBPARAMS structure.
params.pData = pData;
params.cParamSets = 1;
params.hAccessor = hAcc;
// Execute the command with paramters.
hr = pICmdText->Execute(NULL, IID_NULL, ¶ms, &cRowsAffected, NULL);
// Error handling for the command
if (FAILED(hr) || (1 != cRowsAffected))
{
MessageBox(NULL,L"An error occured",L"error",MB_OK);
}
}
m_lchange = 0;
Exit:
// Clean up resources.
free(pData);
CoTaskMemFree(rgParamInfo);
CoTaskMemFree(pNamesBuffer);
if(pIAcc) pIAcc->Release();
if(pICmdPrepare) pICmdPrepare->Release();
if(pICmdWParams) pICmdWParams->Release();
if(pICmdText) pICmdText->Release();
if(pIDBCrtCmd) pIDBCrtCmd->Release();
return S_OK;
}
STDMETHODIMP CDictionary::Hello(LONG HelloNo, LONG* pHello)
{
// TODO: Add your implementation code here
*pHello = HelloNo;
return S_OK;
}
// 打开字典数据库
HRESULT CDictionary::OpenDatabase(void)
{
HRESULT hr = NOERROR; // Error code reporting
DBPROP dbprop[1]; // property used in property set to initialize provider
DBPROPSET dbpropset[1]; // Property Set used to initialize provider
IDBInitialize *pIDBInitialize = NULL; // Provider Interface Pointer
IDBProperties *pIDBProperties = NULL; // Provider Interface Pointer
VariantInit(&dbprop[0].vValue);
// Create an instance of the OLE DB Provider
//
hr = CoCreateInstance( CLSID_SQLSERVERCE_3_0,
0,
CLSCTX_INPROC_SERVER,
IID_IDBInitialize,
(void**)&pIDBInitialize);
if(FAILED(hr))
{
goto Exit;
}
// Initialize a property with name of database
//
dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
dbprop[0].vValue.vt = VT_BSTR;
dbprop[0].vValue.bstrVal= SysAllocString(m_dictname);
if(NULL == dbprop[0].vValue.bstrVal)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Initialize the property set
//
dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
dbpropset[0].rgProperties = dbprop;
dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]);
//Set initialization properties.
//
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties);
if(FAILED(hr))
{
goto Exit;
}
// Sets properties in the Data Source and initialization property groups
//
hr = pIDBProperties->SetProperties(1, dbpropset);
if(FAILED(hr))
{
goto Exit;
}
// Initializes a data source object
//
hr = pIDBInitialize->Initialize();
if(FAILED(hr))
{
goto Exit;
}
// Get IDBCreateSession interface
//
hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&m_pIDBCreateSession);
Exit:
// Clear Variant
//
VariantClear(&dbprop[0].vValue);
// Release interfaces
//
if(pIDBProperties)
{
pIDBProperties->Release();
}
if (pIDBInitialize)
{
pIDBInitialize->Release();
}
return hr;
}
// 创建数据库
HRESULT CDictionary::CreateDatabase(void)
{
HRESULT hr = NOERROR; // Error code reporting
DBPROPSET dbpropset[1]; // Property Set used to initialize provider
DBPROP dbprop[1]; // property array used in property set to initialize provider
IDBInitialize *pIDBInitialize = NULL; // Provider Interface Pointer
IDBDataSourceAdmin *pIDBDataSourceAdmin = NULL; // Provider Interface Pointer
IUnknown *pIUnknownSession = NULL; // Provider Interface Pointer
IDBCreateCommand *pIDBCrtCmd = NULL; // Provider Interface Pointer
ICommandText *pICmdText = NULL; // Provider Interface Pointer
VariantInit(&dbprop[0].vValue);
// Delete the DB if it already exists
//
DeleteFile((LPCTSTR) m_dictname);
// Create an instance of the OLE DB Provider
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -