Server : Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6 System : Windows NT USER-PC 6.1 build 7601 (Windows 7 Professional Edition Service Pack 1) AMD64 User : User ( 0) PHP Version : 7.4.6 Disable Function : NONE Directory : C:/xampp/FileZillaFTP/source/interface/misc/ |
////////////////////////////////////////////////////////////////////// // // ShellBrowser.cpp: implementation of the CShellBrowser class. // #include "stdafx.h" #include "BrowseForFolder.h" #if defined(_DEBUG) && !defined(MMGR) #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // // Construction/Destruction // CBrowseForFolder::CBrowseForFolder(const HWND hParent /*= NULL*/, const LPITEMIDLIST pidl /*= NULL*/, const int nTitleID /*= 0*/) { m_hwnd = NULL; SetOwner(hParent); SetRoot(pidl); SetTitle(nTitleID); m_bi.lpfn = BrowseCallbackProc; m_bi.lParam = reinterpret_cast<long>(this); m_bi.pszDisplayName = m_szSelected; m_szSelected[0] = 0; } CBrowseForFolder::CBrowseForFolder(const HWND hParent, const LPITEMIDLIST pidl, const CString& strTitle) { m_hwnd = NULL; SetOwner(hParent); SetRoot(pidl); SetTitle(strTitle); m_bi.lpfn = BrowseCallbackProc; m_bi.lParam = reinterpret_cast<long>(this); m_bi.pszDisplayName = m_szSelected; m_szSelected[0] = 0; } CBrowseForFolder::~CBrowseForFolder() { } ////////////////////////////////////////////////////////////////////// // // Implementation // void CBrowseForFolder::SetOwner(const HWND hwndOwner) { if (m_hwnd != NULL) return; m_bi.hwndOwner = hwndOwner; } void CBrowseForFolder::SetRoot(const LPITEMIDLIST pidl) { if (m_hwnd != NULL) return; m_bi.pidlRoot = pidl; } CString CBrowseForFolder::GetTitle() const { return m_bi.lpszTitle; } void CBrowseForFolder::SetTitle(const CString& strTitle) { if (m_hwnd != NULL) return; m_pchTitle=strTitle; m_bi.lpszTitle = m_pchTitle; } bool CBrowseForFolder::SetTitle(const int nTitle) { if (nTitle <= 0) return false; CString strTitle; if(!strTitle.LoadString(static_cast<size_t>(nTitle))) { return false; } SetTitle(strTitle); return true; } void CBrowseForFolder::SetFlags(const UINT ulFlags) { if (m_hwnd != NULL) return; m_bi.ulFlags = ulFlags; } CString CBrowseForFolder::GetSelectedFolder() const { return m_szSelected; } bool CBrowseForFolder::SelectFolder() { bool bRet = false; LPITEMIDLIST pidl; if ((pidl = ::SHBrowseForFolder(&m_bi)) != NULL) { m_strPath.Empty(); if (::SHGetPathFromIDList(pidl, m_szSelected)) { bRet = true; m_strPath = m_szSelected; } LPMALLOC pMalloc; //Retrieve a pointer to the shell's IMalloc interface if (SUCCEEDED(SHGetMalloc(&pMalloc))) { // free the PIDL that SHBrowseForFolder returned to us. pMalloc->Free(pidl); // release the shell's IMalloc interface (void)pMalloc->Release(); } } m_hwnd = NULL; return bRet; } void CBrowseForFolder::OnInit() const { } void CBrowseForFolder::OnSelChanged(const LPITEMIDLIST pidl) const { (void)pidl; } void CBrowseForFolder::EnableOK(const bool bEnable) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_ENABLEOK, NULL, static_cast<WPARAM>(bEnable)); } void CBrowseForFolder::SetSelection(const LPITEMIDLIST pidl) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_SETSELECTION, FALSE, reinterpret_cast<long>(pidl)); } void CBrowseForFolder::SetSelection(const CString& strPath) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_SETSELECTION, TRUE, reinterpret_cast<long>(LPCTSTR(strPath))); } void CBrowseForFolder::SetStatusText(const CString& strText) const { if (m_hwnd == NULL) return; CString oPathString = FormatLongPath(strText); (void)SendMessage(m_hwnd, BFFM_SETSTATUSTEXT, NULL, reinterpret_cast<long>(LPCTSTR(oPathString/*strText*/))); } int __stdcall CBrowseForFolder::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { CBrowseForFolder* pbff = reinterpret_cast<CBrowseForFolder*>(lpData); pbff->m_hwnd = hwnd; if (uMsg == BFFM_INITIALIZED) pbff->OnInit(); else if (uMsg == BFFM_SELCHANGED) pbff->OnSelChanged(reinterpret_cast<LPITEMIDLIST>(lParam)); return 0; } /************************* 3. Finally, the body of FormatLongPath looks like that: **************************/ CString CBrowseForFolder::FormatLongPath(CString oLongPath) const { //will be passed instead of original CString oModifString( oLongPath ); //will be used to get measurements CWnd oWnd; if( !oModifString.IsEmpty() && IsWindow(m_hwnd) && oWnd.Attach(m_hwnd) ) { //margins must be considered RECT Rect = { 0, 0, 7, 0 }; //my lucky guess the margin would be seven units. It used to be 7 in resource editor, so why not here? int nMargin = MapDialogRect( m_hwnd, &Rect ) ? Rect.right : 20; //convert into pixels then //measure the width first CRect oClientRect; oWnd.GetClientRect( &oClientRect ); oClientRect.NormalizeRect(); int nMaxTextWidth = oClientRect.Width() - nMargin*2; CClientDC oClientDC(&oWnd); //trying to determine the system metrix to create apropriate fonts for measurement NONCLIENTMETRICS NonClientMetrics; NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS); BOOL bSystemMetrics = SystemParametersInfo( SPI_GETNONCLIENTMETRICS, NonClientMetrics.cbSize, &NonClientMetrics, 0 ); if( bSystemMetrics ) { CFont oMessageFont;//lets create the fonts same as the selected Message Font on the Display/Appearance tab if( oMessageFont.CreateFontIndirect(&NonClientMetrics.lfMessageFont) ) { oClientDC.SelectObject( &oMessageFont ); } } else { oClientDC.SelectStockObject( SYSTEM_FONT ); //it MUST NOT happen, but in case... } //measure the actual text width int nTextWidth = oClientDC.GetTextExtent( oModifString ).cx; //to check whether it's correct uncoment below and change directory few times... //oClientDC.SelectStockObject( BLACK_PEN ); //oClientDC.Rectangle( 0, 0, nMargin, nMargin*5 ); //oClientDC.Rectangle( nMaxTextWidth+nMargin, 0, oClientRect.Width(), nMargin*5 ); //oClientDC.Rectangle( nMargin, 0, nMaxTextWidth+nMargin, nMargin ); //oClientDC.TextOut( nMargin, 0, oModifString ); //after all this measurements time to do the real job if( nTextWidth > nMaxTextWidth ) { int nRootDirIndex, nLastDirIndex; //this is the testing line: //oModifString = "\\\\computer_name\\dir1\\subdir1" + oModifString.Right(oModifString.GetLength() - 2 ); nRootDirIndex = oModifString.Find( '\\' ); nLastDirIndex = oModifString.ReverseFind( '\\' ); if( nRootDirIndex == 0 ) //we have to deal with the network 'drive', which would look like that: \\computer_name\dir1\subdir1 { nRootDirIndex = oModifString.Find( '\\', nRootDirIndex+1 ); if( nRootDirIndex != -1 ) { nRootDirIndex = oModifString.Find( '\\', nRootDirIndex+1 ); } } if( nRootDirIndex != -1 && nLastDirIndex != -1 ) { nRootDirIndex += 1; //increase for the tactical reasons CString oDottedText( "..." );//this three dots will be used to indicate the cut part of the path CString oRootDirectory; //this can be cut as the last one CString oMidDirectoryPart; //we will try to shorten this part first CString oLastDirectory; //and then, if still too long we'll cut this one oRootDirectory = oModifString.Left( nRootDirIndex ); oMidDirectoryPart = oModifString.Mid( nRootDirIndex, nLastDirIndex - nRootDirIndex ); oLastDirectory = oModifString.Mid( nLastDirIndex ); while( nTextWidth > nMaxTextWidth ) { int nMidPartLenght = oMidDirectoryPart.GetLength(); oModifString = oRootDirectory + oMidDirectoryPart + oDottedText + oLastDirectory; //measure the actual text width again nTextWidth = oClientDC.GetTextExtent( oModifString ).cx; if( nMidPartLenght > 0 ) { //prepare for the next loop (if any) oMidDirectoryPart = oMidDirectoryPart.Left(oMidDirectoryPart.GetLength() - 1 ); } else { int nLastDirectoryLenght = oLastDirectory.GetLength(); if( nLastDirectoryLenght > 0 ) { //prepare for the next loop (if any) oLastDirectory = oLastDirectory.Right(oLastDirectory.GetLength() - 1 ); } else { //should not come here, what size of the fonts are you using?! //anyway, we will do different now, cutting from the end... int nRootDirectoryLenght = oRootDirectory.GetLength(); if( nRootDirectoryLenght > 0 ) { oRootDirectory = oRootDirectory.Left(oRootDirectory.GetLength() - 1 ); } else { TRACE0( "Mayday, Mayday!!!\n" ); oModifString = oLongPath; //something wrong, give me a... break; } } } }//end while } } oWnd.Detach(); } return oModifString; }