Initial Commit
This commit is contained in:
341
database/FileZillaFTP/source/interface/misc/BrowseForFolder.cpp
Normal file
341
database/FileZillaFTP/source/interface/misc/BrowseForFolder.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user