📄 voipdemo.cpp
字号:
//
// 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 + -