|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
RemoteDesktopClientSession
Abstract:
RemoteDesktopClientSession manages the client side GUI for the application hostiving the Salem ActiveX control.
Author:
Marc Reyhner 7/11/2000
--*/
#include "stdafx.h"
#ifdef TRC_FILE
#undef TRC_FILE
#endif
#define TRC_FILE "rcrdcs"
#include "RemoteDesktopClientSession.h"
#include "RemoteDesktopClientEventSink.h"
#include "resource.h"
#include "exception.h"
//
// The guid for the ActiveX control we are creating the child window for.
//
#define REMOTEDESKTOPHOST_TEXTGUID TEXT("{299BE050-E83E-4DB7-A7DA-D86FDEBFE6D0}")
CRemoteDesktopClientSession::CRemoteDesktopClientSession( IN OUT HINSTANCE hInstance )
/*++
Routine Description:
The only thing the constructor does is to save hInstance and to set gm_Session to be this class.
Arguments:
hInstance - The instance for this module.
Return value:
None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::CRemoteDesktopClientSession");
m_hWnd = NULL; m_hRdcHostWnd = NULL; m_RemDeskClient = NULL; m_Sink = NULL;
m_hInstance = hInstance;
DC_END_FN(); }
CRemoteDesktopClientSession::~CRemoteDesktopClientSession( )
/*++
Routine Description:
We just NULL the gm_Session pointer here since everything else was already cleaned up.
Arguments:
None.
Return value:
None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::~CRemoteDesktopClientSession");
DC_END_FN(); }
VOID CRemoteDesktopClientSession::DoClientSession( IN BSTR parms )
/*++
Routine Description:
Here we start and manage the entire client GUI.
Arguments:
parms - The string needed for Salem to connect to the remote server.
Return value:
None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::DoClientSession"); HRESULT hr;
ATOM atom; TCHAR wndTitle[MAX_STR_LEN]; HICON wndIcon = (HICON)LoadImage(m_hInstance,MAKEINTRESOURCE(IDI_TRAYICON), IMAGE_ICON,0,0,0); WNDCLASS wndClass = { CS_PARENTDC, _WindowProc, 0, 0, m_hInstance, wndIcon, NULL, (HBRUSH)COLOR_WINDOWFRAME,MAKEINTRESOURCE(IDR_CLIENTMENU),TEXT("RdcWndClass") }; AtlAxWinInit(); atom = RegisterClass(&wndClass); if (!atom) { TRC_ERR((TB,TEXT("Error registering window class for main frame."))); goto FAILURE; } LoadStringSimple(IDS_CLIENTWNDTITLE,wndTitle); m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,(LPCTSTR)atom,wndTitle, WS_VISIBLE|WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, 50,50,690,530,NULL,NULL,m_hInstance,this); if (!m_hWnd) { TRC_ERR((TB,TEXT("Error creating main frame."))); goto FAILURE; }
SetForegroundWindow(m_hWnd); m_Sink = new CRemoteDesktopClientEventSink(this); if (!m_Sink) { TRC_ERR((TB,TEXT("Error creating client event sink."))); goto FAILURE; } hr = m_Sink->DispEventAdvise(m_RemDeskClient); if (hr != S_OK) { goto FAILURE; }
hr = m_RemDeskClient->put_ConnectParms(parms); if (hr != S_OK) { goto FAILURE; } hr = m_RemDeskClient->ConnectToServer(NULL); if (hr != S_OK) { goto FAILURE; }
DoMessageLoop(); delete m_Sink; m_Sink = NULL;
DestroyIcon(wndIcon); DC_END_FN(); return;
FAILURE: throw CException(IDS_CLIENTERRORCREATE); }
LRESULT CALLBACK CRemoteDesktopClientSession::_WindowProc( IN OUT HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam )
/*++
Routine Description:
The window proc calls the appropriate message handler for the messages that we care about.
Arguments:
hWnd - The window the message is for.
uMsg - The message.
wParam - WPARAM for the message.
lParam - LPARAM for the message.
Return value:
LRESULT - The message specific return code. See MSDN for details.
--*/ { LRESULT retValue = 0; CRemoteDesktopClientSession *session;
DC_BEGIN_FN("CRemoteDesktopClientSession::_WindowProc");
if (uMsg != WM_CREATE) { session = (CRemoteDesktopClientSession*)GetWindowLongPtr(hWnd,GWLP_USERDATA); }
switch (uMsg) { case WM_CREATE: session = (CRemoteDesktopClientSession*) ((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowLongPtr(hWnd,GWLP_USERDATA,(long)session); retValue = session->OnCreate(hWnd); break; case WM_COMMAND: if (session) { retValue = session->OnCommand(wParam,lParam); } break; case WM_DESTROY: if (session) { session->OnDestroy(); } break; case WM_SETFOCUS: if (session) { session->OnSetFocus(); } break; case WM_SIZE: if (session) { session->OnSize(LOWORD(lParam),HIWORD(lParam)); } break; default: retValue = DefWindowProc(hWnd,uMsg,wParam,lParam); }
DC_END_FN(); return retValue; }
VOID CRemoteDesktopClientSession::DoMessageLoop( )
/*++
Routine Description:
This runs through your normal event loop until we get a WM_QUIT. Any dialogs that messages should be caught for need to be inserted into this function.
Arguments:
None.
Return value:
None.
--*/ { MSG msg;
DC_BEGIN_FN("CRemoteDesktopClientSession::DoMessageLoop");
while (GetMessage(&msg,NULL,0,0)>0) { if (!m_AboutDlg.DialogMessage(&msg) && !m_ApprovalDlg.DialogMessage(&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
DC_END_FN(); }
LRESULT CRemoteDesktopClientSession::OnCreate( IN OUT HWND hWnd )
/*++
Routine Description:
When the window is being created we create the child window and get a pointer to the IRemoteDesktopClient for the control. If there is a problem we return -1 and the window is not created.
Arguments:
hWnd - The window being created.
Return value: 0 - The window was created correctly.
-1 - There was an error creating the window.
--*/ { HRESULT hr; IUnknown *pUnk = NULL; ISAFRemoteDesktopClientHost *remClientHost = NULL;
DC_BEGIN_FN("CRemoteDesktopClientSession::OnCreate");
m_hRdcHostWnd = CreateWindow(TEXT("AtlAxWin"),REMOTEDESKTOPHOST_TEXTGUID, WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,0,0,0,0,hWnd,NULL,m_hInstance,NULL); if (!m_hRdcHostWnd) { TRC_ERR((TB,TEXT("Error creating Salem window."))); goto FAILURE; } hr = AtlAxGetControl(m_hRdcHostWnd,&pUnk); if (hr != S_OK) { TRC_ERR((TB,TEXT("Error getting IUnknown from salem window."))); goto FAILURE; } hr = pUnk->QueryInterface(__uuidof(ISAFRemoteDesktopClientHost),(LPVOID*)&remClientHost); if (hr != S_OK) { TRC_ERR((TB,TEXT("Error getting IRemoteDesktopClientHost from Salem control."))); goto FAILURE; } pUnk->Release(); pUnk = NULL; hr = remClientHost->GetRemoteDesktopClient(&m_RemDeskClient); if (hr != S_OK) { TRC_ERR((TB,TEXT("Error gettin IRemoteDesktopClient from host."))); goto FAILURE; } remClientHost->Release(); remClientHost = NULL; DC_END_FN();
return 0;
FAILURE: if (m_hRdcHostWnd) { DestroyWindow(m_hRdcHostWnd); m_hRdcHostWnd = NULL; } if (pUnk) { pUnk->Release(); pUnk = NULL; } if (remClientHost) { remClientHost->Release(); remClientHost = NULL; } return -1; }
VOID CRemoteDesktopClientSession::OnSize( IN WORD width, IN WORD height )
/*++
Routine Description:
We keep the child window the same as our new size.
Arguments:
None.
Return value: None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::OnSize"); SetWindowPos(m_hRdcHostWnd,NULL,0,0,width,height,SWP_NOZORDER);
DC_END_FN(); }
VOID CRemoteDesktopClientSession::ConnectRemoteDesktop( )
/*++
Routine Description:
We initiate a request to control the remote desktop and pop up the approval warning dialog.
Arguments:
None.
Return value: None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::ConnectRemoteDesktop"); m_RemDeskClient->ConnectRemoteDesktop(); m_ApprovalDlg.m_rObj = this; m_ApprovalDlg.Create(m_hInstance,IDD_APPROVALWAIT,m_hWnd);
DC_END_FN(); }
VOID CRemoteDesktopClientSession::OnAbout( )
/*++
Routine Description:
We either create or bring to the foreground the about box.
Arguments:
None.
Return value: None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::OnAbout");
if (m_AboutDlg.IsCreated()) { m_AboutDlg.Activate(); } else { m_AboutDlg.Create(m_hInstance,IDD_ABOUT,m_hWnd); }
DC_END_FN(); }
LRESULT CRemoteDesktopClientSession::OnCommand( IN WPARAM wParam, IN LPARAM lParam )
/*++
Routine Description:
When the window is destroyed we disconnect from the remote host and then send a quit message to exit the event loop.
Arguments:
wParam - The command which was triggered.
lParam - The control the command came from.
Return value: 0 - We handled the command.
1 - We did not handle the command.
--*/ { LRESULT retValue = 0;
DC_BEGIN_FN("CRemoteDesktopClientSession::OnCommand");
switch (wParam) { case ID_EXIT: DestroyWindow(m_hWnd); break; case ID_ABOUT: OnAbout(); break; default: retValue = 1; }
DC_END_FN();
return retValue; }
VOID CRemoteDesktopClientSession::OnDestroy( )
/*++
Routine Description:
When the window is destroyed we disconnect from the remote host and then send a quit message to exit the event loop.
Arguments:
None.
Return value: None.
--*/ { BOOL isConnected; HRESULT hr; DC_BEGIN_FN("CRemoteDesktopClientSession::OnDestroy");
if(m_RemDeskClient) { hr = m_RemDeskClient->get_IsRemoteDesktopConnected(&isConnected); if (hr == S_OK && isConnected) { m_RemDeskClient->DisconnectRemoteDesktop(); } m_RemDeskClient->DisconnectFromServer(); } PostQuitMessage(0);
DC_END_FN(); }
VOID CRemoteDesktopClientSession::ShowRemdeskControl( )
/*++
Routine Description:
This makes our child window visible.
Arguments:
None.
Return value: None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::ShowRemdeskControl");
ShowWindow(m_hRdcHostWnd,SW_SHOW);
DC_END_FN(); }
VOID CRemoteDesktopClientSession::OnSetFocus( )
/*++
Routine Description:
When we get focus we pass it off to our child window.
Arguments:
None.
Return value: None.
--*/ { DC_BEGIN_FN("CRemoteDesktopClientSession::OnSetFocus"); SetFocus(m_hRdcHostWnd);
DC_END_FN(); }
|