// Application class
class CClientApp : public CWinApp
{
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
};
// Main window class, inherits also from DDEClient
class CMainWindow : public CFrameWnd, public DDEClient
{
UINT PointClipFormat; // Clipboard format for Position
CPoint Position; // Position of circle in client area
public:
CMainWindow();
// Overridden DDEClient's virtual functions
virtual BOOL
ReceiveAdvise(const DDEString & Item,
const DDEDataIn * const data, UINT format);
virtual void
TransactionCompleted(const DDEString & Item,
const DDEDataIn * const data, UINT format, DWORD UserID,
BOOL Ok);
virtual void Disconnected();
virtual void
Register(const DDEString & BaseServiceName,
const DDEString & InstanceServiceName, BOOL Register);
protected:
// Windows message handlers
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
//client.cpp
#include <afxwin.h>
#include "ddegio.h" // DDE framework
#include "Client.h"
// How to use the program:
// Click left mouse button to connect to DDE server
// Click right mouse button to disconnect from server
// Move mouse on client area to send position to server
// Doubleclick left button to send Maximize command
CClientApp ClientApp;
BOOL CClientApp::InitInstance()
{
DDEInitialize(); // Framework initialization
m_pMainWnd=new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
int CClientApp::ExitInstance()
{
DDEUninitialize(); // Framework cleanup
return CWinApp::ExitInstance();
}
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
CMainWindow::CMainWindow()
: Position(0,0),
PointClipFormat(RegisterClipboardFormat("POINT"))
{
Create(NULL,"DDE Client"); // Create main window
}
// Draw status of client and rectangle at current position
void CMainWindow::OnPaint()
{
CPaintDC DC(this);
CString Status=IsConnected()?"Connected":"Disconnected";
DC.TextOut(0,0,Status);
DC.Rectangle(Position.x-9, Position.y-9,
Position.x+9,Position.y+9);
}
// Try to connect to server if not already connected
// If it connects, it also requests current circle position
// and starts advise link on it
void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!IsConnected() && Connect("DDEServerTest","Mouse"))
{
Request("Position",NULL,PointClipFormat,111);
StartAdvise("Position",FALSE,FALSE,PointClipFormat,222);
}
}
// Disconnect from DDE server
void CMainWindow::OnRButtonDown(UINT nFlags, CPoint point)
{
if (IsConnected())
{
Disconnect();
InvalidateRect(NULL);
}
}
// Tell the server the new position for its circle
void CMainWindow::OnMouseMove(UINT nFlags, CPoint point)
{
if (IsConnected()) // Asyncronous to avoid reentrancy problems
Poke("Position",&point,sizeof(point),PointClipFormat,333);
}
// Send maximize command to server
void CMainWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (IsConnected())
Execute("[Maximize()]",444); // Asynchronous
}
// Receive new position of server's circle when it changes
BOOL
CMainWindow::ReceiveAdvise(const DDEString & Item,
const DDEDataIn * const pData, UINT format)
{
if (Item=="Position" && pData!=NULL)
{
memcpy(&Position,pData->GetData(),sizeof(Position));
InvalidateRect(NULL);
return TRUE;
}
else return FALSE;
}
// Receive notification that asynchronous transaction completed
void
CMainWindow::TransactionCompleted(const DDEString & Item,
const DDEDataIn * const pData,UINT format,DWORD UserID,BOOL Ok)
{
// I only care when a request transaction completes
// I started the request transaction with ID 111
if (Ok && UserID==111 && pData!=NULL)
{
memcpy(&Position,pData->GetData(),sizeof(Position));
InvalidateRect(NULL);
}
}
// Receive notification that client got disconnected
void CMainWindow::Disconnected()
{
InvalidateRect(NULL);
}
// Flash your window when a server registers a service
void
CMainWindow::Register(const DDEString & BaseServiceName,
const DDEString & InstanceServiceName, BOOL Register)
{
TRACE("A server %sregistered the %s service\n",
Register?"":"un", (LPCSTR)BaseServiceName);
}
// Report DDE errors
void ReportDDEErrorToApp(UINT,LPCSTR message)
{
MessageBox(AfxGetMainWnd()->GetSafeHwnd(),
message,"Dde Error",MB_OK);
}
/*
// Just to show you a synchronous request
void CMainWindow::ShowYouSynchronousRequestTransaction()
{
if (IsConnected())
{
DDEDataIn Data;
if (Request("Position",&Data) &&
Data.GetSize()>=sizeof(Position))
{
memcpy(&Position,Data.GetData(),sizeof(Position));
InvalidateRect(NULL);
}
}
}
*/