// File: dlgcall.cpp // // Outgoing call progress dialog #include "precomp.h" #include "resource.h" #include "call.h" #include "dlgcall.h" #include "conf.h" #include "ConfUtil.h" static int g_cDlgCall = 0; // number of outgoing call dialogs static int g_dypOffset = 0; /* C D L G C A L L */ /*------------------------------------------------------------------------- %%Function: CDlgCall -------------------------------------------------------------------------*/ CDlgCall::CDlgCall(CCall * pCall): RefCount(NULL), m_pCall(pCall), m_hwnd(NULL) { ASSERT(NULL != m_pCall); m_pCall->AddRef(); // Released in destructor AddRef(); // Destroyed when call goes to a completed state if(!_Module.InitControlMode()) { CreateCallDlg(); g_cDlgCall++; } } CDlgCall::~CDlgCall(void) { m_pCall->Release(); g_cDlgCall--; if (0 == g_cDlgCall) { g_dypOffset = 0; // center new dialogs } } STDMETHODIMP_(ULONG) CDlgCall::AddRef(void) { return RefCount::AddRef(); } STDMETHODIMP_(ULONG) CDlgCall::Release(void) { return RefCount::Release(); } /* C R E A T E C A L L D L G */ /*------------------------------------------------------------------------- %%Function: CreateCallDlg Create the outgoing call progress dialog -------------------------------------------------------------------------*/ VOID CDlgCall::CreateCallDlg() { ASSERT(NULL == m_hwnd); ASSERT(NULL != m_pCall); LPCTSTR pcszName = m_pCall->GetPszName(); if (NULL == pcszName) return; // determine the maximum width of the string TCHAR szMsg[MAX_PATH*2]; FLoadString1(IDS_STATUS_WAITING, szMsg, (PVOID) pcszName); m_nTextWidth = DxpSz(szMsg); FLoadString1(IDS_STATUS_FINDING, szMsg, (PVOID) pcszName); int dxp = DxpSz(szMsg); if (m_nTextWidth < dxp) { m_nTextWidth = dxp; } m_hwnd = ::CreateDialogParam(::GetInstanceHandle(), MAKEINTRESOURCE(IDD_CALL_PROGRESS), ::GetMainWindow(), CDlgCall::DlgProc, (LPARAM) this); if (NULL == m_hwnd) return; ::SetDlgItemText(m_hwnd, IDC_MSG_STATIC, szMsg); RECT rc; ::GetWindowRect(m_hwnd, &rc); // Stretch the width to fit the person's name, int nWidth = RectWidth(rc) + m_nTextWidth; int nHeight = RectHeight(rc); MoveWindow(m_hwnd, 0, 0, nWidth, nHeight, FALSE); // Center it CenterWindow(m_hwnd, HWND_DESKTOP); ::GetWindowRect(m_hwnd, &rc); // Move it down OffsetRect(&rc, 0, g_dypOffset); // Show, move, make topmost HWND hwndInsertAfter = HWND_TOPMOST; #ifdef DEBUG { // Hack to allow call placement to be debugged RegEntry reDebug(DEBUG_KEY, HKEY_LOCAL_MACHINE); if (0 == reDebug.GetNumber(REGVAL_DBG_CALLTOP, DEFAULT_DBG_CALLTOP)) { hwndInsertAfter = HWND_NOTOPMOST; } } #endif ::SetWindowPos(m_hwnd, hwndInsertAfter, rc.left, rc.top, nWidth, nHeight, SWP_SHOWWINDOW | SWP_DRAWFRAME); // Adjust for next time g_dypOffset += nHeight; // Check for wrap-around RECT rcDeskTop; GetWindowRect(GetDesktopWindow(), &rcDeskTop); if ((rc.bottom + nHeight) > rcDeskTop.bottom) { g_dypOffset -= rc.top; } } /* O N I N I T D I A L O G */ /*------------------------------------------------------------------------- %%Function: OnInitDialog -------------------------------------------------------------------------*/ VOID CDlgCall::OnInitDialog(HWND hdlg) { HWND hwnd; RECT rc; ::SetWindowLongPtr(hdlg, DWLP_USER, (LONG_PTR) this); AddModelessDlg(hdlg); // Move the Cancel button hwnd = ::GetDlgItem(hdlg, IDCANCEL); if ((NULL != hwnd) && ::GetWindowRect(hwnd, &rc)) { // Turn rc top and left into client coords: ::MapWindowPoints(NULL, hdlg, (LPPOINT) &rc, 1); ::SetWindowPos(hwnd, NULL, rc.left + m_nTextWidth, rc.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW); } // Stretch the text field: hwnd = ::GetDlgItem(hdlg, IDC_MSG_STATIC); if ((NULL != hwnd) && ::GetWindowRect(hwnd, &rc)) { ::SetWindowPos(hwnd, NULL, 0, 0, m_nTextWidth, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW); // and set the font ::SendMessage(hwnd, WM_SETFONT, (WPARAM) g_hfontDlg, 0); } // Start the animation hwnd = GetDlgItem(hdlg, IDC_CALL_ANIMATION); Animate_Open(hwnd, MAKEINTRESOURCE(IDA_CALL_ANIMATION)); Animate_Play(hwnd, 0, -1, -1); } // Change the state of the call VOID CDlgCall::OnStateChange(void) { if (NULL == m_hwnd) return; // Assume the only state change is to "Waiting" TCHAR szMsg[MAX_PATH*2]; FLoadString1(IDS_STATUS_WAITING, szMsg, (PVOID) m_pCall->GetPszName()); SetWindowText(GetDlgItem(m_hwnd, IDC_MSG_STATIC), szMsg); } // Destroy the window // Can be called by OnCancel or the owner VOID CDlgCall::Destroy(void) { if (NULL != m_hwnd) { ASSERT(IsWindow(m_hwnd)); DestroyWindow(m_hwnd); m_hwnd = NULL; } } // Cancel/Close the dialog VOID CDlgCall::OnCancel(void) { ASSERT(NULL != m_pCall); m_pCall->Cancel(FALSE); return; } // Handle the destruction of the dialog VOID CDlgCall::OnDestroy(void) { SetWindowLongPtr(m_hwnd, DWLP_USER, 0L); HWND hwnd = GetDlgItem(m_hwnd, IDC_CALL_ANIMATION); if (NULL != hwnd) { Animate_Stop(hwnd); Animate_Close(hwnd); } ::RemoveModelessDlg(m_hwnd); Release(); // This normally destroys the object } /* D L G P R O C */ /*------------------------------------------------------------------------- %%Function: DlgProc -------------------------------------------------------------------------*/ INT_PTR CALLBACK CDlgCall::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { CDlgCall * ppm = (CDlgCall*) lParam; ASSERT(NULL != ppm); ppm->AddRef(); ppm->OnInitDialog(hDlg); return TRUE; } case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: { CDlgCall * pDlg = (CDlgCall*) GetWindowLongPtr(hDlg, DWLP_USER); if (NULL != pDlg) { // OnCancel will cause this window to be destoyed // AddRef this object so that it does not go away. pDlg->AddRef(); pDlg->OnCancel(); pDlg->Release(); } break; } default: break; } return TRUE; } case WM_DESTROY: { CDlgCall * pDlg = (CDlgCall*) GetWindowLongPtr(hDlg, DWLP_USER); if (NULL != pDlg) { pDlg->OnDestroy(); pDlg->Release(); } break; } default: break; } return FALSE; }