Skip to content

Instantly share code, notes, and snippets.

@gaxar77
Created August 29, 2010 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaxar77/555774 to your computer and use it in GitHub Desktop.
Save gaxar77/555774 to your computer and use it in GitHub Desktop.
Interprocess Communication without named pipes, memory mapped files, or sockets.
//AppTalk.cpp
//Author: Guido Arbia
#include <istream>
#include <algorithm>
#include "AppTalk.h"
namespace AppTalking
{
AppPhone::AppPhone(AppSenator* AppSenator, Augerate* LocalAugerate, HWND RemoteAugerateWindow, HWND RemoteAppSenatorWindow)
{
m_Senator = AppSenator;
m_LocalAugerate = LocalAugerate;
m_RemoteAugerateWindow = RemoteAugerateWindow;
m_RemoteAppSenatorWindow = RemoteAppSenatorWindow;
if (m_Senator) m_Senator->OnCreateAppPhone(this, m_LocalAugerate, m_RemoteAugerateWindow, m_RemoteAppSenatorWindow);
}
AppPhone::~AppPhone()
{
if (m_Senator) m_Senator->OnDeleteAppPhone(this, m_LocalAugerate, m_RemoteAugerateWindow, m_RemoteAppSenatorWindow);
}
void AppPhone::SetAppSenator(AppSenator *Senator)
{
m_Senator = Senator;
}
void AppPhone::SetLocalAugerate(Augerate *LocalAugerate)
{
m_LocalAugerate = LocalAugerate;
}
void AppPhone::SetRemoteAugerateWindow(HWND RemoteAugerateWindow)
{
m_RemoteAugerateWindow = RemoteAugerateWindow;
}
void AppPhone::SetRemoteAppSenatorWindow(HWND RemoteSenatorWindow)
{
m_RemoteAppSenatorWindow = RemoteSenatorWindow;
}
AppSenator* AppPhone::GetAppSenator()
{
return m_Senator;
}
Augerate* AppPhone::GetLocalAugerate()
{
return m_LocalAugerate;
}
HWND AppPhone::GetRemoteAugerateWindow()
{
return m_RemoteAugerateWindow;
}
HWND AppPhone::GetRemoteAppSenatorWindow()
{
return m_RemoteAppSenatorWindow;
}
void AppPhone::WriteString(string Message)
{
m_LocalAugerate->WriteString(m_RemoteAugerateWindow, Message);
}
string AppPhone::ReadString()
{
return m_LocalAugerate->ReadString(m_RemoteAugerateWindow);
}
bool AppPhone::IsReferenceValid()
{
Augric* aug = Augric::GetMainAugric();
if (!aug->IsWindowAugerate(m_RemoteAugerateWindow)) return false;
if (aug->GetAugerateProtocol(m_RemoteAugerateWindow) != -2) return false;
return true;
}
AppSenator::AppSenator(string &AppName)
{
InitLocking();
m_hReceiveEvent = NULL;
m_AppName = AppName;
if (!Augric::GetMainAugric()) throw new AugraException("An AppSenator uses an Augerate, and Augerates necesitate an Augric! No Augric was thus far created.");
m_Augerate = new Augerate(-1);
m_Augerate->SetEraseBeforeProcess(true);
m_Augerate->AddMessageHandler(this);
}
AppSenator::~AppSenator()
{
vector<AppPhone*> dels;
vector<AppPhone*>::iterator itr;
for (itr = m_AppPhones.begin(); itr != m_AppPhones.end(); itr++)
dels.push_back(*itr);
for (itr = dels.begin(); itr != dels.end(); itr++)
delete *itr;
delete m_Augerate;
}
bool AppSenator::ProcessStringMessage(HWND hSource, string Message)
{
if (Message == string("name?", 5))
{
//while (!m_Augerate->CanWriteFresh(hSource));
m_Augerate->WriteString(hSource, string("name: ", 6) + m_AppName);
}
if (Message.length() > 6)
{
if (Message.substr(0, 6) == string("name: ", 6))
{
Lock();
m_RemoteAppName = Message.substr(6, Message.length() - 6);
if (m_hReceiveEvent) SetEvent(m_hReceiveEvent);
Unlock();
}
if (Message.substr(0, 6) == string("dial? ", 6))
{
string strRemote = Message.substr(6, Message.length() - 6);
HWND hRemote = (HWND) atoi(strRemote.c_str());
Augerate *localAugerate = new Augerate(-2);
char num[10];
_itoa_s((int) localAugerate->GetWindow(), num, 10);
string reply = (string)"dial: " + (string) num;
AppPhone *appPhone = new AppPhone(this, localAugerate, hRemote, hSource);
//Add storage code here. Something like channels or something.
m_Augerate->WriteString(hSource, reply);
}
if (Message.substr(0, 6) == string("dial: ", 6))
{
string strRemote = Message.substr(6, Message.length() - 6);
HWND hRemote = (HWND) atoi(strRemote.c_str());
m_newPhone = new AppPhone(this, m_dialAug, hRemote, hSource);
SetEvent(m_hReceiveEvent);
}
if (Message.substr(0, 6) == string("kill? ", 6))
{
string strRemote = Message.substr(6, Message.length() - 6);
HWND hRemote = (HWND) atoi(strRemote.c_str());
for (vector<AppPhone*>::iterator itr = m_AppPhones.begin(); itr != m_AppPhones.end(); itr++)
{
if ((*itr)->GetRemoteAugerateWindow() == hRemote)
{
delete *itr;
break;
}
}
}
}
return false;
}
string AppSenator::GetRemoteAppName(HWND hAppSenatorWindow)
{
Lock();
m_hReceiveEvent = CreateEvent(NULL, false, false, NULL);
m_RemoteAppName.erase();
Unlock();
m_Augerate->WriteString(hAppSenatorWindow, string("name?", 5));
WaitForSingleObject(m_hReceiveEvent, 500);
CloseHandle(m_hReceiveEvent);
return m_RemoteAppName;
}
vector<HWND> AppSenator::GetAppSenatorWindows(bool bIncludeSelf)
{
Augric* augric = Augric::GetMainAugric();
vector<HWND> augerates = augric->GetGlobalAugerateWindows();
vector<HWND> senators;
for (vector<HWND>::iterator itr = augerates.begin(); itr != augerates.end(); itr++)
{
if (augric->GetAugerateProtocol(*itr) == -1)
if (bIncludeSelf)
senators.push_back(*itr);
else if (m_Augerate->GetWindow() != *itr)
senators.push_back(*itr);
}
return senators;
}
vector<HWND> AppSenator::GetAppSenatorWindowsByName(string AppName, bool bIncludeSelf)
{
vector<HWND> senators = GetAppSenatorWindows(bIncludeSelf);
vector<HWND> named;
for (vector<HWND>::iterator itr = senators.begin(); itr != senators.end(); itr++)
{
string RemoteName = GetRemoteAppName(*itr);
if (RemoteName == AppName) named.push_back(*itr);
}
return named;
}
AppPhone* AppSenator::ConnectToApplication(HWND hAppSenatorWindow)
{
m_hReceiveEvent = CreateEvent(NULL, false, false, NULL);
Lock();
m_dialAug = new Augerate(-2);
m_newPhone = NULL;
Unlock();
char num[10];
_itoa_s((int) m_dialAug->GetWindow(), num, 10);
string Message = (string)"dial? " + (string) num;
m_Augerate->WriteString(hAppSenatorWindow, Message);
WaitForSingleObject(m_hReceiveEvent, 500);
CloseHandle(m_hReceiveEvent);
return m_newPhone;
}
vector<AppPhone*> AppSenator::GetPhones(HWND hAppSenatorWindow)
{
vector<AppPhone*> phones;
Lock();
for (vector<AppPhone*>::iterator itr = m_AppPhones.begin(); itr != m_AppPhones.end(); itr++)
{
if (hAppSenatorWindow)
{
if ((*itr)->GetRemoteAugerateWindow() == hAppSenatorWindow)
phones.push_back(*itr);
}
else phones.push_back(*itr);
}
Unlock();
return phones;
}
void AppSenator::OnDeleteAppPhone(AppPhone *phone, Augerate *localAugerate, HWND RemoteAugerateWindow, HWND RemoteAppSenatorWindow)
{
Lock();
vector<AppPhone*>::iterator itr = find<vector<AppPhone*>::iterator, AppPhone*>(m_AppPhones.begin(), m_AppPhones.end(), phone);
if (itr != m_AppPhones.end()) m_AppPhones.erase(itr);
Unlock();
if (Augric::GetMainAugric()->IsWindowAugerate(RemoteAugerateWindow))
{
char num[10];
_itoa_s((int) localAugerate->GetWindow(), num, 10);
string Message = (string)"kill? " + (string)num;
m_Augerate->WriteString(RemoteAppSenatorWindow, Message);
}
delete localAugerate;
}
void AppSenator::OnCreateAppPhone(AppPhone *phone, Augerate *localAugerate, HWND RemoteAugerateWindow, HWND RemoteAppSenatorWindow)
{
Lock();
m_AppPhones.push_back(phone);
Unlock();
}
bool AppSenator::IsAppPhoneRegistered(AppPhone *phone)
{
vector<AppPhone*>::iterator itr = find<vector<AppPhone*>::iterator, AppPhone*>(m_AppPhones.begin(), m_AppPhones.end(), phone);
if (itr != m_AppPhones.end()) return true;
else return false;
}
void AppSenator::DeleteDanglingPhones()
{
vector<AppPhone*> dangling;
for (vector<AppPhone*>::iterator itr = m_AppPhones.begin(); itr != m_AppPhones.end(); itr++)
{
if (!(*itr)->IsReferenceValid())
dangling.push_back(*itr);
}
while (dangling.size())
{
delete dangling.back();
dangling.pop_back();
}
}
}
//AppTalk.h
//Author: Guido Arbia
#ifndef _APPTALK
#define _APPTALK
#include <string>
#include "Augra.h"
using namespace Augra;
namespace AppTalking
{
class AppSenator;
class AppPhone;
class AppPhone
{
AppSenator *m_Senator;
Augerate* m_LocalAugerate;
HWND m_RemoteAugerateWindow;
HWND m_RemoteAppSenatorWindow;
public:
AppPhone(){}
AppPhone(AppSenator *AppSenator, Augerate *localAugerate, HWND remoteAugerateWindow, HWND remoteAppSenatorWindow);
~AppPhone();
void SetAppSenator(AppSenator* senator);
void SetRemoteAugerateWindow(HWND hWnd);
void SetLocalAugerate(Augerate* localAugerate);
void SetRemoteAppSenatorWindow(HWND hWnd);
AppSenator* GetAppSenator();
HWND GetRemoteAugerateWindow();
Augerate* GetLocalAugerate();
HWND GetRemoteAppSenatorWindow();
bool IsReferenceValid();
void WriteString(string Message);
string ReadString();
};
class AppSenator : public AugerateMessageHandler, Lockable
{
string m_AppName;
Augerate *m_Augerate;
string m_RemoteAppName;
HANDLE m_hReceiveEvent;
Augerate* m_dialAug;
AppPhone *m_newPhone;
vector<AppPhone*> m_AppPhones;
public:
AppSenator(string &AppName);
~AppSenator();
bool ProcessStringMessage(HWND hSource, string Message);
string GetRemoteAppName(HWND hAppSenatorWindow);
HWND GetAugerateWindow() {return m_Augerate->GetWindow();}
vector<HWND> GetAppSenatorWindows(bool bIncludeSelf = false);
vector<HWND> GetAppSenatorWindowsByName(string AppName, bool bIncludeSelf = false);
AppPhone *ConnectToApplication(HWND hAppSenatorWindow);
vector<AppPhone*> GetPhones(HWND hAppSenatorWindow = NULL);
void OnDeleteAppPhone(AppPhone *phone, Augerate *localAugerate, HWND RemoteAugerateWindow, HWND RemoteAppSenatorWindow);
void OnCreateAppPhone(AppPhone *phone, Augerate *localAugerate, HWND RemoteAugerateWindow, HWND RemoteAppSenatorWindow);
bool IsAppPhoneRegistered(AppPhone *phone);
void DeleteDanglingPhones();
};
}
#endif
//Augra.cpp
//Author: Guido Arbia
#include "Augra.h"
UINT TestMsg;
UINT AugricMsg_CreateAugerate;
UINT AugricMsg_DestroyAugerate;
UINT AugricMsg_Destruct;
UINT AugerateMsg_IsAugerate;
UINT AugerateMsg_ConfirmAugerate;
UINT AugerateMsg_GetProtocol;
UINT AugerateMsg_CanWriteFresh;
namespace Augra
{
Augric* Augric::AppAugric = 0;
bool Augric::bInitialized = false;
Augerate::Augerate(int protocol)
{
InitLocking();
bEraseBeforeProcess = false;
m_protocol = protocol;
Augric *aug = Augric::GetMainAugric();
if (!aug) throw new AugraException("No Augric created!");
hWindow = aug->CreateAugerateWindow();
if (!hWindow) throw new AugraException("Unable to create augerate window!");
//this->SetReceiverProc(NULL, NULL);
aug->RegisterAugerate(this);
}
Augerate::~Augerate()
{
Augric *aug = Augric::GetMainAugric();
if (!aug) throw new AugraException("No Augric Exists");
aug->DestroyAugerateWindow(hWindow);
aug->UnregisterAugerate(this);
}
LRESULT Augerate::ProcessWindowMessages(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_COPYDATA)
{
HWND hSource = (HWND) wParam;
COPYDATASTRUCT *cds = (COPYDATASTRUCT*) lParam;
Lock();
data[hSource].append((char*) cds->lpData, cds->cbData);
if (data[hSource].length() && MessageHandlers.size())
{
//MessageBox(NULL, data[hSource].c_str(), "Hmm.", MB_OK);
map<HWND, string>::iterator itr = data.find(hSource);
if (ProcessStringMessages(hSource, (*itr).second))
{
itr = data.find(hSource);
if (itr != data.end())
data.erase(itr);
}
}
Unlock();
return TRUE;
}
if (Msg == AugerateMsg_IsAugerate)
{
SendMessage((HWND) wParam, AugerateMsg_ConfirmAugerate, (WPARAM) hWindow, NULL);
return 0;
}
if (Msg == AugerateMsg_GetProtocol)
{
Lock();
int pr = m_protocol;
Unlock();
return pr;
}
if (Msg == AugerateMsg_CanWriteFresh)
{
Lock();
map<HWND, string>::iterator itr = data.find((HWND) wParam);
Unlock();
if (itr == data.end()) return 1; else return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
bool Augerate::CanWriteFresh(HWND hAugerateWindow)
{
return SendMessage(hAugerateWindow, AugerateMsg_CanWriteFresh, (WPARAM) hWindow, NULL) ? true : false;
}
string Augerate::ReadString(HWND hAugerateWindow)
{
string retString;
retString.erase();
Lock();
map<HWND, string>::iterator itr = data.find(hAugerateWindow);
if (itr != data.end())
{
retString = (*itr).second;
data.erase(itr);
}
Unlock();
return retString;
}
void Augerate::WriteString(HWND hAugerateWindow, string& str)
{
COPYDATASTRUCT cds;
int size = str.length();
char *ch = new char[size];
str.copy(ch, size);
cds.cbData = size;
cds.lpData = (LPVOID) ch;
SendMessage(hAugerateWindow, WM_COPYDATA, (WPARAM) hWindow, (LPARAM) &cds);
delete ch;
}
vector<HWND> Augerate::GetReadableAugerateWindows()
{
vector<HWND> augs;
Lock();
for (map<HWND, string>::iterator itr = data.begin(); itr != data.end(); itr++)
{
augs.push_back((*itr).first);
}
Unlock();
return augs;
}
bool Augerate::ProcessStringMessages(HWND hSource, string Message)
{
bool bDelete = false;
if (bEraseBeforeProcess)
{
map<HWND, string>::iterator itr = data.find(hSource);
if (itr != data.end()) data.erase(itr);
}
for (vector<AugerateMessageHandler*>::iterator itr = MessageHandlers.begin(); itr != MessageHandlers.end(); itr++)
{
bDelete = (*itr)->ProcessStringMessage(hSource, Message) ? true : bDelete;
}
return bDelete;
}
void Augerate::AddMessageHandler(AugerateMessageHandler *handler)
{
for (vector<AugerateMessageHandler*>::iterator itr = MessageHandlers.begin(); itr != MessageHandlers.end(); itr++)
{
if (*itr == handler) return;
}
MessageHandlers.push_back(handler);
}
void Augerate::RemoveMessageHandler(AugerateMessageHandler *handler)
{
for (vector<AugerateMessageHandler*>::iterator itr = MessageHandlers.begin(); itr != MessageHandlers.end(); itr++)
{
if (*itr == handler)
{
MessageHandlers.erase(itr);
return;
}
}
throw new AugraException("No such handler registered!");
}
Augric::Augric()
{
InitLocking();
if (!bInitialized)
{
if (!Init())
{
throw new AugraException("Could not initialize Augra! Could not register window class!");
}
}
if (AppAugric)
{
delete AppAugric;
}
EventWinMade = CreateEvent(NULL, false, false, NULL);
hThread = CreateThread(NULL, 0, AugricThreadProc, this, 0, 0);
if (!hThread) throw new AugraException("Could not create Augrical Thread!");
WaitForSingleObject(EventWinMade, INFINITE);
CloseHandle(EventWinMade);
if (!hWindow) throw new AugraException("Could not create Augrical Window!");
bConfirmAugerate = false;
AppAugric = this;
}
int Augric::GetAugerateProtocol(HWND hAugerateWindow)
{
return SendMessage(hAugerateWindow, AugerateMsg_GetProtocol, (WPARAM) hWindow, NULL);
}
bool Augric::Init()
{
WNDCLASSEX wcx;
ZeroMemory(&wcx, sizeof(WNDCLASSEX));
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpfnWndProc = &Augric::WinProc;
wcx.lpszClassName = "AugricalWindow";
if (!RegisterClassEx(&wcx)) return false;
TestMsg = RegisterWindowMessage("Augric_Test");
AugricMsg_CreateAugerate = RegisterWindowMessage("Augric_CreateAugerate");
AugricMsg_DestroyAugerate = RegisterWindowMessage("Augric_DestroyAugerate");
AugricMsg_Destruct = RegisterWindowMessage("Augric_Destruct");
AugerateMsg_IsAugerate = RegisterWindowMessage("Augerate_IsAugerate");
AugerateMsg_ConfirmAugerate = RegisterWindowMessage("Augerate_ConfirmAugerate");
AugerateMsg_GetProtocol = RegisterWindowMessage("Augerate_GetProtocol");
AugerateMsg_CanWriteFresh = RegisterWindowMessage("Augerate_CanWriteFresh");
bInitialized = true;
return true;
}
Augric::~Augric()
{
AppAugric = 0;
SendMessage(hWindow, AugricMsg_Destruct, NULL, (LPARAM) this);
}
DWORD WINAPI Augric::AugricThreadProc(LPVOID lpParam)
{
Augric* augric = (Augric*) lpParam;
augric->hWindow = CreateWindow("AugricalWindow", "", NULL, 0, 0, 10, 10, NULL, NULL, GetModuleHandle(NULL), NULL);
SetEvent(augric->EventWinMade);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 1;
}
LRESULT CALLBACK Augric::WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
//if (!AppAugric) return DefWindowProc(hWnd, Msg, wParam, lParam);
if (!AppAugric) goto ret;
if (AppAugric->hWindow == hWnd || AppAugric->GetAugerateByWindow(hWnd))
return AppAugric->ProcessWindowMessages(hWnd, Msg, wParam, lParam);
ret:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
LRESULT Augric::ProcessWindowMessages(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
Augerate* a = GetAugerateByWindow(hWnd);
if (a) return a->ProcessWindowMessages(hWnd, Msg, wParam, lParam);
if (Msg == TestMsg)
{
MessageBox(NULL, "Test functions. So, window must have been created and is capable of receiving messages.", "Yeah!", MB_OK);
return 0;
}
if (Msg == AugricMsg_CreateAugerate)
return (LRESULT) CreateWindow("AugricalWindow", "", NULL, 0, 0, 10, 10, NULL, NULL, GetModuleHandle(NULL), NULL);
if (Msg == AugricMsg_DestroyAugerate)
{
DestroyWindow((HWND) lParam);
return 0;
}
if (Msg == AugricMsg_Destruct)
{
if ((Augric*) lParam == Augric::GetMainAugric())
{
DestroyWindow(hWindow);
ExitThread(0);
}
return 0;
}
if (Msg == AugerateMsg_ConfirmAugerate)
bConfirmAugerate = true;
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
Augerate* Augric::GetAugerateByWindow(HWND hWnd)
{
map<HWND, Augerate*>::iterator itr = m_Augerates.find(hWnd);
return itr != m_Augerates.end() ? m_Augerates[hWnd] : NULL;
}
void Augric::Test()
{
SendMessage(hWindow, TestMsg, 0, 0);
}
HWND Augric::CreateAugerateWindow()
{
return (HWND) SendMessage(hWindow, AugricMsg_CreateAugerate, NULL, NULL);
}
void Augric::DestroyAugerateWindow(HWND hWnd)
{
SendMessage(hWindow, AugricMsg_DestroyAugerate, NULL, (LPARAM) hWnd);
}
void Augric::RegisterAugerate(Augerate* aug)
{
m_Augerates[aug->GetWindow()] = aug;
}
void Augric::UnregisterAugerate(Augerate* aug)
{
map<HWND, Augerate*>::iterator itr = m_Augerates.find(aug->GetWindow());
if (itr != m_Augerates.end())
{
m_Augerates.erase(itr);
}
}
bool Augric::IsWindowAugerate(HWND hWnd)
{
bConfirmAugerate = false;
SendMessageTimeout(hWnd, AugerateMsg_IsAugerate, (WPARAM) hWindow, NULL, SMTO_NORMAL, 100, NULL);
return bConfirmAugerate;
}
vector<HWND> Augric::GetGlobalAugerateWindows()
{
vector<HWND> augs;
EnumWindows(EnumAugWinProc, (LPARAM) &augs);
return augs;
}
BOOL CALLBACK Augric::EnumAugWinProc(HWND hWnd, LPARAM lParam)
{
vector<HWND> *augs = (vector<HWND>*) lParam;
Augric *a = Augric::GetMainAugric();
if (a->IsWindowAugerate(hWnd)) augs->push_back(hWnd);
return TRUE;
}
AugerateMessageHandler::AugerateMessageHandler(AugerateMessageReceiver *ReceivingObject, ProcessStringMessageProc Proc)
{
m_Receiver = ReceivingObject;
m_Proc = Proc;
}
bool AugerateMessageHandler::ProcessStringMessage(HWND hSource, string Message)
{
return (m_Receiver->*m_Proc)(hSource, Message);
}
}
//Augra.h
//Author: Guido Arbia
#ifndef _AUGRA
#define _AUGRA
#include <Windows.h>
#include <vector>
#include <map>
#include <string>
using namespace std;
namespace Augra
{
class AugerateMessageHandler;
class AugerateMessageReceiver;
class Receivable
{
};
class Lockable
{
private:
CRITICAL_SECTION m_cs;
public:
void InitLocking() {InitializeCriticalSection(&m_cs);}
void Lock() {EnterCriticalSection(&m_cs);}
void Unlock() {LeaveCriticalSection(&m_cs);}
~Lockable() {DeleteCriticalSection(&m_cs);}
};
class Augerate : Lockable
{
HWND hWindow;
map<HWND, string> data;
int m_protocol;
Receivable* m_Receiver;
vector<AugerateMessageHandler*> MessageHandlers;
bool bEraseBeforeProcess;
public:
Augerate(int protocol = 0);
~Augerate();
HWND GetWindow() {Lock(); HWND hWnd = hWindow; Unlock(); return hWnd;}
LRESULT ProcessWindowMessages(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
string ReadString(HWND hAugerateWindow);
void WriteString(HWND hAugerateWindow, string& str);
bool CanWriteFresh(HWND hAugerateWindow);
vector<HWND> GetReadableAugerateWindows();
bool ProcessStringMessages(HWND hSource, string Message);
void AddMessageHandler(AugerateMessageHandler *handler);
void RemoveMessageHandler(AugerateMessageHandler *handler);
void SetEraseBeforeProcess(bool EraseBeforeProcess) {bEraseBeforeProcess = EraseBeforeProcess;}
};
class AugraException
{
char* m_desc;
public:
AugraException(char* description) {m_desc = description;}
char* GetDescription() {return m_desc;}
};
class Augric : Lockable
{
map<HWND, Augerate*> m_Augerates;
HWND hWindow;
HANDLE hThread;
HANDLE EventWinMade;
bool bConfirmAugerate;
static Augric* AppAugric;
static bool bInitialized;
static bool Init();
public:
Augric();
LRESULT ProcessWindowMessages(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Augerate* GetAugerateByWindow(HWND hWnd);
HWND CreateAugerateWindow();
void DestroyAugerateWindow(HWND hWnd);
bool IsWindowAugerate(HWND hWnd);
int GetAugerateProtocol(HWND hAugerateWindow);
vector<HWND> GetGlobalAugerateWindows();
void RegisterAugerate(Augerate *Aug);
void UnregisterAugerate(Augerate *Aug);
void Test();
static DWORD WINAPI AugricThreadProc(LPVOID lpParam);
static LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
static Augric* GetMainAugric() {return AppAugric;}
static BOOL CALLBACK EnumAugWinProc(HWND hWnd, LPARAM lParam);
~Augric();
};
typedef bool (AugerateMessageReceiver::*ProcessStringMessageProc)(HWND hSource, string Message);
class AugerateMessageHandler
{
AugerateMessageReceiver *m_Receiver;
ProcessStringMessageProc m_Proc;
public:
AugerateMessageHandler() {}
AugerateMessageHandler(AugerateMessageReceiver *ReceivingObject, ProcessStringMessageProc Proc);
virtual bool ProcessStringMessage(HWND hSource, string Message);
};
class AugerateMessageReceiver
{
};
typedef bool (AugerateMessageReceiver::*AugerateMessageProc)(HWND hSource, string Message);
}
#endif
//main.cpp
//Author: Guido Arbia
/*This code demonstrates the use of a few classes to achieve interprocess communication without using named pipes, sockets, or memory
* mapped files. All communicating processes must have an Augric object created. They must also create an AppSenator object
* to represent the application and to handle all connections extending from them to other processes. The end points of such connections
* are represented by AppPhone objects in the processs that contains the point.
* Note: Everything is done entirely through windows messages, but you don't have to bother yourself with a message quee or any such
* thing because these classes take care of it in a seperate thread, a thread you don't ever have to worry about. Further, please note
* that this is my first successful use of multithreading. If you see a problem with my multithreading techniques, please email
* me at gaxar77@hotmail.com.
* Actually, if you want to make any comment on my code, suggestions, etc, you can contact the same address. If you find my code
* worthwhile, you may request documentation, in which case I will be most oblidged to explain the use of my code in more detail.
* For now, I will just see what you think.
*/
#include <iostream>
#include <string>
#include <algorithm>
#include "Augra.h"
#include "AppTalk.h"
using namespace Augra;
using namespace AppTalking;
using namespace std;
void ListApps(AppSenator &senator)
{
vector<HWND> appsw = senator.GetAppSenatorWindows(true);
for (vector<HWND>::iterator itr = appsw.begin(); itr != appsw.end(); itr++)
{
cout << senator.GetRemoteAppName(*itr) << endl;
}
cout << endl;
}
void ListConnections(AppSenator &senator)
{
senator.DeleteDanglingPhones();
vector<AppPhone*> phones = senator.GetPhones();
for (vector<AppPhone*>::iterator itr = phones.begin(); itr != phones.end(); itr++)
{
/*if (!(*itr)->IsReferenceValid())
{
cout << "Invalid AppPhone reference found. Deleting it." << endl << endl;
delete *itr;
return;
}*/
string appName = senator.GetRemoteAppName((*itr)->GetRemoteAppSenatorWindow());
int cid = (int) *itr;
cout << "Connection ID: " << cid << ", Application Name: " << appName << endl;
}
cout << endl;
}
void Connect(AppSenator &senator)
{
char tmpChar[101];
cout << "Process Name: ";
cin.getline(tmpChar, 100);
string appName = tmpChar;
cout << "Searching for applications to with that name to make separate connections with." << endl;
vector<HWND> appsw = senator.GetAppSenatorWindowsByName(appName, true);
if (appsw.size() == 0)
{
cout << "Found no processes with that name." << endl << endl;
return;
}
for (vector<HWND>::iterator itr = appsw.begin(); itr != appsw.end(); itr++)
{
cout << "Found app named " << appName << endl;
AppPhone *newPhone = senator.ConnectToApplication(*itr);
if (newPhone != NULL) cout << "Made connection: " << (int) newPhone << endl;
else cout << "Unable to connect." << endl;
}
cout << endl;
}
void ListMessages(AppSenator &senator)
{
vector<AppPhone*> phones = senator.GetPhones();
for (vector<AppPhone*>::iterator itr = phones.begin(); itr != phones.end(); itr++)
{
string instr = (*itr)->ReadString();
if (instr.size())
{
cout << "Message received through connection " << (int) *itr << endl;
cout << "Content: " << instr << endl;
}
}
cout << endl;
}
void Kill(AppSenator &senator)
{
AppPhone *phone;
int id;
cout << "Please enter connection ID: ";
cin >> id;
phone = (AppPhone*) id;
if (!senator.IsAppPhoneRegistered(phone))
{
cout << "Invalid connection ID." << endl << endl;
return;
}
delete phone;
}
void Send(AppSenator &senator)
{
AppPhone *phone;
int id;
cout << "Please enter connection ID: ";
cin >> id;
phone = (AppPhone*) id;
if (!senator.IsAppPhoneRegistered(phone))
{
cout << "Invalid connection ID." << endl << endl;
return;
}
cin.clear();
cin.sync();
cout << "Please enter message: ";
char tmpChar[300];
cin.getline(tmpChar, 299);
string message = tmpChar;
phone->WriteString(message);
cout << endl;
}
void ListOptions()
{
cout << "-1. Exit" << endl;
cout << "0. Options" << endl;
cout << "-------------" << endl;
cout << "1. List Applications" << endl;
cout << "2. List connections" << endl;
cout << "3. Make connection" << endl;
cout << "4. Check Messages" << endl;
cout << "5. Send Messages" << endl;
cout << "6. Kill Connection" << endl;
cout << endl;
}
int main(int argc, char* argv[])
{
char tmpChar[101];
string AppName;
cout << "Please enter a name for this application: " << endl;
cin.getline(tmpChar, 100);
AppName = tmpChar;
Augric augric;
AppSenator senator(AppName);
while (true)
{
int choice;
cin >> choice;
cin.clear();
cin.sync();
switch(choice)
{
case -1:
return 0;
case 0:
ListOptions();
break;
case 1:
ListApps(senator);
break;
case 2:
ListConnections(senator);
break;
case 3:
Connect(senator);
break;
case 4:
ListMessages(senator);
break;
case 5:
Send(senator);
break;
case 6:
Kill(senator);
break;
default:
cout << "Not recognized as a command. 0 for a list of options." << endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment