📄 hhctrl.cpp
字号:
COleVariant vFlags((long) dwFlags, VT_I4);
m_pBrowserApp->Navigate2(vURL,
vFlags, vTargetFrameName, vPostData, vHeaders);
}
void CHHCtrl::Navigate2(LPCTSTR lpszURL, DWORD dwFlags,
CByteArray& baPostData, LPCTSTR lpszTargetFrameName /* = NULL */,
LPCTSTR lpszHeaders /* = NULL */)
{
ASSERT(m_pBrowserApp != NULL);
COleVariant vPostData = baPostData;
COleVariant vURL(lpszURL, VT_BSTR);
COleVariant vHeaders(lpszHeaders, VT_BSTR);
COleVariant vTargetFrameName(lpszTargetFrameName, VT_BSTR);
COleVariant vFlags((long) dwFlags, VT_I4);
ASSERT(m_pBrowserApp != NULL);
m_pBrowserApp->Navigate2(vURL, vFlags, vTargetFrameName,
vPostData, vHeaders);
}
void CHHCtrl::PutProperty(LPCTSTR lpszProperty, const VARIANT& vtValue)
{
ASSERT(m_pBrowserApp != NULL);
CString strProp(lpszProperty);
BSTR bstrProp = strProp.AllocSysString();
m_pBrowserApp->PutProperty(bstrProp, vtValue);
::SysFreeString(bstrProp);
}
BOOL CHHCtrl::GetProperty(LPCTSTR lpszProperty, CString& strValue)
{
ASSERT(m_pBrowserApp != NULL);
CString strProperty(lpszProperty);
BSTR bstrProperty = strProperty.AllocSysString();
BOOL bResult = FALSE;
VARIANT vReturn;
vReturn.vt = VT_BSTR;
vReturn.bstrVal = NULL;
HRESULT hr = m_pBrowserApp->GetProperty(bstrProperty, &vReturn);
if (SUCCEEDED(hr)) {
strValue = CString(vReturn.bstrVal);
bResult = TRUE;
}
::SysFreeString(bstrProperty);
return bResult;
}
COleVariant CHHCtrl::GetProperty(LPCTSTR lpszProperty)
{
COleVariant result;
static BYTE parms[] =
VTS_BSTR;
InvokeHelper(0x12f, DISPATCH_METHOD,
VT_VARIANT, (void*)&result, parms, lpszProperty);
return result;
}
CString CHHCtrl::GetFullName() const
{
ASSERT(m_pBrowserApp != NULL);
BSTR bstr;
m_pBrowserApp->get_FullName(&bstr);
CString retVal(bstr);
return retVal;
}
/////////////////////////////////////////////////////////////////////////////
// CHHCtrl event reflectors
void CHHCtrl::NavigateComplete2(LPDISPATCH /* pDisp */, VARIANT* URL)
{
ASSERT(V_VT(URL) == VT_BSTR);
// USES_CONVERSION;
CString str(V_BSTR(URL));
OnNavigateComplete2(str);
}
void CHHCtrl::BeforeNavigate2(LPDISPATCH /* pDisp */, VARIANT* URL,
VARIANT* Flags, VARIANT* TargetFrameName,
VARIANT* PostData, VARIANT* Headers, BOOL* pfCancel)
{
ASSERT(V_VT(URL) == VT_BSTR);
ASSERT(V_VT(TargetFrameName) == VT_BSTR);
ASSERT(V_VT(PostData) == (VT_VARIANT | VT_BYREF));
ASSERT(V_VT(Headers) == VT_BSTR);
ASSERT(pfCancel != NULL);
// USES_CONVERSION;
VARIANT* vtPostedData = V_VARIANTREF(PostData);
CByteArray array;
if (V_VT(vtPostedData) & VT_ARRAY) {
// must be a vector of bytes
ASSERT(vtPostedData->parray->cDims == 1 && vtPostedData->parray->cbElements == 1);
vtPostedData->vt |= VT_UI1;
COleSafeArray safe(vtPostedData);
DWORD dwSize = safe.GetOneDimSize();
LPVOID pVoid;
safe.AccessData(&pVoid);
array.SetSize(dwSize);
LPBYTE lpByte = array.GetData();
memcpy(lpByte, pVoid, dwSize);
safe.UnaccessData();
}
// make real parameters out of the notification
CString strTargetFrameName(V_BSTR(TargetFrameName));
CString strURL = V_BSTR(URL);
CString strHeaders = V_BSTR(Headers);
DWORD nFlags = V_I4(Flags);
// notify the user's class
OnBeforeNavigate2(strURL, nFlags, strTargetFrameName, array, strHeaders, pfCancel);
}
void CHHCtrl::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
{
UNUSED_ALWAYS(pDisp);
ASSERT(V_VT(URL) == VT_BSTR);
CString str(V_BSTR(URL));
OnDocumentComplete(str);
}
/////////////////////////////////////////////////////////////////////////////
// CHHCtrl Events
void CHHCtrl::OnProgressChange(long lProgress, long lProgressMax)
{
UNUSED_ALWAYS(lProgress);
UNUSED_ALWAYS(lProgressMax);
}
void CHHCtrl::OnCommandStateChange(long lCommand, BOOL bEnable)
{
switch (lCommand) {
case CSC_NAVIGATEFORWARD:
if (m_pTB)
m_pTB->EnableButton(HH_TB_FORWARD, bEnable);
break;
case CSC_NAVIGATEBACK:
if (m_pTB)
m_pTB->EnableButton(HH_TB_BACK, bEnable);
break;
}
}
void CHHCtrl::OnDownloadBegin()
{
}
void CHHCtrl::OnQuit()
{
}
void CHHCtrl::OnDocumentComplete(LPCTSTR lpszURL)
{
UNUSED_ALWAYS(lpszURL);
}
void CHHCtrl::OnDownloadComplete()
{
}
void CHHCtrl::OnTitleChange(LPCTSTR lpszText)
{
UNUSED_ALWAYS(lpszText);
}
void CHHCtrl::OnPropertyChange(LPCTSTR lpszProperty)
{
UNUSED_ALWAYS(lpszProperty);
}
void CHHCtrl::OnNewWindow2(LPDISPATCH* ppDisp, BOOL* pfCancel)
{
*pfCancel = FALSE; // default to continuing
UNUSED_ALWAYS(ppDisp);
}
void CHHCtrl::OnVisible(BOOL fVisible)
{
UNUSED_ALWAYS(fVisible);
}
void CHHCtrl::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags,
LPCTSTR lpszTargetFrameName, CByteArray& baPostData,
LPCTSTR lpszHeaders, BOOL* pfCancel)
{
*pfCancel = FALSE; // default to continuing
UNUSED_ALWAYS(lpszURL);
UNUSED_ALWAYS(nFlags);
UNUSED_ALWAYS(lpszTargetFrameName);
UNUSED_ALWAYS(baPostData);
UNUSED_ALWAYS(lpszHeaders);
}
void CHHCtrl::OnStatusTextChange(LPCTSTR pszText)
{
UNUSED_ALWAYS(pszText);
}
void CHHCtrl::OnNavigateComplete2(LPCTSTR strURL)
{
UNUSED_ALWAYS(strURL);
}
HRESULT CHHCtrl::NavigateChm(LPCTSTR URL, LPCTSTR lpszTargetFrameName)
{
ASSERT(!m_cszChm.IsEmpty()); // You must call SetChmFile() first
if (m_cszChm.IsEmpty())
return STG_E_FILENOTFOUND; // CHM file wasn't located
char szURL[MAX_PATH * 2];
wsprintf(szURL, "its:%s::%s", (LPCTSTR) m_cszChm, URL);
return Navigate(szURL, NULL, lpszTargetFrameName);
}
bool CHHCtrl::SetChmFile(LPCTSTR pszChm)
{
TCHAR szCHM[MAX_PATH];
if (!FindChmFile(pszChm, szCHM)) {
CString csz;
AfxFormatString1(csz, IDS_HHCTRL_NO_CHM, pszChm);
AfxMessageBox(csz, MB_ICONEXCLAMATION);
return false;
}
m_cszChm = szCHM;
return true;
}
// Look for the CHM file -- this is basically the same algorithm that
// HTML Help uses with the addition of looking in the same location as
// the executable.
bool CHHCtrl::FindChmFile(LPCTSTR pszFile, LPTSTR pszDst)
{
if (GetFileAttributes(pszFile) != HFILE_ERROR) {
GetFullPathName(pszFile, MAX_PATH, pszDst, NULL);
return true;
}
// turn all forward slashes into back slashes
TCHAR szCHM[1024];
strcpy(szCHM, pszFile); // copy so we can modify
// Convert forward slashes to backslashes for consistency
LPTSTR pszTmp = StrChr(szCHM, '/');
while (pszTmp) {
*pszTmp = '\\';
pszTmp = StrChr(pszTmp + 1, '/');
}
pszTmp = StrRChr(szCHM, '\\');
if (pszTmp)
pszTmp++;
else
pszTmp = szCHM;
{ // Try the same directory as the executable
char szModule[MAX_PATH];
GetModuleFileName(NULL, szModule, sizeof(szModule));
LPTSTR pszFile = StrRChr(szModule, '\\');
if (pszFile) {
strcpy(pszFile + 1, pszTmp);
if (GetFileAttributes(szModule) != HFILE_ERROR) {
strcpy(pszDst, szModule);
return true;
}
}
}
// Try the current directory
if (GetFileAttributes(pszTmp) != HFILE_ERROR) {
GetFullPathName(pszTmp, MAX_PATH, pszDst, NULL);
return true;
}
// Try the registry
HKEY hkey;
LONG result;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\HTML Help",
0, KEY_READ, &hkey) == ERROR_SUCCESS) {
DWORD cbPath = MAX_PATH;
DWORD type;
result = RegQueryValueEx(hkey, pszTmp, 0, &type, (PBYTE) pszDst, &cbPath);
RegCloseKey(hkey);
if (result == ERROR_SUCCESS) {
AddTrailingBackslash(pszDst);
strcat(pszDst, pszTmp);
if (GetFileAttributes(pszDst) != HFILE_ERROR) {
return true;
}
}
}
// Try the Windows\help directory
GetRegWindowsDirectory(pszDst);
AddTrailingBackslash(pszDst);
strcat(pszDst, "Help");
AddTrailingBackslash(pszDst);
strcat(pszDst, pszTmp);
if (GetFileAttributes(pszDst) != HFILE_ERROR)
return true;
// Try hh.ini
if (GetPrivateProfileString("files", pszTmp, "", pszDst, MAX_PATH, "hh.ini") > 1) {
TCHAR* pszComma = StrChr(pszDst, ',');
if (pszComma)
*pszComma++ = 0;
if (GetFileAttributes(pszDst) != HFILE_ERROR) {
return true;
}
if (pszComma && *pszComma) {
do {
if (AfxMessageBox(pszComma, MB_OKCANCEL | MB_ICONHAND) != IDOK)
break;
} while (GetFileAttributes(pszDst) == HFILE_ERROR);
return true;
}
}
return false;
}
// This function supports diskless workstations -- GetWindowsDirectory() won't
// always give the same result in that environment
void CHHCtrl::GetRegWindowsDirectory(TCHAR* pszDst)
{
HKEY hkey;
DWORD cbPath = MAX_PATH;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_READ, &hkey) ==
ERROR_SUCCESS) {
DWORD type;
RegQueryValueEx(hkey, "SharedDir", 0, &type, (PBYTE) pszDst, &cbPath);
RegCloseKey(hkey);
}
if (cbPath == MAX_PATH) // means couldn't read registry key
GetWindowsDirectory(pszDst, MAX_PATH);
}
// DBCS-enabled searching
LPTSTR CHHCtrl::StrChr(LPCTSTR psz, TCHAR ch)
{
while (*psz && *psz != ch)
psz = CharNext(psz);
return (*psz ? (TCHAR*) psz : NULL);
}
LPTSTR CHHCtrl::StrRChr(LPCTSTR psz, TCHAR ch)
{
LPCTSTR pszLastFound = StrChr(psz, ch);
if (!pszLastFound)
return NULL;
while ((psz = StrChr(pszLastFound + 1, ch)))
pszLastFound = psz;
return (LPTSTR) pszLastFound;
}
void CHHCtrl::AddTrailingBackslash(LPTSTR psz)
{
ASSERT(psz && *psz);
TCHAR* pszEnd = psz + strlen(psz);
if (*(CharPrev(psz, pszEnd)) != '\\' &&
*(CharPrev(psz, pszEnd)) != '/' &&
*(CharPrev(psz, pszEnd)) != ':') {
*pszEnd++ = '\\';
*pszEnd++ = '\0';
}
}
HRESULT CHHCtrl::NavigateChm(UINT mapID, LPCTSTR lpszTargetFrameName)
{
ASSERT(!m_cszChm.IsEmpty()); // You must call SetChmFile() first
if (m_cszChm.IsEmpty())
return STG_E_PATHNOTFOUND ; // CHM file wasn't located
if (!m_paMapIds) {
CItsFile its; // ITS and CHM files are effectively the same thing
if (FAILED(its.OpenITS(m_cszChm))) // theoretically impossible as SetChmFile() should have failed first
return STG_E_PATHNOTFOUND ; // CHM file wasn't located
IStream* pStream;
if (FAILED(its.OpenStream("#IVB", &pStream, its.GetStorage()))) {
TRACE1("Missing [MAP] section in the file %s", m_cszChm);
return STG_E_FILENOTFOUND;
}
ULONG cbRead;
DWORD cbMapIds;
if (FAILED(pStream->Read(&cbMapIds, sizeof(DWORD), &cbRead)) || (cbRead != sizeof(DWORD))) {
pStream->Release();
return STG_E_READFAULT;
}
if (!(m_paMapIds = (MAPID*) LocalAlloc(LMEM_FIXED, cbMapIds))) {
pStream->Release();
return E_OUTOFMEMORY ;
}
if (FAILED(pStream->Read(m_paMapIds, cbMapIds, &cbRead)) || (cbRead != (ULONG) cbMapIds)) {
pStream->Release();
return STG_E_READFAULT;
}
pStream->Release();
m_cMapIds = cbMapIds / sizeof(MAPID);
}
for (int i = 0; i < m_cMapIds; i++) {
if (mapID == m_paMapIds[i].mapid) {
CItsFile its; // ITS and CHM files are effectively the same thing
if (FAILED(its.OpenITS(m_cszChm))) // theoretically impossible as SetChmFile() should have failed first
return STG_E_PATHNOTFOUND ; // CHM file wasn't located
CStringSubFile ssf(&its);
TCHAR szURL[MAX_PATH * 2];
wsprintf(szURL, "its:%s::", (LPCTSTR) m_cszChm);
ssf.GetString(m_paMapIds[i].offset, szURL + strlen(szURL), sizeof(szURL) - strlen(szURL));
return Navigate(szURL, NULL, lpszTargetFrameName);
}
}
return E_FAIL; // couldn't find the requested map id
}
void CHHCtrl::OnCommand(DWORD id)
{
switch (id) {
case HH_TB_HOME:
ASSERT(m_pBrowserApp);
// Check for a ':' in the URL in case the URL has a protocol (file:, http:, etc.)
if (!m_cszChm.IsEmpty() && StrChr(m_cszHome, ':') == NULL) {
if (!m_cszHome.IsEmpty())
NavigateChm(m_cszHome);
else if (m_mapHome)
NavigateChm(m_mapHome);
}
else
Navigate(m_cszHome);
break;
case HH_TB_BACK:
GoBack();
break;
case HH_TB_FORWARD:
GoForward();
break;
case HH_TB_PRINT:
OnFilePrint();
break;
case HH_TB_CLOSE:
GetParent()->PostMessage(WM_CLOSE, 0, 0);
break;
}
}
void CHHCtrl::MoveWindow(CRect* prc, BOOL fRepaint)
{
if (m_pTB) {
CRect rcBtn;
m_pTB->GetClientRect(&rcBtn);
rcBtn.OffsetRect(prc->left, prc->top);
::MoveWindow(m_pTB->m_hWnd, rcBtn.left, rcBtn.top, rcBtn.Width(), rcBtn.Height(), fRepaint);
prc->top += rcBtn.Height() + TB_PAD;
}
::MoveWindow(m_hWnd, prc->left, prc->top, prc->Width(), prc->Height(), fRepaint);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -