513 lines
18 KiB
C++
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;
|
|
}
|