Figure 2 Simple Hyperlink Navigation APIs
Function | Description |
HlinkSimpleNavigateToString | Executes a hyperlink jump to a new document or object represented as a string |
HlinkSimpleNavigateToMoniker | Executes a hyperlink jump to a new document or object represented as a moniker |
HlinkGoBack | Executes a hyperlink jump backwards within the navigation stack |
HlinkGoForward | Executes a hyperlink jump forwards within the navigation stack |
Figure 4 WM_CONTEXTMENU Message Handler
void CScribView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CRect rect;
GetClientRect (&rect);
ClientToScreen (&rect);
if (rect.PtInRect (point))
{
CMenu menu;
menu.LoadMenu (IDR_CONTEXTMENU);
CMenu* pContextMenu = menu.GetSubMenu (0);
// If the Scribble application is not hosted in a frame that
// is capable of hosting ActiveX Document Objects, disable the
// "Go Back" and "Go Forward" menu items. The Simple
// Hyperlink Navigation APIs related to Go Back and Go Forward
// only work in-frame.
CScribDoc* pScribDocument = GetDocument ();
if (!pScribDocument -> IsDocObject())
{
pContextMenu -> EnableMenuItem(ID_GOBACK, MF_GRAYED);
pContextMenu -> EnableMenuItem(ID_GOFORWARD, MF_GRAYED);
}
// Display the context menu.
pContextMenu -> TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_RIGHTBUTTON, point.x,
point.y, this);
}
}
Figure 5 Context Menu Item Message Handlers
////////////////////////////////////////////////////////////////////
//
// OnGoBack: Context menu handler for "Go Back". Calls the
// Simple Hyperlink Navigation API HlinkGoBack to go
// back in the Hyperlink history stack.
//
////////////////////////////////////////////////////////////////////
void CScribDoc::OnGoBack()
{
IUnknown* pUnk = NULL;
// Obtain the IUnknown pointer to the document.
HRESULT hr = this -> ExternalQueryInterface ((void*)&IID_IUnknown,
LPVOID *)&pUnk);
if (hr == S_OK)
// Go Back in the hyperlink history stack
HlinkGoBack (pUnk);
}
///////////////////////////////////////////////////////////////////
// OnGoForward: Context menu handler for "Go Back". Calls
// the Simple Hyperlink Navigation API HlinkGoForward
// to go forward in the Hyperlink history stack.
//
///////////////////////////////////////////////////////////////////
void CScribDoc::OnGoForward()
{
IUnknown* pUnk = NULL;
// Obtain the IUnknown pointer to the document.
HRESULT hr = this -> ExternalQueryInterface ((void*)&IID_IUnknown,
LPVOID *)&pUnk);
if (hr == S_OK)
// Go Forward in the hyperlink history stack
hr = HlinkGoForward (pUnk);
}
///////////////////////////////////////////////////////////////////
//
// OnMSHomePage: Context menu handler for "Microsoft Home Page".
// Calls the Simple Hyperlink Hyperlink Navigation
// API HlinkSimpleNavigateToString to display the
// HTML page for Microsoft's Web site
//
///////////////////////////////////////////////////////////////////
void CScribDoc::OnMSHomePage()
{
HRESULT hr;
IUnknown* pUnk = NULL;
if (this -> IsDocObject())
// Obtain the IUnknown pointer to the document.
hr = this -> ExternalQueryInterface ((void*)&IID_IUnknown,
LPVOID *)&pUnk);
HlinkSimpleNavigateToString(L"http://www.microsoft.com/default.htm",
NULL, NULL, pUnk, 0, NULL, NULL, 0);
}
Figure 8 URL Open Stream Functions
Function | Description |
URLOpenStream | Creates a push-type stream object from a URL |
URLOpenBlockingStream | Creates a blocking-type stream object from a URL |
URLDownloadToFile | Downloads bits from the Internet and saves them to a file |
URLOpenPullStream | Creates a pull-type stream object from a URL |
URLOpenHttpStream | Advanced function for doing more sophisticated HTTP and FTP downloads, such as performing an HTTP POST |
Figure 9 IBindStatusCallback Interface
interface IBindStatusCallback: IUnknown
{
HRESULT GetBindInfo([out] DWORD* pgrfBINDF,
[in, out] BINDINFO* pbindinfo);
HRESULT OnStartBinding([in] DWORD dwReserved, [in] IBinding* pbinding);
HRESULT GetPriority([out] LONG* pnPriority);
HRESULT OnProgress([in] ULONG ulProgress, [in] ULONG ulProgressMax,
[in] ULONG ulStatusCode, [in] LPCWSTR szStatusText);
HRESULT OnDataAvailable([in] DWORD grfBSC, [in] DWORD dwSize, [in]
FORMATETC* pformatetc, [in] STGMEDIUM* pstgmed);
HRESULT OnObjectAvailable( [in] REFIID riid, [in] IUnknown *punk);
HRESULT OnLowResource([in] DWORD dwReserved);
HRESULT OnStopBinding([in] HRESULT hrStatus, [in] LPCWSTR szStatusText);
};
Figure 10 IBindStatusCallback Implementation
Function | Implementation |
URLOpenStream | Mandatory |
URLOpenBlockingStream | Optional |
URLDownloadToFile | Optional |
URLOpenPullStream | Mandatory |
URLOpenHttpStream | Optional |
Figure 11 PushCBindStatusCallback::OnDataAvailable
HRESULT CBindStatusCallback::OnDataAvailable
(DWORD grfBSCF, DWORD dwSize, FORMATETC* pfmtetc, STGMEDIUM* pstgmed)
{
.
.
.
if (dwSize < sizeof(BITMAPINFOHEADER) )
return (NOERROR); // not enough has been read yet
// if we did not get the header information, read it now
if (!g_bGotInfoHeader)
{
if (pstgmed->pstm != NULL)
{
DWORD dwRead;
HRESULT hr = pstgmed->pstm->Read (&bmih, sizeof(bmih), &dwRead);
if (SUCCEEDED(hr))
{
g_bGotInfoHeader = TRUE;
return(hr);
}
}
}
.
.
.
}
Figure 12 PullCBindStatusCallback::OnDataAvailable
HRESULT CBindStatusCallback::OnDataAvailable (DWORD grfBSCF, DWORD dwSize,
FORMATETC* pfmtetc,
STGMEDIUM* pstgmed)
{
HRESULT hr = NOERROR;
DWORD dwAmountToRead = dwSize - m_readSoFar;
BYTE *buffer = new BYTE [dwAmountToRead];
while (TRUE)
{
DWORD dwRead;
hr = pstgmed->pstrm->Read (buffer, dwAmountToRead, &dwRead);
if (hr == E_PENDING)
{
// we'll get notified again when more data comes
return (NOERROR);
}
if (SUCCEEDED(hr))
{
// ok, process bits .... and keep looping
}
else
{
// we have an error...
return(hr);
}
}
}
Figure 13 Members of the UOS Structure
Member | Description |
ULONG ulSize | Size of this structure. |
LPUNKNOWN punkCaller | Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX control in the context of an HTML page). The argument represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download. |
LPCTSTR szURL | URL to be downloaded. |
LPCTSTR szVerb | GET, PUT, POST, or a custom verb understood by the server. If NULL, GET is assumed. |
LPCTSTR szHeaders | HTTP headers to use during connection to server. Can be NULL. |
LPBYTE szPostData | Additional data to send after the headers. Typically this will be a POST data arguments. Can be NULL. |
ULONG ulPostDataLen | Size of szPostData. Must not be 0 if szPostData is not NULL. |
ULONG fURLEncode | Flags with either the UOS_URLENCODPOSTDATA, UOS_URLENCODEURL, or can be NULL. The two flags can be combined by a bitwise OR. |
ULONG ulMode | Can be one of UOSM_PUSH, UOSM_PULL, UOS_BLOCK, or UOS_FILE. Each of these maps to one of the functions above and makes this function's programming model fit the corresponding function. |
LPCTSTR szFileName | Name of the local file to write URL data to if ulMode is UOS_FILE. Otherwise, must be NULL. |
LPSTREAM *ppStream | Pointer to IStream pointer if ulMode is UOS_BLOCK. Otherwise, must be NULL. |
LPBINDSTATUSCALLBACK lpbscb | Pointer to IBindStatusCallback interface. This interface and the caller's programming model responsibility depend on the ulMode flag above. The function will behave exactly like the corresponding UOS functions above, depending on the flag settings. |
Figure 15 AVIDNLDR Retrieve Button Message Handler
///////////////////////////////////////////////////////////////////
// CAVIDownloaderDlg::OnBtnRetrieve - Message handler for the Retrieve
// command button. Downloads the .AVI file from the Internet and runs // it in the Media Architects Video Play OCX Control.
//
///////////////////////////////////////////////////////////////////
void CAVIDownloaderDlg::OnBtnRetrieve()
{
// This application does not do any checking to insure that the
// user has entered a valid URL. This exercise is left to the
// reader.
// Create a IBindStatusCallback object
ptrURLDownloadToFileCallback pURLDownloadToFileCallback;
if (!pURLDownloadToFileCallback)
{
AfxMessageBox (_T("Unable to create IBindStatusCallback object."));
return;
}
// Disable the "Retrieve" button
m_btnRetrieve.EnableWindow(FALSE);
BeginWaitCursor();
// Create a temporary file to hold the the .AVI file. This demo
// does not manage files.
LPTSTR lpTempFileName = new TCHAR[MAX_PATH];
LPTSTR lpPathName= new TCHAR[MAX_PATH];
// Retrieve the path of the directory designated for temporary
// files.
::GetTempPath(MAX_PATH,lpPathName);
// Create a name for a temporary file.
if (0 != GetTempFileName (lpPathName, _T("AVI"), 0,
lpTempFileName))
{
// Swap out the .TMP extension with .AVI
CString szFileName = lpTempFileName;
szFileName = szFileName.Left ((szFileName.GetLength() - 3)) +
_T("AVI");
// Call the UOS function to do the file download
CString szURL;
m_URLString.GetWindowText (szURL);
HRESULT hr = URLDownloadToFile (NULL, szURL, szFileName, 0,
pURLDownloadToFileCallback);
if ((hr == S_OK) && (pURLDownloadToFileCallback -> got_File ()
== TRUE))
{
// Setup the Media Architects Video Play OCX Control
// and play the .AVI file that was downloaded.
m_VideoPlay.SetFilename (szFileName);
m_VideoPlay.SetLoop (TRUE);
// Play the entire video
VARIANT varEntireVideo;
varEntireVideo.vt = VT_ERROR;
m_VideoPlay.Play (varEntireVideo, varEntireVideo);
}
}
delete [] lpTempFileName;
delete [] lpPathName;
pURLDownloadToFileCallback -> Release();
m_btnRetrieve.EnableWindow(TRUE);
EndWaitCursor();
}