2174 lines
46 KiB
C++
2174 lines
46 KiB
C++
// File: rtoolbar.cpp
|
|
|
|
#include "precomp.h"
|
|
|
|
#include "RToolbar.h"
|
|
#include "GenContainers.h"
|
|
#include "GenControls.h"
|
|
#include "Conf.h"
|
|
#include "ConfRoom.h"
|
|
#include "RoomList.h"
|
|
#include "particip.h"
|
|
#include "VidView.h"
|
|
#include "ProgressBar.h"
|
|
#include "AudioCtl.h"
|
|
#include "CallingBar.h"
|
|
#include "resource.h"
|
|
#include "topWindow.h"
|
|
#include "dlgCall2.h"
|
|
#include "ulswizrd.h"
|
|
#include "audiowiz.h"
|
|
#include "sdialdlg.h"
|
|
|
|
#include "callto.h"
|
|
|
|
#define ZeroArray(_a) ZeroMemory(_a, sizeof(_a))
|
|
|
|
static void ShiftFocus(HWND hwndTop, BOOL bForward);
|
|
|
|
class CRemoteVideo : public CVideoWindow
|
|
{
|
|
public:
|
|
CRemoteVideo(BOOL bEmbedded = FALSE) :
|
|
CVideoWindow(REMOTE, bEmbedded)
|
|
{
|
|
}
|
|
|
|
// Stick the child in the lower-right corner of the window
|
|
virtual void Layout()
|
|
{
|
|
CVideoWindow::Layout();
|
|
|
|
HWND hwnd = GetWindow();
|
|
|
|
HWND hwndLocal = GetFirstChild(hwnd);
|
|
|
|
if (NULL != hwndLocal)
|
|
{
|
|
RECT rcRemote;
|
|
GetClientRect(hwnd, &rcRemote);
|
|
|
|
int left = rcRemote.right *5/8;
|
|
int top = rcRemote.bottom *5/8;
|
|
|
|
SetWindowPos(hwndLocal, NULL, left, top,
|
|
rcRemote.right-left, rcRemote.bottom-top, SWP_NOZORDER);
|
|
}
|
|
}
|
|
} ;
|
|
|
|
// This just exists to send WM_NOTIFY messages back to the Roster
|
|
class CRosterParent : public CFillWindow
|
|
{
|
|
private:
|
|
CRoomListView *m_pRoster;
|
|
|
|
void OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
|
|
{
|
|
POINT pt = { xPos, yPos };
|
|
|
|
CRoomListView *pView = GetRoster();
|
|
if ((NULL != pView) && (pView->GetHwnd() == hwndContext))
|
|
{
|
|
pView->OnPopup(pt);
|
|
}
|
|
|
|
FORWARD_WM_CONTEXTMENU(hwnd, hwndContext, xPos, yPos, CFillWindow::ProcessMessage);
|
|
}
|
|
|
|
inline LRESULT RosterNotify(CRoomListView *pRoster, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(pRoster->OnNotify(wParam, lParam));
|
|
}
|
|
|
|
// Just forward to the Roster
|
|
LRESULT OnNotify(HWND hwnd, int id, NMHDR *pHdr)
|
|
{
|
|
// pass on all notifications:
|
|
if (ID_LISTVIEW == pHdr->idFrom)
|
|
{
|
|
CRoomListView *pView = GetRoster();
|
|
if (NULL != pView)
|
|
{
|
|
// Forward to the roster
|
|
return(FORWARD_WM_NOTIFY(pView, id, pHdr, RosterNotify));
|
|
}
|
|
}
|
|
|
|
return(FORWARD_WM_NOTIFY(hwnd, id, pHdr, CFillWindow::ProcessMessage));
|
|
}
|
|
|
|
|
|
protected:
|
|
~CRosterParent()
|
|
{
|
|
// delete can handle NULL
|
|
delete m_pRoster;
|
|
}
|
|
|
|
virtual LRESULT ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
HANDLE_MSG(hwnd, WM_NOTIFY, OnNotify);
|
|
HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
|
|
|
|
case WM_DESTROY:
|
|
delete m_pRoster;
|
|
m_pRoster = NULL;
|
|
break;
|
|
}
|
|
|
|
return(CFillWindow::ProcessMessage(hwnd, uMsg, wParam, lParam));
|
|
}
|
|
|
|
public:
|
|
CRosterParent() : m_pRoster(NULL) {}
|
|
|
|
BOOL Create(HWND hwndParent)
|
|
{
|
|
m_pRoster = new CRoomListView();
|
|
if (NULL == m_pRoster)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!CFillWindow::Create(hwndParent, 0))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(m_pRoster->Create(GetWindow()));
|
|
}
|
|
|
|
CRoomListView *GetRoster() const
|
|
{
|
|
return(m_pRoster);
|
|
}
|
|
} ;
|
|
|
|
CToolbar *CreateToolbar(
|
|
CGenWindow *pParent,
|
|
const Buttons buttons[]=NULL,
|
|
int nButtons=0,
|
|
LPARAM lHideModes=0,
|
|
DWORD dwExStyle=0
|
|
);
|
|
|
|
#define ReleaseIt(pUnk) if (NULL != (pUnk)) { (pUnk)->Release(); (pUnk) = NULL; }
|
|
|
|
enum CheckStates
|
|
{
|
|
Unchecked = 0,
|
|
Checked = 1,
|
|
} ;
|
|
|
|
const static int MainHMargin = 8;
|
|
const static int MainVMargin = 5;
|
|
const static int MainGap = 4;
|
|
|
|
const static int SunkenHMargin = 8;
|
|
const static int SunkenVMargin = 2;
|
|
|
|
const static int ButtonsGap = 12;
|
|
|
|
const static int AudioMax = 100;
|
|
const static int AudioVolMax = 0xffff;
|
|
const static int AudioBump = 10;
|
|
|
|
enum MainTimers
|
|
{
|
|
IDT_AUDIO = 1,
|
|
} ;
|
|
|
|
// Set these bits in the hide mode to hide in certain situations
|
|
enum HideModes
|
|
{
|
|
Inherit = 0x0000,
|
|
|
|
Normal = 0x0001,
|
|
Compact = 0x0002,
|
|
DataOnly = 0x0004,
|
|
NoAVTB = 0x0008,
|
|
Roster = 0x0010,
|
|
AudioTuning = 0x0020,
|
|
Dialing = 0x0040,
|
|
Receiving = 0x0080,
|
|
ReceivingWPiP = 0x0100,
|
|
Previewing = 0x0200,
|
|
Video = Receiving|ReceivingWPiP|Previewing,
|
|
|
|
Ignore = 0x4000,
|
|
IfNoChildren = 0x8000,
|
|
} ;
|
|
|
|
// Sets the hide mode bits on a window
|
|
static inline void SetHideModes(CGenWindow *pWin, LPARAM modes)
|
|
{
|
|
if (NULL != pWin)
|
|
{
|
|
pWin->SetUserData(modes);
|
|
}
|
|
}
|
|
|
|
// Gets the hide mode bits on a window
|
|
static inline LPARAM GetHideModes(IGenWindow *pWin)
|
|
{
|
|
return(pWin->GetUserData());
|
|
}
|
|
|
|
CMainUI::CMainUI() :
|
|
m_hbBack(NULL),
|
|
m_eViewMode(ViewNormal),
|
|
m_pLocalVideo(NULL),
|
|
m_pRemoteVideo(NULL),
|
|
m_pAudioMic(NULL),
|
|
m_pAudioSpeaker(NULL),
|
|
m_pRoster(NULL),
|
|
m_pCalling(NULL),
|
|
m_bDialing(FALSE),
|
|
m_bAudioTuning(FALSE),
|
|
m_bPreviewing(TRUE),
|
|
m_bPicInPic(FALSE),
|
|
m_bStateChanged(FALSE),
|
|
m_bShowAVTB(FALSE)
|
|
{
|
|
}
|
|
|
|
CMainUI::~CMainUI()
|
|
{
|
|
if (NULL != m_hbBack)
|
|
{
|
|
DeleteObject(m_hbBack);
|
|
m_hbBack = NULL;
|
|
}
|
|
|
|
ReleaseIt(m_pLocalVideo);
|
|
ReleaseIt(m_pRemoteVideo);
|
|
ReleaseIt(m_pAudioMic);
|
|
ReleaseIt(m_pAudioSpeaker);
|
|
ReleaseIt(m_pRoster);
|
|
ReleaseIt(m_pCalling);
|
|
}
|
|
|
|
void SplitBitmap(UINT nCols, UINT nRows, HBITMAP hbmSrc, HBITMAP hbmDst[])
|
|
{
|
|
BITMAP bm;
|
|
GetObject(hbmSrc, sizeof(bm), &bm);
|
|
int nWid = bm.bmWidth / nCols;
|
|
int nHgt = bm.bmHeight / nRows;
|
|
|
|
HDC hdcScreen = GetDC(NULL);
|
|
HDC hdcSrc = CreateCompatibleDC(hdcScreen);
|
|
HDC hdcDst = CreateCompatibleDC(hdcScreen);
|
|
ReleaseDC(NULL, hdcScreen);
|
|
|
|
if (NULL != hdcSrc && NULL != hdcDst)
|
|
{
|
|
SelectObject(hdcSrc, hbmSrc);
|
|
|
|
for(UINT i=0; i<nRows; ++i)
|
|
{
|
|
for (UINT j=0; j<nCols; ++j)
|
|
{
|
|
HBITMAP hbmTemp = CreateCompatibleBitmap(hdcSrc, nWid, nHgt);
|
|
if (NULL != hbmTemp)
|
|
{
|
|
SelectObject(hdcDst, hbmTemp);
|
|
BitBlt(hdcDst, 0, 0, nWid, nHgt, hdcSrc, j*nWid, i*nHgt, SRCCOPY);
|
|
}
|
|
hbmDst[i*nCols + j] = hbmTemp;
|
|
}
|
|
}
|
|
}
|
|
|
|
DeleteDC(hdcSrc);
|
|
DeleteDC(hdcDst);
|
|
}
|
|
|
|
// Helper function for adding a bunch of buttons to a parent window
|
|
void AddButtons(
|
|
CGenWindow *pParent, // The parent window
|
|
const Buttons buttons[], // Array of structures describing the buttons
|
|
int nButtons, // Number of buttons to create
|
|
BOOL bTranslateColors, // Use system background colors
|
|
CGenWindow *pCreated[], // Created CGenWindow's will be put here
|
|
IButtonChange *pNotify // Notification of clicks
|
|
)
|
|
{
|
|
if (NULL == buttons)
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
HWND hwnd = pParent->GetWindow();
|
|
|
|
for (int i=0; i<nButtons; ++i)
|
|
{
|
|
if (NULL != pCreated)
|
|
{
|
|
// Init in case of error
|
|
pCreated[i] = NULL;
|
|
}
|
|
|
|
CBitmapButton *pButton;
|
|
|
|
pButton = new CBitmapButton();
|
|
if (NULL == pButton)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Create the actual window
|
|
if (!pButton->Create(hwnd, buttons[i].idCommand, _Module.GetModuleInstance(),
|
|
buttons[i].idbStates, bTranslateColors,
|
|
buttons[i].nInputStates, buttons[i].nCustomStates, pNotify))
|
|
{
|
|
pButton->Release();
|
|
continue;
|
|
}
|
|
|
|
// Save off the created button if requested
|
|
if (NULL != pCreated)
|
|
{
|
|
// HACKHACK georgep: Not AddRef'ing; will let caller do that if interested
|
|
pCreated[i] = pButton;
|
|
}
|
|
|
|
if (0 != buttons[i].idTooltip)
|
|
{
|
|
pButton->SetTooltip(RES2T(buttons[i].idTooltip));
|
|
}
|
|
|
|
// By default, do not hide individual buttons
|
|
SetHideModes(pButton, Ignore);
|
|
|
|
// Release our reference to the button
|
|
pButton->Release();
|
|
}
|
|
}
|
|
|
|
CToolbar *CreateToolbar(
|
|
CGenWindow *pParent,
|
|
const Buttons buttons[],
|
|
int nButtons,
|
|
LPARAM lHideModes,
|
|
DWORD dwExStyle
|
|
)
|
|
{
|
|
CToolbar *ret;
|
|
|
|
ret = new CToolbar();
|
|
if (NULL == ret)
|
|
{
|
|
return(NULL);
|
|
}
|
|
if (!ret->Create(pParent->GetWindow(), dwExStyle))
|
|
{
|
|
ret->Release();
|
|
return(NULL);
|
|
}
|
|
|
|
SetHideModes(ret, lHideModes);
|
|
AddButtons(ret, buttons, nButtons, TRUE);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
void CMainUI::CreateDialTB(CGenWindow *pParent)
|
|
{
|
|
// Create the toolbar
|
|
m_pCalling = new CCallingBar();
|
|
if (NULL != m_pCalling)
|
|
{
|
|
SetHideModes(m_pCalling, Compact);
|
|
|
|
m_pCalling->Create(pParent, m_pConfRoom);
|
|
|
|
// m_pCalling->Release();
|
|
}
|
|
}
|
|
|
|
void CMainUI::CreateAppsTB(CGenWindow *pParent)
|
|
{
|
|
const static int AppsHMargin = 5;
|
|
const static int AppsVMargin = 0;
|
|
const static int AppsHGap = 11;
|
|
|
|
static const Buttons appButtons[] =
|
|
{
|
|
{ IDB_SHARE , CBitmapButton::Disabled+1, 1, ID_TB_SHARING , IDS_TT_TB_SHARING , },
|
|
{ IDB_CHAT , CBitmapButton::Disabled+1, 1, ID_TB_CHAT , IDS_TT_TB_CHAT , },
|
|
{ IDB_WHITEBOARD , CBitmapButton::Disabled+1, 1, ID_TB_NEWWHITEBOARD , IDS_TT_TB_NEWWHITEBOARD , },
|
|
{ IDB_FILE_TRANSFER , CBitmapButton::Disabled+1, 1, ID_TB_FILETRANSFER , IDS_TT_TB_FILETRANSFER , },
|
|
} ;
|
|
|
|
// Create the "data" buttons toolbar
|
|
CToolbar *pApps = CreateToolbar(pParent, appButtons, ARRAY_ELEMENTS(appButtons), Compact);
|
|
if (NULL != pApps)
|
|
{
|
|
// HACKHACK georgep: These numbers make it appear about right
|
|
pApps->m_hMargin = AppsHMargin;
|
|
pApps->m_vMargin = AppsVMargin;
|
|
pApps->m_gap = AppsHGap;
|
|
|
|
// pApps->m_bMinDesiredSize = TRUE;
|
|
|
|
pApps->Release();
|
|
}
|
|
}
|
|
|
|
void CMainUI::CreateVideoAndAppsTB(CGenWindow *pParent, CreateViewMode eMode, BOOL bEmbedded)
|
|
{
|
|
CLayeredView::LayoutStyle lVidDialStyle = CLayeredView::Center;
|
|
|
|
switch (eMode)
|
|
{
|
|
case CreateFull:
|
|
case CreatePreviewOnly:
|
|
case CreateRemoteOnly:
|
|
case CreateTelephone:
|
|
break;
|
|
|
|
case CreatePreviewNoPause:
|
|
case CreateRemoteNoPause:
|
|
lVidDialStyle = CLayeredView::Fill;
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// Create the toolbar
|
|
CBorderWindow *pVideoAndCalling = new CBorderWindow();
|
|
if (NULL != pVideoAndCalling)
|
|
{
|
|
if (pVideoAndCalling->Create(pParent->GetWindow()))
|
|
{
|
|
SetHideModes(pVideoAndCalling, DataOnly);
|
|
|
|
pVideoAndCalling->m_hGap = 4;
|
|
pVideoAndCalling->m_vGap = 4;
|
|
|
|
// This is the center part of the border window
|
|
CLayeredView *pVidAndDial = new CLayeredView();
|
|
if (NULL != pVidAndDial)
|
|
{
|
|
if (pVidAndDial->Create(pVideoAndCalling->GetWindow()))
|
|
{
|
|
pVideoAndCalling->m_uParts |= CBorderWindow::Center;
|
|
|
|
pVidAndDial->m_lStyle = lVidDialStyle;
|
|
|
|
CGenWindow *pLocalParent = pVidAndDial;
|
|
|
|
if (CreateFull == eMode
|
|
|| CreateTelephone == eMode
|
|
)
|
|
{
|
|
CreateDialingWindow(pVidAndDial);
|
|
}
|
|
|
|
if (CreateFull == eMode
|
|
|| CreateRemoteOnly == eMode
|
|
|| CreateRemoteNoPause == eMode
|
|
)
|
|
{
|
|
// Create the remote video window
|
|
m_pRemoteVideo = new CRemoteVideo(bEmbedded);
|
|
if (NULL != m_pRemoteVideo)
|
|
{
|
|
SetHideModes(m_pRemoteVideo, Dialing|Previewing|DataOnly);
|
|
|
|
m_pRemoteVideo->Create(pVidAndDial->GetWindow(), GetPalette(), this);
|
|
|
|
pLocalParent = m_pRemoteVideo;
|
|
}
|
|
}
|
|
|
|
if (CreateFull == eMode
|
|
|| CreatePreviewOnly == eMode
|
|
|| CreatePreviewNoPause == eMode
|
|
)
|
|
{
|
|
// Create the local video window, even though we don't show it yet
|
|
m_pLocalVideo = new CVideoWindow(CVideoWindow::LOCAL, bEmbedded);
|
|
if (NULL != m_pLocalVideo)
|
|
{
|
|
SetHideModes(m_pLocalVideo, Dialing|Receiving|DataOnly);
|
|
|
|
m_pLocalVideo->Create(pLocalParent->GetWindow(), GetPalette(), this);
|
|
ShowWindow(m_pLocalVideo->GetWindow(), SW_HIDE);
|
|
}
|
|
}
|
|
}
|
|
|
|
pVidAndDial->Release();
|
|
}
|
|
|
|
if (CreateFull == eMode
|
|
|| CreateTelephone == eMode
|
|
)
|
|
{
|
|
// create the toolbar
|
|
static const Buttons abOsr2Calling[] =
|
|
{
|
|
{ IDB_DIAL , CBitmapButton::Disabled+1, 1, ID_TB_NEW_CALL , IDS_TT_TB_NEW_CALL , },
|
|
{ IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
|
|
{ IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
|
|
{ IDB_SHOWAV , CBitmapButton::Hot+1, Checked+1, ID_TB_SHOWAVTB , IDS_TT_TB_SHOWAVTB , },
|
|
} ;
|
|
CGenWindow *agwOsr2Calling[ARRAY_ELEMENTS(abOsr2Calling)];
|
|
|
|
// This is the right-hand part of the border window
|
|
CToolbar *ptbOsr2Calling = CreateToolbar(pVideoAndCalling, NULL, 0, DataOnly);
|
|
if (NULL != ptbOsr2Calling)
|
|
{
|
|
pVideoAndCalling->m_uParts |= CBorderWindow::Right;
|
|
|
|
ptbOsr2Calling->m_bVertical = TRUE;
|
|
ptbOsr2Calling->m_nAlignment = Center;
|
|
|
|
ZeroArray(agwOsr2Calling);
|
|
AddButtons(ptbOsr2Calling, abOsr2Calling, ARRAY_ELEMENTS(abOsr2Calling),
|
|
TRUE, agwOsr2Calling);
|
|
|
|
SetHideModes(agwOsr2Calling[0], Normal);
|
|
SetHideModes(agwOsr2Calling[3], Normal);
|
|
|
|
ptbOsr2Calling->m_uRightIndex = 3;
|
|
|
|
ptbOsr2Calling->Release();
|
|
}
|
|
}
|
|
|
|
// This is the bottom part of the border window
|
|
CreateAVTB(pVideoAndCalling, eMode);
|
|
pVideoAndCalling->m_uParts |= CBorderWindow::Bottom;
|
|
}
|
|
|
|
pVideoAndCalling->Release();
|
|
}
|
|
}
|
|
|
|
void CMainUI::CreateAVTB(CGenWindow *pParent, CreateViewMode eMode)
|
|
{
|
|
switch (eMode)
|
|
{
|
|
case CreateFull:
|
|
case CreatePreviewOnly:
|
|
case CreateRemoteOnly:
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
const static int AVHMargin = 10;
|
|
const static int AVVMargin = 2;
|
|
const static int AVHGap = ButtonsGap;
|
|
|
|
// create the toolbar
|
|
static const Buttons avButtons[] =
|
|
{
|
|
{ IDB_PLAYPAUSE, CBitmapButton::Disabled+1, 2, ID_TB_PLAYPAUSE , IDS_TT_TB_PLAYPAUSE , },
|
|
{ IDB_PIP , CBitmapButton::Disabled+1, 1, ID_TB_PICINPIC , IDS_TT_TB_PICINPIC , },
|
|
{ IDB_AUDIO , CBitmapButton::Disabled+1, Checked+1, ID_TB_AUDIOTUNING, IDS_TT_TB_AUDIOTUNING, },
|
|
} ;
|
|
|
|
int nButtons = eMode == CreateFull ? ARRAY_ELEMENTS(avButtons) : 1;
|
|
|
|
CToolbar *pAV = CreateToolbar(pParent, NULL, 0, NoAVTB|DataOnly);
|
|
if (NULL != pAV)
|
|
{
|
|
CGenWindow *aButtons[ARRAY_ELEMENTS(avButtons)];
|
|
ZeroArray(aButtons);
|
|
AddButtons(pAV, avButtons, nButtons, TRUE, aButtons);
|
|
|
|
CGenWindow *pAT;
|
|
|
|
//
|
|
// If video is completely disabled by policy, disable video buttons
|
|
//
|
|
if (!FIsSendVideoAllowed() && !FIsReceiveVideoAllowed())
|
|
{
|
|
pAT = aButtons[0];
|
|
if (NULL != pAT)
|
|
{
|
|
EnableWindow(pAT->GetWindow(), FALSE);
|
|
}
|
|
|
|
pAT = aButtons[1];
|
|
if (NULL != pAT)
|
|
{
|
|
EnableWindow(pAT->GetWindow(), FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// If audio is completely disabled by policy, disable audio buttons
|
|
//
|
|
pAT = aButtons[2];
|
|
if (NULL != pAT)
|
|
{
|
|
ASSERT(ID_TB_AUDIOTUNING == GetDlgCtrlID(pAT->GetWindow()));
|
|
|
|
if (!FIsAudioAllowed())
|
|
{
|
|
EnableWindow(pAT->GetWindow(), FALSE);
|
|
}
|
|
}
|
|
|
|
pAV->m_hMargin = AVHMargin;
|
|
pAV->m_vMargin = AVVMargin;
|
|
pAV->m_gap = AVHGap;
|
|
pAV->Release();
|
|
}
|
|
}
|
|
|
|
#if FALSE // {
|
|
void CMainUI::CreateCallsTB(CGenWindow *pParent)
|
|
{
|
|
// create the toolbar
|
|
static const Buttons callsButtons[] =
|
|
{
|
|
{ IDB_INCOMING , CBitmapButton::Hot+1, 1, ID_TB_INCOMING , IDS_TT_TB_INCOMING , },
|
|
{ IDB_HANGUP , CBitmapButton::Hot+1, 1, IDM_FILE_HANGUP , IDS_TT_FILE_HANGUP , },
|
|
{ IDB_CREDENTIALS, CBitmapButton::Hot+1, 1, ID_TB_CREDENTIALS, IDS_TT_TB_CREDENTIALS, },
|
|
} ;
|
|
|
|
CToolbar *pCalls = CreateToolbar(pParent, callsButtons, ARRAY_ELEMENTS(callsButtons),
|
|
Compact);
|
|
if (NULL != pCalls)
|
|
{
|
|
pCalls->Release();
|
|
}
|
|
}
|
|
#endif // FALSE }
|
|
|
|
void CMainUI::CreateDialingWindow(
|
|
CGenWindow *pParent // The parent window
|
|
)
|
|
{
|
|
const static int DialHMargin = 17;
|
|
const static int DialVMargin = 4;
|
|
const static int DialHGap = 5;
|
|
const static int DialVGap = 0;
|
|
|
|
CEdgedWindow *pEdge = new CEdgedWindow();
|
|
if (NULL == pEdge)
|
|
{
|
|
return;
|
|
}
|
|
SetHideModes(pEdge, Video|DataOnly);
|
|
|
|
if (pEdge->Create(pParent->GetWindow()))
|
|
{
|
|
CToolbar *pDialing = CreateToolbar(pEdge, NULL, 0, Ignore);
|
|
if (NULL != pDialing)
|
|
{
|
|
pDialing->m_bVertical = TRUE;
|
|
pDialing->m_gap = DialVGap;
|
|
pDialing->m_hMargin = DialHMargin;
|
|
pDialing->m_vMargin = DialVMargin;
|
|
|
|
static const Buttons dialButtons[] =
|
|
{
|
|
{ IDB_DIAL1 , CBitmapButton::Hot+1, 1, ID_TB_DIAL1 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL2 , CBitmapButton::Hot+1, 1, ID_TB_DIAL2 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL3 , CBitmapButton::Hot+1, 1, ID_TB_DIAL3 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL4 , CBitmapButton::Hot+1, 1, ID_TB_DIAL4 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL5 , CBitmapButton::Hot+1, 1, ID_TB_DIAL5 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL6 , CBitmapButton::Hot+1, 1, ID_TB_DIAL6 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL7 , CBitmapButton::Hot+1, 1, ID_TB_DIAL7 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL8 , CBitmapButton::Hot+1, 1, ID_TB_DIAL8 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL9 , CBitmapButton::Hot+1, 1, ID_TB_DIAL9 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIALSTAR , CBitmapButton::Hot+1, 1, ID_TB_DIALSTAR , IDS_TT_DIALPAD, },
|
|
{ IDB_DIAL0 , CBitmapButton::Hot+1, 1, ID_TB_DIAL0 , IDS_TT_DIALPAD, },
|
|
{ IDB_DIALPOUND, CBitmapButton::Hot+1, 1, ID_TB_DIALPOUND, IDS_TT_DIALPAD, },
|
|
} ;
|
|
|
|
for (int row=0; row<4; ++row)
|
|
{
|
|
CToolbar *pRowTB = CreateToolbar(pDialing);
|
|
if (NULL != pRowTB)
|
|
{
|
|
pRowTB->m_gap = DialHGap;
|
|
|
|
AddButtons(pRowTB, &dialButtons[row*3], 3, TRUE, NULL, this);
|
|
pRowTB->Release();
|
|
}
|
|
}
|
|
|
|
pDialing->Release();
|
|
}
|
|
}
|
|
|
|
pEdge->Release();
|
|
}
|
|
|
|
// Creates the audio-tuning window
|
|
void CMainUI::CreateAudioTuningWindow(
|
|
CGenWindow *pParent // The parent window
|
|
)
|
|
{
|
|
static const int ATHMargin = 8;
|
|
static const int ATVMargin = 6;
|
|
|
|
static const int ATControlWidth = 170;
|
|
|
|
CToolbar *pATWindow = CreateToolbar(pParent, NULL, 0, NoAVTB|Roster|DataOnly);
|
|
if (NULL != pATWindow)
|
|
{
|
|
pATWindow->m_bVertical = TRUE;
|
|
pATWindow->m_nAlignment = Fill;
|
|
|
|
pATWindow->m_gap = MainGap;
|
|
|
|
CEdgedWindow *pEdge;
|
|
|
|
pEdge = new CEdgedWindow();
|
|
if (NULL != pEdge)
|
|
{
|
|
pEdge->m_hMargin = ATHMargin;
|
|
pEdge->m_vMargin = ATVMargin;
|
|
|
|
if (pEdge->Create(pATWindow->GetWindow()))
|
|
{
|
|
SetHideModes(pEdge, Ignore);
|
|
|
|
CButton *pButton = new CButton();
|
|
if (NULL != pButton)
|
|
{
|
|
pButton->Create(pEdge->GetWindow(), ID_TB_TUNEMIC_UNMUTE, NULL,
|
|
BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
|
|
pButton->SetTooltip(RES2T(IDS_TT_MUTE_MIC));
|
|
|
|
HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
|
|
MAKEINTRESOURCE(IDI_MICFONE),
|
|
IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
|
|
LR_DEFAULTCOLOR));
|
|
pButton->SetIcon(hIcon);
|
|
|
|
pEdge->SetHeader(pButton);
|
|
|
|
pButton->Release();
|
|
}
|
|
UpdateMuteState(FALSE, pButton);
|
|
|
|
m_pAudioMic = new CProgressTrackbar();
|
|
if (NULL != m_pAudioMic)
|
|
{
|
|
if (m_pAudioMic->Create(pEdge->GetWindow(), 0, this))
|
|
{
|
|
m_pAudioMic->SetTooltip(RES2T(IDS_TT_ADJUST_MIC));
|
|
|
|
m_pAudioMic->SetMaxValue(AudioMax);
|
|
|
|
SIZE size;
|
|
m_pAudioMic->GetDesiredSize(&size);
|
|
size.cx = ATControlWidth;
|
|
m_pAudioMic->SetDesiredSize(&size);
|
|
}
|
|
|
|
// m_pAudioMic->Release();
|
|
}
|
|
}
|
|
|
|
pEdge->Release();
|
|
}
|
|
|
|
|
|
pEdge = new CEdgedWindow();
|
|
if (NULL != pEdge)
|
|
{
|
|
pEdge->m_hMargin = ATHMargin;
|
|
pEdge->m_vMargin = ATVMargin;
|
|
|
|
if (pEdge->Create(pATWindow->GetWindow()))
|
|
{
|
|
SetHideModes(pEdge, Ignore);
|
|
|
|
CButton *pButton = new CButton();
|
|
if (NULL != pButton)
|
|
{
|
|
pButton->Create(pEdge->GetWindow(), ID_TB_TUNESPEAKER_UNMUTE, NULL,
|
|
BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
|
|
pButton->SetTooltip(RES2T(IDS_TT_MUTE_SPK));
|
|
|
|
HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
|
|
MAKEINTRESOURCE(IDI_SPEAKER),
|
|
IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
|
|
LR_DEFAULTCOLOR));
|
|
pButton->SetIcon(hIcon);
|
|
|
|
pEdge->SetHeader(pButton);
|
|
|
|
pButton->Release();
|
|
}
|
|
UpdateMuteState(TRUE, pButton);
|
|
|
|
m_pAudioSpeaker = new CProgressTrackbar();
|
|
if (NULL != m_pAudioSpeaker)
|
|
{
|
|
if (m_pAudioSpeaker->Create(pEdge->GetWindow(), 0, this))
|
|
{
|
|
m_pAudioSpeaker->SetTooltip(RES2T(IDS_TT_ADJUST_SPK));
|
|
|
|
m_pAudioSpeaker->SetMaxValue(AudioMax);
|
|
|
|
SIZE size;
|
|
m_pAudioSpeaker->GetDesiredSize(&size);
|
|
size.cx = ATControlWidth;
|
|
m_pAudioSpeaker->SetDesiredSize(&size);
|
|
}
|
|
|
|
// m_pAudioSpeaker->Release();
|
|
}
|
|
}
|
|
|
|
pEdge->Release();
|
|
}
|
|
|
|
pATWindow->Release();
|
|
}
|
|
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
// Force an update of the controls
|
|
OnAudioLevelChange(TRUE , pAudioControl->GetSpeakerVolume());
|
|
OnAudioLevelChange(FALSE, pAudioControl->GetRecorderVolume());
|
|
}
|
|
}
|
|
|
|
void CMainUI::CreateRosterArea(CGenWindow *pParent, CreateViewMode eMode)
|
|
{
|
|
switch (eMode)
|
|
{
|
|
case CreateFull:
|
|
case CreateDataOnly:
|
|
case CreateTelephone:
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
CLayeredView *pView = new CLayeredView();
|
|
if (NULL == pView)
|
|
{
|
|
// Pretty bad
|
|
return;
|
|
}
|
|
|
|
if (pView->Create(pParent->GetWindow()))
|
|
{
|
|
SetHideModes(pView, IfNoChildren);
|
|
|
|
pView->m_lStyle = CLayeredView::Fill;
|
|
|
|
if (eMode != CreateDataOnly)
|
|
{
|
|
CreateAudioTuningWindow(pView);
|
|
}
|
|
|
|
if (eMode != CreateTelephone)
|
|
{
|
|
CToolbar *pRosterAndCall = CreateToolbar(pView);
|
|
if (NULL != pRosterAndCall)
|
|
{
|
|
pRosterAndCall->m_nAlignment = CToolbar::Fill;
|
|
|
|
m_pRoster = new CRosterParent();
|
|
if (NULL != m_pRoster)
|
|
{
|
|
m_pRoster->Create(pRosterAndCall->GetWindow());
|
|
|
|
// HACKHACK georgep: Just calling SetUserData directly for now
|
|
SetHideModes(m_pRoster, Compact|AudioTuning);
|
|
}
|
|
|
|
if (CreateDataOnly != eMode)
|
|
{
|
|
CToolbar *pCalling = CreateToolbar(pRosterAndCall);
|
|
if (NULL != pCalling)
|
|
{
|
|
SetHideModes(pCalling, Normal|Compact);
|
|
|
|
pCalling->m_bVertical = TRUE;
|
|
|
|
static const Buttons abCalling[] =
|
|
{
|
|
{ IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
|
|
{ IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
|
|
} ;
|
|
AddButtons(pCalling, abCalling, ARRAY_ELEMENTS(abCalling),
|
|
TRUE, NULL, this);
|
|
|
|
pCalling->Release();
|
|
}
|
|
}
|
|
|
|
pRosterAndCall->m_uRightIndex = 1;
|
|
pRosterAndCall->m_bHasCenterChild = TRUE;
|
|
|
|
pRosterAndCall->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
pView->Release();
|
|
}
|
|
|
|
BOOL CMainUI::Create(
|
|
HWND hwndParent,
|
|
CConfRoom *pConfRoom,
|
|
CreateViewMode eMode,
|
|
BOOL bEmbedded
|
|
)
|
|
{
|
|
// Store this away so we can call some methods in it later
|
|
m_pConfRoom = pConfRoom;
|
|
ASSERT(m_pConfRoom);
|
|
|
|
if (NULL == m_pConfRoom)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
// Create the window
|
|
if (!CToolbar::Create(hwndParent))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
// Try to remain a little bit abstract
|
|
CToolbar *pMain = this;
|
|
|
|
m_pConfRoom->AddConferenceChangeHandler(this);
|
|
|
|
// A vertical toolbar that fills all its area
|
|
pMain->m_hMargin = MainHMargin;
|
|
pMain->m_vMargin = MainVMargin;
|
|
pMain->m_gap = MainGap;
|
|
|
|
if (CreateRemoteNoPause == eMode
|
|
|| CreatePreviewNoPause == eMode
|
|
)
|
|
{
|
|
pMain->m_hMargin = 0;
|
|
pMain->m_vMargin = 0;
|
|
|
|
pMain->m_bHasCenterChild = TRUE;
|
|
|
|
//HACKHACK This only works because all these views have only 1 window
|
|
pMain->m_uRightIndex = 1;
|
|
}
|
|
|
|
pMain->m_bVertical = TRUE;
|
|
pMain->m_nAlignment = Fill;
|
|
|
|
m_hbBack = CGenWindow::GetStandardBrush();
|
|
|
|
// Create all the sub toolbars
|
|
if (CreateFull == eMode
|
|
|| CreateTelephone == eMode
|
|
)
|
|
{
|
|
CreateDialTB(pMain);
|
|
}
|
|
|
|
CreateVideoAndAppsTB(pMain, eMode, bEmbedded);
|
|
CreateRosterArea(pMain, eMode);
|
|
|
|
if (CreateFull == eMode
|
|
|| CreateDataOnly == eMode
|
|
)
|
|
{
|
|
CreateAppsTB(pMain);
|
|
}
|
|
|
|
// Now we need to update to the current state of the conference
|
|
if (m_pConfRoom->FIsConferenceActive())
|
|
{
|
|
OnCallStarted();
|
|
|
|
CSimpleArray<CParticipant*>& lMembers = m_pConfRoom->GetParticipantList();
|
|
for (int i=lMembers.GetSize()-1; i>=0; --i)
|
|
{
|
|
OnChangeParticipant(lMembers[i], NM_MEMBER_ADDED);
|
|
}
|
|
|
|
// Need to tell everybody what the active channels are
|
|
INmConference2 *pNmConf = m_pConfRoom->GetActiveConference();
|
|
if (NULL != pNmConf)
|
|
{
|
|
// Just in case
|
|
pNmConf->AddRef();
|
|
|
|
IEnumNmChannel *pEnumCh;
|
|
if (SUCCEEDED(pNmConf->EnumChannel(&pEnumCh)))
|
|
{
|
|
INmChannel *pChannel;
|
|
ULONG uGot;
|
|
while (S_OK == pEnumCh->Next(1, &pChannel, &uGot) && 1 == uGot)
|
|
{
|
|
OnVideoChannelChanged(NM_CHANNEL_ADDED, pChannel);
|
|
pChannel->Release();
|
|
}
|
|
|
|
pEnumCh->Release();
|
|
}
|
|
|
|
pNmConf->Release();
|
|
}
|
|
}
|
|
|
|
if (CreateDataOnly == eMode)
|
|
{
|
|
SetDataOnly(TRUE);
|
|
}
|
|
|
|
if (CreateTelephone == eMode)
|
|
{
|
|
SetDialing(TRUE);
|
|
SetAudioTuning(TRUE);
|
|
}
|
|
|
|
OnChangePermissions();
|
|
|
|
UpdateViewState();
|
|
|
|
UpdatePlayPauseState();
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
HBRUSH CMainUI::GetBackgroundBrush()
|
|
{
|
|
return(m_hbBack);
|
|
}
|
|
|
|
// REVIEW georgep: Should this loop until it gets an IGenWindow?
|
|
HPALETTE CMainUI::GetPalette()
|
|
{
|
|
return(m_pConfRoom->GetPalette());
|
|
}
|
|
|
|
// Recursive function to hide/show windows for the current view
|
|
// Returns whether any of the children are visible
|
|
BOOL ShowWindows(
|
|
HWND hwndParent, // The parent window to start from
|
|
LPARAM lDefMode, // The hide mode to use if Inherit
|
|
LPARAM hideMode // The current hide mode
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
for (HWND hwndChild=::GetWindow(hwndParent, GW_CHILD); NULL!=hwndChild;
|
|
hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT))
|
|
{
|
|
IGenWindow *pChild = IGenWindow::FromHandle(hwndChild);
|
|
if (NULL == pChild)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LPARAM lMode = GetHideModes(pChild);
|
|
if (Ignore == lMode)
|
|
{
|
|
if ((GetWindowStyle(hwndChild)&WS_VISIBLE) != 0)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if (Inherit == lMode)
|
|
{
|
|
lMode = lDefMode;
|
|
}
|
|
|
|
// recurse to child windows first to avoid flicker
|
|
LPARAM lNoChildren = ShowWindows(hwndChild, lMode, hideMode) ? 0 : IfNoChildren;
|
|
|
|
// If any of the hide mode bits are set, then hide the window
|
|
// otherwise show it
|
|
BOOL bShow = ((lMode&(hideMode|lNoChildren)) == 0);
|
|
if (bShow)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
ShowWindow(hwndChild, bShow ? SW_SHOW : SW_HIDE);
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
BOOL CMainUI::CanPreview()
|
|
{
|
|
HWND hwndLocal = GetVideoWindow(TRUE);
|
|
|
|
return(NULL!=hwndLocal && GetLocalVideo()->IsXferAllowed());
|
|
}
|
|
|
|
void CMainUI::UpdateViewState()
|
|
{
|
|
// Put together all the modes we ARE in, and hide any windows that want
|
|
// to be hidden while in one of those modes
|
|
// The default mode
|
|
LPARAM hideModes;
|
|
|
|
if (IsCompact())
|
|
{
|
|
hideModes = Compact;
|
|
|
|
if (!IsShowAVTB())
|
|
{
|
|
hideModes |= NoAVTB;
|
|
}
|
|
}
|
|
else if (IsDataOnly())
|
|
{
|
|
hideModes = DataOnly;
|
|
}
|
|
else
|
|
{
|
|
hideModes = Normal;
|
|
}
|
|
|
|
if (IsDialing())
|
|
{
|
|
hideModes |= Dialing;
|
|
}
|
|
else
|
|
{
|
|
// hwndRemote will be NULL for PreviewOnly mode
|
|
HWND hwndRemote = GetVideoWindow(FALSE);
|
|
if (NULL == hwndRemote)
|
|
{
|
|
hideModes |= Previewing;
|
|
}
|
|
else
|
|
{
|
|
HWND hwndLocal = GetVideoWindow(TRUE);
|
|
|
|
BOOL bPreviewing = IsPreviewing();
|
|
|
|
HWND parent = NULL;
|
|
BOOL bZoomable;
|
|
LONG style = GetWindowLong(hwndLocal, GWL_EXSTYLE);
|
|
if (bPreviewing)
|
|
{
|
|
hideModes |= Previewing;
|
|
parent = GetParent(hwndRemote);
|
|
style |= WS_EX_CLIENTEDGE;
|
|
bZoomable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
hideModes |= (m_bPicInPic && CanPreview()) ? ReceivingWPiP : Receiving;
|
|
parent = hwndRemote;
|
|
style &= ~WS_EX_CLIENTEDGE;
|
|
bZoomable = FALSE;
|
|
}
|
|
|
|
if (GetParent(hwndLocal) != parent)
|
|
{
|
|
SetWindowLong(hwndLocal, GWL_EXSTYLE, style);
|
|
SetParent(hwndLocal, parent);
|
|
SetWindowPos(hwndLocal, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
|
|
|
|
CVideoWindow *pVideo = GetLocalVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->SetZoomable(bZoomable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Enable/disable the PiP window
|
|
IGenWindow *pPiP = FindControl(ID_TB_PICINPIC);
|
|
if (NULL != pPiP)
|
|
{
|
|
CComPtr<CGenWindow> spButton = com_cast<CGenWindow>(pPiP);
|
|
|
|
BOOL bEnable = !IsPreviewing() && CanPreview() && !IsDialing();
|
|
EnableWindow(spButton->GetWindow(), bEnable);
|
|
}
|
|
|
|
hideModes |= IsAudioTuning() && !IsDataOnly() ? AudioTuning : Roster;
|
|
|
|
HWND hwnd = GetWindow();
|
|
|
|
ShowWindows(hwnd, 0, hideModes);
|
|
|
|
// If the focus is on a child window which is now not visible, but we are,
|
|
// then change the focus to this window
|
|
if (!IsWindowVisible(GetFocus()) && IsWindowActive(hwnd) && IsWindowVisible(hwnd))
|
|
{
|
|
SetFocus(hwnd);
|
|
}
|
|
|
|
IGenWindow *pButton = FindControl(ID_TB_AUDIOTUNING);
|
|
CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
|
|
if (spButton)
|
|
{
|
|
BOOL bAudioTuning = IsAudioTuning() && !IsCompact();
|
|
spButton->SetCustomState(bAudioTuning ? Checked : Unchecked);
|
|
spButton->SetTooltip(RES2T(bAudioTuning ? IDS_TT_TB_SHOWROSTER : IDS_TT_TB_AUDIOTUNING));
|
|
}
|
|
|
|
OnDesiredSizeChanged();
|
|
}
|
|
|
|
void CMainUI::SetCompact(BOOL bCompact)
|
|
{
|
|
bCompact = bCompact != FALSE;
|
|
if (IsCompact() == bCompact)
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_eViewMode = bCompact ? ViewCompact : ViewNormal;
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
void CMainUI::SetDataOnly(BOOL bDataOnly)
|
|
{
|
|
bDataOnly = bDataOnly != FALSE;
|
|
if (IsDataOnly() == bDataOnly)
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_eViewMode = bDataOnly ? ViewDataOnly : ViewNormal;
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
void CMainUI::SetDialing(BOOL bDialing)
|
|
{
|
|
bDialing = bDialing != FALSE;
|
|
if (IsDialing() == bDialing)
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_bDialing = bDialing;
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
void CMainUI::SetPicInPic(BOOL bPicInPic)
|
|
{
|
|
bPicInPic = bPicInPic != FALSE;
|
|
if (IsPicInPic() == bPicInPic)
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_bPicInPic = bPicInPic;
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
BOOL CMainUI::IsPicInPicAllowed()
|
|
{
|
|
return(!IsDataOnly() && !m_bPreviewing && CanPreview());
|
|
}
|
|
|
|
void CMainUI::SetAudioTuning(BOOL bAudioTuning)
|
|
{
|
|
if ((IsAudioTuning() && bAudioTuning) || (!IsAudioTuning() && !bAudioTuning))
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_bAudioTuning = bAudioTuning;
|
|
|
|
if (IsAudioTuning())
|
|
{
|
|
SetTimer(GetWindow(), IDT_AUDIO, AUDIODLG_MIC_TIMER_PERIOD, NULL);
|
|
}
|
|
else
|
|
{
|
|
KillTimer(GetWindow(), IDT_AUDIO);
|
|
}
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
void CMainUI::SetShowAVTB(BOOL bShowAVTB)
|
|
{
|
|
if ((IsShowAVTB() && bShowAVTB) || (!IsShowAVTB() && !bShowAVTB))
|
|
{
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
m_bShowAVTB = bShowAVTB;
|
|
|
|
UpdateViewState();
|
|
}
|
|
|
|
LRESULT CMainUI::ProcessMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static const UINT c_uMsgMSWheel = ::IsWindowsNT() ? WM_MOUSEWHEEL :
|
|
::RegisterWindowMessage(_TEXT("MSWHEEL_ROLLMSG"));
|
|
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(hwnd, WM_TIMER , OnTimer);
|
|
HANDLE_MSG(hwnd, WM_DESTROY , OnDestroy);
|
|
|
|
case WM_CREATE:
|
|
{
|
|
// Allow dialog-like keyboard support
|
|
HACCEL hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDR_MAINUI));
|
|
if (NULL != hAccel)
|
|
{
|
|
m_pAccel = new CTranslateAccelTable(hwnd, hAccel);
|
|
if (NULL != m_pAccel)
|
|
{
|
|
AddTranslateAccelerator(m_pAccel);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_SETFOCUS:
|
|
ShiftFocus(GetWindow(), TRUE);
|
|
break;
|
|
|
|
default:
|
|
if (message == c_uMsgMSWheel)
|
|
{
|
|
CRoomListView *pView = GetRoster();
|
|
if (NULL != pView)
|
|
{
|
|
::SendMessage(pView->GetHwnd(), message, wParam, lParam);
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return(CToolbar::ProcessMessage(hwnd, message, wParam, lParam));
|
|
}
|
|
|
|
void CMainUI::OnScroll(CProgressTrackbar *pTrackbar, UINT code, int pos)
|
|
{
|
|
BOOL bSpeaker = FALSE;
|
|
|
|
if (m_pAudioSpeaker == pTrackbar)
|
|
{
|
|
bSpeaker = TRUE;
|
|
}
|
|
else if (m_pAudioMic == pTrackbar)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
// I don't think we should get here
|
|
return;
|
|
}
|
|
|
|
// Can't trust the pos passed in
|
|
pos = pTrackbar->GetTrackValue();
|
|
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL == pAudioControl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DWORD dwVolume = (pos*AudioVolMax + AudioMax/2)/AudioMax;
|
|
dwVolume = min(max(dwVolume, 0), AudioVolMax);
|
|
|
|
if (bSpeaker)
|
|
{
|
|
pAudioControl->SetSpeakerVolume(dwVolume);
|
|
}
|
|
else
|
|
{
|
|
pAudioControl->SetRecorderVolume(dwVolume);
|
|
}
|
|
}
|
|
|
|
HWND CMainUI::GetVideoWindow(BOOL bLocal)
|
|
{
|
|
CVideoWindow *pVideo = bLocal ? GetLocalVideo() : GetRemoteVideo();
|
|
return(NULL == pVideo ? NULL : pVideo->GetWindow());
|
|
}
|
|
|
|
void CMainUI::ToggleMute(BOOL bSpeaker)
|
|
{
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
|
|
pAudioControl->MuteAudio(bSpeaker, !bMuted);
|
|
}
|
|
}
|
|
|
|
void CMainUI::UpdateMuteState(BOOL bSpeaker, CButton *pButton)
|
|
{
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
|
|
|
|
pButton->SetChecked(!bMuted);
|
|
}
|
|
}
|
|
|
|
void CMainUI::BumpAudio(BOOL bSpeaker, int pct)
|
|
{
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
int dwVolume = static_cast<int>(bSpeaker ?
|
|
pAudioControl->GetSpeakerVolume() : pAudioControl->GetRecorderVolume());
|
|
dwVolume += (pct*AudioVolMax/100);
|
|
dwVolume = min(max(dwVolume, 0), AudioVolMax);
|
|
|
|
if (bSpeaker)
|
|
{
|
|
pAudioControl->SetSpeakerVolume(dwVolume);
|
|
}
|
|
else
|
|
{
|
|
pAudioControl->SetRecorderVolume(dwVolume);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainUI::SetAudioProperty(BOOL bSpeaker, NM_AUDPROP uID, ULONG uValue)
|
|
{
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
pAudioControl->SetProperty(bSpeaker, uID, uValue);
|
|
}
|
|
}
|
|
|
|
// IButtonChange
|
|
void CMainUI::OnClick(CButton *pButton)
|
|
{
|
|
HWND hwndCtl = pButton->GetWindow();
|
|
|
|
OnCommand(GetWindow(), GetWindowLong(hwndCtl, GWL_ID), hwndCtl, BN_CLICKED);
|
|
}
|
|
|
|
void CMainUI::OnInitMenu(HMENU hMenu)
|
|
{
|
|
CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->UpdateVideoMenu(hMenu);
|
|
|
|
pVideo = GetLocalVideo();
|
|
EnableMenuItem(hMenu, IDM_VIDEO_UNDOCK,
|
|
MF_BYCOMMAND|(NULL != pVideo && pVideo->IsXferAllowed() ? MF_ENABLED : MF_GRAYED|MF_DISABLED));
|
|
}
|
|
}
|
|
|
|
static void AppendText(CCallingBar *pCalling, TCHAR cAdd)
|
|
{
|
|
if (NULL != pCalling)
|
|
{
|
|
// I don't want to change a string that you can't see
|
|
if (IsWindowVisible(pCalling->GetWindow()))
|
|
{
|
|
TCHAR szText[] = TEXT("0");
|
|
szText[0] = cAdd;
|
|
|
|
TCHAR szTemp[MAX_PATH];
|
|
|
|
int nLen = pCalling->GetText(szTemp, ARRAY_ELEMENTS(szTemp));
|
|
if (nLen + lstrlen(szText) <= ARRAY_ELEMENTS(szTemp) - 1)
|
|
{
|
|
lstrcat(szTemp, szText);
|
|
pCalling->SetText(szTemp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static BOOL ShouldTry(HWND child)
|
|
{
|
|
// REVIEW georgep: I could look at WS_EX_CONTROLPARENT also
|
|
return((WS_VISIBLE) == (GetWindowStyle(child) & (WS_DISABLED|WS_VISIBLE)));
|
|
}
|
|
|
|
static BOOL IsTabbable(HWND child)
|
|
{
|
|
return((WS_TABSTOP|WS_VISIBLE) == (GetWindowStyle(child) & (WS_TABSTOP|WS_DISABLED|WS_VISIBLE)));
|
|
}
|
|
|
|
// BUGBUG georgep: I should move this into CGenWindow
|
|
// Determine the next control in the tab order
|
|
static HWND NextControl(HWND hwndTop, HWND hwndFocus)
|
|
{
|
|
// Loop detection stuff
|
|
BOOL bGotToTop = FALSE;
|
|
|
|
// We'll loop to avoid really deep recursion
|
|
while (TRUE)
|
|
{
|
|
// First try the children of hwndFocus
|
|
if (hwndFocus == hwndTop || ShouldTry(hwndFocus))
|
|
{
|
|
HWND next = GetFirstChild(hwndFocus);
|
|
if (NULL != next)
|
|
{
|
|
if (IsTabbable(next))
|
|
{
|
|
return(next);
|
|
}
|
|
|
|
hwndFocus = next;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (hwndFocus == hwndTop)
|
|
{
|
|
// Apparently hwndTop has no children
|
|
return(NULL);
|
|
}
|
|
|
|
HWND next;
|
|
while (NULL == (next = GetNextSibling(hwndFocus)))
|
|
{
|
|
hwndFocus = GetParent(hwndFocus);
|
|
if (NULL == hwndFocus)
|
|
{
|
|
// Invalid params
|
|
return(NULL);
|
|
}
|
|
|
|
if (hwndTop == hwndFocus)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hwndTop == hwndFocus)
|
|
{
|
|
// Detect if we have looped back to the top again
|
|
if (bGotToTop)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
bGotToTop = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (IsTabbable(next))
|
|
{
|
|
return(next);
|
|
}
|
|
|
|
hwndFocus = next;
|
|
}
|
|
|
|
// We looped back to the beginning, so I guess nobody can take the focus
|
|
return(NULL);
|
|
}
|
|
|
|
// Determine the previous control in the tab order
|
|
static HWND PrevControl(HWND hwndTop, HWND hwndFocus)
|
|
{
|
|
// LAZYLAZY georgep: It's hard to do this directly, so I'll just loop
|
|
// on the NextControl. It should be fast enough.
|
|
|
|
// In case hwndFocus is not focusable for some reason, we still need to
|
|
// detect the loop
|
|
HWND hwndStart = NextControl(hwndTop, hwndFocus);
|
|
|
|
// HACK for combo boxes: go from the edit control to the combo box control
|
|
while (NULL != hwndFocus
|
|
&& hwndTop != hwndFocus
|
|
&& !IsTabbable(hwndFocus)
|
|
)
|
|
{
|
|
hwndFocus = GetParent(hwndFocus);
|
|
}
|
|
|
|
HWND ret = hwndStart;
|
|
while (TRUE)
|
|
{
|
|
HWND next = NextControl(hwndTop, ret);
|
|
if (NULL == next)
|
|
{
|
|
// Oops!
|
|
return(NULL);
|
|
}
|
|
|
|
if (hwndFocus == next
|
|
|| hwndStart == next
|
|
)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ret = next;
|
|
}
|
|
|
|
return(ret);
|
|
}
|
|
|
|
static void ShiftFocus(HWND hwndTop, BOOL bForward)
|
|
{
|
|
HWND hwndFocus = GetFocus();
|
|
|
|
if (!IsWindowActive(hwndTop))
|
|
{
|
|
hwndFocus = hwndTop;
|
|
}
|
|
|
|
HWND next = bForward ? NextControl(hwndTop, hwndFocus) : PrevControl(hwndTop, hwndFocus);
|
|
if (NULL != next)
|
|
{
|
|
SetFocus(next);
|
|
}
|
|
else
|
|
{
|
|
MessageBeep(MB_ICONHAND);
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
|
|
{
|
|
switch (id)
|
|
{
|
|
case ID_NAV_TAB:
|
|
ShiftFocus(hwnd, TRUE);
|
|
break;
|
|
|
|
case ID_NAV_SHIFT_TAB:
|
|
ShiftFocus(hwnd, FALSE);
|
|
break;
|
|
|
|
case IDM_VIEW_DIALPAD:
|
|
SetDialing(!IsDialing());
|
|
break;
|
|
|
|
case ID_TB_PICINPIC:
|
|
SetPicInPic(!IsPicInPic());
|
|
break;
|
|
|
|
case ID_TB_REJECT:
|
|
case ID_TB_CREDENTIALS:
|
|
break;
|
|
|
|
case ID_TB_AUDIOTUNING:
|
|
{
|
|
m_bStateChanged = TRUE;
|
|
|
|
SetAudioTuning(!IsAudioTuning());
|
|
break;
|
|
}
|
|
|
|
case ID_TB_SHOWAVTB:
|
|
{
|
|
m_bStateChanged = TRUE;
|
|
|
|
SetShowAVTB(!IsShowAVTB());
|
|
CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(IGenWindow::FromHandle(hwndCtl));
|
|
if (spButton)
|
|
{
|
|
BOOL bShow = IsShowAVTB();
|
|
|
|
spButton->SetCustomState(bShow ? Checked : Unchecked);
|
|
spButton->SetTooltip(RES2T(bShow ? IDS_TT_TB_HIDEAVTB : IDS_TT_TB_SHOWAVTB));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ID_TB_TUNEMIC_UNMUTE:
|
|
ToggleMute(FALSE);
|
|
break;
|
|
|
|
case ID_TB_TUNESPEAKER_UNMUTE:
|
|
ToggleMute(TRUE);
|
|
break;
|
|
|
|
case ID_TB_DIAL0:
|
|
case ID_TB_DIAL1:
|
|
case ID_TB_DIAL2:
|
|
case ID_TB_DIAL3:
|
|
case ID_TB_DIAL4:
|
|
case ID_TB_DIAL5:
|
|
case ID_TB_DIAL6:
|
|
case ID_TB_DIAL7:
|
|
case ID_TB_DIAL8:
|
|
case ID_TB_DIAL9:
|
|
SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, id-ID_TB_DIAL0);
|
|
AppendText(m_pCalling, '0'+id-ID_TB_DIAL0);
|
|
break;
|
|
|
|
case ID_TB_DIALSTAR:
|
|
SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 10);
|
|
AppendText(m_pCalling, '*');
|
|
break;
|
|
|
|
case ID_TB_DIALPOUND:
|
|
SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 11);
|
|
AppendText(m_pCalling, '#');
|
|
break;
|
|
|
|
case ID_TB_DIRECTORY:
|
|
{
|
|
CFindSomeone::findSomeone(m_pConfRoom);
|
|
}
|
|
break;
|
|
|
|
case ID_TB_PLAYPAUSE:
|
|
TogglePlayPause();
|
|
break;
|
|
|
|
case IDM_VIDEO_ZOOM1:
|
|
case IDM_VIDEO_ZOOM2:
|
|
case IDM_VIDEO_ZOOM3:
|
|
case IDM_VIDEO_ZOOM4:
|
|
case IDM_VIDEO_UNDOCK:
|
|
case IDM_VIDEO_GETACAMERA:
|
|
{
|
|
CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->OnCommand(id);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDM_POPUP_EJECT:
|
|
case IDM_POPUP_PROPERTIES:
|
|
case IDM_POPUP_SPEEDDIAL:
|
|
case IDM_POPUP_ADDRESSBOOK:
|
|
case IDM_POPUP_GIVECONTROL:
|
|
case IDM_POPUP_CANCELGIVECONTROL:
|
|
{
|
|
CRoomListView *pView = GetRoster();
|
|
if (NULL != pView)
|
|
{
|
|
CParticipant * pPart = pView->GetParticipant();
|
|
if (NULL != pPart)
|
|
{
|
|
pPart->OnCommand(hwnd, (WORD)id);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ID_FILE_CREATE_SPEED_DIAL:
|
|
{
|
|
TCHAR szAddress[MAX_EMAIL_NAME_LENGTH + MAX_SERVER_NAME_LENGTH + 1];
|
|
LPCTSTR pszAddress = NULL;
|
|
CRoomListView *pView = GetRoster();
|
|
if (NULL != pView)
|
|
{
|
|
CParticipant * pPart = pView->GetParticipant();
|
|
if (NULL != pPart)
|
|
{
|
|
if (S_OK == pPart->GetUlsAddr(szAddress, CCHMAX(szAddress)))
|
|
{
|
|
pszAddress = szAddress;
|
|
}
|
|
}
|
|
}
|
|
|
|
CSpeedDialDlg sdd(hwnd, NM_ADDR_ULS);
|
|
sdd.DoModal(pszAddress);
|
|
break;
|
|
}
|
|
|
|
case ID_TB_CHAT:
|
|
case ID_TB_NEWWHITEBOARD:
|
|
case ID_TB_SHARING:
|
|
case ID_TB_NEW_CALL:
|
|
default:
|
|
m_pConfRoom->OnCommand(hwnd, id, hwndCtl, codeNotify);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnDestroy(HWND hwnd)
|
|
{
|
|
if (NULL != m_pConfRoom)
|
|
{
|
|
m_pConfRoom->RemoveConferenceChangeHandler(this);
|
|
}
|
|
|
|
if (NULL != m_pAccel)
|
|
{
|
|
RemoveTranslateAccelerator(m_pAccel);
|
|
m_pAccel->Release();
|
|
m_pAccel = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL CMainUI::OnQueryEndSession()
|
|
{
|
|
CMainUI::OnClose();
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
void CMainUI::OnClose()
|
|
{
|
|
CVideoWindow *pLocal = GetLocalVideo();
|
|
if (NULL != pLocal)
|
|
{
|
|
pLocal->Pause(TRUE);
|
|
}
|
|
}
|
|
|
|
VOID CMainUI::SaveSettings()
|
|
{
|
|
CVideoWindow *pVideo;
|
|
pVideo = GetLocalVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->SaveSettings();
|
|
}
|
|
pVideo = GetRemoteVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->SaveSettings();
|
|
}
|
|
}
|
|
|
|
VOID CMainUI::ForwardSysChangeMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CVideoWindow *pVideo;
|
|
pVideo = GetLocalVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
|
|
}
|
|
pVideo = GetRemoteVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
|
|
}
|
|
|
|
CRoomListView *pView = GetRoster();
|
|
if (NULL != pView)
|
|
{
|
|
pView->ForwardSysChangeMsg(uMsg, wParam, lParam);
|
|
}
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_PALETTECHANGED:
|
|
::RedrawWindow(GetWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnTimer(HWND hwnd, UINT id)
|
|
{
|
|
if (IDT_AUDIO == id)
|
|
{
|
|
CAudioControl *pAudioControl = GetAudioControl();
|
|
if (NULL != pAudioControl)
|
|
{
|
|
DWORD dwLevel;
|
|
|
|
dwLevel = pAudioControl->GetAudioSignalLevel(FALSE /*fSpeaker*/); // This level ranges from 0-100
|
|
m_pAudioMic->SetProgressValue(dwLevel);
|
|
|
|
dwLevel = pAudioControl->GetAudioSignalLevel(TRUE /*fSpeaker*/); // This level ranges from 0-100
|
|
m_pAudioSpeaker->SetProgressValue(dwLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get the associated audion control object
|
|
CAudioControl *CMainUI::GetAudioControl()
|
|
{
|
|
return(m_pConfRoom->GetAudioControl());
|
|
}
|
|
|
|
static void EnableControl(IGenWindow *pControl, BOOL bEnable)
|
|
{
|
|
if (NULL == pControl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CComPtr<CGenWindow> spControl = com_cast<CGenWindow>(pControl);
|
|
if (spControl)
|
|
{
|
|
HWND hwnd = spControl->GetWindow();
|
|
if (NULL != hwnd)
|
|
{
|
|
EnableWindow(hwnd, bEnable);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnChangePermissions()
|
|
{
|
|
EnableControl(FindControl(ID_TB_NEW_CALL ), m_pConfRoom->IsNewCallAllowed());
|
|
EnableControl(FindControl(ID_TB_SHARING ), m_pConfRoom->IsSharingAllowed());
|
|
EnableControl(FindControl(ID_TB_CHAT ), m_pConfRoom->IsChatAllowed());
|
|
EnableControl(FindControl(ID_TB_NEWWHITEBOARD), m_pConfRoom->IsNewWhiteboardAllowed());
|
|
EnableControl(FindControl(ID_TB_FILETRANSFER ), m_pConfRoom->IsFileTransferAllowed());
|
|
}
|
|
|
|
void CMainUI::OnCallStarted()
|
|
{
|
|
m_bPreviewing = FALSE;
|
|
UpdateViewState();
|
|
UpdatePlayPauseState();
|
|
}
|
|
|
|
void CMainUI::OnCallEnded()
|
|
{
|
|
m_bPreviewing = TRUE;
|
|
UpdateViewState();
|
|
UpdatePlayPauseState();
|
|
}
|
|
|
|
void CMainUI::OnAudioLevelChange(BOOL fSpeaker, DWORD dwVolume)
|
|
{
|
|
CProgressTrackbar *pBar = fSpeaker ? m_pAudioSpeaker : m_pAudioMic;
|
|
if (NULL != pBar)
|
|
{
|
|
pBar->SetTrackValue((dwVolume*AudioMax + AudioVolMax/2) / AudioVolMax);
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnAudioMuteChange(BOOL fSpeaker, BOOL fMute)
|
|
{
|
|
IGenWindow *pButton = FindControl(fSpeaker ? ID_TB_TUNESPEAKER_UNMUTE : ID_TB_TUNEMIC_UNMUTE);
|
|
if (NULL != pButton)
|
|
{
|
|
CComPtr<CButton> spButton = com_cast<CButton>(pButton);
|
|
if (spButton)
|
|
{
|
|
UpdateMuteState(fSpeaker, spButton);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CMainUI::GetPlayPauseState()
|
|
{
|
|
BOOL bMuted = TRUE;
|
|
|
|
// We're just going to show the state for the "big" window
|
|
if (IsPreviewing())
|
|
{
|
|
if (NULL != m_pLocalVideo)
|
|
{
|
|
bMuted = bMuted && m_pLocalVideo->IsPaused();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (NULL != m_pRemoteVideo)
|
|
{
|
|
bMuted = bMuted && m_pRemoteVideo->IsPaused();
|
|
}
|
|
}
|
|
|
|
return(bMuted);
|
|
}
|
|
|
|
void CMainUI::UpdatePlayPauseState()
|
|
{
|
|
BOOL bMuted = GetPlayPauseState();
|
|
|
|
IGenWindow *pButton = FindControl(ID_TB_PLAYPAUSE);
|
|
if (NULL != pButton)
|
|
{
|
|
CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
|
|
if (spButton)
|
|
{
|
|
spButton->SetCustomState(bMuted ? 0 : 1);
|
|
spButton->SetTooltip(RES2T(bMuted ? IDS_TT_TB_PLAYPAUSE : IDS_TT_TB_PAUSE));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainUI::TogglePlayPause()
|
|
{
|
|
// We're going to apply the current state to both videos
|
|
BOOL bMute = !GetPlayPauseState();
|
|
|
|
if (NULL != m_pRemoteVideo)
|
|
{
|
|
m_pRemoteVideo->Pause(bMute);
|
|
}
|
|
if (NULL != m_pLocalVideo)
|
|
{
|
|
m_pLocalVideo->Pause(bMute);
|
|
}
|
|
|
|
UpdatePlayPauseState();
|
|
}
|
|
|
|
void CMainUI::OnChangeParticipant(CParticipant *pPart, NM_MEMBER_NOTIFY uNotify)
|
|
{
|
|
CRoomListView *pView = GetRoster();
|
|
|
|
if (NULL != pView)
|
|
{
|
|
pView->OnChangeParticipant(pPart, uNotify);
|
|
}
|
|
}
|
|
|
|
void CMainUI::OnVideoChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
|
|
{
|
|
// BUGBUG georgep: This really should only go to one or the other,
|
|
// depending on if it is incoming, but I'm sending to both
|
|
CVideoWindow *pVideo;
|
|
pVideo = GetRemoteVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->OnChannelChanged(uNotify, pChannel);
|
|
}
|
|
pVideo = GetLocalVideo();
|
|
if (NULL != pVideo)
|
|
{
|
|
pVideo->OnChannelChanged(uNotify, pChannel);
|
|
}
|
|
}
|
|
|
|
void CMainUI::StateChange(CVideoWindow *pVideo, NM_VIDEO_STATE uState)
|
|
{
|
|
UpdatePlayPauseState();
|
|
}
|
|
|
|
CFrame *CMainUI::s_pVideoFrame = NULL;
|
|
|
|
class CVideoFrame : public CFrame
|
|
{
|
|
protected:
|
|
virtual LRESULT ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_DESTROY:
|
|
{
|
|
RECT rc;
|
|
::GetWindowRect(hwnd, &rc);
|
|
|
|
RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
|
|
|
|
reVideo.SetValue(REGVAL_VIDEO_XPOS, rc.left);
|
|
reVideo.SetValue(REGVAL_VIDEO_YPOS, rc.top);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(CFrame::ProcessMessage(hwnd, uMsg, wParam, lParam));
|
|
}
|
|
} ;
|
|
|
|
BOOL CMainUI::NewVideoWindow(CConfRoom *pConfRoom)
|
|
{
|
|
if (NULL == s_pVideoFrame)
|
|
{
|
|
s_pVideoFrame = new CVideoFrame();
|
|
if (NULL == s_pVideoFrame)
|
|
{
|
|
// Could not initialize
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
HWND hwnd = s_pVideoFrame->GetWindow();
|
|
if (NULL != hwnd)
|
|
{
|
|
return(s_pVideoFrame->SetForeground());
|
|
}
|
|
|
|
TCHAR szTitle[256];
|
|
LoadString(::GetInstanceHandle(), IDS_MYVIDEO, szTitle, ARRAY_ELEMENTS(szTitle));
|
|
HICON hiBig = LoadIcon(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_CONFROOM));
|
|
|
|
if (!s_pVideoFrame->Create(
|
|
NULL, // Window owner
|
|
szTitle, // Window name
|
|
(WS_OVERLAPPEDWINDOW&~(WS_THICKFRAME|WS_MAXIMIZEBOX)), // Window style
|
|
0, // Extended window style
|
|
0, // Window pos: x
|
|
0, // Window pos: y
|
|
500, // Window size: width
|
|
500, // Window size: height
|
|
_Module.GetModuleInstance(), // The hInstance to create the window on
|
|
hiBig, // The icon for the window
|
|
NULL // Window menu
|
|
))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
CMainUI *pMainUI = new CMainUI();
|
|
if (NULL != pMainUI)
|
|
{
|
|
if (pMainUI->Create(s_pVideoFrame->GetWindow(), pConfRoom, CreatePreviewOnly))
|
|
{
|
|
// Make sure it is the right size before showing the window
|
|
s_pVideoFrame->Resize();
|
|
|
|
RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
|
|
int x = reVideo.GetNumber(
|
|
REGVAL_VIDEO_XPOS, 0x7fff );
|
|
int y = reVideo.GetNumber(
|
|
REGVAL_VIDEO_YPOS, 0x7fff );
|
|
|
|
s_pVideoFrame->MoveEnsureVisible(x, y);
|
|
|
|
bRet = s_pVideoFrame->SetForeground();
|
|
}
|
|
pMainUI->Release();
|
|
}
|
|
|
|
if (!bRet)
|
|
{
|
|
DestroyWindow(s_pVideoFrame->GetWindow());
|
|
}
|
|
return(bRet);
|
|
}
|
|
|
|
void CMainUI::CleanUpVideoWindow()
|
|
{
|
|
if (NULL != s_pVideoFrame)
|
|
{
|
|
HWND hwnd = s_pVideoFrame->GetWindow();
|
|
if (NULL != hwnd)
|
|
{
|
|
DestroyWindow(hwnd);
|
|
}
|
|
|
|
s_pVideoFrame->Release();
|
|
s_pVideoFrame = NULL;
|
|
}
|
|
}
|
|
|
|
CRoomListView *CMainUI::GetRoster() const
|
|
{
|
|
return(NULL == m_pRoster ? NULL : m_pRoster->GetRoster());
|
|
}
|