/*++ Microsoft Windows Copyright (C) Microsoft Corporation, 1981 - 1999 Module Name: irrecvprogress.cpp Abstract: Author: Rahul Thombre (RahulTh) 4/30/1998 Revision History: 4/30/1998 RahulTh Created this module. --*/ // IrRecvProgress.cpp : implementation file // #include "precomp.hxx" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CIrRecvProgress dialog CIrRecvProgress::CIrRecvProgress(wchar_t * MachineName, boolean bSuppressRecvConf, CWnd* pParent /*=NULL*/) : m_szMachineName (MachineName), m_fFirstXfer (TRUE), m_bDlgDestroyed (TRUE) { DWORD dwPrompt; m_ptl = NULL; m_dwMagicID = RECV_MAGIC_ID; m_bRecvFromCamera = FALSE; if (bSuppressRecvConf) { m_fDontPrompt = TRUE; m_bRecvFromCamera = TRUE; if (m_szMachineName.IsEmpty()) { m_szMachineName.LoadString (IDS_CAMERA); } } else { dwPrompt = GetIRRegVal (TEXT("RecvConf"), 1); m_fDontPrompt = dwPrompt ? FALSE : TRUE; if (m_szMachineName.IsEmpty()) { m_szMachineName.LoadString (IDS_UNKNOWN_DEVICE); } } // // No permitted directory yet. // m_LastPermittedDirectory[0] = 0; appController->PostMessage (WM_APP_KILL_TIMER); InterlockedIncrement (&g_lUIComponentCount); Create(IDD,appController); //{{AFX_DATA_INIT(CIrRecvProgress) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } void CIrRecvProgress::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CIrRecvProgress) DDX_Control(pDX, IDC_RECV_XFERANIM, m_xferAnim); DDX_Control(pDX, IDC_SAVEDICON, m_icon); DDX_Control(pDX, IDC_DONETEXT, m_DoneText); DDX_Control(pDX, IDC_RECV_CONNECTIONTEXT, m_machDesc); DDX_Control(pDX, IDC_RECVDESCRIPTION, m_recvDesc); DDX_Control(pDX, IDC_XFER_DESC, m_xferDesc); DDX_Control(pDX, IDC_MACHNAME, m_Machine); DDX_Control(pDX, IDC_FILENAME, m_File); DDX_Control(pDX, IDC_CLOSEONCOMPLETE, m_btnCloseOnComplete); DDX_Control(pDX, IDC_ABORT, m_btnCancel); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CIrRecvProgress, CDialog) //{{AFX_MSG_MAP(CIrRecvProgress) ON_BN_CLICKED (IDC_ABORT, OnCancel) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CIrRecvProgress message handlers void CIrRecvProgress::OnCancel() { m_xferAnim.Stop(); m_xferAnim.Close(); _CancelReceive( NULL, (COOKIE) this ); DestroyWindow(); } void CIrRecvProgress::PostNcDestroy() { BOOL fNoUIComponents = (0 == InterlockedDecrement (&g_lUIComponentCount)); if (fNoUIComponents && !g_deviceList.GetDeviceCount()) { //there are no UI components displayed and there are no devices in //range. Start the timer. If the timer expires, the app. will quit. appController->PostMessage (WM_APP_START_TIMER); } delete this; } void CIrRecvProgress::ShowProgressControls (int nCmdShow) { m_xferAnim.ShowWindow (nCmdShow); m_xferDesc.ShowWindow (nCmdShow); m_machDesc.ShowWindow (nCmdShow); m_Machine.ShowWindow (nCmdShow); m_recvDesc.ShowWindow (nCmdShow); m_File.ShowWindow (nCmdShow); m_btnCloseOnComplete.ShowWindow (nCmdShow); } void CIrRecvProgress::ShowSummaryControls (int nCmdShow) { m_icon.ShowWindow (nCmdShow); m_DoneText.ShowWindow (nCmdShow); } void CIrRecvProgress::DestroyAndCleanup( DWORD status ) { //AFX_MANAGE_STATE (AfxGetStaticModuleState()); CString szFormat; CString szDisplay; m_xferAnim.Stop(); m_xferAnim.Close(); //destroy the window right away if the "Close on complete" check-box is //checked. if (m_btnCloseOnComplete.GetCheck()) { DestroyWindow(); return; } //if we are here, the user wanted the window to stay even after the //receive was completed. So hide the progress controls and show the //summary controls. ShowProgressControls (SW_HIDE); ShowSummaryControls (SW_SHOW); if (0 == status) { szFormat = g_Strings.CompletedSuccess; szDisplay.Format (szFormat, m_szMachineName); m_DoneText.SetWindowText(szDisplay); } else if (ERROR_CANCELLED == status) { m_DoneText.SetWindowText (g_Strings.RecvCancelled); } else { LPVOID lpMessageBuffer; TCHAR ErrDesc [ERROR_DESCRIPTION_LENGTH]; CString ErrorDescription; CString Message; if (!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, // ignored status, 0, // try default language ids (LPTSTR) &lpMessageBuffer, 0, NULL // ignored )) { StringCbPrintf(ErrDesc, sizeof(ErrDesc),g_Strings.ErrorNoDescription, status); //using the overloaded CString assignment operator. It is //essentially a string copy, but MFC takes care of allocating //and freeing the destination buffer. ErrorDescription = ErrDesc; } else { //Note: this is not a pointer assignment. We are using the //overloaded CString assignment operator which essentially //does a string copy. (see comments above) ErrorDescription = (TCHAR *) lpMessageBuffer; LocalFree (lpMessageBuffer); } Message = g_Strings.ReceiveError; //using overloaded CString + operator. Has the same effect as wcscat //but MFC takes care of allocating and freeing the destination buffers Message += ErrorDescription; m_DoneText.SetWindowText(Message); } m_btnCancel.SetWindowText(g_Strings.Close); m_btnCancel.SetFocus(); } BOOL CIrRecvProgress::DestroyWindow() { if (m_bDlgDestroyed) return m_bDlgDestroyed; //if a taskbar button had been put up, remove it now. if (m_ptl) { m_ptl->DeleteTab(m_hWnd); m_ptl->Release(); m_ptl = NULL; } m_bDlgDestroyed=TRUE; CWnd::DestroyWindow(); return TRUE; } BOOL CIrRecvProgress::OnInitDialog() { HRESULT hr = E_FAIL; RECT rc; int newWidth, newHeight, xshift, yshift; CWnd * pDesktop = NULL; CDialog::OnInitDialog(); m_bDlgDestroyed = FALSE; //start with a hidden window if prompting is not turned off. if (!m_fDontPrompt) ShowWindow (SW_HIDE); else ShowWindow (SW_SHOW); //if the sender is a camera, the cancel operation is not supported, //so change the cancel button to Close if (m_bRecvFromCamera) m_btnCancel.SetWindowText(g_Strings.Close); //first display the progress controls and hide the summary controls. ShowProgressControls (SW_SHOW); ShowSummaryControls (SW_HIDE); //set the appropriate values for the progress controls. m_xferAnim.Open(IDR_TRANSFER_AVI); m_xferAnim.Play(0, -1, -1); m_File.SetWindowText (TEXT("")); m_Machine.SetWindowText (m_szMachineName); //add a button to the taskbar for this window hr = CoInitialize(NULL); if (SUCCEEDED(hr)) hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (LPVOID*)&m_ptl); if (SUCCEEDED(hr)) { hr = m_ptl->HrInit(); } else { m_ptl = NULL; } if (m_ptl) { if (SUCCEEDED(hr)) m_ptl->AddTab(m_hWnd); else { m_ptl->Release(); m_ptl = NULL; } } //reposition the window so that it is at the center of the screen //also push this window to the top after activating it GetClientRect (&rc); newHeight = rc.bottom; newWidth = rc.right; pDesktop = GetDesktopWindow(); pDesktop->GetClientRect (&rc); yshift = (rc.bottom - newHeight)/2; xshift = (rc.right - newWidth)/2; //there might be a problem if someday the dialog should //get larger than the desktop. But then, there is no way //we can fit that window inside the desktop anyway. //So the best we can do is place it at the top left corner xshift = (xshift >= 0)?xshift:0; yshift = (yshift >= 0)?yshift:0; appController->SetForegroundWindow(); SetActiveWindow(); SetWindowPos (&wndTop, xshift, yshift, -1, -1, SWP_NOSIZE | SWP_NOOWNERZORDER); m_btnCancel.SetFocus(); return FALSE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } DWORD CIrRecvProgress::GetPermission( wchar_t Name[], BOOL fDirectory ) { TCHAR szCompactName [COMPACT_PATHLEN + 1]; CString szName; DWORD len; DWORD Status = ERROR_SUCCESS; if (Name[0] == '\\') { ++Name; } // // Don't issue a blanket authorization for files in the RFF, // but allow the service to chdir there. // if (fDirectory && wcslen(Name) == 0) { return ERROR_SUCCESS; } // // If the file or directory lies outside our last approved directory tree, ask permission. // if (m_LastPermittedDirectory[0] == 0 || 0 != wcsncmp(m_LastPermittedDirectory, Name, wcslen(m_LastPermittedDirectory))) { Status = PromptForPermission(Name, fDirectory); } // // Update the current file name if we got the permission // if (ERROR_SUCCESS == Status) { szName = Name; len = wcslen (Name); if (COMPACT_PATHLEN < len) { if (PathCompactPathEx (szCompactName, Name, COMPACT_PATHLEN + 1, 0)) szName = szCompactName; } m_File.SetWindowText(szName); } return Status; } DWORD CIrRecvProgress::PromptForPermission( wchar_t Name[], BOOL fDirectory ) { CRecvConf dlgConfirm (this); DWORD Status = ERROR_SUCCESS; DWORD len; BOOL bUnhide = FALSE; if (m_fDontPrompt) goto PromptEnd; //we need to ask the user for permission. if (m_fFirstXfer) { // dlgConfirm.ShowAllYes (FALSE); m_fFirstXfer = FALSE; bUnhide = TRUE; } dlgConfirm.InitNames (m_szMachineName, Name, fDirectory); switch (dlgConfirm.DoModal()) { case IDALLYES: m_fDontPrompt = TRUE; case IDYES: Status = ERROR_SUCCESS; break; case IDCANCEL: Status = ERROR_CANCELLED; break; default: Status = GetLastError(); } PromptEnd: if (fDirectory && ERROR_SUCCESS == Status) { StringCbCopy(m_LastPermittedDirectory,sizeof(m_LastPermittedDirectory), Name); len = wcslen (Name); // // make sure that the name is slash terminated. // if (L'\\' != Name[len - 1]) { StringCbCat(m_LastPermittedDirectory, sizeof(m_LastPermittedDirectory), TEXT("\\")); } } if (m_fFirstXfer || bUnhide) ShowWindow(SW_SHOW); return Status; }