void CMyExtractDlg::OnBnClickedButton1()
{
IWP_Comm* pCom ;
CLSID clsid ;
CoInitialize (NULL);
HRESULT hr = CLSIDFromProgID (L"WP_Anlayze_Com.WP_Comm",&clsid) ;
hr = CoCreateInstance (clsid, NULL, CLSCTX_ALL, IWP_CommPtr::GetIID(),(void**)&pCom);
int cnt = 0 ;
CFileFind finder;
CString strFile, strContent, strExtractTitle, strExtractContent, strPreviousDirectory ;
_bstr_t _bstrContent ;
BSTR bstrExtractTitle, bstrExtractContent ;
CString m_path ;//当前打开目录路径
BROWSEINFO bf;
LPITEMIDLIST pidlbf;
ZeroMemory((LPVOID)&bf,sizeof(BROWSEINFO));
bf.hwndOwner = this->m_hWnd;
bf.pszDisplayName = m_path.GetBuffer(MAX_PATH);
bf.lpszTitle = _T( "选择打开位置 ");
bf.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS | BIF_USENEWUI ;
bf.lpfn = NULL;
bf.lParam = 0;
if((pidlbf = ::SHBrowseForFolder(&bf)) == NULL) return;
char temp[MAX_PATH] = {0};
if(::SHGetPathFromIDList(pidlbf,temp) == NULL)return;
strFile = temp ;
strFile += _T("\\*.*") ;
// 找出当前指定路径下的文件数目
BOOL bWorking = finder.FindFile((LPCTSTR)strFile) ;
while (bWorking)
{
bWorking = finder.FindNextFile() ;
cnt++;
}
cnt -= 2 ;
// 找到上一级目录加上extractor_content
strPreviousDirectory = temp ;
strPreviousDirectory += _T("extractor_content.txt") ;
int k = strPreviousDirectory.ReverseFind('\\') ;
strPreviousDirectory.Delete(k+1, 4) ;
// 创建extractor_content.txt文件
CFile fileExtractContent ((LPCTSTR)strPreviousDirectory, CFile::modeCreate | CFile::modeWrite) ;
for (int i = 1; i <= cnt; ++i)
{
strFile = temp ;
strFile.AppendFormat(_T("\\%d.htm"), i) ;
CFile file ((LPCTSTR)strFile, CFile::modeRead) ;
DWORD dwFileLen = file.GetLength() ;
char* pCString = new char[dwFileLen+1];//strContent.GetBuffer(dwFileLen) ;
file.Read(pCString, dwFileLen) ;
pCString[dwFileLen] = '\0';
//strContent = pCString;
_bstrContent = _com_util::ConvertStringToBSTR(pCString) ;
pCom->GetWP_Content(_bstrContent, &bstrExtractTitle, &bstrExtractContent) ;
strExtractTitle = _com_util::ConvertBSTRToString(bstrExtractTitle) ;
strExtractContent = _com_util::ConvertBSTRToString(bstrExtractContent) ;
// 写入extractor_content.txt
DWORD dwExtractTitleLen = strExtractTitle.GetLength() ;
DWORD dwExtractContentLen = strExtractContent.GetLength () ;
char* strExtractTitleChar = new char [dwExtractTitleLen + 1] ;
char* strExtractContentChar = new char [dwExtractContentLen + 1] ;
strExtractTitleChar = _com_util::ConvertBSTRToString(bstrExtractTitle) ;
strExtractContentChar = _com_util::ConvertBSTRToString(bstrExtractContent) ;
strExtractTitleChar[dwExtractTitleLen] = '\0' ;
strExtractContentChar[dwExtractContentLen] = '\0' ;
fileExtractContent.Write(strExtractTitleChar, dwExtractTitleLen) ;
fileExtractContent.Write("\r\n", strlen("\r\n")) ;
fileExtractContent.Write(strExtractContentChar, dwExtractContentLen) ;
fileExtractContent.Write("\r\n", strlen("\r\n")) ;
fileExtractContent.Write("####", strlen("####")) ;
fileExtractContent.Write("\r\n", strlen("\r\n")) ;
delete strExtractTitleChar ;
delete strExtractContentChar ;
delete pCString;
strContent.ReleaseBuffer() ;
file.Close() ;
}
fileExtractContent.Close() ;
CoTaskMemFree (pidlbf) ;
pCom->Release();
}
PS:首先要将对应的COM组建注册 命令:regsvr32 com名 ,反注册命令为 regsvr32 /u com名
然后在工程对应的 afx.h 加入类似的如下语句: #import "WP_Anlayze_Com.tlb" no_namespace
WP_Anlayze_Com.tlb放在当前工程目录,并且可以加入到VS里来(当然加入到VS里来不是必须的)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
现在总结一下最新的结论:
声明一下:下面的讲解是建立在我个人的一个com的dll基础上,所以你看到有些莫名其妙的东西不要感到奇怪,比如IStore。
1.首先将com的dll注册一下,注册命令为 regsvr32 *.dll(需要包含全路径),不要要在工程中指定dll的路径,因为注册的过程已经让你的工程知晓了dll的路径。
2.将对应的.tlb放到工程的.vcproject目录下。
3.将.tlb加载到工程的资源目录下(这一步可做可不做)
4.写下下面的代码,梳理dll的接口:
BOOL CRedisCliEx::Init()
{
CLSID clsid ;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
bool bRet = false;
HRESULT hr = CLSIDFromProgID(L"RedisCli.Store",&clsid);// 有人可能会问这是什么东西,哈哈,这来自.tlb,你可以把.tlb加进你的工程,然后打开看下,从里面可以看到你的dll能导出的所有接口。
if (SUCCEEDED(hr))
{
hr=CoCreateInstance (clsid, NULL, CLSCTX_ALL, IStorePtr::GetIID(),(void**)&m_pIStore);
if (SUCCEEDED(hr))
{
if (SUCCEEDED(hr) && NULL != m_pIStore)
{
CHDTLog::Instance()->WriteLogInfo("CNode::InitRedisCli", "初始化RedisCli成功!", "Dll");
bRet = true;
}
else
{
CHDTLog::Instance()->WriteLogInfo("CNode::InitRedisCli", "初始化RedisCli失败!", "Dll");
}
}
}
return bRet;
}
然后再定义如下变量:IStore* m_pIStore;可能有人会问这个IStore是从哪里来的,我们的工程怎么知道有这个变量,原来啊这个变量在我们之前注册.dll的时候再C盘下生成了,可以从C:\Documents and Settings\Administrator.49801BCF518C445\Local Settings\Temp\rediscli.tlh中找到(当然我的dll是这样,你的就未必了),我们可以直接利用。
5.接下来我们对com之dll的操作只要用到m_pIStore就可以了。例如:
ULONGLONG CRedisCliEx::Connect(BSTR ip, LONG port)
{
return m_pIStore->Connect(ip, port) ;
}
LONG CRedisCliEx::AddSSMQ(ULONGLONG handle, BSTR mqname, double score, BSTR msg)
{
return m_pIStore->AddSSMQ(handle, mqname, score, msg) ;
}