Created
August 29, 2010 00:41
-
-
Save gaxar77/555774 to your computer and use it in GitHub Desktop.
Interprocess Communication without named pipes, memory mapped files, or sockets.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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