⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voipdemo.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*************************************************************************


  Disclaimer:

    This code and information is provided "as is" without warranty of
    any kind, either expressed or implied, including but not limited to
    the implied warranties of merchantability and/or fitness for a
    particular purpose.

Module Name:

	VoipDemo.cpp

Abstract:
	
	  (UI) Main Window procedure, child window procs, listview related functions

Notes:
	
	This file contains the bulk of the UI code for VoipDemo.  Refer to the 
	Readme.txt file for more information.

**************************************************************************/

#include "stdafx.h"
#include "VoIPDemo.h"
#include "sessionwnd.h"
#include "splashscr.h"
#include "dbase.h"
#include "rtcs.h"
#include <commctrl.h>
#include <iptypes.h>
#include <iphlpapi.h>

#define LV_ONLINEBUDDY_STATUSDATA_I		3
#define LV_OFFLINEBUDDY_STATUSDATA_I	4

#define NO_SIP_ADDR_MSG		L"You did not specify the address.\r\n"\
							L"Please use a proper SIP identifier:\r\n"\
							L"IP address, Machine name, or email address, e.g.\r\n"\
							L"1.2.3.4 -or- MyMachine -or- user@microsoft.com"

#define NO_PHONE_NUM_MSG  	L"You did not specify the contact's phone number.\r\n"\
							L"e.g.: +1-555-555-1212"

#define NO_USER_NAME_MSG	L"You did not specify the contact's name.\r\n"


/************************************************************************************************
	Global Variables
 ************************************************************************************************/

// make accessible to some other areas (rtcs, sessionwnd)
LOCAL_USER_INFO*		g_pLocalUserInfo = NULL;
DWORD					g_dwMainThreadID = 0;
VOID					InitializeLocalUser();

// Filescope Globals
HINSTANCE				m_hInstance = NULL;		// The current instance
HWND					m_hWndMain = NULL;		// Main window handle
HWND					hwndCB = NULL;			// The command bar handle
HWND					m_hwndOnlineView = NULL;			// handle to online buddies listview
HWND					m_hwndOfflineView = NULL;			// handle to offline buddies listview
RECT					m_rMyStatus = {28,101,240,121 };	// Region my status occupies
LOGFONT					m_lfBuddyFont;			// font structure for buddy/listview font object
HFONT					m_hFont = NULL;			// instantiated buddy font used by the listviews
INT						m_nButtonPointed = -1;	// button on the toolbar pointed by the cursor
INT						m_idActiveListView = 0;	// listview associated with selected buddy
BUDDY_SELECTION			m_cSelectedBuddy;		// buddy selection object (used by listviews and call scenarios)
CSessionWndContainer*	pSessionWndContainer = NULL;
PROPERTIES				m_sProp = { 20, 30, MAINWND_DEFAULTWIDTH, MAINWND_DEFAULTHEIGHT, TRUE, TRUE, FALSE,
						L"Myself", ES_ONLINE };

// index icons into the image list
IRES_TBL OnlineIconResTbl[] = {
	IDI_STATUSONLINE,		1,
	IDI_STATUSAWAY,			0,
	IDI_STATUSPHONE,		2,
	IDI_STATUSLUNCH,		3,  
	IDI_STATUSBUSY,			4,
	IDI_STATUSBEBACK,		5,
	IDI_STATUSPHONEBUDDY,	6,
	END_VAL,	-1
}; // used in InitListViews()

// index estatus into an icon list
EINDEX_TBL EstatIconTbl[] = {
	ES_ONLINE,		1,
	ES_AWAY,		0,	
	ES_BUSY,		2,
	ES_BEBACK,		3,
	ES_PHONE,		4,
	ES_LUNCH,		5,
	ES_OFFLINE,		0,
	ES_NOSTATUS,	-1,
	END_VAL,		-1
}; // used to decode ESTATUS into an icon to display (adding to a listview or changing status)

// index estatus to an icon for display
IRES_TBL EstatResTbl[] = {
	ES_ONLINE,		IDI_STATUSONLINE,
	ES_AWAY,		IDI_STATUSAWAY,	
	ES_OFFLINE,		IDI_STATUSOFFLINE,
	ES_BUSY,		IDI_STATUSBUSY,
	ES_BEBACK,		IDI_STATUSBEBACK,
	ES_PHONE,		IDI_STATUSPHONE,
	ES_LUNCH,		IDI_STATUSLUNCH,
	ES_NOSTATUS,	-1,
	END_VAL,		-1
}; // used to display my status in DoMainPaint

SBUTTONDATA			m_sButtons[]=	// Buttons
	{ { 10, 10, 50, 50, { IDB_ADDBTN, IDB_ADDBTN, IDB_ADDBTN } },
	  { 62, 10, 50, 50, { IDB_SENDBTN, IDB_STOPSENDBTN, IDB_SENDDISABLEDBTN } },
	  { 114, 10, 50, 50, { IDB_CALLBTN, IDB_HANGUPBTN, IDB_CALLDISABLEDBTN } } };

SSTATUSDATA			m_sStatus[] =	// Status lines
	{ { 4, SL_MYSTATUS, SL_MYSTATUS, RGB( 0, 196, 0 ), FW_NORMAL, TRUE },
	  { 4, SL_NOSTATUS, SL_ONLINETEXT, RGB( 0, 0, 0 ), FW_BOLD, FALSE },
	  { 4, SL_NOSTATUS, SL_OFFLINETEXT, RGB( 0, 0, 0 ), FW_BOLD, FALSE },
	  { 4, SL_ONLINEBUDDIES, SL_ONLINEBUDDIES, RGB( 0, 196, 0 ), FW_NORMAL, FALSE },
	  { 4, SL_OFFLINEBUDDIES, SL_OFFLINEBUDDIES, RGB( 224, 0, 0 ), FW_NORMAL, FALSE } };


DBGPARAM dpCurSettings = {
    TEXT("VoipDemo"), {
        TEXT("Status"),TEXT(""),TEXT(""),TEXT(""),
        TEXT("Call Info"),TEXT(""),TEXT(""),TEXT(""),
        TEXT("Init"),TEXT(""),TEXT("Presence Info"),TEXT("Provisioning Info"),
        TEXT(""),TEXT("Function"),TEXT("Warning"),TEXT("Error") },
    0xC011
}; 

/************************************************************************************************
	Filescope function prototypes
 ************************************************************************************************/

VOID DoStaticBuddyPaint(HDC hdc, RECT rWnd, int nY, int nViewTop);
VOID InvalidateButton( int nButton );
VOID CenterDialog(HWND hDlg, RECT& rt1);


/************************************************************************************************

  WinMain

	Main program entry

	Ensure another instance of this app is not in place.  Show a splash screen to ensure the app
	is not interrupted in the lengthy initialization phase (retail might be faster, but debug is
	slow due to PPFS & loading symbols).  Initialize all necessary data.  Message loop.  Shutdown.

 ************************************************************************************************/

int WINAPI WinMain(	HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	CSplashScreen* StartSplashScreen;
	CSplashScreen* QuitSplashScreen;

	// Lets see if we find an other instance
	TCHAR szTitle[ MAX_LOADSTRING ]; // The title bar text
	LoadString( hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING );

	HWND hWndOld = FindWindow( 0, szTitle );

	if ( hWndOld )
	{
		// Yes, bring it into focus and close this instance
		SetForegroundWindow( hWndOld );
		return 0;
	}

    DEBUGREGISTER(0);

	StartSplashScreen = new CSplashScreen( hInstance, IDB_SPLASHSCR );
	StartSplashScreen->Show();
	
	g_dwMainThreadID = GetCurrentThreadId();

	InitializeLocalUser();

	if (!InitializeRTC((FARPROC) CSessionWndContainer::SessionWndCallback, hInstance )) {
		delete StartSplashScreen;
		return FALSE;
	}	
	
	// Perform application initialization:
	if ( !InitInstance ( hInstance, nCmdShow ) ) 
	{
		delete StartSplashScreen;
		return FALSE;
	}

	HACCEL hAccelTable;
	hAccelTable = LoadAccelerators( hInstance, ( LPCTSTR )IDC_VOIPDEMO );

	pSessionWndContainer = new CSessionWndContainer( hInstance );

	delete StartSplashScreen;
	QuitSplashScreen = new CSplashScreen( hInstance, IDB_QUITSCR );
//	QuitSplashScreen->Show();

	// Main message loop
	// We need the hocus-pocus around shutdown here, as the RTC shutdown procedure
	//  requires a running message loop

	MSG msg;
	HANDLE hSth = 0;
	while ( 1 )
	{
		// Start shutdown procedure when WM_QUIT arrives
		if ( !GetMessage( &msg, NULL, 0, 0 ) )
		{
			QuitSplashScreen->Show();
			hSth = CreateThread( NULL, NULL, ShutdownRTC, 0, 0, NULL );
		}
		else
			if ( !TranslateAccelerator( msg.hwnd, hAccelTable, &msg ) ) 
			{
				// Wait until shutdown is done
				if ( msg.message == MSG_END_TESTCASE )
					break;

				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
	}

	// Wait until shutdown thread exits
	WaitForSingleObject( hSth, INFINITE );
	CloseHandle( hSth );

	delete pSessionWndContainer;
	delete QuitSplashScreen;
	
	return msg.wParam;
}

/************************************************************************************************

  MyRegisterMainWnd

	Register main window class to ensure well-formed icons, etc.

 ************************************************************************************************/

ATOM MyRegisterMainWnd( HINSTANCE hInstance, LPTSTR szWindowClass )
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon( hInstance, MAKEINTRESOURCE( IDI_VOIPDEMO ) );
    wc.hCursor			= 0;
    wc.hbrBackground	= ( HBRUSH ) CreateSolidBrush( RGB( 128, 128, 255 ) );
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= szWindowClass;

	return RegisterClass(&wc);
}

/************************************************************************************************

  InitInstance

	Saves instance handle and creates main window.

	Also call InitListViews() and instantiate associated font.
		
 ************************************************************************************************/

BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
	HWND	hWnd;
	TCHAR	szTitle[ MAX_LOADSTRING ];			// The title bar text
	TCHAR	szWindowClass[ MAX_LOADSTRING ];	// The main window class name
	TCHAR	szWindowSession[ MAX_LOADSTRING ];	// The session window class name

	m_hInstance = hInstance;							// Store instance handle in our global variable

	LoadString(hInstance, IDC_VOIPDEMO, szWindowClass, MAX_LOADSTRING);
	LoadString(hInstance, IDC_SESSIONWND, szWindowSession, MAX_LOADSTRING);
	MyRegisterMainWnd( hInstance, szWindowClass );
	CSessionWndContainer::MyRegisterSessionWnd( hInstance, szWindowSession );

	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	hWnd = CreateWindow( szWindowClass, szTitle, WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_SYSMENU,
		m_sProp.nWndX, m_sProp.nWndY, m_sProp.nWndCx, m_sProp.nWndCy, NULL, NULL, hInstance, NULL );

	if ( !hWnd )
		return FALSE;


	HICON hSmallIcon = ( HICON )LoadImage( hInstance, MAKEINTRESOURCE( IDI_VOIPDEMO ), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR );
	if ( NULL != hSmallIcon ) 
	{
		SendMessage( hWnd, WM_SETICON, ICON_SMALL, ( LPARAM )hSmallIcon );
	}

	// Set up the font used for display inside the main window (buddies + mystatus, etc.)
	ZeroMem(m_lfBuddyFont);
	m_lfBuddyFont.lfHeight = 16;
	m_lfBuddyFont.lfWeight = m_sStatus[ LV_ONLINEBUDDY_STATUSDATA_I ].nTextWeight;
	m_lfBuddyFont.lfUnderline = m_sStatus[ LV_ONLINEBUDDY_STATUSDATA_I ].bTextUnderline;
	m_lfBuddyFont.lfCharSet = DEFAULT_CHARSET;
	m_lfBuddyFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
	m_lfBuddyFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	m_lfBuddyFont.lfQuality = DEFAULT_QUALITY;
	m_lfBuddyFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
	wcscpy( m_lfBuddyFont.lfFaceName, L"Arial" );

	m_hWndMain = hWnd;

	if (!InitListViews()) {
		return FALSE;	
	}

	ShowWindow( hWnd, nCmdShow );
	UpdateWindow( hWnd );

	if ( hwndCB )
		CommandBar_Show( hwndCB, TRUE );

	// Load the buddies from the persistent store
	return InitBuddiesRTC();
}


/************************************************************************************************

  InitializeLocalUser()

	Sets the local user's information at RTC initiliazation, after presence and profile is
	initialized.

	Get local network information and use the machine name as both our name and our URI. 
    If network information is not retrievable, use default string values for name
	and address.

 ************************************************************************************************/

VOID
InitializeLocalUser()
{
	DEBUGMSG( ZONE_INIT|ZONE_STATUS, (L"VoipDemo: Setting the local user's Name and URI") );
	BOOL bFound = FALSE;
	
	HANDLE hDB = NULL;
	CEOID oid = 0;

	g_pLocalUserInfo = new LOCAL_USER_INFO;

	// first we'll check the registry for the local user
	
	BSTR bstrName = NULL;
	BSTR bstrURI = NULL;
	BSTR bstrLocalPhoneURI = NULL;

	if (ReadLocalUserRegistry(NULL, &bstrName, &bstrURI, &bstrLocalPhoneURI)) {
		bFound = TRUE;

		g_pLocalUserInfo->put_Addr(bstrURI);
		g_pLocalUserInfo->put_Name(bstrName);
		
		if (bstrLocalPhoneURI) {
			g_pLocalUserInfo->put_LocalPhoneURI(bstrLocalPhoneURI);
		}
	}    
    
	if (!bFound) {
		// reg key not found
		// get the machine name
		// use the machine name, etc. as the default values for the user's information		
		
		PIP_ADAPTER_INFO pAdapterInfo = NULL;
		ULONG ulSizeAdapterInfo = 0;
		TCHAR szHost[MAX_HOSTNAME_LEN + 4];

		PFIXED_INFO pNetworkParams  = NULL;
		ULONG uSizeNetworkParams = 0;
		
		DWORD dwReturnvalueGetNetworkParams = GetNetworkParams( pNetworkParams, &uSizeNetworkParams );
		pNetworkParams = ( PFIXED_INFO )malloc( uSizeNetworkParams );
		if ( !pNetworkParams )
		{
			DEBUGMSG( 1, ( L"VoIPDemo: Insufficient Memory for network data: using defult values\r\n" ) );
		}
		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -