|
|
// File: ftui.h
#include "mbftpch.h"
#include <commctrl.h>
#include <regentry.h>
#include "ftui.h"
#include "version.h"
#include <iappldr.h>
#include <nmhelp.h>
static ULONG s_cMsgBox2Dlg = 0; // for alignment
static ULONG s_cRecvDlg = 0; // for alignment
static ULONG s_sort = -1; ULONG _GetPercent(ULONG cbTotalRecvSize , ULONG cbFileSize);
TCHAR s_szMSFT[64]; static TCHAR s_szScratchText[MAX_PATH*2]; static const TCHAR s_cszHtmlHelpFile[] = TEXT("conf.chm");
#define MAX_FILE_NAME_LENGTH 30
LRESULT CALLBACK FtMainWndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK RecvDlgProc(HWND, UINT, WPARAM, LPARAM); LPTSTR PathNameToFileName(LPTSTR pszPathName); HRESULT GetRecvFolder(LPTSTR pszInFldr, LPTSTR pszOutFldr); BOOL MsgBox2(CAppletWindow *pWindow, LPTSTR pszText);
void ShiftFocus(HWND hwndTop, BOOL bForward);
void EnsureTrailingSlash(LPTSTR); int MyLoadString(UINT idStr); int MyLoadString(UINT idStr, LPTSTR pszDstStr); int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement); int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement1, LPTSTR pszElement2); __inline int MyLoadString(UINT idStr, LPTSTR pszDstStr, UINT_PTR nElement) { return MyLoadString(idStr, pszDstStr, (LPTSTR) nElement); } __inline int MyLoadString(UINT idStr, LPTSTR pszDstStr, UINT_PTR nElement1, UINT_PTR nElement2) { return MyLoadString(idStr, pszDstStr, (LPTSTR) nElement1, (LPTSTR) nElement2); } int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement1, UINT_PTR nElement2) { return MyLoadString(idStr, pszDstStr, pszElement1, (LPTSTR) nElement2); } __inline int MyLoadString(UINT idStr, LPTSTR pszDstStr, UINT_PTR nElement1, LPTSTR pszElement2) { return MyLoadString(idStr, pszDstStr, (LPTSTR) nElement1, pszElement2); }
#define count_of(array) (sizeof(array) / sizeof(array[0]))
void OnChangeFolder(void); BOOL FBrowseForFolder(LPTSTR pszFolder, UINT cchMax, LPCTSTR pszTitle); extern BOOL g_fShutdownByT120;
void OPT_GetFTWndPosition(RECT *pRect) { int iLeft, iTop, iRight, iBottom; RegEntry reWnd( FILEXFER_KEY, HKEY_CURRENT_USER);
iLeft = reWnd.GetNumber(REGVAL_WINDOW_XPOS, 0); iTop = reWnd.GetNumber(REGVAL_WINDOW_YPOS, 0); iRight = reWnd.GetNumber(REGVAL_WINDOW_WIDTH, 0) + iLeft; iBottom = reWnd.GetNumber(REGVAL_WINDOW_HEIGHT, 0) + iTop;
// If it was empty, use the new rect
if (!(iBottom || iTop || iLeft || iRight)) { return; }
// Make sure that the window rectangle is (at least partially) on
// screen, and not too large. First get the screen size
int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); // Check the window size
if ((iRight - iLeft) > screenWidth) { iRight = iLeft + screenWidth; }
if ((iBottom - iTop) > screenHeight) { iTop = screenHeight; }
// Check the window position
if (iLeft >= screenWidth) { // Off screen to the right - keep the width the same
iLeft = screenWidth - (iRight - iLeft); iRight = screenWidth; }
if (iRight < 0) { // Off screen to the left - keep the width the same
iRight = iRight - iLeft; iLeft = 0; }
if (iTop >= screenHeight) { // Off screen to the bottom - keep the height the same
iTop = screenHeight - (iBottom - iTop); iBottom = screenHeight; }
if (iBottom < 0) { // Off screen to the top - keep the height the same
iBottom = (iBottom - iTop); iTop = 0; }
pRect->left = iLeft; pRect->top = iTop; pRect->right = iRight - iLeft; pRect->bottom = iBottom - iTop; }
CAppletWindow::CAppletWindow(BOOL fNoUI, HRESULT *pHr) : CRefCount(MAKE_STAMP_ID('F','T','U','I')), m_hwndMainUI(NULL), m_pToolbar(NULL), m_hwndListView(NULL), m_hwndStatusBar(NULL), m_pEngine(NULL), m_fInFileOpenDialog(FALSE), m_pCurrSendFileInfo(NULL), m_nCurrSendEventHandle(0), m_hIconInCall(NULL), m_hIconNotInCall(NULL) { m_UIMode = fNoUI ? FTUIMODE_NOUI : FTUIMODE_UIHIDDEN; ::GetCurrentDirectory(MAX_PATH, m_szDefaultDir);
*pHr = E_FAIL; // failure, at default
// create window class name
::wsprintf(&m_szFtMainWndClassName[0], TEXT("FTMainWnd%0X_%0X"), ::GetCurrentProcessId(), ::GetTickCount()); ASSERT(::lstrlenA(&m_szFtMainWndClassName[0]) < sizeof(m_szFtMainWndClassName));
// register window class first
WNDCLASS wc; ::ZeroMemory(&wc, sizeof(wc)); //wc.style = 0;
wc.lpfnWndProc = FtMainWndProc; // wc.cbClsExtra = 0;
// wc.cbWndExtra = 0;
wc.hInstance = g_hDllInst; wc.hIcon = ::LoadIcon(g_hDllInst, MAKEINTRESOURCE(IDI_FILE_TRANSFER)); // wc.hbrBackground = NULL;
// wc.hCursor = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU_FT); wc.lpszClassName = m_szFtMainWndClassName; if (::RegisterClass(&wc)) { ::MyLoadString(IDS_MSFT_NOT_IN_CALL_WINDOW_CAPTION); m_hwndMainUI = ::CreateWindow( m_szFtMainWndClassName, s_szScratchText, WS_OVERLAPPEDWINDOW | WS_TABSTOP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, // no parent window
NULL, // use class' menu
g_hDllInst, (LPVOID) this); // this window is for this object
if (NULL != m_hwndMainUI) { // success
*pHr = S_OK; } } m_hAccel = ::LoadAccelerators(g_hDllInst, MAKEINTRESOURCE(RECVDLGACCELTABLE)); m_hLVAccel = ::LoadAccelerators(g_hDllInst, MAKEINTRESOURCE(LISTVIEWACCELTABLE)); }
CAppletWindow::~CAppletWindow(void) { ASSERT(NULL == m_hwndMainUI);
::UnregisterClass(m_szFtMainWndClassName, g_hDllInst);
ClearSendInfo(FALSE); ClearRecvInfo();
if (m_hIconInCall) ::DestroyIcon(m_hIconInCall); if (m_hIconNotInCall) ::DestroyIcon(m_hIconNotInCall);
ASSERT(NULL == m_pEngine); }
BOOL CAppletWindow::FilterMessage(MSG *pMsg) { CRecvDlg *pRecvDlg; HWND hwndError; HWND hwndForeground = ::GetForegroundWindow();
m_RecvDlgList.Reset(); while (NULL != (pRecvDlg = m_RecvDlgList.Iterate())) { if (::IsDialogMessage(pRecvDlg->GetHwnd(), pMsg)) { return TRUE; } } if (hwndForeground == m_hwndMainUI) { BOOL fRet = ::TranslateAccelerator(m_hwndMainUI, m_hLVAccel, pMsg); return fRet; }
m_ErrorDlgList.Reset(); while (NULL != (hwndError = m_ErrorDlgList.Iterate())) { if (::IsDialogMessage(hwndError, pMsg)) { return TRUE; } } return FALSE; }
BOOL CAppletWindow::QueryShutdown(BOOL fShutdown) { if (m_UIMode != FTUIMODE_NOUI) { int id = 0; if (m_nCurrSendEventHandle) { id = (fShutdown)?IDS_QUERY_SEND_SHUTDOWN:IDS_QUERY_SEND_HANGUP; } else if (IsReceiving()) { id = (fShutdown)?IDS_QUERY_RECVING_SHUTDOWN:IDS_QUERY_RECVING_HANGUP; }
if (id) { // could be in any thread
TCHAR szText[MAX_PATH]; if (::MyLoadString(id, szText)) { if (IDNO == ::MessageBox(NULL, szText, s_szMSFT, MB_TASKMODAL | MB_YESNO | MB_ICONQUESTION)) { return FALSE; } } } }
if (m_nCurrSendEventHandle) { OnStopSending(); } if (IsReceiving()) { CRecvDlg *pRecvDlg = NULL; m_RecvDlgList.Reset(); while (NULL != (pRecvDlg = m_RecvDlgList.Iterate())) { DBG_SAVE_FILE_LINE GetEngine()->SafePostMessage( new FileTransferControlMsg( pRecvDlg->GetEventHandle(), pRecvDlg->GetFileHandle(), NULL, NULL, FileTransferControlMsg::EnumAbortFile)); } } return TRUE; }
void CAppletWindow::RegisterEngine(MBFTEngine *pEngine) { ASSERT(NULL == m_pEngine); pEngine->AddRef(); m_pEngine = pEngine; UpdateUI(); }
void CAppletWindow::UnregisterEngine(void) { if (NULL != m_pEngine) { m_pEngine->Release(); m_pEngine = NULL; ClearSendInfo(TRUE); ClearRecvInfo(); } if (UIHidden()) { // exit
::PostMessage(m_hwndMainUI, WM_CLOSE, 0, 0); } else { UpdateUI(); // don't quit
} }
void CAppletWindow::RegisterRecvDlg(CRecvDlg *pDlg) { m_RecvDlgList.Prepend(pDlg); }
void CAppletWindow::UnregisterRecvDlg(CRecvDlg *pDlg) { m_RecvDlgList.Remove(pDlg); FocusNextRecvDlg(); }
BOOL CAppletWindow::IsReceiving(void) { BOOL fRet = FALSE; CRecvDlg *pDlg; CUiRecvFileInfo *pRecvFile; m_RecvDlgList.Reset(); while (NULL != (pDlg = m_RecvDlgList.Iterate())) { pRecvFile = pDlg->GetRecvFileInfo(); if (pRecvFile && (pRecvFile->GetTotalRecvSize() < pRecvFile->GetSize())) { fRet = TRUE; break; } } return fRet; }
CRecvDlg * CAppletWindow::FindDlgByHandles(MBFTEVENTHANDLE nEventHandle, MBFTFILEHANDLE nFileHandle) { CRecvDlg *pDlg; m_RecvDlgList.Reset(); while (NULL != (pDlg = m_RecvDlgList.Iterate())) { if (nEventHandle == pDlg->GetEventHandle() && nFileHandle == pDlg->GetFileHandle()) { break; } } return pDlg; }
/////////////////////////////////////////////////////////////////
//
// WM_CREATE
//
LRESULT OnCreate(HWND hwnd, WPARAM wParam, LPARAM lParam) { CREATESTRUCT *p = (CREATESTRUCT *) lParam; CAppletWindow *pWindow = (CAppletWindow *) p->lpCreateParams;
ASSERT(NULL != pWindow); ::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM) p->lpCreateParams);
pWindow->SetHwnd(hwnd);
::InitCommonControls();
pWindow->CreateToolBar(); pWindow->CreateStatusBar(); pWindow->CreateListView();
::DragAcceptFiles(hwnd, g_fSendAllowed);
// resize the window
MINMAXINFO mmi; ::ZeroMemory(&mmi, sizeof(mmi)); pWindow->OnGetMinMaxInfo(&mmi); RECT rcUI;
::GetWindowRect(pWindow->GetHwnd(), &rcUI); rcUI.right = mmi.ptMinTrackSize.x; rcUI.bottom = mmi.ptMinTrackSize.y + 30; OPT_GetFTWndPosition(&rcUI);
::MoveWindow(pWindow->GetHwnd(), rcUI.left, rcUI.top, rcUI.right, rcUI.bottom, TRUE);
pWindow->UpdateUI();
#if defined(TEST_PLUGABLE) && defined(_DEBUG)
::OnPluggableBegin(hwnd); #endif
return 0; }
enum { TB_IDX_ADD_FILES = 0, TB_IDX_REMOVE_FILES, TB_IDX_BREAK_1, TB_IDX_IDM_SEND_ALL, TB_IDX_IDM_SEND_ONE, TB_IDX_IDM_STOP_SENDING, TB_IDX_BREAK_2, TB_IDX_IDM_OPEN_RECV_FOLDER, TB_IDX_IDM_CHANGE_FOLDER, TB_IDX_BREAK_3, TB_IDX_IDM_HELP, };
static Buttons buttons [] = { {IDB_ADDFILES, CBitmapButton::Disabled+1, 1, IDM_ADD_FILES, (LPCSTR)IDS_MENU_ADD_FILES,}, {IDB_REMOVEFILES, CBitmapButton::Disabled+1, 1, IDM_REMOVE_FILES, (LPCSTR)IDS_MENU_REMOVE_FILES,}, {0, 0, 0, 0, 0,}, {IDB_SENDFILE, CBitmapButton::Disabled+1, 1, IDM_SEND_ALL, (LPCSTR)IDS_MENU_SEND_ALL,}, {IDB_STOPSEND, CBitmapButton::Disabled+1, 1, IDM_STOP_SENDING, (LPCSTR)IDS_MENU_STOP_SENDING,}, {0, 0, 0, 0, 0,}, {IDB_FOLDER, CBitmapButton::Disabled+1, 1, IDM_OPEN_RECV_FOLDER, (LPCSTR)IDS_MENU_OPEN_RECV_FOLDER,}, {0, 0, 0, 0, 0}, };
BOOL CAppletWindow::CreateToolBar(void) { DBG_SAVE_FILE_LINE m_pToolbar = new CComboToolbar(); if (m_pToolbar) { m_pToolbar->Create(m_hwndMainUI, &buttons[0], count_of(buttons), this); m_pToolbar->Release(); return TRUE; } return FALSE; }
BOOL CAppletWindow::CreateStatusBar(void) { m_hwndStatusBar = ::CreateWindowEx(0, STATUSCLASSNAME, // status bar class
TEXT(""), // no default text
WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP, 0, 0, 0, 0, m_hwndMainUI, (HMENU) IDC_STATUS_BAR, g_hDllInst, NULL); ASSERT(NULL != m_hwndStatusBar); if (NULL != m_hwndStatusBar) { // Load Call Icons
m_hIconInCall = (HICON) ::LoadImage(g_hDllInst, MAKEINTRESOURCE(IDI_INCALL), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); m_hIconNotInCall = (HICON) ::LoadImage(g_hDllInst, MAKEINTRESOURCE(IDI_NOT_INCALL), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); if (CreateProgressBar()) { return TRUE; } } return FALSE; }
BOOL CAppletWindow::CreateProgressBar(void) { RECT rcl;
GetClientRect(m_hwndStatusBar, &rcl); m_hwndProgressBar = ::CreateWindowEx(0, PROGRESS_CLASS, TEXT(""), WS_CHILD | WS_VISIBLE | PBS_SMOOTH, rcl.right/2 + 2, 2, rcl.right - rcl.right/2 - 40, rcl.bottom - 8, m_hwndStatusBar, (HMENU)IDC_PROGRESS_BAR, g_hDllInst, NULL); if (m_hwndProgressBar) { ::SendMessage(m_hwndProgressBar, PBM_SETRANGE, 0L, MAKELONG(0, 100)); return TRUE; } return FALSE; }
BOOL CAppletWindow::CreateListView(void) { // get the size and position of the main window
RECT rcWindow, rcToolBar, rcStatusBar; SIZE szToolBar; ::GetClientRect(m_hwndMainUI, &rcWindow); m_pToolbar->GetDesiredSize(&szToolBar); ::GetWindowRect(m_hwndStatusBar, &rcStatusBar);
ULONG x = 0; ULONG y = szToolBar.cy - 1; ULONG cx = rcWindow.right - rcWindow.left; ULONG cy = rcWindow.bottom - rcWindow.top - y - (rcStatusBar.bottom - rcStatusBar.top) + 1;
// create the list view window
m_hwndListView = ::CreateWindowEx(WS_EX_CLIENTEDGE, // sunken look
WC_LISTVIEW , // list view class
TEXT(""), // no default text
WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT |WS_TABSTOP | LVS_AUTOARRANGE | WS_CLIPCHILDREN | LVS_SHOWSELALWAYS, x, y, cx, cy, m_hwndMainUI, (HMENU) IDC_LIST_VIEW, g_hDllInst, NULL); ASSERT(NULL != m_hwndListView); if (NULL != m_hwndListView) { // set extended list view styles
DWORD dwExtStyle = ListView_GetExtendedListViewStyle(m_hwndListView); dwExtStyle |= (LVS_EX_HEADERDRAGDROP | LVS_EX_SUBITEMIMAGES | LVS_EX_FULLROWSELECT); ListView_SetExtendedListViewStyle(m_hwndListView, dwExtStyle);
// enable window only if we can send files
::EnableWindow(m_hwndListView, g_fSendAllowed);
// set up the columns
ULONG i; LVCOLUMN lvc; LVITEM lvi; TCHAR szText[64]; int iColumnSize[NUM_LIST_VIEW_COLUMNS] = {150, 80, 70, 130}; // listview column size
// initialize the common part of the columns
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; // left-aligned column
lvc.pszText = szText;
// initialize columns one by one
for (i = 0; i < NUM_LIST_VIEW_COLUMNS; i++) { lvc.iSubItem = i; ::LoadString(g_hDllInst, IDS_LV_FILE_NAME + i, szText, count_of(szText)); lvc.cx = iColumnSize[i]; int iRet = ListView_InsertColumn(m_hwndListView, lvc.iSubItem, &lvc); ASSERT(-1 != iRet); } return TRUE; } return FALSE; }
BOOL CAppletWindow::DrawItem(LPDRAWITEMSTRUCT pdis) { ASSERT(pdis); if (NULL != (pdis->itemData)) { int nWidth = pdis->rcItem.right - pdis->rcItem.left; int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; int nLeft = pdis->rcItem.left; int nTop = pdis->rcItem.top; int xSmIcon = ::GetSystemMetrics(SM_CXSMICON); int ySmIcon = ::GetSystemMetrics(SM_CYSMICON);
if (nWidth > xSmIcon) { nLeft += (nWidth - xSmIcon) / 2 - 5; nWidth = xSmIcon; } if (nHeight > ySmIcon) { nTop += (nHeight - ySmIcon) / 2; nHeight = ySmIcon; }
::DrawIconEx( pdis->hDC, nLeft, nTop, (HICON) (pdis->itemData), nWidth, nHeight, 0, NULL, DI_NORMAL); }
return TRUE; }
void CAppletWindow::OnCommand(WORD wId, HWND hwndCtl, WORD codeNotify) { switch (wId) { case IDM_ADD_FILES: OnAddFiles(); UpdateUI(); break;
case IDM_REMOVE_FILES: OnRemoveFiles(); UpdateUI(); break;
case IDM_SEND_ALL: s_cMsgBox2Dlg = 0; SetSendMode(TRUE); OnSendAll(); UpdateUI(); break;
case IDM_SEND_ONE: s_cMsgBox2Dlg = 0; SetSendMode(FALSE); OnSendOne(); UpdateUI(); break;
case IDM_STOP_SENDING: OnStopSending(); UpdateUI(); break;
case IDM_OPEN_RECV_FOLDER: OnOpenRecvFolder(); break;
case IDM_CHANGE_FOLDER: OnChangeFolder(); break;
case IDM_EXIT: OnExit(); break;
case IDM_HELP: OnHelp(); break;
case ID_NAV_TAB: ShiftFocus(m_hwndMainUI, TRUE); if(GetFocus() == m_hwndListView) { SetListViewFocus(); } break;
case ID_NAV_SHIFT_TAB: ShiftFocus(m_hwndMainUI, FALSE); if(GetFocus() == m_hwndListView) { SetListViewFocus(); } break;
case IDM_ABOUT: OnAbout(); break;
default: WARNING_OUT(("FT::OnCommand: unknown command ID=%u", (UINT) wId)); break; } return; }
/////////////////////////////////////////////////////////////////
//
// WM_COMMAND
//
LRESULT OnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); if (NULL != pWindow) { WORD wNotifyCode = GET_WM_COMMAND_CMD(wParam, lParam); // notification code
WORD wID = GET_WM_COMMAND_ID(wParam, lParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
pWindow->OnCommand(wID, hwndCtl, wNotifyCode); return 0; } else { WARNING_OUT((" CAppletWindow::OnCommand--Received unhandled window message.\n")); } return (DefWindowProc(hwnd, WM_COMMAND, wParam, lParam)); }
//
// OnAddFiles
//
UINT_PTR APIENTRY SendFileDlgHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (WM_INITDIALOG == uMsg) { hdlg = ::GetParent(hdlg); // Real dialog is this window's parent
if (::MyLoadString(IDS_FILEDLG_SEND)) { ::SetDlgItemText(hdlg, IDOK, s_szScratchText); } } return 0; }
void CAppletWindow::OnAddFiles(void) { TCHAR szTitle[MAX_PATH]; TCHAR szFilter[MAX_PATH]; TCHAR szDirSav[MAX_PATH]; TCHAR szSendDir[MAX_PATH];
// Load dialog title and filter strings
if (::MyLoadString(IDS_FILEDLG_TITLE, szTitle) && ::MyLoadString(IDS_FILEDLG_FILTER, szFilter)) { // replace '|' to '\0'
LPTSTR pszFltr = szFilter; while (TEXT('\0') != *pszFltr) { if (TEXT('|') == *pszFltr) { *pszFltr = TEXT('\0'); pszFltr++; // cannot use CharNext
} else { pszFltr = ::CharNext(pszFltr); } }
// only allow one "Select a file to send" dialog
if (! m_fInFileOpenDialog) { m_fInFileOpenDialog = TRUE;
// Allocate a really large buffer to hold the file list
ULONG cbBufSize = 8192; DBG_SAVE_FILE_LINE LPTSTR pszBuffer = new TCHAR[cbBufSize]; if (NULL != pszBuffer) { *pszBuffer = TEXT('\0'); // start with null string
OPENFILENAME ofn; ::ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hwndMainUI; ofn.hInstance = g_hDllInst; ofn.lpstrFilter = &szFilter[0]; ofn.nFilterIndex = 1L; // FUTURE: remember filter preference
ofn.lpstrFile = pszBuffer; ofn.nMaxFile = cbBufSize - 1; // Number of TCHAR in pszFiles (not including NULL)
ofn.lpstrTitle = &szTitle[0]; ofn.lpstrInitialDir = m_szDefaultDir; ofn.lpfnHook = SendFileDlgHookProc;
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_ENABLEHOOK | // OFN_HIDEREADONLY |
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER;
// remember current directory
::ZeroMemory(szSendDir, sizeof(szSendDir)); ::GetCurrentDirectory(count_of(szDirSav), szDirSav); ::lstrcpyn(szSendDir, szDirSav, count_of(szSendDir));
if (::GetOpenFileName(&ofn)) { // if there is only a single file, the first string is the full path.
// if there are more than one file, the first string is the directory path
// and followed by a list of file names. terminated by double null
// remember the working directory for next time
ULONG cchDirPath; LPTSTR pszFileName; ULONG cchFile = ::lstrlen(ofn.lpstrFile); if (TEXT('\0') == ofn.lpstrFile[cchFile] && TEXT('\0') == ofn.lpstrFile[cchFile+1]) { //
// only a single file
//
pszFileName = ::PathNameToFileName(ofn.lpstrFile); cchDirPath = (ULONG)(pszFileName - ofn.lpstrFile); if (cchDirPath) { cchDirPath--; // back to '\\'
} ASSERT(TEXT('\\') == ofn.lpstrFile[cchDirPath]); ofn.lpstrFile[cchDirPath] = TEXT('\0'); } else { //
// multiple files
//
cchDirPath = ::lstrlen(ofn.lpstrFile); pszFileName = ofn.lpstrFile + cchDirPath + 1; } ::lstrcpy(m_szDefaultDir, ofn.lpstrFile);
EnsureTrailingSlash(m_szDefaultDir);
::ZeroMemory(szSendDir, sizeof(szSendDir)); ::CopyMemory(szSendDir, ofn.lpstrFile, cchDirPath * sizeof(TCHAR)); EnsureTrailingSlash(szSendDir);
// set up the common portion of list view item
LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); // lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
// iterate the file name
while ('\0' != *pszFileName) { BOOL fRet; DBG_SAVE_FILE_LINE CUiSendFileInfo *pFileInfo = new CUiSendFileInfo(this, szSendDir, pszFileName, &fRet); if (NULL != pFileInfo && fRet) { // put it to the list view
lvi.iItem = ListView_GetItemCount(m_hwndListView); lvi.iSubItem = 0; // we are responsible for storing the text to display
lvi.pszText = LPSTR_TEXTCALLBACK; lvi.cchTextMax = MAX_PATH; lvi.lParam = (LPARAM) pFileInfo; int iRet = ListView_InsertItem(m_hwndListView, &lvi); ASSERT(-1 != iRet); // UpdateListView(pFileInfo);
} else { delete pFileInfo; }
// get to the next file name
pszFileName += ::lstrlen(pszFileName) + 1; } // while
} else { // err code for cancel is zero, which is ok.
ASSERT(! ::CommDlgExtendedError()); }
// restore old working directory
::SetCurrentDirectory(szDirSav); }
delete [] pszBuffer; m_fInFileOpenDialog = FALSE; } else { // bring the active dialog to the front
BringToFront(); } } // if LoadString
}
//
// OnRemoveFiles
//
void CAppletWindow::OnRemoveFiles(void) { UINT nState; ULONG cItems = ListView_GetItemCount(m_hwndListView); LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_SELECTED; ULONG i = 0; while (i < cItems) { lvi.iItem = i; BOOL fRet = ListView_GetItem(m_hwndListView, &lvi); if (fRet && lvi.state & LVIS_SELECTED) { CUiSendFileInfo *pFileInfo = (CUiSendFileInfo *) lvi.lParam; if (pFileInfo == m_pCurrSendFileInfo) { OnStopSending(); ClearSendInfo(FALSE); } delete pFileInfo;
fRet = ListView_DeleteItem(m_hwndListView, i); ASSERT(fRet);
cItems--; ASSERT((ULONG) ListView_GetItemCount(m_hwndListView) == cItems); } else { i++; } } if (cItems > 0) // set focus to first remaining item
{ SetListViewFocus(); } }
void CAppletWindow::OnRemoveAllFiles(void) { BOOL fRet; CUiSendFileInfo *pFileInfo; ULONG cItems = ListView_GetItemCount(m_hwndListView); LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; for (ULONG i = 0; i < cItems; i++) { lvi.iItem = i; fRet = ListView_GetItem(m_hwndListView, &lvi); ASSERT(fRet); pFileInfo = (CUiSendFileInfo *) lvi.lParam; if (pFileInfo == m_pCurrSendFileInfo) { ClearSendInfo(FALSE); } delete pFileInfo; }
fRet = ListView_DeleteAllItems(m_hwndListView); ASSERT(fRet); }
void CAppletWindow::OnSendAll(void) { if ((NULL == m_pCurrSendFileInfo)&&(NULL != m_pEngine)) { CUiSendFileInfo *pFileInfo = ChooseFirstUnSentFile(); SendNow(pFileInfo); } }
void CAppletWindow::OnSendOne(void) { if ((NULL == m_pCurrSendFileInfo)&&(NULL != m_pEngine)) { CUiSendFileInfo *pFileInfo = ChooseSelectedFile(); if (!pFileInfo) { pFileInfo = ChooseFirstUnSentFile(); } SendNow(pFileInfo); } }
//
// SendNow
//
BOOL CAppletWindow::SendNow(CUiSendFileInfo *pFileInfo) { BOOL fRet;
if (NULL != pFileInfo) { // send this file now...
m_pCurrSendFileInfo = pFileInfo; m_nCurrSendEventHandle = ::GetNewEventHandle(); pFileInfo->SetFileHandle(::GetNewFileHandle());
// duplicate full file name
ULONG cbSize = ::lstrlen(pFileInfo->GetFullName()) + 1; DBG_SAVE_FILE_LINE LPTSTR pszFullName = new TCHAR[cbSize]; if (NULL != pszFullName) { ::CopyMemory(pszFullName, pFileInfo->GetFullName(), cbSize);
DBG_SAVE_FILE_LINE if (S_OK == m_pEngine->SafePostMessage( new CreateSessionMsg(MBFT_PRIVATE_SEND_TYPE, m_nCurrSendEventHandle))) { int iSelect; MEMBER_ID nMemberID; iSelect = m_pToolbar->GetSelectedItem((LPARAM*)&nMemberID); if (0 == iSelect) { // Send to All
DBG_SAVE_FILE_LINE if (S_OK == m_pEngine->SafePostMessage( new SubmitFileSendMsg(0, 0, pszFullName, pFileInfo->GetFileHandle(), m_nCurrSendEventHandle, FALSE))) { return TRUE; } else { ERROR_OUT(("CAppletWindow::SendNow: cannot create SubmitFileSendMsg")); } } else { // Send to one
T120UserID uidRecv = GET_PEER_ID_FROM_MEMBER_ID(nMemberID);
DBG_SAVE_FILE_LINE if (S_OK == m_pEngine->SafePostMessage( new SubmitFileSendMsg(uidRecv, 0, pszFullName, pFileInfo->GetFileHandle(), m_nCurrSendEventHandle, FALSE))) { return TRUE; } else { ERROR_OUT(("CAppletWindow::SendNow: cannot create SubmitFileSendMsg to 1")); } } } else { ERROR_OUT(("CAppletWindow::SendNow: cannot create CreateSessionMsg")); }
delete [] pszFullName; } ClearSendInfo(TRUE); } return FALSE; }
CUiSendFileInfo *CAppletWindow::ChooseFirstUnSentFile(void) { CUiSendFileInfo *pFileInfo = NULL; ULONG cItems = ListView_GetItemCount(m_hwndListView);
if (cItems > 0) { // examine each item one by one
LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; for (ULONG i = 0; i < cItems; i++, pFileInfo = NULL) { lvi.iItem = i; BOOL fRet = ListView_GetItem(m_hwndListView, &lvi); ASSERT(fRet); pFileInfo = (CUiSendFileInfo *) lvi.lParam; // if file handle is not zero, then it has been sent
if (! pFileInfo->GetFileHandle()) { break; } } } return pFileInfo; }
CUiSendFileInfo *CAppletWindow::ChooseSelectedFile(void) { CUiSendFileInfo *pFileInfo = NULL; ULONG cItems = ListView_GetItemCount(m_hwndListView); LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_SELECTED; ULONG i = 0; while (i < cItems) { lvi.iItem = i; BOOL fRet = ListView_GetItem(m_hwndListView, &lvi); if (fRet && lvi.state & LVIS_SELECTED) { pFileInfo = (CUiSendFileInfo *) lvi.lParam; pFileInfo->SetErrorCode(iMBFT_OK); break; } else { i++; pFileInfo = NULL; } } return pFileInfo; }
//
// OnMenuSelect
//
void CAppletWindow::OnMenuSelect(UINT uiItemID, UINT uiFlags, HMENU hSysMenu) { UINT firstMenuId; UINT statusId;
//
// Work out the help ID for the menu item. We have to store this now
// because when the user presses F1 from a menu item, we can't tell
// which item it was.
//
if ((uiFlags & MF_POPUP) && (uiFlags & MF_SYSMENU)) { // System menu selected
statusId = (m_pCurrSendFileInfo)?IDS_STBAR_SENDING_XYZ:IDS_STBAR_NOT_TRANSFERING; } else if (uiFlags & MF_POPUP) { // get popup menu handle and first item
HMENU hPopup = ::GetSubMenu( hSysMenu, uiItemID ); firstMenuId = ::GetMenuItemID( hPopup, 0 );
switch(firstMenuId) { case IDM_ADD_FILES: statusId = IDS_MENU_FILE; break;
case IDM_HELP: statusId = IDS_MENU_HELP; break;
default: statusId = (m_pCurrSendFileInfo)?IDS_STBAR_SENDING_XYZ:IDS_STBAR_NOT_TRANSFERING; } } else { // A normal menu item has been selected
statusId = uiItemID; }
// Set the new help text
TCHAR szStatus[256];
if (::LoadString(g_hDllInst, statusId, szStatus, 256)) { ::SendMessage(m_hwndStatusBar, SB_SETTEXT, SBP_TRANSFER_FILE, (LPARAM)szStatus); } }
//
// OnStopSending
//
void CAppletWindow::OnStopSending(void) { m_fSendALL = FALSE; if (m_nCurrSendEventHandle) { DBG_SAVE_FILE_LINE HRESULT hr = m_pEngine->SafePostMessage( new FileTransferControlMsg( m_nCurrSendEventHandle, m_pCurrSendFileInfo->GetFileHandle(), NULL, NULL, FileTransferControlMsg::EnumAbortFile)); ASSERT(hr == S_OK); } }
//
// OnOpenRecvFolder
//
void CAppletWindow::OnOpenRecvFolder(void) { TCHAR szRecvFolder[MAX_PATH];
while (1) { if (S_OK == ::GetRecvFolder(NULL, szRecvFolder)) { ::ShellExecute(NULL, NULL, szRecvFolder, NULL, NULL, SW_SHOWNORMAL); break; } else if (m_UIMode != FTUIMODE_NOUI) { ::MyLoadString(IDS_RECVDLG_DIRNOEXIST, s_szScratchText, szRecvFolder); if (IDYES == ::MessageBox(m_hwndMainUI, s_szScratchText, s_szMSFT, MB_YESNO)) { OnChangeFolder(); } else { break; } } } }
//
// OnChageFolder
//
void OnChangeFolder(void) { BOOL rc; TCHAR szPath[MAX_PATH];
::GetRecvFolder(NULL, szPath); if (::lstrlen(szPath) > MAX_FILE_NAME_LENGTH) { LPTSTR psz = szPath; int i = MAX_FILE_NAME_LENGTH - 1; while (i) { psz = CharNext(psz); i--; } ::lstrcpy(psz, TEXT("...")); } ::MyLoadString(IDS_BROWSETITLE, s_szScratchText, szPath);
if (FBrowseForFolder(szPath, CCHMAX(szPath), s_szScratchText)) { ::GetRecvFolder(szPath, szPath); } }
//
// OnExit
//
void CAppletWindow::OnExit(BOOL fNoQuery) { if ((g_pFileXferApplet->InConf() || g_pFileXferApplet->HasSDK()) && ! g_fShutdownByT120) { // There 2.x node inside the conference
// hide the window
::ShowWindow(m_hwndMainUI, SW_HIDE); m_UIMode = g_fNoUI ? FTUIMODE_NOUI : FTUIMODE_UIHIDDEN; } else if (fNoQuery || QueryShutdown()) { #if defined(TEST_PLUGABLE) && defined(_DEBUG)
::OnPluggableEnd(); #endif
MBFTEngine *pEngine = m_pEngine;
::T120_AppletStatus(APPLET_ID_FT, APPLET_CLOSING);
if (NULL != m_pEngine) { GCCAppPermissionToEnrollInd Ind; ::ZeroMemory(&Ind, sizeof(Ind)); Ind.nConfID = m_pEngine->GetConfID(); Ind.fPermissionGranted = FALSE; m_pEngine->OnPermitToEnrollIndication(&Ind); UnregisterEngine(); }
OnRemoveAllFiles();
::SetWindowLongPtr(m_hwndMainUI, GWLP_USERDATA, 0); SaveWindowPosition(); HWND hwnd = m_hwndMainUI; m_hwndMainUI = NULL; ::DestroyWindow(hwnd);
if (NULL != g_pFileXferApplet) { g_pFileXferApplet->UnregisterWindow(this); g_pFileXferApplet->UnregisterEngine(pEngine); }
Release(); } }
//
// OnHelp
//
void CAppletWindow::OnHelp(void) { DebugEntry(CAppletWindow::OnHelp); ShowNmHelp(s_cszHtmlHelpFile); DebugExitVOID(CAppletWindow::OnHelp); }
//
// OnAbout
//
INT_PTR AboutDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fHandled = FALSE;
switch (uMsg) { case WM_INITDIALOG: { TCHAR szFormat[256]; TCHAR szVersion[512];
::GetDlgItemText(hdlg, IDC_ABOUT_VERSION, szFormat, count_of(szFormat)); ::wsprintf(szVersion, szFormat, VER_PRODUCTRELEASE_STR, VER_PRODUCTVERSION_STR); ::SetDlgItemText(hdlg, IDC_ABOUT_VERSION, szVersion);
fHandled = TRUE; } break;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: case IDCANCEL: case IDCLOSE: switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case BN_CLICKED: ::EndDialog(hdlg, IDCANCEL); break; } break; }
fHandled = TRUE; break; }
return(fHandled); }
void CAppletWindow::OnAbout(void) { ::DialogBoxParam(g_hDllInst, MAKEINTRESOURCE(IDD_ABOUTBOX), m_hwndMainUI, AboutDlgProc, 0); }
BOOL FBrowseForFolder(LPTSTR pszFolder, UINT cchMax, LPCTSTR pszTitle) { LPITEMIDLIST pidlRoot; if(FAILED(SHGetSpecialFolderLocation(HWND_DESKTOP, CSIDL_DRIVES, &pidlRoot))) { return FALSE; }
BROWSEINFO bi; ClearStruct(&bi); bi.hwndOwner = NULL; bi.lpszTitle = pszTitle; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.pidlRoot = pidlRoot;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi); BOOL fRet = (pidl != NULL); if (fRet) { ASSERT(cchMax >= MAX_PATH); SHGetPathFromIDList(pidl, pszFolder); ASSERT(lstrlen(pszFolder) < (int) cchMax); }
// Get the shell's allocator to free PIDLs
LPMALLOC lpMalloc; if (FAILED(SHGetMalloc(&lpMalloc)) && (NULL != lpMalloc)) { if (NULL != pidlRoot) { lpMalloc->Free(pidlRoot); } if (pidl) { lpMalloc->Free(pidl); } lpMalloc->Release(); } return fRet; }
/////////////////////////////////////////////////////////////////
//
// WM_NOTIFY
//
LRESULT OnNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); if (NULL != pWindow) { switch (wParam) { case IDC_LIST_VIEW: pWindow->OnNotifyListView(lParam); break;
default: if (TTN_NEEDTEXT == ((NMHDR *) lParam)->code) { // display the tool tip text
TOOLTIPTEXT *pToolTipText = (TOOLTIPTEXT *) lParam; ULONG_PTR nID;
// get id and hwnd
if (pToolTipText->uFlags & TTF_IDISHWND) { // idFrom is actually the HWND of the tool
nID = ::GetDlgCtrlID((HWND) pToolTipText->hdr.idFrom); } else { nID = pToolTipText->hdr.idFrom; }
// give it to em
pToolTipText->lpszText = MAKEINTRESOURCE(nID); pToolTipText->hinst = g_hDllInst; } break; } }
return 0; }
int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CUiSendFileInfo *pFileInfo1 = (CUiSendFileInfo *) lParam1; CUiSendFileInfo *pFileInfo2 = (CUiSendFileInfo *) lParam2; int iResult;
iResult = 0; // equal, at default
switch (lParamSort) { case (IDS_LV_FILE_NAME - IDS_LV_FILE_NAME): iResult = lstrcmpi(pFileInfo1->GetName(), pFileInfo2->GetName()); break; case (IDS_LV_FILE_SIZE - IDS_LV_FILE_NAME): if (pFileInfo1->GetSize() > pFileInfo2->GetSize()) { iResult = 1; } else if (pFileInfo1->GetSize() < pFileInfo2->GetSize()) { iResult = -1; } break; case (IDS_LV_FILE_STATUS - IDS_LV_FILE_NAME): if ((pFileInfo1->GetTotalSend() == pFileInfo1->GetSize()) >( pFileInfo2->GetTotalSend() == pFileInfo2->GetSize())) { iResult = 1; } else if ((pFileInfo1->GetTotalSend() == pFileInfo1->GetSize()) < (pFileInfo2->GetTotalSend() == pFileInfo2->GetSize())) { iResult = -1; } break;
case (IDS_LV_FILE_MODIFIED - IDS_LV_FILE_NAME): FILETIME fTime1 = pFileInfo1->GetLastWrite(); FILETIME fTime2 = pFileInfo2->GetLastWrite(); iResult = CompareFileTime(&fTime1,&fTime2); break; } return iResult*s_sort; }
void CAppletWindow::OnNotifyListView(LPARAM lParam) { LV_DISPINFO *pDispInfo = (LV_DISPINFO *) lParam; NM_LISTVIEW *pLVN = (NM_LISTVIEW *) lParam; FILETIME ftFileTime; SYSTEMTIME stSystemTime; CUiSendFileInfo *pFileInfo; int iSize; TCHAR szBuffer[MAX_PATH];
switch (pLVN->hdr.code) { case LVN_GETDISPINFO: pFileInfo = (CUiSendFileInfo *) pDispInfo->item.lParam; ASSERT(NULL != pFileInfo);
switch (pDispInfo->item.iSubItem) { case (IDS_LV_FILE_NAME - IDS_LV_FILE_NAME): pDispInfo->item.pszText = pFileInfo->GetName(); break; case (IDS_LV_FILE_SIZE - IDS_LV_FILE_NAME): ::wsprintf(szBuffer, TEXT("%u"), pFileInfo->GetSize()); iSize = GetNumberFormat(LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, szBuffer, NULL, s_szScratchText, MAX_PATH); s_szScratchText[iSize - 4] = '\0'; // remove the trailing ".00"
pDispInfo->item.pszText = s_szScratchText; break; case (IDS_LV_FILE_STATUS - IDS_LV_FILE_NAME): { ULONG cbTotalSend = pFileInfo->GetTotalSend(); ULONG cbFileSize = pFileInfo->GetSize(); s_szScratchText[0] = TEXT('\0');
switch (pFileInfo->GetErrorCode()) { case iMBFT_OK: case iMBFT_MULT_RECEIVER_ABORTED: if (!pFileInfo->GetFileHandle()) break; // handle == NULL, if cbTotalSend == 0, zero length file to be sent.
if (cbTotalSend >= cbFileSize) { ::MyLoadString(IDS_LV_FILE_SENT); } else if (cbTotalSend) { if (m_pEngine) { ::MyLoadString(IDS_LV_FILE_SENDING); } else { ::MyLoadString(IDS_LV_FILE_CANCELED); } } break;
case iMBFT_SENDER_ABORTED: case iMBFT_RECEIVER_ABORTED: case iMBFT_NO_MORE_FILES: ::MyLoadString(IDS_LV_FILE_CANCELED); break;
default: ::MyLoadString(IDS_LV_FILE_FAILED); break; }
pDispInfo->item.pszText = s_szScratchText; } break;
case (IDS_LV_FILE_MODIFIED - IDS_LV_FILE_NAME): ftFileTime = pFileInfo->GetLastWrite(); FileTimeToSystemTime(&ftFileTime, &stSystemTime); iSize = GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &stSystemTime, "MM'/'dd'/'yyyy", s_szScratchText, MAX_PATH); GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &stSystemTime, " hh':'mm tt", &s_szScratchText[iSize - 1], MAX_PATH-iSize-1); pDispInfo->item.pszText = s_szScratchText; break; } break;
case LVN_COLUMNCLICK: { s_sort = s_sort *(-1); BOOL fRet = ListView_SortItems(pLVN->hdr.hwndFrom, ListViewCompareProc, (LPARAM) pLVN->iSubItem); ASSERT(fRet); } break; } }
/////////////////////////////////////////////////////////////////
//
// WM_DROPFILES
//
LRESULT OnDropFiles(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
if (g_fSendAllowed) { return pWindow->OnDropFiles((HANDLE) wParam); } else { ::MyLoadString(IDS_MSGBOX_POL_PREVENT); ::MessageBox(pWindow->GetHwnd(), s_szScratchText, s_szMSFT, MB_OK | MB_ICONSTOP); return 1; } }
LRESULT CAppletWindow::OnDropFiles(HANDLE hDrop) { if (NULL != m_pEngine && m_pEngine->GetPeerCount() > 1) { HRESULT hr;
// get the number of dropped files
ULONG cFiles = ::DragQueryFile((HDROP) hDrop, 0xFFFFFFFF, NULL, 0);
// set up the common portion of list view item
LVITEM lvi; ::ZeroMemory(&lvi, sizeof(lvi)); // lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
// iterate on these files
for (ULONG i = 0; i < cFiles; i++) { BOOL fRet; TCHAR szFile[MAX_PATH];
if (::DragQueryFile((HDROP) hDrop, i, szFile, count_of(szFile))) { DBG_SAVE_FILE_LINE CUiSendFileInfo *pFileInfo = new CUiSendFileInfo(this, NULL, szFile, &fRet); if (NULL != pFileInfo && fRet) { // put it to the list view
lvi.iItem = ListView_GetItemCount(m_hwndListView); lvi.iSubItem = 0; // we are responsible for storing the text to display
lvi.pszText = LPSTR_TEXTCALLBACK; lvi.cchTextMax = MAX_PATH; lvi.lParam = (LPARAM) pFileInfo; int iRet = ListView_InsertItem(m_hwndListView, &lvi); ASSERT(-1 != iRet); // UpdateListView(pFileInfo);
} else { // BUGBUG: we should pop up some error message box here!
::MyLoadString(IDS_INVALID_FILENAME, s_szScratchText, szFile); ::MessageBox(m_hwndMainUI, s_szScratchText, s_szMSFT, MB_OK | MB_ICONSTOP); delete pFileInfo; } } }
::DragFinish((HDROP) hDrop); SetForegroundWindow(m_hwndMainUI);
UpdateUI(); return 0; }
::MyLoadString(IDS_MSGBOX_NO_CONF); ::SetForegroundWindow(m_hwndMainUI); ::MessageBox(m_hwndMainUI, s_szScratchText, s_szMSFT, MB_OK | MB_ICONSTOP); return 1; }
/////////////////////////////////////////////////////////////////
//
// WM_CONTEXTMENU
//
LRESULT OnContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam) { LRESULT rc = 0;
CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
if ((WPARAM) pWindow->GetHwnd() == wParam) { // BUGBUG use TrackPopupMenu to show context sensitive menu
pWindow->OnContextMenuForMainUI(lParam); } else if ((WPARAM) pWindow->GetListView() == wParam) { // BUGBUG use TrackPopupMenu to show context sensitive menu
pWindow->OnContextMenuForListView(lParam); } else { rc = 1; }
return rc; }
enum { MENU_IDX_ADD_FILES, MENU_IDX_REMOVE_FILES, MENU_IDX_BREAK_1, MENU_IDX_SEND_ALL, MENU_IDX_SEND_ONE, MENU_IDX_STOP_SENDING, MENU_IDX_BREAK_2, MENU_IDX_OPEN_RECV_FOLDER, };
static UI_MENU_INFO s_aMenuInfo[] = { { IDS_MENU_ADD_FILES, IDM_ADD_FILES, MF_ENABLED | MF_STRING }, { IDS_MENU_REMOVE_FILES, IDM_REMOVE_FILES, MF_ENABLED | MF_STRING }, { 0, 0, MF_SEPARATOR}, // menu break
{ IDS_MENU_SEND_ALL, IDM_SEND_ALL, MF_ENABLED | MF_STRING }, { IDS_MENU_SEND_ONE, IDM_SEND_ONE, MF_ENABLED | MF_STRING }, { IDS_MENU_STOP_SENDING, IDM_STOP_SENDING, MF_ENABLED | MF_STRING }, { 0, 0, MF_SEPARATOR}, // menu break
{ IDS_MENU_OPEN_RECV_FOLDER, IDM_OPEN_RECV_FOLDER, MF_ENABLED | MF_STRING }, { IDS_MENU_CHANGE_FOLDER, IDM_CHANGE_FOLDER, MF_ENABLED | MF_STRING }, { 0, 0, MF_SEPARATOR }, // menu break
{ IDS_MENU_EXIT, IDM_EXIT, MF_ENABLED | MF_STRING }, };
void CAppletWindow::SetContextMenuStates(void) { if (g_fSendAllowed) { BOOL fMoreThanOne = (NULL != m_pEngine) && (m_pEngine->GetPeerCount() > 1); s_aMenuInfo[MENU_IDX_ADD_FILES].nFlags = fMoreThanOne ? (MF_ENABLED | MF_STRING) : (MF_GRAYED | MF_STRING);
ULONG cItems = ListView_GetItemCount(m_hwndListView); s_aMenuInfo[MENU_IDX_REMOVE_FILES].nFlags = cItems ? (MF_ENABLED | MF_STRING) : (MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_SEND_ALL].nFlags = (fMoreThanOne && ! m_nCurrSendEventHandle && HasUnSentFiles(TRUE)) ? (MF_ENABLED | MF_STRING) : (MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_SEND_ONE].nFlags = (fMoreThanOne && ! m_nCurrSendEventHandle && HasUnSentFiles(FALSE)) ? (MF_ENABLED | MF_STRING) : (MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_STOP_SENDING].nFlags = m_nCurrSendEventHandle ? (MF_ENABLED | MF_STRING) : (MF_GRAYED | MF_STRING); } else { s_aMenuInfo[MENU_IDX_ADD_FILES].nFlags =(MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_REMOVE_FILES].nFlags =(MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_SEND_ALL].nFlags = (MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_SEND_ONE].nFlags = (MF_GRAYED | MF_STRING); s_aMenuInfo[MENU_IDX_STOP_SENDING].nFlags = (MF_GRAYED | MF_STRING); } }
void CAppletWindow::OnContextMenuForMainUI(LPARAM lParam) { SetContextMenuStates(); CreateMenu(lParam, count_of(s_aMenuInfo), &s_aMenuInfo[0]); }
void CAppletWindow::OnContextMenuForListView(LPARAM lParam) { SetContextMenuStates(); CreateMenu(lParam, 6, &s_aMenuInfo[0]); }
void CAppletWindow::CreateMenu(LPARAM lParam, ULONG cItems, UI_MENU_INFO aMenuInfo[]) { HMENU hMenu = ::CreatePopupMenu(); if (NULL != hMenu) { for (ULONG i = 0; i < cItems; i++) { if (aMenuInfo[i].idCommand) { if (::MyLoadString(aMenuInfo[i].idString)) { ::AppendMenu(hMenu, aMenuInfo[i].nFlags, aMenuInfo[i].idCommand, s_szScratchText); } } else { ::AppendMenu(hMenu, aMenuInfo[i].nFlags, 0, 0); } }
::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RIGHTBUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, // reserved, must be zero
m_hwndMainUI, NULL); // ignore
} }
/////////////////////////////////////////////////////////////////
//
// WM_SIZE
//
LRESULT OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
pWindow->OnSizeToolBar(); pWindow->OnSizeStatusBar(); pWindow->OnSizeListView();
return 0; }
void CAppletWindow::OnSizeToolBar(void) { RECT rcWindow; SIZE szToolBar;
::GetClientRect(m_hwndMainUI, &rcWindow); m_pToolbar->GetDesiredSize(&szToolBar);
ULONG cx = rcWindow.right - rcWindow.left; ULONG cy = szToolBar.cy;; ULONG x = 0; ULONG y = 0;
::MoveWindow(m_pToolbar->GetWindow(), x, y, cx, cy, TRUE); }
void CAppletWindow::OnSizeStatusBar(void) { RECT rcWindow, rcStatusBar; ::GetClientRect(m_hwndMainUI, &rcWindow); ::GetWindowRect(m_hwndStatusBar, &rcStatusBar);
ULONG cx = rcWindow.right - rcWindow.left; ULONG cy = rcStatusBar.bottom - rcStatusBar.top; ULONG x = 0; ULONG y = rcWindow.bottom - cy;
::MoveWindow(m_hwndStatusBar, x, y, cx, cy, TRUE); ::MoveWindow(m_hwndProgressBar, x + cx/2, y, cx/2 - 40, cy, TRUE);
int aWidths[NUM_STATUS_BAR_PARTS]; aWidths[0] = cx / 2; // conference state
aWidths[1] = cx - 40; // transfer name
aWidths[2] = -1; // transfer percentage
ASSERT(3 == NUM_STATUS_BAR_PARTS);
::SendMessage(m_hwndStatusBar, SB_SETPARTS, NUM_STATUS_BAR_PARTS, (LPARAM) &aWidths[0]); }
void CAppletWindow::OnSizeListView(void) { // get the size and position of the main window
RECT rcWindow, rcToolBar, rcStatusBar; SIZE szToolBar; ::GetClientRect(m_hwndMainUI, &rcWindow); m_pToolbar->GetDesiredSize(&szToolBar); ::GetWindowRect(m_hwndStatusBar, &rcStatusBar);
ULONG x = 0; ULONG y = szToolBar.cy - 1; ULONG cx = rcWindow.right - rcWindow.left; ULONG cy = rcWindow.bottom - rcWindow.top - y - (rcStatusBar.bottom - rcStatusBar.top) + 1;
::MoveWindow(m_hwndListView, x, y, cx, cy, TRUE); }
/////////////////////////////////////////////////////////////////
//
// WM_HELP
//
LRESULT OnHelp(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
pWindow->OnHelp(); return 0; }
/////////////////////////////////////////////////////////////////
//
// WM_CLOSE
//
LRESULT OnClose(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
if (NULL != pWindow) { pWindow->OnExit(); }
return 0; }
/////////////////////////////////////////////////////////////////
//
// WM_INITMENUPOPUP
//
/*
LRESULT OnInitMenuPopup(HWND hwnd, WPARAM wParam, LPARAM lParam) { if (0 != HIWORD(lParam)) // System menu flag
{ HMENU hMenu = (HMENU) wParam; // handle of pop-up menu
::EnableMenuItem(hMenu, SC_MAXIMIZE, MF_GRAYED); ::EnableMenuItem(hMenu, SC_SIZE, MF_GRAYED); return 0; } return 1; } */
/////////////////////////////////////////////////////////////////
//
// WM_MENUSELECT
//
LRESULT OnMenuSelect(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
if (NULL != pWindow) { pWindow->OnMenuSelect(GET_WM_MENUSELECT_CMD(wParam, lParam), GET_WM_MENUSELECT_FLAGS(wParam, lParam), GET_WM_MENUSELECT_HMENU(wParam, lParam)); }
return 0; }
/////////////////////////////////////////////////////////////////
//
// WM_INITMENUPOPUP
//
LRESULT OnGetMinMaxInfo(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (NULL != pWindow) { pWindow->OnGetMinMaxInfo((LPMINMAXINFO) lParam); return 0; } return 1; }
void CAppletWindow::OnGetMinMaxInfo(LPMINMAXINFO pMMI) { static BOOL s_fEnterBefore = FALSE;
static SIZE s_csFrame; static SIZE s_csSeparator; static SIZE s_csScrollBars; static SIZE s_csToolBar; static SIZE s_csStatusBar; static SIZE s_csSum;
if (! s_fEnterBefore) { s_fEnterBefore = TRUE;
s_csFrame.cx = ::GetSystemMetrics(SM_CXSIZEFRAME); s_csFrame.cy = ::GetSystemMetrics(SM_CYSIZEFRAME);
s_csSeparator.cx = ::GetSystemMetrics(SM_CXEDGE); s_csSeparator.cy = ::GetSystemMetrics(SM_CYEDGE);
s_csScrollBars.cx = ::GetSystemMetrics(SM_CXVSCROLL); s_csScrollBars.cy = ::GetSystemMetrics(SM_CYHSCROLL);
m_pToolbar->GetDesiredSize(&s_csToolBar);
RECT rcStatusBar; ::GetWindowRect(m_hwndStatusBar, &rcStatusBar); s_csStatusBar.cx = rcStatusBar.right - rcStatusBar.left; s_csStatusBar.cy = rcStatusBar.bottom - rcStatusBar.top;
s_csSum.cx = (s_csFrame.cx << 1); s_csSum.cy = (s_csFrame.cy << 1) + (s_csSeparator.cy << 3) + s_csToolBar.cy + (rcStatusBar.bottom - rcStatusBar.top) + ::GetSystemMetrics( SM_CYCAPTION ) + ::GetSystemMetrics( SM_CYMENU ); }
RECT rcListViewItem; SIZE csListView; csListView.cx = 0; for (ULONG i = 0; i < NUM_LIST_VIEW_COLUMNS; i++) { csListView.cx += ListView_GetColumnWidth(m_hwndListView, i); } if (ListView_GetItemRect(m_hwndListView, 0, &rcListViewItem, LVIR_BOUNDS)) { csListView.cy = 20 + 3 * (rcListViewItem.bottom - rcListViewItem.top); } else { csListView.cy = 20 + 30; }
// Set the minimum width and height of the window
pMMI->ptMinTrackSize.x = s_csSum.cx + max(s_csToolBar.cx, csListView.cx); pMMI->ptMinTrackSize.y = s_csSum.cy + csListView.cy;
//
// Retrieves the size of the work area on the primary display monitor. The work
// area is the portion of the screen not obscured by the system taskbar or by
// application desktop toolbars
//
RECT rcWorkArea; ::SystemParametersInfo( SPI_GETWORKAREA, 0, (&rcWorkArea), NULL );
SIZE csMaxSize; csMaxSize.cx = rcWorkArea.right - rcWorkArea.left; csMaxSize.cy = rcWorkArea.bottom - rcWorkArea.top;
pMMI->ptMaxPosition.x = 0; pMMI->ptMaxPosition.y = 0; pMMI->ptMaxSize.x = csMaxSize.cx; pMMI->ptMaxSize.y = csMaxSize.cy; pMMI->ptMaxTrackSize.x = csMaxSize.cx; pMMI->ptMaxTrackSize.y = csMaxSize.cy; }
/////////////////////////////////////////////////////////////////
//
// WM_QUERYENDSESSION
//
LRESULT OnQueryEndSession(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA); ASSERT(NULL != pWindow);
if (NULL != pWindow) { return pWindow->QueryShutdown(); // TRUE: ok to send session; FALSE, no.
} return TRUE; // ok to end session
}
/////////////////////////////////////////////////////////////////
//
// WM_ENDSESSION
//
LRESULT OnEndSession(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (wParam && NULL != pWindow) { pWindow->OnExit(TRUE); }
return 0; }
/////////////////////////////////////////////////////////////////
//
// WM_DRAWITEM
//
LRESULT OnDrawItem(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (wParam && NULL != pWindow) { pWindow->DrawItem((DRAWITEMSTRUCT *)lParam); }
return 0; }
/////////////////////////////////////////////////////////////////
//
// WM_SEND_NEXT
//
LRESULT OnSendNext(HWND hwnd, WPARAM wParam, LPARAM lParam) { CAppletWindow *pWindow = (CAppletWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (NULL != pWindow) { pWindow->OnSendAll(); pWindow->UpdateUI(); }
return 0; }
/////////////////////////////////////////////////////////////////
//
// Main windows procedure
//
LRESULT CALLBACK FtMainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT rc = 0;
switch (uMsg) { case WM_CREATE: rc = ::OnCreate(hwnd, wParam, lParam); break;
case WM_COMMAND: rc = ::OnCommand(hwnd, wParam, lParam); break;
case WM_NOTIFY: rc = ::OnNotify(hwnd, wParam, lParam); break;
case WM_DROPFILES: rc = ::OnDropFiles(hwnd, wParam, lParam); break;
case WM_CONTEXTMENU: rc = ::OnContextMenu(hwnd, wParam, lParam); break;
case WM_SIZE: rc = ::OnSize(hwnd, wParam, lParam); break;
case WM_HELP: rc = ::OnHelp(hwnd, wParam, lParam); break;
case WM_DRAWITEM: rc = ::OnDrawItem(hwnd, wParam, lParam); break;
case WM_CLOSE: rc = ::OnClose(hwnd, wParam, lParam); break;
case WM_INITMENUPOPUP: // rc = ::OnInitMenuPopup(hwnd, wParam, lParam);
break;
case WM_MENUSELECT: rc = ::OnMenuSelect(hwnd, wParam, lParam); break;
case WM_GETMINMAXINFO: rc = ::OnGetMinMaxInfo(hwnd, wParam, lParam); break;
case WM_QUERYENDSESSION: rc = OnQueryEndSession(hwnd, wParam, lParam); break;
case WM_ENDSESSION: rc = ::OnEndSession(hwnd, wParam, lParam); break;
case WM_SEND_NEXT: rc = ::OnSendNext(hwnd, wParam, lParam); break;
#if defined(TEST_PLUGABLE) && defined(_DEBUG)
case WM_PLUGABLE_SOCKET: rc = ::OnPluggableSocket(hwnd, wParam, lParam); break; #endif
default: rc = ::DefWindowProc(hwnd, uMsg, wParam, lParam); break; }
return rc; }
/////////////////////////////////////////////////////////////////
//
// OnEngineNotify
//
void CAppletWindow::OnEngineNotify(MBFTMsg *pMsg) { BOOL fHeartBeat = FALSE;
switch (pMsg->GetMsgType()) { case EnumFileOfferNotifyMsg: if (m_UIMode != FTUIMODE_NOUI) { HandleFileOfferNotify((FileOfferNotifyMsg *) pMsg); } break;
case EnumFileTransmitMsg: if (m_UIMode != FTUIMODE_NOUI) { HandleProgressNotify((FileTransmitMsg *) pMsg); } fHeartBeat = TRUE; break;
case EnumFileErrorMsg: if (m_UIMode != FTUIMODE_NOUI) { HandleErrorNotify((FileErrorMsg *) pMsg); } break;
case EnumPeerMsg: HandlePeerNotification((PeerMsg *) pMsg); break;
case EnumInitUnInitNotifyMsg: HandleInitUninitNotification((InitUnInitNotifyMsg *) pMsg); break;
case EnumFileEventEndNotifyMsg: if (m_UIMode != FTUIMODE_NOUI) { HandleFileEventEndNotification((FileEventEndNotifyMsg *) pMsg); } break;
default: ASSERT(0); break; } // switch
}
void CAppletWindow::HandleFileOfferNotify(FileOfferNotifyMsg *pMsg) { HRESULT hr = S_OK; if (g_fRecvAllowed) { DBG_SAVE_FILE_LINE CUiRecvFileInfo *pRecvFileInfo = new CUiRecvFileInfo(pMsg, &hr); if (NULL != pRecvFileInfo && S_OK == hr) { if (NULL != m_pEngine) { DBG_SAVE_FILE_LINE CRecvDlg *pDlg = new CRecvDlg(this, m_pEngine->GetConfID(), pMsg->m_NodeID, pMsg->m_EventHandle, pRecvFileInfo, &hr); if (NULL != pDlg && S_OK == hr) { DBG_SAVE_FILE_LINE if (S_OK == m_pEngine->SafePostMessage( new FileTransferControlMsg( pMsg->m_EventHandle, pMsg->m_hFile, pRecvFileInfo->GetRecvFolder(), pMsg->m_szFileName, FileTransferControlMsg::EnumAcceptFile))) { return; } else { ERROR_OUT(("CAppletWindow::HandleFileOfferNotify: cannot confirm file offer")); } } else { ERROR_OUT(("CAppletWindow::HandleFileOfferNotify: cannot allocate CRecvDlg, hr=0x%x", hr)); } delete pDlg; } else { ERROR_OUT(("CAppletWindow::HandleFileOfferNotify: no file transfer engine")); } } else { ERROR_OUT(("CAppletWindow::HandleFileOfferNotify: cannot allocate CUiRecvFileInfo, hr=0x%x", hr)); } delete pRecvFileInfo; } else { DBG_SAVE_FILE_LINE if (S_OK != m_pEngine->SafePostMessage( new FileTransferControlMsg( pMsg->m_EventHandle, pMsg->m_hFile, NULL, pMsg->m_szFileName, FileTransferControlMsg::EnumRejectFile))) { ERROR_OUT(("CAppletWindow::HandleFileOfferNotify: cannot confirm file offer")); } } }
void CAppletWindow::HandleProgressNotify(FileTransmitMsg *pMsg) { CRecvDlg *pDlg = NULL; MBFT_NOTIFICATION wMBFTCode = (MBFT_NOTIFICATION) pMsg->m_TransmitStatus; ULONG totalSent = 0; ULONG fileSize = 0; ULONG percentSent = 0;
switch (wMBFTCode) { case iMBFT_FILE_SEND_BEGIN: // fall through... because the file start PDU can have data.
case iMBFT_FILE_SEND_PROGRESS: if (NULL != m_pCurrSendFileInfo) { ASSERT(m_nCurrSendEventHandle == pMsg->m_EventHandle); ASSERT(m_pCurrSendFileInfo->GetFileHandle() == pMsg->m_hFile); ASSERT(m_pCurrSendFileInfo->GetSize() == pMsg->m_FileSize); fileSize = m_pCurrSendFileInfo->GetSize(); totalSent = m_pCurrSendFileInfo->GetTotalSend();
m_pCurrSendFileInfo->SetTotalSend(pMsg->m_BytesTransmitted);
percentSent = _GetPercent(totalSent, fileSize)*10;
if(m_pCurrSendFileInfo->GetPercentSent()!= percentSent || fileSize == totalSent) { UpdateListView(m_pCurrSendFileInfo); UpdateStatusBar(); m_pCurrSendFileInfo->SetPercentSent(percentSent); } } break;
break;
case iMBFT_FILE_SEND_END: if (NULL != m_pCurrSendFileInfo) { UpdateListView(m_pCurrSendFileInfo); UpdateStatusBar(); } break;
case iMBFT_FILE_RECEIVE_BEGIN: // fall through... because the file start PDU can have data.
case iMBFT_FILE_RECEIVE_PROGRESS: pDlg = FindDlgByHandles(pMsg->m_EventHandle, pMsg->m_hFile); if (NULL != pDlg) { pDlg->OnProgressUpdate(pMsg); } break;
case iMBFT_FILE_RECEIVE_END: // doing nothing...
break;
default: ASSERT(0); break; } }
void CAppletWindow::HandleErrorNotify(FileErrorMsg *pMsg) { MBFTFILEHANDLE nFileHandle = pMsg->m_hFile; if(LOWORD(nFileHandle) == LOWORD(_iMBFT_PROSHARE_ALL_FILES)) { nFileHandle = _iMBFT_PROSHARE_ALL_FILES; }
if (m_nCurrSendEventHandle == pMsg->m_EventHandle && m_pCurrSendFileInfo->GetFileHandle() == nFileHandle) { m_pCurrSendFileInfo->SetErrorCode((MBFT_ERROR_CODE) pMsg->m_ErrorCode);
UINT idString; switch ((MBFT_ERROR_CODE) pMsg->m_ErrorCode) { case iMBFT_OK: idString = 0; break; case iMBFT_SENDER_ABORTED: case iMBFT_RECEIVER_ABORTED: case iMBFT_NO_MORE_FILES: idString = IDS_MSGBOX2_CANCELED; break; case iMBFT_MULT_RECEIVER_ABORTED: idString = IDS_MSGBOX2_MULT_CANCEL; break; // case iMBFT_RECEIVER_REJECTED:
default: idString = IDS_MSGBOX2_SEND_FAILED; break; } if (idString) { if (! m_pCurrSendFileInfo->HasShownUI()) { if (::MyLoadString(idString, s_szScratchText, m_pCurrSendFileInfo->GetName())) { m_pCurrSendFileInfo->SetShowUI(); ::MsgBox2(this, s_szScratchText); } else { ASSERT(0); } } }
UpdateListView(m_pCurrSendFileInfo); UpdateStatusBar();
ClearSendInfo(TRUE); if (! idString) { // send the next one now
if (m_fSendALL) { ::PostMessage(m_hwndMainUI, WM_SEND_NEXT, 0, 0); } } } else { CRecvDlg *pDlg = FindDlgByHandles(pMsg->m_EventHandle, nFileHandle); if (NULL != pDlg) { switch ((MBFT_ERROR_CODE) pMsg->m_ErrorCode) { case iMBFT_RECEIVER_ABORTED: case iMBFT_MULT_RECEIVER_ABORTED: pDlg->OnCanceled(); break; default: pDlg->OnRejectedFile(); break; } } else { switch((MBFT_ERROR_CODE) pMsg->m_ErrorCode) { case iMBFT_INVALID_PATH: ::MyLoadString(IDS_MSGBOX2_INVALID_DIRECTORY, s_szScratchText, pMsg->m_stFileInfo.szFileName); break;
case iMBFT_DIRECTORY_FULL_ERROR: ::MyLoadString(IDS_MSGBOX2_DIRECTORY_FULL, s_szScratchText, pMsg->m_stFileInfo.lFileSize, pMsg->m_stFileInfo.szFileName); break;
case iMBFT_FILE_ACCESS_DENIED: ::MyLoadString(IDS_MSGBOX2_FILE_CREATE_FAILED, s_szScratchText, pMsg->m_stFileInfo.szFileName); break;
default: return; } ::MsgBox2(this, s_szScratchText); } } }
void CAppletWindow::HandlePeerNotification(PeerMsg *pMsg) { m_pToolbar->HandlePeerNotification(m_pEngine->GetConfID(), m_pEngine->GetNodeID(), pMsg); }
void CAppletWindow::HandleInitUninitNotification(InitUnInitNotifyMsg *pMsg) { if (pMsg->m_iNotifyMessage == EnumInvoluntaryUnInit) { UnregisterEngine(); } }
void CAppletWindow::HandleFileEventEndNotification(FileEventEndNotifyMsg *pMsg) { if (m_nCurrSendEventHandle == pMsg->m_EventHandle) { ClearSendInfo(TRUE); // send the next one now
if (m_fSendALL) { ::PostMessage(m_hwndMainUI, WM_SEND_NEXT, 0, 0); } } }
/////////////////////////////////////////////////////////////////
//
// Main UI methods
//
void CAppletWindow::BringToFront(void) { if (NULL != m_hwndMainUI) { int nCmdShow = SW_SHOW;
WINDOWPLACEMENT wp; ::ZeroMemory(&wp, sizeof(wp)); wp.length = sizeof(wp);
if (::GetWindowPlacement(m_hwndMainUI, &wp)) { if (SW_MINIMIZE == wp.showCmd || SW_SHOWMINIMIZED == wp.showCmd) { // The window is minimized - restore it:
nCmdShow = SW_RESTORE; } }
// show the window now
::ShowWindow(m_hwndMainUI, nCmdShow); m_UIMode = FTUIMODE_SHOWUI; // bring it to the foreground
::SetForegroundWindow(m_hwndMainUI); } }
void CAppletWindow::ClearSendInfo(BOOL fUpdateUI) { m_pCurrSendFileInfo = NULL; m_nCurrSendEventHandle = NULL;
if (fUpdateUI) { UpdateUI(); } }
void CAppletWindow::ClearRecvInfo(void) { CRecvDlg *pDlg; while (NULL != (pDlg = m_RecvDlgList.Get())) { ::EndDialog(pDlg->GetHwnd(), IDCLOSE); pDlg->Release(); } }
BOOL CAppletWindow::HasUnSentFiles(BOOL fUnSentOnly) { BOOL fRc = FALSE; ULONG cItems = ListView_GetItemCount(m_hwndListView); CUiSendFileInfo *pFileInfo; LVITEM lvi;
if (!fUnSentOnly && cItems) { return TRUE; }
::ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; // examine each item one by one
for (ULONG i = 0; i < cItems; i++, pFileInfo = NULL) { lvi.iItem = i; BOOL fRet = ListView_GetItem(m_hwndListView, &lvi); ASSERT(fRet); pFileInfo = (CUiSendFileInfo *) lvi.lParam; if (!pFileInfo->GetFileHandle()) // if file handle is not zero, then it has been sent or cancelled
{ fRc = TRUE; break; } } return fRc; }
void CAppletWindow::UpdateUI(void) { UpdateTitle(); UpdateMenu(); UpdateToolBar(); UpdateStatusBar(); }
void CAppletWindow::UpdateTitle(void) { UINT captionID; if ((! m_pEngine) || (m_pEngine->GetPeerCount() <= 1)) { captionID = IDS_MSFT_NOT_IN_CALL_WINDOW_CAPTION; } else { captionID = IDS_MSFT_IN_CALL_WINDOW_CAPTION; }
::LoadString(g_hDllInst, captionID, s_szMSFT, sizeof(s_szMSFT));
SetWindowText(m_hwndMainUI, s_szMSFT); }
void CAppletWindow::UpdateMenu(void) { HMENU hMenu = ::GetMenu(m_hwndMainUI); if (NULL != hMenu) { if (g_fSendAllowed) { BOOL fMoreThanOne = (NULL != m_pEngine) && (m_pEngine->GetPeerCount() > 1); ::EnableMenuItem(hMenu, IDM_ADD_FILES, fMoreThanOne ? MF_ENABLED : MF_GRAYED);
ULONG cItems = ListView_GetItemCount(m_hwndListView); ::EnableMenuItem(hMenu, IDM_REMOVE_FILES, cItems ? MF_ENABLED : MF_GRAYED); ::EnableMenuItem(hMenu, IDM_SEND_ALL, (fMoreThanOne && ! m_nCurrSendEventHandle && HasUnSentFiles(TRUE)) ? MF_ENABLED : MF_GRAYED); ::EnableMenuItem(hMenu, IDM_SEND_ONE, (fMoreThanOne && ! m_nCurrSendEventHandle && HasUnSentFiles(FALSE)) ? MF_ENABLED : MF_GRAYED); ::EnableMenuItem(hMenu, IDM_STOP_SENDING, m_nCurrSendEventHandle ? MF_ENABLED : MF_GRAYED); } else { ::EnableMenuItem(hMenu, IDM_ADD_FILES, MF_GRAYED); ::EnableMenuItem(hMenu, IDM_REMOVE_FILES, MF_GRAYED); ::EnableMenuItem(hMenu, IDM_SEND_ALL, MF_GRAYED); ::EnableMenuItem(hMenu, IDM_SEND_ONE, MF_GRAYED); ::EnableMenuItem(hMenu, IDM_STOP_SENDING, MF_GRAYED); } } }
void CAppletWindow::UpdateToolBar(void) { int iFlags[count_of(buttons)];
::ZeroMemory(iFlags, sizeof(iFlags));
iFlags[2] = iFlags[5] = iFlags[6] = 1; // separators
iFlags[7] = 1; // open recv folders
if (g_fSendAllowed) { BOOL fMoreThanOne = (NULL != m_pEngine) && (m_pEngine->GetPeerCount() > 1); ULONG cItems = ListView_GetItemCount(m_hwndListView); iFlags[0] = fMoreThanOne ? TRUE : FALSE; // Add files
iFlags[1] = cItems ? TRUE : FALSE; // Delete files
iFlags[3] = (fMoreThanOne && ! m_nCurrSendEventHandle && HasUnSentFiles(TRUE)) ? TRUE : FALSE; // Send file(s)
iFlags[4] = m_nCurrSendEventHandle ? TRUE : FALSE; // Stop sending
m_pToolbar->UpdateButton(iFlags); } else { m_pToolbar->UpdateButton(iFlags); } }
void CAppletWindow::UpdateStatusBar(void) { int idString, iPos = 0; HICON hIcon; RECT rc;
// set the text in part 0
s_szScratchText[0] = TEXT('\0'); if ((NULL != m_pEngine) && (NULL != m_pCurrSendFileInfo)) { idString = IDS_STBAR_SENDING_XYZ; ::MyLoadString(idString, s_szScratchText, m_pCurrSendFileInfo->GetName()); } else if (NULL == m_pEngine) { ::MyLoadString(IDS_STBAR_NOT_IN_CALL); } else { ::MyLoadString(IDS_STBAR_NOT_TRANSFERING); } ::SendMessage(m_hwndStatusBar, SB_SETTEXT, SBP_TRANSFER_FILE, (LPARAM) s_szScratchText); // set the progres bar in part 1
if ((NULL != m_pCurrSendFileInfo)&&m_pCurrSendFileInfo->GetSize()) { iPos = (int)_GetPercent(m_pCurrSendFileInfo->GetTotalSend(), m_pCurrSendFileInfo->GetSize()); } ::SendMessage(m_hwndStatusBar, SB_GETRECT, SBP_PROGRESS, (LPARAM)&rc); ::MoveWindow(m_hwndProgressBar, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE); ::SendMessage(m_hwndProgressBar, PBM_SETPOS, iPos, 0); // set the icon in part 2
hIcon = (NULL != m_pEngine) ? m_hIconInCall : m_hIconNotInCall; ::SendMessage(m_hwndStatusBar, SB_SETTEXT, SBP_SBICON | SBT_OWNERDRAW, (LPARAM)hIcon); }
void CAppletWindow::UpdateListView(CUiSendFileInfo *pFileInfo) { LVFINDINFO lvfi; ::ZeroMemory(&lvfi, sizeof(lvfi)); lvfi.flags = LVFI_PARAM; lvfi.lParam = (LPARAM) pFileInfo; int iItem = ListView_FindItem(m_hwndListView, -1, &lvfi);
if (-1 != iItem) { for (ULONG i = 0; i < NUM_LIST_VIEW_COLUMNS; i++) { ListView_SetItemText(m_hwndListView, iItem, i, LPSTR_TEXTCALLBACK); } } }
////////////////////////////////////////////////////////////////////
//
// Save window position for File Transfer
//
void CAppletWindow::SaveWindowPosition(void) { RECT rcWnd; RegEntry reWnd( FILEXFER_KEY, HKEY_CURRENT_USER);
// If we are not maximized or minimized
if (!::IsZoomed(m_hwndMainUI) && !::IsIconic(m_hwndMainUI)) { ::GetWindowRect(m_hwndMainUI, &rcWnd);
reWnd.SetValue (REGVAL_WINDOW_XPOS, rcWnd.left); reWnd.SetValue (REGVAL_WINDOW_YPOS, rcWnd.top); reWnd.SetValue (REGVAL_WINDOW_WIDTH, rcWnd.right - rcWnd.left); reWnd.SetValue (REGVAL_WINDOW_HEIGHT, rcWnd.bottom - rcWnd.top); } }
void CAppletWindow::FocusNextRecvDlg(void) { if (!m_RecvDlgList.IsEmpty()) { m_RecvDlgList.Reset(); CRecvDlg *pRecvDlg = m_RecvDlgList.Iterate(); if (pRecvDlg) { SetFocus(pRecvDlg->GetHwnd()); } } }
void CAppletWindow::FocusNextErrorDlg(void) { if (!m_ErrorDlgList.IsEmpty()) { m_ErrorDlgList.Reset(); HWND hwndErrorDlg = m_ErrorDlgList.Iterate(); if (hwndErrorDlg) { ::SetFocus(hwndErrorDlg); } } }
/////////////////////////////////////////////////////////////////
//
// Utilities
//
LPTSTR PathNameToFileName(LPTSTR pszPathName) { LPTSTR psz = pszPathName; while (*psz != '\0') { BOOL fDirChar = (*psz == TEXT('\\')); psz = ::CharNext(psz); if (fDirChar) { pszPathName = psz; } } return pszPathName; }
int MyLoadString(UINT idStr) { s_szScratchText[0] = TEXT('\0'); int iRet = ::LoadString(g_hDllInst, idStr, s_szScratchText, MAX_PATH); ASSERT(iRet); return iRet; }
int MyLoadString(UINT idStr, LPTSTR pszDstStr) { *pszDstStr = TEXT('\0'); int iRet = ::LoadString(g_hDllInst, idStr, pszDstStr, MAX_PATH); ASSERT(iRet); return iRet; }
int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement) { int cch; TCHAR szText[MAX_PATH];
cch = ::LoadString(g_hDllInst, idStr, szText, count_of(szText)); if (cch) { ::wsprintf(pszDstStr, szText, pszElement); } else { ASSERT(0); *pszDstStr = TEXT('\0'); } return cch; }
int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement1, LPTSTR pszElement2) { int cch; TCHAR szText[MAX_PATH];
cch = ::LoadString(g_hDllInst, idStr, szText, count_of(szText)); if (cch) { ::wsprintf(pszDstStr, szText, pszElement1, pszElement2); } else { ASSERT(0); *pszDstStr = TEXT('\0'); } return cch; }
void LoadDefaultStrings(void) { // load file transfer name
s_szMSFT[0] = TEXT('\0'); ::LoadString(g_hDllInst, IDS_MSFT_NOT_IN_CALL_WINDOW_CAPTION, s_szMSFT, count_of(s_szMSFT)); }
/////////////////////////////////////////////////////////////////
//
// CUiSendFileInfo
//
CUiSendFileInfo::CUiSendFileInfo(CAppletWindow *pWindow, TCHAR szDir[], TCHAR szFile[], BOOL *pfRet) : m_nFileHandle(0), m_cbTotalSend(0), m_eSendErrorCode(iMBFT_OK), m_percentSent(-1), m_fAlreadyShowUI(FALSE), m_pszFullName(NULL) { *pfRet = FALSE; // failure as default
HANDLE hFile;
// build a full name
hFile = GetOpenFile(pWindow, szDir, szFile, TRUE); // try to resolve
if (INVALID_HANDLE_VALUE == hFile) { hFile = GetOpenFile(pWindow, szDir, szFile, FALSE); } if (INVALID_HANDLE_VALUE != hFile) { // get the file info
::ZeroMemory(&m_FileInfo, sizeof(m_FileInfo)); BOOL rc = ::GetFileInformationByHandle(hFile, &m_FileInfo); ::CloseHandle(hFile); if (rc) { ASSERT(0 == m_FileInfo.nFileSizeHigh);
// make sure the file size is smaller than what the policy says
if ((! g_cbMaxSendFileSize) || GetSize() <= g_cbMaxSendFileSize * 1024) { *pfRet = TRUE; } else if (pWindow->GetUIMode() != FTUIMODE_NOUI) { ::MyLoadString(IDS_MSGBOX_SEND_BIG_FILE, s_szScratchText, (LPTSTR) g_cbMaxSendFileSize, m_pszFileName); ::MessageBox(pWindow->GetHwnd(), s_szScratchText, s_szMSFT, MB_OK | MB_ICONSTOP); } } } }
CUiSendFileInfo::~CUiSendFileInfo(void) { delete m_pszFullName; }
HANDLE CUiSendFileInfo::GetOpenFile(CAppletWindow *pWindow, TCHAR szDir[], TCHAR szFile[], BOOL fResolve) { // build a full name
ULONG cch; TCHAR szName[MAX_PATH*2]; HANDLE hFile = INVALID_HANDLE_VALUE;
if ((NULL != szDir)&&(!_StrChr(szFile, '\\'))) { cch = ::lstrlen(szDir); ::wsprintf(szName, (TEXT('\\') == szDir[cch-1]) ? TEXT("%s%s") : TEXT("%s\\%s"), szDir, szFile); } else { // file name is the full name
::lstrcpy(szName, szFile); }
// resolve shortcut if necessary
cch = ::lstrlen(szName) + 1; if (fResolve&&(cch >= 4)) { if (! lstrcmpi(&szName[cch-5], TEXT(".lnk"))) { pWindow->ResolveShortcut(szName, szName); cch = ::lstrlen(szName) + 1; } }
if (m_pszFullName) { delete [] m_pszFullName; }
// construct the full name
DBG_SAVE_FILE_LINE m_pszFullName = new TCHAR[cch]; if (NULL != m_pszFullName) { ::CopyMemory(m_pszFullName, szName, cch * sizeof(TCHAR)); m_pszFileName = ::PathNameToFileName(m_pszFullName);
// open the file
hFile = ::CreateFile(m_pszFullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } return hFile; }
/////////////////////////////////////////////////////////////////
//
// CUiRecvFileInfo
//
CUiRecvFileInfo::CUiRecvFileInfo(FileOfferNotifyMsg *pMsg, HRESULT *pHr) : m_nFileHandle(pMsg->m_hFile), m_FileDateTime(pMsg->m_FileDateTime), m_cbFileSize(pMsg->m_FileSize), m_cbTotalRecvSize(0), m_pszFullName(NULL), m_pszRecvFolder(NULL) { *pHr = E_FAIL; // failure, at default
ULONG cchTotal = ::lstrlen(pMsg->m_szFileName);
// construct the full name
DBG_SAVE_FILE_LINE m_pszFullName = new TCHAR[cchTotal+2]; if (NULL != m_pszFullName) { // construct full name and file name
strcpy(m_pszFullName, pMsg->m_szFileName); m_pszFileName = PathNameToFileName(m_pszFullName); ULONG cchFile = ::lstrlen(m_pszFileName); DBG_SAVE_FILE_LINE m_pszRecvFolder = new TCHAR[cchTotal - cchFile + 2]; if (NULL != m_pszRecvFolder) { ::CopyMemory(m_pszRecvFolder, m_pszFullName, cchTotal - cchFile); m_pszRecvFolder[cchTotal - cchFile - 1] = TEXT('\0'); *pHr = S_OK; } } }
CUiRecvFileInfo::~CUiRecvFileInfo(void) { delete m_pszFullName; delete m_pszRecvFolder; }
/////////////////////////////////////////////////////////////////
//
// Receive Dialog
//
CRecvDlg::CRecvDlg ( CAppletWindow *pWindow, T120ConfID nConfID, T120NodeID nidSender, MBFTEVENTHANDLE nEventHandle, CUiRecvFileInfo *pFileInfo, HRESULT *pHr ) : CRefCount(MAKE_STAMP_ID('F','T','R','D')), m_pWindow(pWindow), m_nConfID(nConfID), m_nidSender(nidSender), m_nEventHandle(nEventHandle), m_pRecvFileInfo(pFileInfo), m_fRecvComplete(FALSE), m_fShownRecvCompleteUI(FALSE), m_idResult(0), m_dwEstTimeLeft(0), m_dwPreviousTime(0), m_dwPreviousTransferred(0), m_dwBytesPerSec(0), m_dwStartTime(::GetTickCount()) { *pHr = E_FAIL; // failure, at default
m_hwndRecvDlg = ::CreateDialogParam(g_hDllInst, MAKEINTRESOURCE(IDD_RECVDLG), pWindow->GetHwnd(), RecvDlgProc, (LPARAM) this); ASSERT(NULL != m_hwndRecvDlg); if (NULL != m_hwndRecvDlg) { ::ShowWindow(m_hwndRecvDlg, SW_SHOWNORMAL); m_pWindow->RegisterRecvDlg(this); *pHr = S_OK; ::SetForegroundWindow(m_hwndRecvDlg); } }
CRecvDlg::~CRecvDlg(void) { delete m_pRecvFileInfo;
m_pWindow->UnregisterRecvDlg(this);
if (NULL != m_hwndRecvDlg) { HWND hwnd = m_hwndRecvDlg; m_hwndRecvDlg = NULL; ::EndDialog(hwnd, IDCLOSE); } }
/////////////////////////////////////////////////////////////////
//
// RecvDlg_OnInitDialog
//
void RecvDlg_OnInitDialog(HWND hdlg, WPARAM wParam, LPARAM lParam) { CRecvDlg *pDlg = (CRecvDlg *) ::GetWindowLongPtr(hdlg, DWLP_USER); ASSERT(NULL != pDlg);
CUiRecvFileInfo *pFileInfo = (CUiRecvFileInfo *) pDlg->GetRecvFileInfo(); ASSERT(NULL != pFileInfo);
// move the window to proper location
ULONG nCaptionHeight = ::GetSystemMetrics(SM_CYCAPTION); ULONG nShift = nCaptionHeight * (s_cRecvDlg++ % 8); RECT rcDlg; ::GetWindowRect(hdlg, &rcDlg); ::MoveWindow(hdlg, rcDlg.left + nShift, rcDlg.top + nShift, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, FALSE);
// Set font (for international)
HFONT hfont = (HFONT) ::GetStockObject(DEFAULT_GUI_FONT); ASSERT(NULL != hfont); ::SendDlgItemMessage(hdlg, IDE_RECVDLG_RECFILE, WM_SETFONT, (WPARAM) hfont, 0); ::SendDlgItemMessage(hdlg, IDE_RECVDLG_RECDIR, WM_SETFONT, (WPARAM) hfont, 0); ::SendDlgItemMessage(hdlg, IDE_RECVDLG_SENDER, WM_SETFONT, (WPARAM) hfont, 0);
// cache names
LPTSTR pszFileName = pFileInfo->GetName(); LPTSTR pszFullName = pFileInfo->GetFullName();
// title
TCHAR szText[MAX_PATH*2]; if (::MyLoadString(IDS_RECVDLG_TITLE, szText, pszFileName)) { ::SetWindowText(hdlg, szText); }
// filename
::lstrcpyn(szText, pszFileName, MAX_FILE_NAME_LENGTH); if (::lstrlen(pszFileName) > MAX_FILE_NAME_LENGTH) { LPTSTR psz = szText; int i = MAX_FILE_NAME_LENGTH - 1; while (i) { psz = CharNext(psz); i--; } ::lstrcpy(psz, TEXT("...")); } ::SetDlgItemText(hdlg, IDE_RECVDLG_RECFILE, szText);
// directory Name
LPTSTR psz = szText; ::lstrcpyn(szText, pszFullName, (int)(pszFileName - pszFullName)); HDC hdc = ::GetDC(hdlg); if (NULL != hdc) { SIZE size; if (::GetTextExtentPoint32(hdc, szText, ::lstrlen(szText), &size)) { RECT rc; ::GetWindowRect(::GetDlgItem(hdlg, IDE_RECVDLG_RECDIR), &rc); if (size.cx > (rc.right - rc.left)) { // Just display the folder name
psz = (LPTSTR) ::GetFileNameFromPath(szText); } } } ::ReleaseDC(hdlg, hdc); ::SetDlgItemText(hdlg, IDE_RECVDLG_RECDIR, psz);
// sender Name
if (::T120_GetNodeName(pDlg->GetConfID(), pDlg->GetSenderID(), szText, count_of(szText))) { ::SetDlgItemText(hdlg, IDE_RECVDLG_SENDER, szText); }
// update "Received xxx bytes of yyy"
if (::MyLoadString(IDS_RECVDLG_RECBYTES, szText, pFileInfo->GetTotalRecvSize(), pFileInfo->GetSize())) { ::SetDlgItemText(hdlg, IDE_RECVDLG_RECBYTES, szText); }
// progress bar
::SendMessage(GetDlgItem(hdlg, IDC_RECVDLG_PROGRESS), PBM_SETPOS, pDlg->GetPercent(), 0);
// start animation
Animate_Open(GetDlgItem(hdlg, IDC_RECVDLG_ANIMATE), MAKEINTRESOURCE(IDA_RECVDLG_ANIMATION));
// do the animation work
if (! pDlg->IsRecvComplete()) { Animate_Play(GetDlgItem(hdlg, IDC_RECVDLG_ANIMATE), 0, -1, -1); if (::LoadString(g_hDllInst, IDS_RECVDLG_START, szText, count_of(szText))) { ::SetDlgItemText(hdlg, IDE_RECVDLG_TIME, szText); } }
// show the window now
::ShowWindow(hdlg, SW_SHOWNORMAL);
// UpdateProgress();
pDlg->OnProgressUpdate(); }
/////////////////////////////////////////////////////////////////
//
// RecvDlg_OnCommand
//
void RecvDlg_OnCommand(HWND hdlg, WPARAM wParam, LPARAM lParam) { CRecvDlg *pDlg = (CRecvDlg *) ::GetWindowLongPtr(hdlg, DWLP_USER); ASSERT(NULL != pDlg);
switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDM_RECVDLG_DELETE: pDlg->OnDelete(); break;
case IDM_RECVDLG_OPEN: pDlg->OnOpen(); break;
case IDM_RECVDLG_ACCEPT: case IDOK: case IDCANCEL: case IDCLOSE: pDlg->OnAccept(); break;
default: return; }
// dismiss the dialog
::EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam)); pDlg->Release(); }
void CRecvDlg::OnOpen(void) { // create short version of the path name
TCHAR szDir[MAX_PATH]; ::GetShortPathName(m_pRecvFileInfo->GetRecvFolder(), szDir, count_of(szDir));
// create short version of the full name
TCHAR szFile[MAX_PATH]; szFile[0] = TEXT('\0'); ::wsprintf(szFile, TEXT("%s\\%s"), szDir, m_pRecvFileInfo->GetName());
TRACE_OUT(("FT: Opening [%s] in [%]", m_pRecvFileInfo->GetName(), szDir));
HINSTANCE hInst = ::ShellExecute(m_pWindow->GetHwnd(), NULL, szFile, NULL, szDir, SW_SHOWDEFAULT); if (32 >= (DWORD_PTR) hInst) { WARNING_OUT(("Unable to open [%s] - showing file", szFile)); ::ShellExecute(m_pWindow->GetHwnd(), NULL, szDir, m_pRecvFileInfo->GetFullName(), NULL, SW_SHOWDEFAULT); } }
void CRecvDlg::OnDelete(void) { StopAnimation();
// check if transfer has completed
if (! m_fRecvComplete) { DBG_SAVE_FILE_LINE m_pWindow->GetEngine()->SafePostMessage( new FileTransferControlMsg( m_nEventHandle, m_pRecvFileInfo->GetFileHandle(), NULL, NULL, FileTransferControlMsg::EnumAbortFile)); } else { ::DeleteFile(m_pRecvFileInfo->GetFullName()); } }
void CRecvDlg::OnAccept(void) { StopAnimation(); }
/////////////////////////////////////////////////////////////////
//
// RecvDlg_OnInitMenuPopup
//
void RecvDlg_OnInitMenuPopup(HWND hdlg, WPARAM wParam, LPARAM lParam) { if (0 != HIWORD(lParam)) // System menu flag
{ HMENU hMenu = (HMENU) wParam; // handle of pop-up menu
::EnableMenuItem(hMenu, SC_MAXIMIZE, MF_GRAYED); ::EnableMenuItem(hMenu, SC_SIZE, MF_GRAYED); } }
/////////////////////////////////////////////////////////////////
//
// RecvDlgProc
//
INT_PTR CALLBACK RecvDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = TRUE; // processed
switch (uMsg) { case WM_INITDIALOG: ASSERT(NULL != lParam); ::SetWindowLongPtr(hdlg, DWLP_USER, lParam); RecvDlg_OnInitDialog(hdlg, wParam, lParam); break;
case WM_COMMAND: RecvDlg_OnCommand(hdlg, wParam, lParam); break;
case WM_INITMENUPOPUP: RecvDlg_OnInitMenuPopup(hdlg, wParam, lParam); fRet = FALSE; break;
// This means user wants to delete the file.
case WM_CLOSE: RecvDlg_OnCommand(hdlg, IDCLOSE, lParam); break;;
default: fRet = FALSE; // not processed
break; }
return fRet; }
/////////////////////////////////////////////////////////////////
//
// RecvDlg Animation
//
void CRecvDlg::StopAnimation(void) { HWND hwnd = ::GetDlgItem(m_hwndRecvDlg, IDC_RECVDLG_ANIMATE); if (NULL != hwnd) { Animate_Stop(hwnd); Animate_Close(hwnd); } }
ULONG _GetPercent(ULONG cbTotalRecvSize , ULONG cbFileSize) {
if (! cbFileSize || (cbTotalRecvSize >= cbFileSize)) { return 100; }
// FUTURE: Consider using EnlargedUnsignedMultiply
if (cbFileSize < 0x01000000) { return (cbTotalRecvSize * 100) / cbFileSize; }
return cbTotalRecvSize / (cbFileSize / 100); }
/////////////////////////////////////////////////////////////////
//
// RecvDlg Progress
//
ULONG CRecvDlg::GetPercent(void) { return _GetPercent(m_pRecvFileInfo->GetTotalRecvSize(), m_pRecvFileInfo->GetSize()); }
void CRecvDlg::OnProgressUpdate(FileTransmitMsg *pMsg) {
if (NULL != pMsg) { ASSERT(iMBFT_FILE_RECEIVE_PROGRESS == (MBFT_NOTIFICATION) pMsg->m_TransmitStatus || iMBFT_FILE_RECEIVE_BEGIN == (MBFT_NOTIFICATION) pMsg->m_TransmitStatus);
ASSERT(m_nEventHandle == pMsg->m_EventHandle); ASSERT(m_pRecvFileInfo->GetFileHandle() == pMsg->m_hFile); ASSERT(m_pRecvFileInfo->GetSize() == pMsg->m_FileSize);
m_pRecvFileInfo->SetTotalRecvSize(pMsg->m_BytesTransmitted);
if (pMsg->m_BytesTransmitted >= pMsg->m_FileSize) { m_fRecvComplete = TRUE; m_idResult = IDS_RECVDLG_COMPLETE; } }
if (m_fRecvComplete && ! m_fShownRecvCompleteUI) { m_fRecvComplete = TRUE;
TCHAR szText[MAX_PATH]; if (::LoadString(g_hDllInst, IDS_RECVDLG_CLOSE, szText, count_of(szText))) { ::SetDlgItemText(m_hwndRecvDlg, IDM_RECVDLG_ACCEPT, szText); }
if (IDS_RECVDLG_COMPLETE == m_idResult) { ::EnableWindow(::GetDlgItem(m_hwndRecvDlg, IDM_RECVDLG_OPEN), TRUE); } else { ::EnableWindow(::GetDlgItem(m_hwndRecvDlg, IDM_RECVDLG_DELETE), FALSE); }
// Reset animation
HWND hwnd = ::GetDlgItem(m_hwndRecvDlg, IDC_RECVDLG_ANIMATE); Animate_Stop(hwnd); Animate_Close(hwnd); Animate_Open(hwnd, MAKEINTRESOURCE(IDA_RECVDLG_DONE)); Animate_Seek(hwnd, ((IDS_RECVDLG_COMPLETE == m_idResult) ? 0 : 1));
m_fShownRecvCompleteUI = TRUE; }
ULONG cbTotalRecvSize = m_pRecvFileInfo->GetTotalRecvSize(); ULONG cbFileSize = m_pRecvFileInfo->GetSize();
DWORD dwNow = ::GetTickCount(); DWORD dwBytesPerSec; DWORD dwBytesRead; TCHAR szOut[MAX_PATH];
if (m_dwPreviousTransferred != cbTotalRecvSize) { TCHAR szFmt[MAX_PATH];
// Update "Received xxx bytes of yyy"
if (::LoadString(g_hDllInst, IDS_RECVDLG_RECBYTES, szFmt, count_of(szFmt))) { ::wsprintf(szOut, szFmt, cbTotalRecvSize, cbFileSize); ::SetDlgItemText(m_hwndRecvDlg, IDE_RECVDLG_RECBYTES, szOut); }
// Update Progress Bar
if (cbTotalRecvSize) { ::SendMessage(GetDlgItem(m_hwndRecvDlg, IDC_RECVDLG_PROGRESS), PBM_SETPOS, GetPercent(), 0); } }
// check if no time estimate is required
if (m_fRecvComplete) { if (::LoadString(g_hDllInst, m_idResult, szOut, count_of(szOut))) { ::SetDlgItemText(m_hwndRecvDlg, IDE_RECVDLG_TIME, szOut); } return; }
// first time we're in here for this file?
if (! m_dwPreviousTime || ! cbTotalRecvSize) { // no data, yet
m_dwPreviousTime = dwNow - 1000; ASSERT(! m_dwPreviousTransferred); ASSERT(! m_dwBytesPerSec); return; }
// Has enough time elapsed to update the display?
// We do this about every 5 seconds (note the adjustment for first time)
if ((dwNow - m_dwPreviousTime) < 5000) return;
dwBytesRead = cbTotalRecvSize - m_dwPreviousTransferred;
// We take 10 times the number of bytes and divide by the number of
// tenths of a second to minimize both overflow and roundoff
dwBytesPerSec = dwBytesRead * 10 / ((dwNow - m_dwPreviousTime) / 100); if (! dwBytesPerSec) { // very low transmission rate! Ignore the information?
return; } if (m_dwBytesPerSec) { // Take the average of the current transfer rate and the
// previously computed one, just to try to smooth out
// some random fluctuations
dwBytesPerSec = (dwBytesPerSec + m_dwBytesPerSec) / 2; } m_dwBytesPerSec = dwBytesPerSec;
// Calculate time remaining (round up by adding 1)
m_dwEstTimeLeft = ((cbFileSize - cbTotalRecvSize) / m_dwBytesPerSec) + 1;
// Reset time and # of bytes read
m_dwPreviousTime = dwNow; m_dwPreviousTransferred = cbTotalRecvSize;
if (m_dwEstTimeLeft < 3) { // szOut[0] = _T('\0'); // don't bother updating when almost done
return; } if (m_dwEstTimeLeft > 99) { // dwTime is about 2 mintes
::MyLoadString(IDS_RECVDLG_MINUTES, szOut, ((m_dwEstTimeLeft / 60) + 1)); } else { // Round up to 5 seconds so it doesn't look so random
::MyLoadString(IDS_RECVDLG_SECONDS, szOut, (((m_dwEstTimeLeft + 4) / 5) * 5) ); }
::SetDlgItemText(m_hwndRecvDlg, IDE_RECVDLG_TIME, szOut); }
void CRecvDlg::OnCanceled(void) { m_idResult = IDS_RECVDLG_CANCEL; m_fRecvComplete = TRUE; OnProgressUpdate(); }
void CRecvDlg::OnRejectedFile(void) { m_idResult = IDS_RECVDLG_SENDER_CANCEL; m_fRecvComplete = TRUE; OnProgressUpdate(); }
//////////////////////////////////////////////////////////////////////
//
// Shortcut/Link Management
//
void CAppletWindow::ResolveShortcut(LPTSTR pszSrcFile, LPTSTR pszDstFile) { ASSERT(NULL != pszSrcFile && '\0' != *pszSrcFile); ASSERT(NULL != pszDstFile);
IShellLink *psl; HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); if (SUCCEEDED(hr)) { IPersistFile *ppf; hr = psl->QueryInterface(IID_IPersistFile, (LPVOID *) &ppf); if (SUCCEEDED(hr)) { WCHAR wsz[MAX_PATH]; /* Buffer for unicode string */ #ifdef _UNICODE
::lstrcpyn(wsz, pszSrcFile, MAX_PATH); #else
::MultiByteToWideChar(CP_ACP, 0, pszSrcFile, -1, wsz, MAX_PATH); #endif
hr = ppf->Load(wsz, STGM_READ); if (SUCCEEDED(hr)) { /* Resolve the link, this may post UI to find the link */ hr = psl->Resolve(m_hwndMainUI, SLR_ANY_MATCH); if (SUCCEEDED(hr)) { psl->GetPath(pszDstFile, MAX_PATH, NULL, 0); }
TRACE_OUT(("CAppletWindow::ResolveShortcut: File resolved to [%s]", pszDstFile)); } ppf->Release(); } psl->Release(); } }
/////////////////////////////////////////////////////////////////
//
// Non-blocking Message Box
//
INT_PTR MsgBox2DlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fHandled = FALSE; CAppletWindow *pWindow;
switch (uMsg) { case WM_INITDIALOG: { // get the text to display
LPTSTR pszText = (LPTSTR) lParam; ASSERT(NULL != pszText && TEXT('\0') != *pszText);
// estimate how big the read-only edit control should be
HDC hdc = ::GetDC(hdlg); if (NULL != hdc) { SIZE csEdit; if (::GetTextExtentPoint32(hdc, pszText, ::lstrlen(pszText), &csEdit)) { const ULONG c_nMarginX = 0; const ULONG c_nMarginY = 10;
ULONG nCaptionHeight = ::GetSystemMetrics(SM_CYCAPTION); ULONG nShift = nCaptionHeight * (s_cMsgBox2Dlg++ % 8);
// move the edit control
HWND hwndEdit = ::GetDlgItem(hdlg, IDE_MSGBOX2_TEXT); POINT ptEdit; ptEdit.x = c_nMarginX; ptEdit.y = c_nMarginY + (c_nMarginY >> 1); csEdit.cx += c_nMarginX << 1; csEdit.cy += c_nMarginY << 1; ::MoveWindow(hwndEdit, ptEdit.x, ptEdit.y, csEdit.cx, csEdit.cy, FALSE);
// move the ok button
HWND hwndOK = ::GetDlgItem(hdlg, IDOK); RECT rcOK; ::GetWindowRect(hwndOK, &rcOK); SIZE csOK; csOK.cx = rcOK.right - rcOK.left; csOK.cy = rcOK.bottom - rcOK.top; POINT ptOK; ptOK.x = ptEdit.x + (csEdit.cx >> 1) - (csOK.cx >> 1); ptOK.y = ptEdit.y + csEdit.cy + (c_nMarginY >> 1); ::MoveWindow(hwndOK, ptOK.x, ptOK.y, csOK.cx, csOK.cy, FALSE);
// adjust all the windows
RECT rcDlg, rcClient; ::GetWindowRect(hdlg, &rcDlg); POINT ptDlg; ptDlg.x = rcDlg.left + nShift; ptDlg.y = rcDlg.top + nShift; ::GetClientRect(hdlg, &rcClient); SIZE csDlg; csDlg.cx = (rcDlg.right - rcDlg.left) - (rcClient.right - rcClient.left); csDlg.cy = (rcDlg.bottom - rcDlg.top) - (rcClient.bottom - rcClient.top); csDlg.cx += ptEdit.x + csEdit.cx + c_nMarginX; csDlg.cy += ptOK.y + csOK.cy + c_nMarginY; ::MoveWindow(hdlg, ptDlg.x, ptDlg.y, csDlg.cx, csDlg.cy, FALSE); } ::ReleaseDC(hdlg, hdc); }
::SetDlgItemText(hdlg, IDE_MSGBOX2_TEXT, pszText); delete [] pszText; // free the display text
fHandled = TRUE; } break;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: case IDCANCEL: case IDCLOSE: switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case BN_CLICKED: pWindow = (CAppletWindow*)::GetWindowLongPtr(hdlg, DWLP_USER); ASSERT (pWindow); if (pWindow) { pWindow->RemoveErrorDlg(hdlg); pWindow->FocusNextErrorDlg(); } ::EndDialog(hdlg, IDOK); break; } break; }
fHandled = TRUE; break; }
return(fHandled); }
BOOL MsgBox2(CAppletWindow *pWindow, LPTSTR pszText) { BOOL fRet = FALSE; ULONG cch = ::lstrlen(pszText) + 1; DBG_SAVE_FILE_LINE LPTSTR pszNew = new TCHAR[cch]; if (NULL != pszNew) { ::CopyMemory(pszNew, pszText, cch); HWND hwndDlg = ::CreateDialogParam(g_hDllInst, MAKEINTRESOURCE(IDD_MSGBOX2), pWindow->GetHwnd(), MsgBox2DlgProc, (LPARAM) pszNew);
ASSERT(NULL != hwndDlg); if (NULL != hwndDlg) { ::ShowWindow(hwndDlg, SW_SHOWNORMAL); fRet = TRUE; ::SetForegroundWindow(hwndDlg); ::SetWindowLongPtr(hwndDlg, DWLP_USER, (LPARAM)pWindow); pWindow->AddErrorDlg(hwndDlg); } } else { ERROR_OUT(("FT::MsgBox2: cannot duplicate string [%s]", pszText)); } return fRet; }
/////////////////////////////////////////////////////////////////
//
// Receive Folder Management
//
HRESULT GetRecvFolder(LPTSTR pszInFldr, LPTSTR pszOutFldr) { LPTSTR psz; TCHAR szPath[MAX_PATH];
RegEntry reFileXfer(FILEXFER_KEY, HKEY_CURRENT_USER);
if (NULL == pszInFldr) { // NULL directory specified - get info from registry or use default
psz = reFileXfer.GetString(REGVAL_FILEXFER_PATH); if (NULL != psz && TEXT('\0') != *psz) { ::lstrcpyn(szPath, psz, count_of(szPath)); } else { TCHAR szInstallDir[MAX_PATH]; ::GetInstallDirectory(szInstallDir); ::MyLoadString(IDS_RECDIR_DEFAULT, szPath, szInstallDir); }
pszInFldr = szPath; }
::lstrcpyn(pszOutFldr, pszInFldr, MAX_PATH);
// Remove trailing backslash, if any
for (psz = pszOutFldr; *psz; psz = CharNext(psz)) { if ('\\' == *psz && '\0' == *CharNext(psz)) { *psz = '\0'; break; } }
HRESULT hr; if (!FEnsureDirExists(pszOutFldr)) { WARNING_OUT(("ChangeRecDir: FT directory is invalid [%s]", pszOutFldr)); hr = E_FAIL; } else { // update the registry
reFileXfer.SetValue(REGVAL_FILEXFER_PATH, pszOutFldr); hr = S_OK; } return hr; }
void EnsureTrailingSlash(LPTSTR psz) { LPTSTR psz2;
// Make sure the directory name has a trailing '\'
while (TEXT('\0') != *psz) { psz2 = ::CharNext(psz); if (TEXT('\\') == *psz && TEXT('\0') == *psz2) { // The path already ends with a backslash
return; } psz = psz2; }
// Append a trailing backslash
*psz = TEXT('\\'); psz = ::CharNext(psz); *psz = TEXT('\0'); }
|