// SelectFile.cpp : Implementation of CSelectFile #include "stdafx.h" #include "CompatUI.h" #include "SelectFile.h" #include "commdlg.h" #include "cderr.h" ///////////////////////////////////////////////////////////////////////////// // CSelectFile // // in upload.c // wstring StrUpCase(wstring& wstr); STDMETHODIMP CSelectFile::get_BrowseTitle(BSTR *pVal) { *pVal = m_bstrTitle.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_BrowseTitle(BSTR newVal) { m_bstrTitle = newVal; return S_OK; } STDMETHODIMP CSelectFile::get_BrowseFilter(BSTR *pVal) { *pVal = m_bstrFilter.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_BrowseFilter(BSTR newVal) { m_bstrFilter = newVal; return S_OK; } STDMETHODIMP CSelectFile::get_BrowseInitialDirectory(BSTR *pVal) { *pVal = m_bstrInitialDirectory; return S_OK; } STDMETHODIMP CSelectFile::put_BrowseInitialDirectory(BSTR newVal) { m_bstrInitialDirectory = newVal; return S_OK; } STDMETHODIMP CSelectFile::get_BrowseFlags(long *pVal) { *pVal = (LONG)m_dwBrowseFlags; return S_OK; } STDMETHODIMP CSelectFile::put_BrowseFlags(long newVal) { m_dwBrowseFlags = (DWORD)newVal; return S_OK; } STDMETHODIMP CSelectFile::get_FileName(BSTR *pVal) { wstring sFileName; GetFileNameFromUI(sFileName); m_bstrFileName = sFileName.c_str(); *pVal = m_bstrFileName.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_FileName(BSTR newVal) { m_bstrFileName = newVal; SetDlgItemText(IDC_EDITFILENAME, m_bstrFileName); return S_OK; } STDMETHODIMP CSelectFile::get_ErrorCode(long *pVal) { *pVal = (LONG)m_dwErrorCode; return S_OK; } #define MAX_BUFFER 2048 LRESULT CSelectFile::OnClickedBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { LRESULT lRes = 0; // TODO: Add your implementation code here OPENFILENAME ofn; LPTSTR pszFileName = NULL; DWORD dwFileNameLength = 0; DWORD dwLen; LPTSTR pszFilter = NULL, pch; m_dwErrorCode = 0; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hWnd; // // part one (straight) - title // ofn.lpstrTitle = (LPCTSTR)m_bstrTitle; // assumes we're unicode (and we are) // // recover the filename from the edit box // wstring sFileName; if (GetFileNameFromUI(sFileName)) { m_bstrFileName = sFileName.c_str(); } // // part two - init filename // dwFileNameLength = __max(MAX_BUFFER, m_bstrFileName.Length() * 2); // in characters pszFileName = new TCHAR[dwFileNameLength * sizeof(*pszFileName)]; if (pszFileName == NULL) { m_dwErrorCode = ERROR_OUTOFMEMORY; goto HandleError; } // so we have the buffer now // if (m_bstrFileName.Length () > 0) { // sanitize the filename with regard to quotes _tcscpy(pszFileName, (LPCTSTR)m_bstrFileName); // hypocritical copy, we are unicode } else { // start with the contents of the text box then *pszFileName = TEXT('\0'); } // // sanity check, if pszFileName ends with \ then we will get an error // PathRemoveBackslash(pszFileName); ofn.lpstrFile = pszFileName; ofn.nMaxFile = dwFileNameLength; // // see if we also need to process filter // if (m_bstrFilter.Length() > 0) { dwLen = m_bstrFilter.Length(); pszFilter = new TCHAR[(dwLen + 2) * sizeof(*pszFilter)]; if (pszFilter == NULL) { m_dwErrorCode = ERROR_OUTOFMEMORY; goto HandleError; } RtlZeroMemory(pszFilter, (dwLen + 2) * sizeof(*pszFilter)); _tcscpy(pszFilter, m_bstrFilter); pch = pszFilter; while (pch) { pch = _tcschr(pch, TEXT('|')); if (pch) { *pch++ = TEXT('\0'); } } // now that the replacement is done -- assign the filter string ofn.lpstrFilter = pszFilter; } // // now check whether we have some in the initial directory // if (m_bstrInitialDirectory.Length() > 0) { ofn.lpstrInitialDir = (LPCTSTR)m_bstrInitialDirectory; } // // flags // if (m_dwBrowseFlags) { ofn.Flags = m_dwBrowseFlags; } else { ofn.Flags = OFN_FILEMUSTEXIST|OFN_EXPLORER; } BOOL bRetry; BOOL bSuccess; do { bRetry = FALSE; bSuccess = GetOpenFileName(&ofn); if (!bSuccess) { m_dwErrorCode = CommDlgExtendedError(); if (m_dwErrorCode == FNERR_INVALIDFILENAME) { *pszFileName = TEXT('\0'); bRetry = TRUE; } } } while (bRetry); if (!bSuccess) { goto HandleError; } SetDlgItemText(IDC_EDITFILENAME, pszFileName); m_bstrFileName = (LPCTSTR)pszFileName; m_dwErrorCode = 0; HandleError: if (pszFileName != NULL) { delete[] pszFileName; } if (pszFilter != NULL) { delete[] pszFilter; } bHandled = TRUE; return lRes; } BOOL CSelectFile::PreTranslateAccelerator( LPMSG pMsg, HRESULT& hRet ) { HWND hWndCtl; HWND hwndEdit = GetDlgItem(IDC_EDITFILENAME); HWND hwndBrowse = GetDlgItem(IDC_BROWSE); BSTR bstrFileName = NULL; WORD wCmd = 0; BOOL bBrowseHandled; hRet = S_OK; hWndCtl = ::GetFocus(); if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd) { do { hWndCtl = ::GetParent(hWndCtl); } while (::GetParent(hWndCtl) != m_hWnd); } if (pMsg->message == WM_KEYDOWN && (LOWORD(pMsg->wParam) == VK_RETURN || LOWORD(pMsg->wParam) == VK_EXECUTE)) { if (hWndCtl == hwndEdit) { BOOL bReturn; wstring sFileName; bReturn = GetFileNameFromUI(sFileName) && ValidateExecutableFile(sFileName.c_str(), TRUE); if (bReturn) { Fire_SelectionComplete(); return TRUE; } } // this either was hwndBrowse or filename was not there -- open // browse dialog then OnClickedBrowse(BN_CLICKED, IDC_BROWSE, hwndBrowse, bBrowseHandled); ::SetFocus(hwndEdit); } // // fixup external accelerators for internal controls (in this case -- edit) // if (m_Accel.IsAccelKey(pMsg, &wCmd) && wCmd == IDC_EDITFILENAME) { ::SetFocus(hwndEdit); return TRUE; } // // check for external accelerators because the next call is going to eat the message // if (m_ExternAccel.IsAccelKey(pMsg)) { // we do not touch external accel messages return FALSE; } // // check whether we are tabbing out of control // if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB) { // check whether we're tabbing out // (perhaps the control wants to eat tab? DWORD_PTR dwDlgCode = ::SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0); if (!(dwDlgCode & DLGC_WANTTAB)) { // control does not want a tab // see whether it's the last control and we're tabbing out HWND hwndFirst = GetNextDlgTabItem(NULL, FALSE); // first HWND hwndLast = GetNextDlgTabItem(hwndFirst, TRUE); BOOL bFirstOrLast; if (::GetKeyState(VK_SHIFT) & 0x8000) { // shift ? bFirstOrLast = (hWndCtl == hwndFirst); } else { bFirstOrLast = (hWndCtl == hwndLast); } if (bFirstOrLast) { IsDialogMessage(pMsg); return FALSE; } } } return CComCompositeControl::PreTranslateAccelerator(pMsg, hRet); } /* STDMETHODIMP CSelectFile::get_Accel(BSTR *pVal) { CComBSTR bstr = (LPCWSTR)m_Accel; *pVal = bstr.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_Accel(BSTR newVal) { m_Accel = (LPCWSTR)newVal; return S_OK; } */ STDMETHODIMP CSelectFile::get_ExternAccel(BSTR *pVal) { CComBSTR bstr = m_ExternAccel.GetAccelString(0).c_str(); *pVal = bstr.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_ExternAccel(BSTR newVal) { m_ExternAccel = (LPCWSTR)newVal; return S_OK; } static TCHAR szU[] = TEXT(""); static TCHAR szUC[] = TEXT(""); #define szU_Len (CHARCOUNT(szU) - 1) #define szUC_Len (CHARCOUNT(szUC) - 1) STDMETHODIMP CSelectFile::get_BrowseBtnCaption(BSTR *pVal) { // TODO: Add your implementation code here CComBSTR bstrCaption; wstring strCaption = m_BrowseBtnCaption; wstring::size_type nPos; nPos = m_BrowseBtnCaption.find(TEXT('&')); if (nPos == wstring::npos || nPos > m_BrowseBtnCaption.length() - 1) { bstrCaption = m_BrowseBtnCaption.c_str(); } else { bstrCaption = m_BrowseBtnCaption.substr(0, nPos).c_str(); bstrCaption += szU; bstrCaption += m_BrowseBtnCaption[nPos+1]; bstrCaption += szUC; if (nPos < m_BrowseBtnCaption.length() - 1) { bstrCaption += m_BrowseBtnCaption.substr(nPos+2).c_str(); } } *pVal = bstrCaption.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_BrowseBtnCaption(BSTR newVal) { // // form a caption from the string // wstring strCaption = newVal; wstring strCaptionU = strCaption; wstring::size_type nPosU, nPosUC; wstring strAccel; StrUpCase(strCaptionU); // // find pair // nPosU = strCaptionU.find(szU); nPosUC = strCaptionU.find(szUC, nPosU); if (nPosUC == wstring::npos || nPosU == wstring::npos || nPosUC < nPosU || nPosUC <= (nPosU + szU_Len)) { goto cleanup; } // extract the char at the & // // strAccel = strCaption.substr(nPosU + szU_Len, nPosUC - (nPosU + szU_Len)); // // add accel please -- with command id IDC_BROWSE // m_Accel.SetAccel(strAccel.c_str(), IDC_BROWSE); // // now we (presumably) found accelchar // m_BrowseBtnCaption = strCaption.substr(0, nPosU); // up to the m_BrowseBtnCaption += TEXT('&'); m_BrowseBtnCaption += strAccel.c_str(); m_BrowseBtnCaption += strCaption.substr(nPosUC + szUC_Len); // all the rest please if (IsWindow()) { SetDlgItemText(IDC_BROWSE, m_BrowseBtnCaption.c_str()); } cleanup: return S_OK; } STDMETHODIMP CSelectFile::get_AccelCmd(LONG lCmd, BSTR *pVal) { CComBSTR bstrVal = m_Accel.GetAccelString((WORD)lCmd).c_str(); *pVal = bstrVal.Copy(); return S_OK; } STDMETHODIMP CSelectFile::put_AccelCmd(LONG lCmd, BSTR newVal) { m_Accel.SetAccel(newVal, (WORD)lCmd); return S_OK; } STDMETHODIMP CSelectFile::ClearAccel() { m_Accel.ClearAccel(); return S_OK; } STDMETHODIMP CSelectFile::ClearExternAccel() { m_ExternAccel.ClearAccel(); return S_OK; }