www.pudn.com > pueblo.zip > ChDDE.cpp
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
The contents of this file are subject to the Andromedia Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.andromedia.com/APL/
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Pueblo client code, released November 4, 1998.
The Initial Developer of the Original Code is Andromedia Incorporated.
Portions created by Andromedia are Copyright (C) 1998 Andromedia
Incorporated. All Rights Reserved.
Andromedia Incorporated 415.365.6700
818 Mission Street - 2nd Floor 415.365.6701 fax
San Francisco, CA 94103
Contributor(s):
--------------------------------------------------------------------------
Chaco team: Dan Greening, Glenn Crocker, Jim Doubek,
Coyote Lussier, Pritham Shetty.
Wrote and designed original codebase.
------------------------------------------------------------------------------
This file consists of the Chaco DDE interface to WEB clients.
----------------------------------------------------------------------------*/
#include "grheader.h"
#include
#include
#if !defined( CH_VRML_VIEWER )
#include
#endif
//#if defined( CH_NOTIFY_MODULE )
//#include
//#endif
#include
#include
#include
#include
#include
#include "ChDDEPrv.h"
#ifdef UNICODE
#define STRICMP wcsicmp
#define ITOA(c, sz, b) (itoa(sizeof(szA), szA, b), mbstowcs(sz, szA, b), sz)
#else
#define STRICMP stricmp
#define ITOA itoa
#endif // UNICODE
#define CH_USE_SOCKET
#define DDE_ERR_MSG "Unable to establish converstion with a web browser. Please start the browser application and retry the operation."
// Static initialization.
ChVisitedList ChHTTPDDE::m_visitedList;
ChConnActiveList ChHTTPDDE::m_connActiveList;
ChConnWaitList ChHTTPDDE::m_connWaitList;
unsigned long ChHTTPDDE::m_numObjects = 0;
string ChHTTPDDE::m_strStatusMsg;
DWORD ChHTTPDDE::m_dwProgress = 0;
DWORD ChHTTPDDE::m_dwMaxRange = 0;
CRITICAL_SECTION ddeSync;
#if defined( CH_USE_SOCKET )
ChHTTPSocketConn* httpSocketConn = 0;
#endif
#define CH_DDE_NOTIFY_CLASS "Chaco-DDE-Notification-Class"
LRESULT CALLBACK EXPORT DDENotifyProc( HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam );
class ChDDEConnInfo;
class ChDDEConnStream : public ChHTTPStream
{
public :
ChDDEConnStream() : m_pUserStreamData( 0 ), m_pDDEInfo(0),
m_uStreamOption(0)
{
}
virtual ~ChDDEConnStream()
{
}
// methods provided my the base class
virtual const string& GetURL();
virtual const string& GetMimeType();
virtual const string& GetCacheFilename();
virtual const char* GetErrorMsg() { return m_strDummy; }
virtual const string& GetContentEncoding() { return m_strDummy; }
virtual const string& GetLastModified() { return m_strDummy; }
virtual const string& GetTargetWindowName() { return m_strDummy; }
virtual long GetContentLength() { return 0; }
virtual void* GetStreamPrivateData() { return m_pUserStreamData; }
// Attributes
virtual void SetStreamPrivateData( void *pData )
{ m_pUserStreamData = pData; }
public :
void* m_pUserStreamData;
ChDDEConnInfo* m_pDDEInfo;
UINT m_uStreamOption;
string m_strDummy;
};
/////////////////////////////////////////////////////////////////////////////
// ChDDEConnInfo
// This class maintains information about the requested URL. There will be one
// instance of this object per GetURL request. If the request is new then
// this goes into the active list and is removed when ViewDocFile is received.
// If this is a duplicate then it goes into the wait list.
class ChDDEConnInfo
{
public :
enum tagDDEWndMsg { msgGetURL = 1, msgRegisterViewer };
ChDDEConnInfo(ChHTTPDDE* pDDE, string& strURL, chuint32 flOptions,
chparam userData ) : m_phttpDDE(pDDE),
m_strURL( strURL ),
m_userData( userData ),
m_flOptions( flOptions ) {}
~ChDDEConnInfo() {}
ChHTTPDDE* GetHTTPDDE() { return m_phttpDDE; }
chparam GetUserData() { return m_userData; }
const string& GetURL() { return m_strURL; }
const string& GetMimeType() { return m_strMimeType; }
const string& GetFileName() { return m_strCacheFile; }
chuint32 GetOptions() { return m_flOptions; }
void DoLoadCompeteNotification( string& strFile, string& strMimeType );
void ChDDEConnInfo::DoErrorNotification( int iError );
private :
ChHTTPDDE *m_phttpDDE;
ChDDEConnStream m_ddeStream;
chparam m_userData;
string m_strURL;
string m_strMimeType;
string m_strCacheFile;
int iError;
chuint32 m_flOptions;
};
/////////////////////////////////////////////////////////////////////////////
// ChVisitedInfo
// This class maintains the URL's visted during this session
class ChVisitedInfo
{
public :
ChVisitedInfo( string& strLocalFile, string strMimeType ) :
m_strLocalFile( strLocalFile ),
m_strMimeType( strMimeType )
{}
~ChVisitedInfo() {}
string& GetLocalFileName()
{
return m_strLocalFile;
}
string& GetMimeType()
{
return m_strMimeType;
}
private :
string m_strLocalFile;
string m_strMimeType;
};
/////////////////////////////////////////////////////////////////////////////
// ChHTTPConnStream Implementation
const string& ChDDEConnStream::GetURL()
{
return m_pDDEInfo->GetURL();
}
const string& ChDDEConnStream::GetMimeType()
{
return m_pDDEInfo->GetMimeType();
}
const string& ChDDEConnStream::GetCacheFilename()
{
return m_pDDEInfo->GetFileName();
}
/////////////////////////////////////////////////////////////////////////////
// ChDDEConnInfo Implementation
void ChDDEConnInfo::DoLoadCompeteNotification( string& strFile, string& strMimeType )
{
if ( !m_phttpDDE->GetStreamMgr() )
{
return;
}
m_strMimeType = strMimeType;
m_strCacheFile = strFile;
m_ddeStream.m_pDDEInfo = this;
m_ddeStream.m_uStreamOption = m_phttpDDE->GetStreamMgr()->
NewStream( GetUserData(), &m_ddeStream, false );
if ( m_ddeStream.m_uStreamOption & ChHTTPStreamManager::streamAsFile )
{
m_phttpDDE->GetStreamMgr()->StreamAsFile( GetUserData(),
&m_ddeStream, strFile );
}
m_phttpDDE->GetStreamMgr()->DestroyStream( GetUserData(), &m_ddeStream, 0 );
}
void ChDDEConnInfo::DoErrorNotification( int iError )
{
if ( !m_phttpDDE->GetStreamMgr() )
{
return;
}
m_ddeStream.m_pDDEInfo = this;
m_ddeStream.m_uStreamOption = m_phttpDDE->GetStreamMgr()->
NewStream( GetUserData(), &m_ddeStream, false );
m_phttpDDE->GetStreamMgr()->DestroyStream( GetUserData(), &m_ddeStream, iError );
}
/////////////////////////////////////////////////////////////////////////////
// ChHTTPDDE implementation
ChHTTPDDE::ChHTTPDDE( ChHTTPStreamManager* pStreamMgr, chuint32 flOptions )
: ChHTTPConn( pStreamMgr, flOptions ),
m_pDDE( 0 ),
m_boolStopLoading(0),
m_boolConnectionValid(0),
m_boolNotifyDone( 0 ),
m_dwTransactionID( 0 ),
m_dwWindowID( 0 ),
m_hWndDDE(0)
{
InitDDEConn();
}
void ChHTTPDDE::InitDDEConn()
{
/*
* Here we tell DDEML what we will be doing.
*
* 1) We let it know our callback proc address - MakeProcInstance
* is called just to be more portable.
*/
if ( 0 == m_numObjects )
{
WNDCLASS wc;
wc.hInstance = AfxGetInstanceHandle( );
wc.lpszClassName = CH_DDE_NOTIFY_CLASS;
wc.lpfnWndProc = DDENotifyProc;
wc.hCursor = 0;
wc.hIcon = 0;
wc.hbrBackground = 0;
wc.lpszMenuName = 0;
wc.style = 0;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
RegisterClass( &wc );
::InitializeCriticalSection( &ddeSync );
if (DdeInitialize(&CDDEObject::m_dwidInst,
(PFNCALLBACK)MakeProcInstance((FARPROC)ChacoVRMLDdeCallback, hInstance),
APPCLASS_STANDARD , 0))
{
CDDEObject::m_dwidInst = 0ul;
}
#if !defined( CH_VRML_VIEWER )
ChCore::SetDDEInstance( CDDEObject::m_dwidInst );
#endif
}
// Incerement the usage count
m_numObjects++;
if ( CDDEObject::m_dwidInst )
{
// new should THROW if unable to allocate.
m_pDDE = new CDDEObject( CDDEObject::srvMosaic, this);
ASSERT( m_pDDE );
EstablishConversation();
}
}
bool ChHTTPDDE::EstablishConversation()
{
// Try connecting to a Web Browser
for ( int i = 0; i < CDDEObject::maxServers; i++ )
{
m_pDDE->SetServer( i );
if ( RegisterViewers() )
{
m_boolConnectionValid = true;
return true;
}
}
m_pDDE->SetServer( CDDEObject::srvMosaic );
return false;
}
class ZapVisitedConn : public ChVisitor2
{
public:
bool Visit( const string& key, const pChVisitedInfo& pVisited )
{
delete pVisited;
return true;
}
};
ChHTTPDDE::~ChHTTPDDE( )
{
// Decerement the usage count
m_numObjects--;
if ( CDDEObject::m_dwidInst )
{
UnregisterViewers();
}
if ( m_pDDE )
{
delete m_pDDE;
}
if ( m_hWndDDE )
{
::DestroyWindow( m_hWndDDE );
}
if ( 0 == m_numObjects )
{
ShutDownHTTP();
}
}
void ChHTTPDDE::ShutDownHTTP()
{
if ( m_numObjects > 0 )
{ // Shutdown when there is a object still active
m_numObjects = 0;
}
if ( 0 == m_numObjects )
{
#if defined( CH_USE_SOCKET )
if ( httpSocketConn )
{
httpSocketConn->ShutDownHTTP();
// to cache management
ChHTTPSocketConn::EnforceCacheLimit();
delete httpSocketConn;
}
#endif
::EnterCriticalSection( &ddeSync );
ChPosition posConn = GetConnectionList().GetHeadPosition();
while (0 != posConn)
{
ChDDEConnInfo *pConn = ChHTTPDDE::GetConnectionList().GetHead();
ChHTTPDDE::GetConnectionList().RemoveHead();
delete pConn;
posConn = ChHTTPDDE::GetConnectionList().GetHeadPosition();
}
// zap all visited entries
//ZapVisitedConn zapVisited;
//GetVisitedList().Infix( zapVisited );
posConn = GetWaitList().GetHeadPosition();
while (0 != posConn)
{
ChDDEConnInfo *pConn = ChHTTPDDE::GetWaitList().GetHead();
ChHTTPDDE::GetWaitList().RemoveHead();
delete pConn;
posConn = ChHTTPDDE::GetWaitList().GetHeadPosition();
}
::LeaveCriticalSection( &ddeSync );
::DeleteCriticalSection( &ddeSync );
if ( CDDEObject::m_dwidInst )
{
DdeNameService(CDDEObject::m_dwidInst, NULL, NULL, DNS_UNREGISTER);
// Uninitialize DDE
DdeUninitialize( CDDEObject::m_dwidInst );
}
}
}
BOOL ChHTTPDDE::RegisterViewers( )
{
CString strServer( m_pDDE->GetServiceName() );
CString strMimeType;
// See if we have a browser that can talk to us
if( !m_pDDE->WWW_Version( ) )
{
// return false;
}
#if defined( CH_VRML_VIEWER )
strMimeType = MIME_VRML;
if( !m_pDDE->WWW_RegisterViewer( strServer, strMimeType, 0x04 ) )
{
return false;
}
strMimeType = MIME_GIF;
if( !m_pDDE->WWW_RegisterViewer( strServer, strMimeType, 0x04 ) )
{
return false;
}
strMimeType = MIME_JPEG;
if ( !m_pDDE->WWW_RegisterViewer( strServer, strMimeType, 0x04 ) )
{
return false;
}
strMimeType = MIME_BMP;
if ( !m_pDDE->WWW_RegisterViewer( strServer, strMimeType, 0x04 ) )
{
return false;
}
#else
// See if we have a browser that can talk to us
if( !m_pDDE->WWW_Version( ) )
{
return false;
}
#endif
return TRUE;
}
BOOL ChHTTPDDE::UnregisterViewers( )
{
if ( !m_boolConnectionValid )
{
return false;
}
#if defined( CH_VRML_VIEWER )
CString strServer( m_pDDE->GetServiceName() );
CString strMimeType;
strMimeType = MIME_VRML;
m_pDDE->WWW_UnRegisterViewer( strServer, strMimeType );
strMimeType = MIME_GIF;
m_pDDE->WWW_UnRegisterViewer( strServer, strMimeType);
strMimeType = MIME_JPEG;
m_pDDE->WWW_UnRegisterViewer( strServer, strMimeType );
strMimeType = MIME_BMP;
m_pDDE->WWW_UnRegisterViewer( strServer, strMimeType );
#endif
return TRUE;
}
void ChHTTPDDE::GetProgressMsg( string& strMsg, int& iPercentComplete )
{
int iConnections = m_connActiveList.GetCount() +
m_connWaitList.GetCount();
if ( httpSocketConn && iConnections == 0 )
{ // our connections
httpSocketConn->GetProgressMsg( strMsg, iPercentComplete );
}
else
{
}
}
bool ChHTTPDDE::IsActive()
{
int iConnections = m_connActiveList.GetCount() +
m_connWaitList.GetCount();
if ( httpSocketConn )
{ // our connections
iConnections += httpSocketConn->NumActive();
}
return iConnections > 0;
}
int ChHTTPDDE::NumActive()
{
int iConnections = m_connActiveList.GetCount() +
m_connWaitList.GetCount();
if ( httpSocketConn )
{ // our connections
iConnections += httpSocketConn->NumActive();
}
return iConnections;
}
void ChHTTPDDE::AbortRequests( bool boolAbortPrefetch /*= false */,
ChHTTPStreamManager* pStreamMgr /*= 0 */ )
{
m_boolStopLoading = true;
::EnterCriticalSection( &ddeSync );
if ( GetConnectionList().GetCount() )
{
if ( m_dwTransactionID )
{
m_pDDE->WWW_CancelProgress( m_dwTransactionID );
}
ChPosition posConn = GetConnectionList().GetHeadPosition();
while (0 != posConn)
{
ChDDEConnInfo *pConn = ChHTTPDDE::GetConnectionList().GetHead();
pConn->DoErrorNotification( CH_HTTP_ERROR_USER_ABORT);
ChHTTPDDE::GetConnectionList().RemoveHead();
delete pConn;
posConn = ChHTTPDDE::GetConnectionList().GetHeadPosition();
}
}
ChPosition posConn = GetWaitList().GetHeadPosition();
while (0 != posConn)
{
ChDDEConnInfo *pConn = GetWaitList().GetHead();
GetWaitList().RemoveHead();
delete pConn;
posConn = ChHTTPDDE::GetWaitList().GetHeadPosition();
}
::LeaveCriticalSection( &ddeSync );
// check if we have our own http requests
if ( httpSocketConn )
{
httpSocketConn->AbortRequests();
}
}
bool ChHTTPDDE::ViewFile( const string strURL, const string& strFile )
{
string strEmpty;
// To prevent recursive calls between client and server
UnregisterViewers( );
DWORD dwResult = m_pDDE->WWW_OpenURL( strURL, strEmpty, 0xFFFFFFFF,
0x04, strEmpty, strEmpty,
m_pDDE->GetServiceName() );
if ( dwResult == 0 )
{ // connection failed, try shell execute
char strBuffer[MAX_PATH];
::GetCurrentDirectory( MAX_PATH, strBuffer );
ShellExecute( AfxGetMainWnd()->GetSafeHwnd(),
"open", strFile, NULL, strBuffer, 0);
}
RegisterViewers( );
return true;
}
bool ChHTTPDDE::ProcessPendingRequest( UINT uType )
{
switch( uType )
{
case ChDDEConnInfo::msgGetURL :
{
if ( ChHTTPDDE::GetWaitList().GetCount() )
{
ProcessConnectionRequest();
}
break;
}
case ChDDEConnInfo::msgRegisterViewer :
{
static int iTryCount = 0;
if ( !IsConnectionValid() )
{
EstablishConversation();
// Send connection done if we successfully connected
}
if( IsConnectionValid() )
{
iTryCount = 0;
m_pDDE->WWW_RegisterDone();
}
else if ( iTryCount++ < 100 )
{ // We are not up yet, post a message to try again
RegisterNow();
}
break;
}
default :
{
break;
}
}
return true;
}
bool ChHTTPDDE::ProcessConnectionRequest( )
{
bool boolSuccess = true;
// check to see if we have a vaild connection established with the server
if ( !IsConnectionValid() )
{ // Not valid try connections
if ( !EstablishConversation() )
{ // have I notified the user of this
if ( !m_boolNotifyDone )
{
#if !defined( CH_USE_SOCKET )
m_boolNotifyDone = true;
AfxMessageBox( DDE_ERR_MSG, MB_OK | MB_ICONEXCLAMATION );
#endif
}
#if !defined( CH_USE_SOCKET )
return false;
#endif
}
}
#if defined( CH_USE_SOCKET )
retry :
if ( !IsConnectionValid() )
{
ChDDEConnInfo *pConn = GetWaitList().GetHead();
GetWaitList().RemoveHead();
// Don't try any other method if user wants URL by DDE only
if ( ChHTTPConn::UseDDEOnly & pConn->GetOptions() )
{
delete pConn;
return false;
}
if ( httpSocketConn == 0 )
{
TRACE( "Unable to establish conversation with a DDE server, using Chaco's HTTP engine\n" );
httpSocketConn = new ChHTTPSocketConn( GetStreamMgr() );
}
// we will do our on notification
httpSocketConn->GetURL( pConn->GetURL(),
pConn->GetUserData(), 0, pConn->GetOptions());
delete pConn;
return true;
}
#endif
::EnterCriticalSection( &ddeSync );
TRACE2( "ProcessConnectionRequest : Num pending %d, Num in wait %d\n", GetConnectionList().GetCount(),
GetWaitList().GetCount( ) );
while( GetConnectionList().GetCount() == 0 && GetWaitList().GetCount( ) )
{ // start the next request
ChDDEConnInfo *pConn = GetWaitList().GetHead();
GetWaitList().RemoveHead();
GetConnectionList().AddTail( pConn );
// Send the request
CString strEmpty, strFileName;
strEmpty.Empty();
//ChUtil::GetTempFileName( strFileName, 0, 0, 0 );
m_dwTransactionID = m_pDDE->WWW_OpenURL( pConn->GetURL(), strFileName, 0xFFFFFFFF,
0x04, strEmpty, strEmpty,
m_pDDE->GetServiceName() );
if ( m_dwTransactionID == 0 )
{ // connection failed
UnregisterViewers();
m_boolConnectionValid = false;
#if !defined( CH_USE_SOCKET )
pConn->DoErrorNotification( CH_HTTP_ERROR_CONNECT );
delete pConn;
ChHTTPDDE::GetConnectionList().RemoveTail();
boolSuccess = false;
#else
GetWaitList().AddTail( pConn );
ChHTTPDDE::GetConnectionList().RemoveTail();
::LeaveCriticalSection( &ddeSync );
goto retry;
#endif
}
}
::LeaveCriticalSection( &ddeSync );
return boolSuccess;
}
bool ChHTTPDDE::GetURL( const string& strURL, chparam userData,
const char* pstrDefURL /* = 0 */,
chuint32 flOptions /*= 0 */,
ChHTTPStreamManager* pStreamMgr /*= 0 */)
{
// resolve the URL
string strRequest;
ChURLParts urlParts;
if ( urlParts.GetURLParts( strURL, pstrDefURL ) )
{
if( urlParts.GetScheme() == ChURLParts::typeFile )
{
// Map URL to localfile
strRequest = urlParts.GetURL();
string strFile, strMimeType;
ChURLParts::MapURLToHostFile( strRequest, strFile );
ChHTTPConn::GetMimeTypeByFileExtn( strFile, strMimeType );
ChDDEConnInfo *pNewConn = new ChDDEConnInfo( this, strRequest, flOptions, userData );
ASSERT( pNewConn );
if ( ChUtil::FileExists( strFile ) )
{
pNewConn->DoLoadCompeteNotification( strFile, strMimeType );
}
else
{
pNewConn->DoErrorNotification( CH_HTTP_ERROR_NOT_FOUND );
}
delete pNewConn;
return TRUE;
}
}
strRequest = urlParts.GetURL();
// check if we have a file scheme for GetURL, if we do
// then resolve path and do a load complete
m_boolStopLoading = false;
#if 0
if ( pstrDefURL && !strURL.IsEmpty() )
{
// Parse anchor
m_pDDE->WWW_ParseAnchor( CString( pstrDefURL ), strURL, strRequest );
}
else
{
strRequest = strURL;
}
#endif
if ( strRequest.IsEmpty() )
{
TRACE( "Error : URL is empty \n" );
ChDDEConnInfo *pNewConn = new ChDDEConnInfo( this, strRequest, flOptions, userData );
ASSERT( pNewConn );
pNewConn->DoErrorNotification( CH_HTTP_ERROR_BAD_URL );
delete pNewConn;
return FALSE;
}
TRACE1( "Getting URL %s\n", LPCSTR( strRequest ) );
// Check if we have already visted the location
ChVisitedInfo ** ppVisted = GetVisitedList().Find( strRequest );
if ( ppVisted && *ppVisted )
{ // return what we have
ChDDEConnInfo *pNewConn = new ChDDEConnInfo( this, strRequest, flOptions, userData );
ASSERT( pNewConn );
pNewConn->DoLoadCompeteNotification( (*ppVisted)->GetLocalFileName(),
(*ppVisted)->GetMimeType() );
delete pNewConn;
return TRUE;
}
// Find if this is a duplicate request, if it is put
// it in our wait list, else add it to our conn list
ChDDEConnInfo *pNewConn = new ChDDEConnInfo( this, strRequest, flOptions, userData );
ASSERT( pNewConn );
::EnterCriticalSection( &ddeSync );
GetWaitList().AddTail( pNewConn );
::LeaveCriticalSection( &ddeSync );
return ProcessConnectionRequest();
}
void ChHTTPDDE::QueryURL( const string& strFile, string& strURL, string& strMimeType )
{
//Unfortunately we cannot find the mime type of the document
strMimeType.Empty();
m_pDDE->WWW_QueryURLFile( strFile, strURL );
}
void ChHTTPDDE::ViewDocFile( CString& strFile, CString& strURL, CString& strMimeType )
{
TRACE1( "ViewDocFile : Num pending %d\n", GetConnectionList().GetCount() - 1 );
ChDDEConnInfo * pConn = 0;
if ( GetConnectionList().GetCount() != 0 )
{
pConn = GetConnectionList().GetHead();
}
if ( pConn )
{
GetConnectionList().RemoveHead();
if ( strFile.IsEmpty() || strURL.IsEmpty() || strMimeType.IsEmpty() )
{
pConn->DoErrorNotification( CH_HTTP_ERROR_NOT_FOUND );
}
else
{
pConn->DoLoadCompeteNotification( strFile, strMimeType );
// Add this to our visted list
ChVisitedInfo *pVisted = new ChVisitedInfo( strFile, strMimeType );
ASSERT( pVisted );
GetVisitedList().Insert( strURL, pVisted );
}
}
else
{
// we have a request from the server to view a file that was not requested
// by me
ChDDEConnInfo *pConn = new ChDDEConnInfo( this, strURL,
0, 0 );
ASSERT( pConn );
pConn->DoLoadCompeteNotification( strFile, strMimeType );
delete pConn;
// Add this to our visted list
ChVisitedInfo *pVisted = new ChVisitedInfo( strFile, strMimeType );
ASSERT( pVisted );
GetVisitedList().Insert( strURL, pVisted );
}
if ( ChHTTPDDE::GetWaitList().GetCount() )
{
#if defined( CH_USE_DDE )
// Process wait request
if ( GetDDEPostingWindow())
{
::PostMessage( GetDDEPostingWindow(), WM_CHACO_HTTP_MSG,
ChDDEConnInfo::msgGetURL, (LPARAM)this );
}
#endif
}
// if ( GetNotificationWnd() )
{
// ::SetFocus( GetNotificationWnd() );
}
return;
}
DWORD ChHTTPDDE::Alert( const CString& csMessage, DWORD dwType, DWORD dwButtons )
{
#if 0
if ( GetNotificationWnd() )
{
#if defined( CH_MSW )
ChHTTPNotification* pInfo = new ChHTTPNotification( ChHTTPNotification::msgAlert,
csMessage, dwType, dwButtons );
ASSERT( pInfo );
::PostMessage( GetNotificationWnd(), WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo );
#endif
}
#endif
return 0;
}
void ChHTTPDDE::SetProgressRange( DWORD dwID, DWORD dwRange )
{
m_dwMaxRange = dwRange;
}
void ChHTTPDDE::BeginProcess( DWORD dwTransactionID, const CString& csInitialMessage )
{
m_strStatusMsg = csInitialMessage;
m_dwTransactionID = dwTransactionID;
#if 0
if ( GetNotificationWnd() )
{
#if defined( CH_MSW )
ChHTTPNotification* pInfo = new ChHTTPNotification(
ChHTTPNotification::msgBeginProcess, csInitialMessage );
ASSERT( pInfo );
::PostMessage( GetNotificationWnd(), WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo );
#endif
}
#endif
}
bool ChHTTPDDE::MakingProgress( DWORD dwTransactionID, const CString& csMessage, DWORD dwProgress )
{
#if 0
if ( GetNotificationWnd() )
{
#if defined( CH_MSW )
ChHTTPNotification* pInfo = new ChHTTPNotification( ChHTTPNotification::msgMakingProgress,
csMessage, dwProgress, m_dwMaxRange );
ASSERT( pInfo );
::PostMessage( GetNotificationWnd(), WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo );
#endif
}
#endif
if ( !csMessage.IsEmpty() )
{
m_strStatusMsg = csMessage;
m_dwProgress = dwProgress;
}
if ( m_dwProgress == m_dwMaxRange )
{
m_dwProgress = m_dwMaxRange = 0;
m_strStatusMsg.Empty();
}
return ( m_boolStopLoading );
}
void ChHTTPDDE::OpenURLResult( DWORD dwTrans, DWORD dwWindow )
{
if ( GetDDEPostingWindow())
{
::PostMessage( GetDDEPostingWindow(), WM_CHACO_HTTP_MSG,
ChDDEConnInfo::msgGetURL, (LPARAM)this );
}
}
void ChHTTPDDE::EndProgress( DWORD dwProgress )
{
TRACE( "End Progress\n" );
m_dwTransactionID = 0;
m_strStatusMsg.Empty();
m_dwProgress = 0;
m_dwMaxRange = 0;
#if 0
// if we still have the connection in the active list because
// we did not get a ViewDocFile, remove it
::EnterCriticalSection( &ddeSync );
ChPosition posConn = GetConnectionList().GetHeadPosition();
while (0 != posConn)
{
ChDDEConnInfo *pConn = GetConnectionList().GetHead();
GetConnectionList().RemoveHead();
delete pConn;
posConn = ChHTTPDDE::GetConnectionList().GetHeadPosition();
}
::LeaveCriticalSection( &ddeSync );
#endif
#if 0
if ( GetNotificationWnd() )
{
#if defined( CH_MSW )
ChHTTPNotification* pInfo = new ChHTTPNotification( ChHTTPNotification::msgEndProgress );
ASSERT( pInfo );
::PostMessage( GetNotificationWnd(), WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo );
#if 0
#if defined( CH_USE_DDE )
// Process wait request
pInfo = new ChHTTPNotification( this );
ASSERT( pInfo );
::PostMessage( GetNotificationWnd(), WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo );
#endif
#endif
#endif
}
#endif
}
void ChHTTPDDE::RegisterNow()
{
// ::DebugBreak();
// Create the posting window
if ( GetDDEPostingWindow())
{
::PostMessage( GetDDEPostingWindow(), WM_CHACO_HTTP_MSG,
ChDDEConnInfo::msgRegisterViewer, (LPARAM)this );
}
}
HWND ChHTTPDDE::GetDDEPostingWindow( )
{
if ( !m_hWndDDE )
{
m_hWndDDE = ::CreateWindow( CH_DDE_NOTIFY_CLASS, "Chaco DDE Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, AfxGetInstanceHandle( ), 0 );
}
return m_hWndDDE;
}
LRESULT CALLBACK EXPORT
DDENotifyProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if (WM_CHACO_HTTP_MSG == uMsg && lParam )
{
ChHTTPDDE* pDDE = (ChHTTPDDE*)lParam;
pDDE->ProcessPendingRequest( wParam );
return 0;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}