📄 originserver.cpp
字号:
// OriginServer.cpp : implementation file
//
#include "stdafx.h"
#include "ODDE.h"
#include <dde.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// OriginServer
const int DDE_TIMEOUT_SECS = 30;
OriginServer::OriginServer()
{
m_hwndClientDDE = NULL;
m_hwndServerDDE = NULL;
m_nAckTimeOut = 30000;// 30 sec
memset(&m_pi, 0, sizeof(PROCESS_INFORMATION));
m_cfDataWksheet = RegisterClipboardFormat("DataWorkSheet");
}
OriginServer::~OriginServer()
{
}
BOOL OriginServer::IsServerRunning()
{
return m_hwndServerDDE? TRUE:FALSE;
}
BOOL OriginServer::IsFirstAttemptToConnect()
{
if(m_hwndClientDDE)
return FALSE;
return TRUE;
}
BOOL OriginServer::IsServerNotFound()
{
if(!IsServerRunning() && !IsFirstAttemptToConnect())
return TRUE;
return FALSE;
}
BOOL OriginServer::ConnectServer(HWND hWnd, LPCTSTR lpCmdLine)
{
ASSERT(hWnd);
ASSERT(IsWindow(hWnd));
if(IsServerRunning())
return TRUE;
if(!IsFirstAttemptToConnect()) // already attempted before
return FALSE;
m_hwndClientDDE = hWnd;
// atemp to start
if(!InitiateConnection())
{
if(!StartNewServer(lpCmdLine))
return FALSE;
// server running, try again
if(!CheckInitiateConnection())
return FALSE;
}
return m_hwndServerDDE? TRUE:FALSE;
}
BOOL OriginServer::InitiateConnection()
{
ATOM aTopic,aApp;
aApp = ::GlobalAddAtom(szcAppName);
aTopic = ::GlobalAddAtom(szcTopicName);
/* The DDE connection is set up to
* the Application Origin and any topic
*
*
* Broadcast it to everyone using SendMessage;
* When we return from this call, hwndSender will be valid.
*/
m_wAckState = INITIATE;/* so the ACK knows this is a init message */
::SendMessage((HWND)-1,WM_DDE_INITIATE,(WPARAM)m_hwndClientDDE,MAKELONG(aApp,aTopic));
m_wAckState = 0;
if (aApp != NULL)
GlobalDeleteAtom(aApp);
if (aTopic != NULL)
GlobalDeleteAtom(aTopic);
return m_hwndServerDDE? TRUE:FALSE;
}
BOOL OriginServer::StartNewServer(LPCTSTR lpCmdLine)
{
// if(CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
if(!CreateProcess(NULL, (LPSTR)lpCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &m_pi))
{
AfxMessageBox(IDS_MSG_NO_CONNECTION);
return FALSE;
}
ASSERT(GetSavedServerProcess());
return TRUE;
}
BOOL OriginServer::CheckInitiateConnection()
{
INT startTime = GetTickCount();
INT maxTime = 1000 * DDE_TIMEOUT_SECS; // 30 sec
/// wait for server
while ( !InitiateConnection() )
{
MSG msg;
if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if((int)GetTickCount() - startTime > maxTime)
break;
}
return m_hwndServerDDE? TRUE:FALSE;
}
///------------------------- DDE window proc commands
void OriginServer::On_WM_DDE_ACK(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch(m_wAckState)
{
case INITIATE:
m_hwndServerDDE = (HWND)wParam; // get the partner's handle
break;
default:
// ClientAcknowledge(hWnd,(HWND)wParam, lParam, FALSE);
break;
}
}
void OriginServer::On_WM_DDE_TERMINATE(HWND hWnd)
{
if(!IsServerRunning())
return;
ASSERT(hWnd);
ASSERT(m_hwndClientDDE == hWnd);
m_bDataTransfer = FALSE;
PostMessage(m_hwndServerDDE, WM_DDE_TERMINATE, (WPARAM)hWnd, 0L);
m_hwndServerDDE = NULL;
m_hwndClientDDE = NULL;
}
// when the client app choose to exit
void OriginServer::On_WM_CLOSE(HWND hWnd)
{
if( m_hwndServerDDE )
{
//::SendMessage(m_hwndServerDDE,WM_CLOSE,0,0);
PostMessage(m_hwndServerDDE, WM_DDE_TERMINATE, (WPARAM)hWnd, 0L);
// wait for termination to finish
INT startTime = GetTickCount();
INT maxTime = 1000 * DDE_TIMEOUT_SECS; // 30 sec
while ( m_hwndServerDDE )
{
MSG msg;
if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if((int)GetTickCount() - startTime > maxTime)
break;
}
if(m_hwndServerDDE)
::MessageBox(NULL,"Timeout","DDE Message",MB_OK);
}
HANDLE hProcess;
if(hProcess = GetSavedServerProcess())
{
DWORD dwExitCode;
BOOL bRetGetExitCode = GetExitCodeProcess(hProcess, &dwExitCode);
BOOL bRet = TerminateProcess(hProcess, dwExitCode);
TRACE("Exit code = %d and ret = %d\n",bRetGetExitCode, bRet);
}
}
BOOL OriginServer::SendData(HANDLE hData, LPCTSTR lpcszItem, WORD wOriginDDEFormat)
{
/* we need to specify the name of the worksheet
* as our DDE item. This name must match that
* in the Origin document that is to receive
* the DDE data.
*/
ATOM atomItem = GlobalAddAtom(lpcszItem);
m_wAckState = POKE;
SetTimer(m_hwndClientDDE, (UINT)m_hwndServerDDE, m_nAckTimeOut, NULL);
if (!PostMessage(m_hwndServerDDE, WM_DDE_POKE, (WPARAM)m_hwndClientDDE, PackDDElParam(WM_DDE_POKE, (UINT)hData, atomItem)))
{
GlobalDeleteAtom(atomItem);
return FALSE;
}
return TRUE;
}
//IV 04/07/99 t3291 FINISH_MOVE_DDEDEMO_32BIT
BOOL OriginServer::SendCommandString(LPCTSTR lpstrCommand)
{
if(!IsServerRunning())
return FALSE;
if(m_wAckState == EXECUTE)
{
AfxMessageBox(IDS_MSG_SCRIPT_SENDIN_BUSY);
return FALSE;
}
LPSTR lpExecuteString;
HANDLE hExecuteString;
if (!(hExecuteString
= GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)lstrlen(lpstrCommand) + 1)))
return FALSE;
if (!(lpExecuteString = (LPSTR)GlobalLock(hExecuteString)))
{
GlobalFree(hExecuteString);
return FALSE;
}
lstrcpy(lpExecuteString, lpstrCommand);
GlobalUnlock(hExecuteString);
m_wAckState = EXECUTE;
SetTimer(m_hwndClientDDE, (UINT)m_hwndServerDDE, m_nAckTimeOut, NULL);
//if (!PostMessage(m_hwndServerDDE, WM_DDE_EXECUTE, (WPARAM)m_hwndClientDDE, MAKELONG(0, hExecuteString)))
if (!PostMessage(m_hwndServerDDE, WM_DDE_EXECUTE, (WPARAM)m_hwndClientDDE, PackDDElParam(WM_DDE_EXECUTE,0, (UINT)hExecuteString)))
{
GlobalFree(hExecuteString);
}
m_wAckState = 0;
return(0);
}
//end FINISH_MOVE_DDEDEMO_32BIT
///--------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -