windows-nt/Source/XPSP1/NT/net/irda/irftp/irftpdlg.cpp
2020-09-26 16:20:57 +08:00

513 lines
18 KiB
C++

/*++
Microsoft Windows
Copyright (C) Microsoft Corporation, 1981 - 1999
Module Name:
irftpdlg.cpp
Abstract:
Author:
Rahul Thombre (RahulTh) 4/30/1998
Revision History:
4/30/1998 RahulTh
Created this module.
--*/
// irftpDlg.cpp : implementation file
//
#include "precomp.hxx"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//the context sensitive help array
const DWORD g_aHelpIDs_IDD_IRDA_DIALOG[]=
{
IDC_IR_DESC, IDH_DISABLEHELP, // Untitled: "You can send..." (Static)
IDC_LOCATION_GROUP, IDH_DISABLEHELP, // Untitled: "Location" (Button)
IDB_HELP_BUTTON, IDH_HELP_BUTTON, // Untitled: "Help" (Button)
IDB_SEND_BUTTON, IDH_SEND_BUTTON, // Untitled: "Send" (Button)
IDB_SETTINGS_BUTTON, IDH_SETTINGS_BUTTON, // Untitled: "Settings" (Button)
IDB_CLOSE_BUTTON, IDH_CLOSE_BUTTON, // Untitled: "Close" (Button)
IDC_ADD_DESC, IDH_DISABLEHELP, //the second line of text describing the ir dialog
IDC_IR_ICON, IDH_DISABLEHELP, //the icon on the dialog
0, 0
};
/////////////////////////////////////////////////////////////////////////////
// CIrftpDlg dialog
CIrftpDlg::CIrftpDlg( ) : CFileDialog(TRUE)
{
//{{AFX_DATA_INIT(CIrftpDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
//get the location of the "My Documents" folder
//this should be used as the initial dir.
m_lpszInitialDir[0] = '\0'; //just in case SHGetSpecialFolderPath fails.
SHGetSpecialFolderPath (NULL, m_lpszInitialDir, CSIDL_PERSONAL, FALSE);
//if the above call fails, then the common file open dialog box will
//default to the current directory.
m_iFileNamesCharCount = 0;
TCHAR szFile[] = TEXT("\0");
m_ptl = NULL;
m_pParentWnd = NULL;
LoadString(g_hInstance, IDS_CAPTION, m_szCaption, MAX_PATH);
LoadFilter();
m_ofn.lStructSize = sizeof(OPENFILENAME);
m_ofn.hInstance = g_hInstance;
m_ofn.lpstrFilter = m_szFilter;
m_ofn.nFilterIndex = 1;
m_ofn.lpstrFile = m_lpstrFile;
m_ofn.lpstrFile[0] = '\0';
m_ofn.nMaxFile = MAX_PATH;
m_ofn.lpstrInitialDir = m_lpszInitialDir;
m_ofn.lpstrTitle = m_szCaption;
m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_IRDA_DIALOG);
m_ofn.Flags |= OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK |
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT |
OFN_PATHMUSTEXIST | OFN_NODEREFERENCELINKS;
m_ofn.Flags &= (~ OFN_ENABLESIZING);
}
void CIrftpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIrftpDlg)
DDX_Control(pDX, IDB_HELP_BUTTON, m_helpBtn);
DDX_Control(pDX, IDB_SETTINGS_BUTTON, m_settingsBtn);
DDX_Control(pDX, IDB_SEND_BUTTON, m_sendBtn);
DDX_Control(pDX, IDB_CLOSE_BUTTON, m_closeBtn);
DDX_Control(pDX, IDC_LOCATION_GROUP, m_locationGroup);
DDX_Control(pDX, 1119, m_commFile);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CIrftpDlg, CFileDialog)
//{{AFX_MSG_MAP(CIrftpDlg)
//ON_WM_PAINT() //uncomment this line only if the dialog has a bitmap instead of an icon that needs to be drawn transparently.
ON_BN_CLICKED(IDB_HELP_BUTTON, OnHelpButton)
ON_BN_CLICKED(IDB_CLOSE_BUTTON, OnCloseButton)
ON_BN_CLICKED(IDB_SEND_BUTTON, OnSendButton)
ON_BN_CLICKED(IDB_SETTINGS_BUTTON, OnSettingsButton)
ON_MESSAGE (WM_HELP, OnHelp)
ON_MESSAGE (WM_CONTEXTMENU, OnContextMenu)
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIrftpDlg message handlers
BOOL CIrftpDlg::OnInitDialog()
{
HWND hWndParent; //handle to the parent window,
//viz.the common file dialog box created by explorer
HRESULT hr = E_FAIL;
CFileDialog::OnInitDialog();
//save the pointer to the parent window
m_pParentWnd = GetParent();
hWndParent = m_pParentWnd->m_hWnd;
//Add icons to the parent window
//to see if we can get the Wireless Link icon on Alt-<Tab>
m_pParentWnd->ModifyStyle (0, WS_SYSMENU | WS_CAPTION, SWP_NOSIZE | SWP_NOMOVE);
//hide the Help, Open and Cancel buttons. We will use our own
//this helps in having a better looking UI
CommDlg_OpenSave_HideControl(hWndParent, pshHelp);
CommDlg_OpenSave_HideControl(hWndParent, IDOK);
CommDlg_OpenSave_HideControl(hWndParent, IDCANCEL);
CommDlg_OpenSave_HideControl(hWndParent, stc2);
CommDlg_OpenSave_HideControl(hWndParent, cmb1);
//Initialize the taskbar list interface
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_pParentWnd->m_hWnd);
else
{
m_ptl->Release();
m_ptl = NULL;
}
}
// return TRUE unless you set the focus to a control
return TRUE;
}
BOOL CIrftpDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
LPOFNOTIFY lpofn = (LPOFNOTIFY)lParam;
switch (lpofn->hdr.code)
{
case CDN_INITDONE:
InitializeUI();
break;
case CDN_FOLDERCHANGE:
//clear the edit box whenever the folder is changed
//using both the controls because of the bug which gives the older
//file dialog in some cases and the new file dialog in some others
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, TEXT(""));
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, TEXT(""));
break;
case CDN_SELCHANGE:
UpdateSelection();
break;
case CDN_FILEOK:
UpdateSelection();
OnSendButton();
*pResult = 1;
return TRUE;
default:
return CFileDialog::OnNotify(wParam, lParam, pResult);
}
return TRUE;
}
void CIrftpDlg::OnHelpButton ()
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
CString szHelpFile;
szHelpFile.LoadString (IDS_HTML_HELPFILE);
g_hwndHelp = HtmlHelp (m_pParentWnd->m_hWnd, (LPCTSTR) szHelpFile, HH_DISPLAY_TOPIC, 0);
}
void CIrftpDlg::OnCloseButton()
{
//owing to UI design issues, we chose to use our own Close button
//rather than the explorer provided Cancel button in the common
//file dialog box
//m_pParentWnd->PostMessage(WM_QUIT);
m_pParentWnd->PostMessage(WM_CLOSE);
}
//this function is invoked when the CDN_INITDONE message is received
//this indicates that explorer has finished placing and resizing the
//controls on the template.
//this function resizes and moves some of the controls to make sure
//that the common file dialog controls and the template controls do
//not overlap
void CIrftpDlg::InitializeUI()
{
//change the geometry of some of the controls so that the UI looks good
//and there are no overlapping controls
RECT rc;
int newWidth, newHeight, xshift, yshift, btnTop, parentLeft, parentTop;
CWnd* pParentWnd;
CWnd* pDesktop;
CWnd* pTemplateParentWnd;
UINT commFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER;
m_commFile.GetClientRect(&rc);
newWidth = rc.right - rc.left + 20;
newHeight = rc.bottom - rc.top + 20;
//resize the Location group box so that the common file controls
//are inscribed in it
m_locationGroup.SetWindowPos(NULL, -1, -1, newWidth, newHeight,
SWP_NOMOVE | commFlags);
//shift the Send, Settings and Close buttons so that the last button
//is aligned with the right edge of the group box controls.
pTemplateParentWnd = m_locationGroup.GetParent();
pParentWnd = GetParent();
pParentWnd->GetWindowRect(&rc);
parentLeft = rc.left;
parentTop = rc.top;
m_locationGroup.GetWindowRect(&rc);
btnTop = rc.bottom - 10;
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
xshift = rc.right;
m_closeBtn.GetWindowRect(&rc);
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
xshift -= rc.right;
m_closeBtn.SetWindowPos(NULL, rc.left + xshift,
btnTop - parentTop, -1, -1,
SWP_NOSIZE | commFlags);
m_sendBtn.GetWindowRect(&rc);
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
m_sendBtn.SetWindowPos(NULL, rc.left + xshift,
btnTop - parentTop, -1, -1,
SWP_NOSIZE | commFlags);
//move the help button so that its left edge aligns with the left
//edge of the location group box.
m_locationGroup.GetWindowRect (&rc);
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
xshift = rc.left;
m_helpBtn.GetWindowRect (&rc);
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
xshift -= rc.left;
m_helpBtn.SetWindowPos (NULL, rc.left + xshift,
btnTop - parentTop,
-1, -1, SWP_NOSIZE | commFlags);
m_settingsBtn.GetWindowRect (&rc);
::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
//move the Settings button so that the distance between the
//Help and Settings button conforms to the UI guidelines.
m_settingsBtn.SetWindowPos (NULL, rc.left + xshift,
btnTop - parentTop, -1, -1,
SWP_NOSIZE | commFlags);
//now that all the controls have been positioned appropriately,
//reposition the entire window so that it appears at the center
//of the screen rather than being partially obscured by the screen.
pParentWnd->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;
pParentWnd->SetWindowPos (NULL, xshift, yshift,
-1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
pParentWnd->SetActiveWindow();
}
void CIrftpDlg::LoadFilter()
{
int strId;
TCHAR* curr;
int step, remainChars;
for(strId = IDS_FILTER_START + 1, curr = m_szFilter, remainChars = MAX_PATH - 1;
strId < IDS_FILTER_END;
strId++, curr += step + 1, remainChars -= (step + 1))
{
step = LoadString(g_hInstance, strId, curr, remainChars);
}
*curr = '\0'; //terminated by 2 NULLs
}
void CIrftpDlg::OnSendButton()
{
int iSize = (m_iFileNamesCharCount>MAX_PATH)?m_iFileNamesCharCount:MAX_PATH; //kluge
TCHAR *lpszName = NULL;
TCHAR lpszPath[MAX_PATH];
TCHAR *lpszFileList = NULL;
TCHAR *lpszFullPathnamesList;
int iFileCount;
int iCharCount;
BOOL bAllocFailed = FALSE;
try
{
lpszName = new TCHAR [iSize];
lpszFileList = new TCHAR [iSize];
}
catch (CMemoryException* e)
{
bAllocFailed = TRUE;
e->Delete();
}
if (bAllocFailed || (NULL == lpszName) || (NULL == lpszFileList))
goto cleanup_onSend;
CommDlg_OpenSave_GetFolderPath(m_pParentWnd->m_hWnd, lpszPath, MAX_PATH);
CommDlg_OpenSave_GetSpec (m_pParentWnd->m_hWnd, lpszName, MAX_PATH);
iFileCount = ParseFileNames(lpszName, lpszFileList, iCharCount);
if (!iFileCount)
goto cleanup_onSend; //no files/dirs have been selected
else if(1 == iFileCount) //this is a special case because if there is only one file, then absolute paths/UNC paths are allowed
lpszFullPathnamesList = ProcessOneFile (lpszPath, lpszFileList, iFileCount, iCharCount);
else
lpszFullPathnamesList = GetFullPathnames(lpszPath, lpszFileList, iFileCount, iCharCount);
CSendProgress* dlgProgress;
dlgProgress = new CSendProgress(lpszFullPathnamesList, iCharCount);
dlgProgress->ShowWindow(SW_SHOW);
dlgProgress->SetFocus();
dlgProgress->SetWindowPos (&wndTop, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE);
cleanup_onSend:
if (lpszName)
delete [] lpszName;
if (lpszFileList)
delete [] lpszFileList;
}
void CIrftpDlg::OnSettingsButton()
{
appController->PostMessage(WM_APP_TRIGGER_SETTINGS);
}
void CIrftpDlg::UpdateSelection()
{
CListCtrl* pDirContents;
pDirContents = (CListCtrl*)(m_pParentWnd->GetDlgItem(lst2))->GetDescendantWindow(1);
TCHAR lpszPath[MAX_PATH];
CString szPath;
CString szFullName;
CString szEditBoxText;
//get the path of the folder
CommDlg_OpenSave_GetFolderPath (m_pParentWnd->m_hWnd, lpszPath, MAX_PATH);
szPath = lpszPath; //easier to manipulate CStrings
LONG nFiles = pDirContents->GetSelectedCount();
TCHAR pszFileName[MAX_PATH];
DWORD dwFileAttributes;
CString szFilesList;
int iSelectedDirCount = 0;
int nIndex;
if (nFiles)
{
//go to the point just before the first selected item
nIndex = pDirContents->GetTopIndex() - 1;
szEditBoxText.Empty();
szPath += '\\';
//first add all the directories
while (-1 != (nIndex = pDirContents->GetNextItem(nIndex, LVNI_ALL | LVNI_SELECTED)))
{
pDirContents->GetItemText(nIndex, 0, pszFileName, MAX_PATH);
szFullName = szPath + pszFileName;
//check if it is a directory.
dwFileAttributes = GetFileAttributes(szFullName);
if (0xFFFFFFFF != dwFileAttributes &&
(FILE_ATTRIBUTE_DIRECTORY & dwFileAttributes))
{
//it is a directory so add it to the edit box text
szEditBoxText += '\"';
szEditBoxText += pszFileName;
szEditBoxText += TEXT("\" ");
iSelectedDirCount++;
}
}
//now we have got all the directories, get the files list if any
if (nFiles > iSelectedDirCount)
{
//if nFiles > iSelectedDirCount, it means that all the selected
//items are not dirs. this check is necessary because the function
//GetFileName will return the names of the last set of files
//selected if no file is currently selected. this is clearly
//not what we want
szFilesList.Empty();
szFilesList = GetFileName();
if ((!szFilesList.IsEmpty()) && '\"' != szFilesList[0])
{
//only one file is selected. we must add the enclosing
//double quotes ourselves, since the common file dialog
//does not do it for us.
szFilesList = '\"' + szFilesList + TEXT("\" ");
}
//add the list of files to the end of the list of directories
szEditBoxText += szFilesList;
}
//populate the controls with this list
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, (LPCTSTR)szEditBoxText);
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, (LPCTSTR)szEditBoxText);
m_iFileNamesCharCount = szEditBoxText.GetLength() + 1;
}
else
{
m_iFileNamesCharCount = 0;
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, TEXT(""));
CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, TEXT(""));
}
}
void CIrftpDlg::PostNcDestroy()
{
if (m_ptl)
{
m_ptl->DeleteTab(m_pParentWnd->m_hWnd);
m_ptl->Release();
m_ptl = NULL;
}
CFileDialog::PostNcDestroy();
}
LONG CIrftpDlg::OnHelp (WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
LONG lResult = 0;
CString szHelpFile;
szHelpFile.LoadString(IDS_HELP_FILE);
::WinHelp((HWND)(((LPHELPINFO)lParam)->hItemHandle),
(LPCTSTR) szHelpFile,
HELP_WM_HELP,
(ULONG_PTR)(LPTSTR)g_aHelpIDs_IDD_IRDA_DIALOG);
return lResult;
}
LONG CIrftpDlg::OnContextMenu (WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
LONG lResult = 0;
CString szHelpFile;
szHelpFile.LoadString(IDS_HELP_FILE);
::WinHelp((HWND)wParam,
(LPCTSTR)szHelpFile,
HELP_CONTEXTMENU,
(ULONG_PTR)(LPVOID)g_aHelpIDs_IDD_IRDA_DIALOG);
return lResult;
}