diff options
Diffstat (limited to 'utils/vmpi/testapps/MessageWatch/MessageWatchDlg.cpp')
| -rw-r--r-- | utils/vmpi/testapps/MessageWatch/MessageWatchDlg.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/utils/vmpi/testapps/MessageWatch/MessageWatchDlg.cpp b/utils/vmpi/testapps/MessageWatch/MessageWatchDlg.cpp new file mode 100644 index 0000000..9098caa --- /dev/null +++ b/utils/vmpi/testapps/MessageWatch/MessageWatchDlg.cpp @@ -0,0 +1,324 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// MessageWatchDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "MessageWatch.h" +#include "MessageWatchDlg.h" +#include "messagemgr.h" +#include "tier1/strtools.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +#define WM_STARTIDLE (WM_USER + 565) + + +// --------------------------------------------------------------------------- // +// CSender. +// --------------------------------------------------------------------------- // + +CSender::CSender() +{ + m_pSocket = NULL; + m_pConsoleWnd = NULL; +} + +CSender::~CSender() +{ + if ( m_pSocket ) + m_pSocket->Release(); + + if ( m_pConsoleWnd ) + m_pConsoleWnd->Release(); +} + + +///////////////////////////////////////////////////////////////////////////// +// CMessageWatchDlg dialog + +CMessageWatchDlg::CMessageWatchDlg(CWnd* pParent /*=NULL*/) + : CDialog(CMessageWatchDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CMessageWatchDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_pListenSocket = NULL; +} + +CMessageWatchDlg::~CMessageWatchDlg() +{ + // destroy the sender objects. + + if ( m_pListenSocket ) + m_pListenSocket->Release(); +} + +void CMessageWatchDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CMessageWatchDlg) + DDX_Control(pDX, IDC_MACHINES, m_Machines); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CMessageWatchDlg, CDialog) + //{{AFX_MSG_MAP(CMessageWatchDlg) + ON_MESSAGE(WM_STARTIDLE, OnStartIdle) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_LBN_DBLCLK(IDC_MACHINES, OnDblclkMachines) + ON_BN_CLICKED(IDSHOWALL, OnShowall) + ON_BN_CLICKED(IDHIDEALL, OnHideall) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMessageWatchDlg message handlers + +BOOL CMessageWatchDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // 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 + + // Setup our listen socket and thread. + m_pListenSocket = CreateIPSocket(); + m_pListenSocket->BindToAny( MSGMGR_BROADCAST_PORT ); + + m_cWinIdle.StartIdle( GetSafeHwnd(), WM_STARTIDLE, 0, 0, 100 ); + m_cWinIdle.NextIdle(); + + return TRUE; // return TRUE unless you set the focus to a control +} + + +LONG CMessageWatchDlg::OnStartIdle( UINT, LONG ) +{ + MSG msg; + if (!PeekMessage(&msg, GetSafeHwnd(), 0,0, PM_NOREMOVE)) + OnIdle(); + m_cWinIdle.NextIdle(); + return 0; +} + + +void CMessageWatchDlg::OnIdle() +{ + // Kill dead connections. + int iNext; + for ( int iSender=m_Senders.Head(); iSender != m_Senders.InvalidIndex(); iSender = iNext ) + { + iNext = m_Senders.Next( iSender ); + + CSender *pSender = m_Senders[iSender]; + if ( pSender->m_pSocket && !pSender->m_pSocket->IsConnected() ) + { + // Just release the socket so the text stays there. + pSender->m_pSocket->Release(); + pSender->m_pSocket = NULL; + } + } + + // Look for new connections. + while ( 1 ) + { + CIPAddr ipFrom; + char data[16]; + int len = m_pListenSocket->RecvFrom( data, sizeof( data ), &ipFrom ); + if ( len == -1 ) + break; + + if ( data[0] == MSGMGR_PACKETID_ANNOUNCE_PRESENCE && + *((int*)&data[1]) == MSGMGR_VERSION ) + { + int iPort = *((int*)&data[5]); + + // See if we have a machine with this info yet. + CIPAddr connectAddr = ipFrom; + connectAddr.port = iPort; + + // NOTE: we'll accept connections from machines we were connected to earlier but + // lost the connection to. + CSender *pSender = FindSenderByAddr( ipFrom.ip ); + if ( !pSender || !pSender->m_pSocket ) + { + // 'nitiate the connection. + ITCPSocket *pNew = CreateTCPSocket(); + if ( pNew->BindToAny( 0 ) && TCPSocket_Connect( pNew, &connectAddr, 1000 ) ) + { + char nameStr[256]; + char title[512]; + if ( !ConvertIPAddrToString( &ipFrom, nameStr, sizeof( nameStr ) ) ) + Q_snprintf( nameStr, sizeof( nameStr ), "%d.%d.%d.%d", ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3] ); + + Q_snprintf( title, sizeof( title ), "%s:%d", nameStr, iPort ); + + // If the sender didn't exist yet, add a new one. + if ( !pSender ) + { + pSender = new CSender; + + IConsoleWnd *pWnd = CreateConsoleWnd( + AfxGetInstanceHandle(), + IDD_OUTPUT, + IDC_DEBUG_OUTPUT, + false + ); + + pSender->m_pConsoleWnd = pWnd; + pWnd->SetTitle( title ); + + Q_strncpy( pSender->m_Name, title, sizeof( pSender->m_Name ) ); + m_Senders.AddToTail( pSender ); + m_Machines.AddString( pSender->m_Name ); + } + + pSender->m_Addr = connectAddr; + pSender->m_pSocket = pNew; + } + else + { + pNew->Release(); + } + } + } + } + + + // Read input from our current connections. + FOR_EACH_LL( m_Senders, i ) + { + CSender *pSender = m_Senders[i]; + + while ( 1 ) + { + if ( !pSender->m_pSocket ) + break; + + CUtlVector<unsigned char> data; + if ( !pSender->m_pSocket->Recv( data ) ) + break; + + if ( data[0] == MSGMGR_PACKETID_MSG ) + { + char *pMsg = (char*)&data[1]; + pSender->m_pConsoleWnd->PrintToConsole( pMsg ); + OutputDebugString( pMsg ); + } + } + } +} + + +void CMessageWatchDlg::OnDestroy() +{ + // Stop the idling thread + m_cWinIdle.EndIdle(); + CDialog::OnDestroy(); +} + + +CSender* CMessageWatchDlg::FindSenderByAddr( const unsigned char ip[4] ) +{ + FOR_EACH_LL( m_Senders, i ) + { + if ( memcmp( m_Senders[i]->m_Addr.ip, ip, 4 ) == 0 ) + return m_Senders[i]; + } + return NULL; +} + + +CSender* CMessageWatchDlg::FindSenderByName( const char *pName ) +{ + FOR_EACH_LL( m_Senders, i ) + { + if ( stricmp( pName, m_Senders[i]->m_Name ) == 0 ) + return m_Senders[i]; + } + return NULL; +} + + +// 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 CMessageWatchDlg::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 CMessageWatchDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +void CMessageWatchDlg::OnDblclkMachines() +{ + int index = m_Machines.GetCurSel(); + if ( index != LB_ERR ) + { + CString str; + m_Machines.GetText( index, str ); + + CSender *pSender = FindSenderByName( str ); + if ( pSender ) + pSender->m_pConsoleWnd->SetVisible( true ); + } +} + +void CMessageWatchDlg::OnShowall() +{ + FOR_EACH_LL( m_Senders, i ) + { + m_Senders[i]->m_pConsoleWnd->SetVisible( true ); + } +} + +void CMessageWatchDlg::OnHideall() +{ + FOR_EACH_LL( m_Senders, i ) + { + m_Senders[i]->m_pConsoleWnd->SetVisible( false ); + } +} |