|
// AutomationClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "AutomationClient.h"
#include "AutomationClientDlg.h"
#include "DefineWindowMessages.h" // Specific notification Windows message definition
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAutomationClientDlg dialog
CAutomationClientDlg::CAutomationClientDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAutomationClientDlg::IDD, pParent),
m_pAdvise(NULL), m_spHandler(NULL)
{
//{{AFX_DATA_INIT(CAutomationClientDlg)
m_sText = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CAutomationClientDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAutomationClientDlg)
DDX_Text(pDX, IDC_EDIT, m_sText);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAutomationClientDlg, CDialog)
//{{AFX_MSG_MAP(CAutomationClientDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_COPY_TEXT, OnButtonCopyText)
ON_BN_CLICKED(IDC_BUTTON_FIND, OnButtonFind)
ON_BN_CLICKED(IDC_BUTTON_APPEND_MENU, OnButtonAppendMenu)
ON_BN_CLICKED(IDC_BUTTON_AUTOMATE, OnButtonAutomate)
//}}AFX_MSG_MAP
// Massage sent by sink object
ON_MESSAGE(WM_SENTENCE_COMPLETED, OnSentenceCompleted)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAutomationClientDlg message handlers
BOOL CAutomationClientDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
SetPreAutomationState();
return TRUE; // return TRUE unless you set the focus to a control
}
void CAutomationClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CAutomationClientDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CAutomationClientDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//
// Set dialog controls to "pre-automation" state
//
void CAutomationClientDlg::SetPreAutomationState()
{
m_spHandler = NULL;
m_sText.Empty();
UpdateData( FALSE );
GetDlgItem(IDC_BUTTON_AUTOMATE)->EnableWindow();
GetDlgItem(IDC_BUTTON_APPEND_MENU)->EnableWindow( FALSE );
GetDlgItem(IDC_BUTTON_FIND)->EnableWindow( FALSE );
GetDlgItem(IDC_BUTTON_COPY_TEXT)->EnableWindow( FALSE );
}
//
// Set dialog controls to "automated" state
//
void CAutomationClientDlg::SetPostAutomationState()
{
GetDlgItem(IDC_BUTTON_AUTOMATE)->EnableWindow( FALSE );
GetDlgItem(IDC_BUTTON_APPEND_MENU)->EnableWindow();
GetDlgItem(IDC_BUTTON_FIND)->EnableWindow();
GetDlgItem(IDC_BUTTON_COPY_TEXT)->EnableWindow();
}
//////////////////////////////////////////////////////////////////////////////////////
//
// Specific includes and buttons handlers
//
#include "ObjectROTToken.h"
#include "GetObjectFromROT.h"
#include "Advise.h"
//
#import "..\NotepadHandlerNotification\NotepadHandlerNotification.tlb"
using namespace NOTEPADHANDLERNOTIFICATIONLib;
const char g_szLoader[] = // Loader application
#ifdef _DEBUG
_T("LoaderD.exe");
#else
_T("Loader.exe");
#endif
//
// Execute Loader application to run target application and
// inject DLL to target process
//
void ExecuteLoader()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if ( CreateProcess(NULL, // No module name (use command line).
(LPTSTR)g_szLoader, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi) // Pointer to PROCESS_INFORMATION structure.
)
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
//
// Obtain proxy of the COM object embedded to target process
//
BOOL CAutomationClientDlg::ObtainObjectFromROT()
{
HRESULT hr = E_FAIL;
#ifdef _MONIKER
hr = GetObjectFromROT<IHandler>( (LPTSTR)g_szROTRegToken, &m_spHandler );
#else
CLSID clsid;
CLSIDFromProgID( g_szProgID, &clsid );
IUnknownPtr spUnk = NULL;
hr = GetActiveObject( clsid, NULL, &spUnk );
if ( SUCCEEDED(hr) )
m_spHandler = (IHandlerPtr)spUnk;
#endif
return (NULL != m_spHandler);
}
//
// Obtain proxy of the COM object embedded to target process
// for the first time
//
BOOL CAutomationClientDlg::ObtainObjectFirstTime()
{
for (int i=0; i<20; i++)
{
if ( ObtainObjectFromROT() )
break;
Sleep( 100 );
}
return (NULL != m_spHandler);
}
//
// Cancel button handler
//
void CAutomationClientDlg::OnCancel()
{
DeleteAdvise();
CoUninitialize(); // uninitialize COM
CDialog::OnCancel();
}
//
// Delete Advise object
//
void CAutomationClientDlg::DeleteAdvise()
{
if ( NULL != m_pAdvise )
{
delete m_pAdvise;
m_pAdvise = NULL;
}
}
//
// Copy Text button handler
//
void CAutomationClientDlg::OnButtonCopyText()
{
BSTR bsText;
try
{
m_spHandler->GetLastTypedCharSequence( &bsText );
_bstr_t bstText( bsText, FALSE );
m_sText = bsText;
UpdateData( FALSE );
}
catch (...)
{
SetPreAutomationState();
}
}
//
// Find button handler
//
void CAutomationClientDlg::OnButtonFind()
{
const int IDM_NOTEPAD_FIND = 3;
try
{
m_spHandler->DoMenuCommand( IDM_NOTEPAD_FIND );
}
catch (...)
{
SetPreAutomationState();
}
}
//
// Append Menu button handler
//
void CAutomationClientDlg::OnButtonAppendMenu()
{
try
{
m_spHandler->AppendMenu();
}
catch (...)
{
SetPreAutomationState();
}
}
//
// Automate Notepad button handler
//
void CAutomationClientDlg::OnButtonAutomate()
{
// Execute Loader application to run target application and
// inject DLL to target process
ExecuteLoader();
if ( FAILED(CoInitialize(NULL)) ) // initialize COM
return;
// Reset m_pAdvise
DeleteAdvise();
if ( NULL == m_pAdvise &&
ObtainObjectFirstTime() /* get proxy of the COM object embedded to target process */)
{
// Actions to advise sink interface to COM object embedded in target process
m_pAdvise = new CAdvise( __uuidof(IHandlerEvents) );
if ( NULL != m_pAdvise )
{
// Implement sink interface
IHandlerEventsPtr spHandlerEvents( __uuidof(Notification) );
// Provide sink object with dialog window handle for subsequent notification
// by message posting
INotificationPtr spNotification = spHandlerEvents;
spNotification->SetMainWnd( (DWORD)m_hWnd );
// Actually advise sink interface to embedded COM object
if ( SUCCEEDED(m_pAdvise->AdviseToServer(m_spHandler, spHandlerEvents)) )
SetPostAutomationState();
}
}
}
//
// Notification message handler
//
void CAutomationClientDlg::OnSentenceCompleted(WPARAM wParam, LPARAM lParam)
{
if ( 0 != wParam )
{
TCHAR* szText = (LPTSTR)wParam;
m_sText.Format( _T("%s"), szText );
UpdateData( FALSE );
delete szText;
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.