📄 browsectrl.cpp
字号:
if (lpszStringBuf == NULL)
return 0;
_tcsncpy(lpszStringBuf, m_sButtonText, nMaxCount);
return _tcslen(lpszStringBuf);
}
void CBrowseCtrl::GetWindowText(CString &rString) const
{
rString = GetButtonText();
}
BOOL CBrowseCtrl::CreateEdit()
{
if (!::IsWindow(m_hWnd))
{
ASSERT(FALSE);
return FALSE;
}
CString str;
if (::IsWindow(m_wndEdit.m_hWnd))
{
m_wndEdit.GetWindowText(str);
m_wndEdit.DestroyWindow();
}
DWORD dwStyle = ES_AUTOHSCROLL | ES_NOHIDESEL | WS_CHILD | WS_VISIBLE;
if ((m_dwStyle & BC_CTL_ALLOWEDIT) == 0)
dwStyle |= ES_READONLY;
if (GetStyle() & WS_DISABLED)
dwStyle |= WS_DISABLED;
m_wndEdit.m_hWnd = NULL;
if (!m_wndEdit.CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), NULL, dwStyle, m_rcEdit, this, EDITCTRL_ID, NULL))
{
ASSERT(FALSE);
return FALSE;
}
m_wndEdit.SetMargins(1, 1);
m_wndEdit.SetFont(GetFont());
m_wndEdit.SetWindowText(str);
m_wndEdit.ShowWindow(SW_SHOW);
return TRUE;
}
void CBrowseCtrl::SetNotifyMessageID(UINT nNotifyMsgID)
{
m_nNotifyMsg = nNotifyMsgID;
}
UINT CBrowseCtrl::GetNotifyMessageID() const
{
return m_nNotifyMsg;
}
void CBrowseCtrl::SetOpenSave(BOOL bOpen)
{
m_bOpenFileDialog = bOpen;
}
BOOL CBrowseCtrl::GetOpenSave() const
{
return m_bOpenFileDialog;
}
void CBrowseCtrl::SetDefExt(LPCTSTR lpszDefExt)
{
m_sDefExt = lpszDefExt;
}
CString CBrowseCtrl::GetDefExt() const
{
return m_sDefExt;
}
void CBrowseCtrl::SetFileFlags(DWORD dwFlags)
{
m_dwFileFlags = dwFlags | OFN_EXPLORER;
}
DWORD CBrowseCtrl::GetFileFlags() const
{
return m_dwFileFlags;
}
void CBrowseCtrl::SetFilter(LPCTSTR lpszFilter)
{
m_sFilter = lpszFilter;
}
CString CBrowseCtrl::GetFilter() const
{
return m_sFilter;
}
CString CBrowseCtrl::GetTooltipText() const
{
return m_sTootipText;
}
CString CBrowseCtrl::GetPathName() const
{
return IsEditManuallyChanged() ? m_sEditText : CString(m_lpszPathNames);
}
CString CBrowseCtrl::GetFileName() const
{
if (m_dwStyle & BC_CTL_FOLDERSONLY)
return _T("");
CString str;
SplitPath(GetPathName(), NULL, NULL, &str, NULL, NULL);
return str;
}
CString CBrowseCtrl::GetFileExt() const
{
if (m_dwStyle & BC_CTL_FOLDERSONLY)
return _T("");
CString str;
SplitPath(GetPathName(), NULL, NULL, NULL, NULL, &str);
return str;
}
CString CBrowseCtrl::GetFileTitle() const
{
if (m_dwStyle & BC_CTL_FOLDERSONLY)
return _T("");
CString str;
SplitPath(GetPathName(), NULL, NULL, NULL, &str, NULL);
return str;
}
POSITION CBrowseCtrl::GetStartPosition() const
{
if (IsEditManuallyChanged())
return m_sEditText.IsEmpty() ? NULL : (POSITION)(LPCTSTR)m_sEditText;
else
return (m_lpszPathNames == NULL || m_lpszPathNames[0] == _T('\0')) ? NULL : (POSITION)(LPCTSTR)m_lpszPathNames;
}
CString CBrowseCtrl::GetNextPathName(POSITION &pos) const
{
// Make sure pos is a valid position
if (pos == NULL)
return _T("");
if (IsEditManuallyChanged())
{
// contents of the edit box has been changed by direct user input
POSITION posOrig = pos;
pos = NULL;
return (DWORD)posOrig == (DWORD)(LPCTSTR)m_sEditText ? m_sEditText : _T("");
}
if (m_lpszPathNames == NULL
|| m_nPathNamesLen == 0
|| m_nSelCount == 0
|| (DWORD)pos < (DWORD)m_lpszPathNames
|| (DWORD)pos >= (DWORD)m_lpszPathNames + (DWORD)m_nPathNamesLen)
{
pos = NULL;
return _T("");
}
LPCTSTR p = (LPCTSTR)pos;
const int LEN = _tcslen(p);
if (LEN == 0)
{
pos = NULL;
return _T("");
}
else
{
pos = (POSITION)(&p[LEN + 1]); // Advance the pointer to next file name
return p;
}
}
BOOL CBrowseCtrl::GetReadOnlyPref() const
{
return m_bReadOnlyRef;
}
BOOL CBrowseCtrl::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwBtnStyles, UINT nNotifyMessageID)
{
// TODO: Add your specialized code here and/or call the base class
if (pParentWnd == NULL)
{
pParentWnd = AfxGetMainWnd();
if (pParentWnd == NULL)
{
ASSERT(FALSE);
return FALSE;
}
}
m_bOwnCreate = TRUE;
m_nNotifyMsg = nNotifyMessageID;
if (!CButton::Create(_T(""), WS_CHILD|WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, rect, pParentWnd, nID))
{
ASSERT(FALSE);
return FALSE;
}
m_dwStyle = dwBtnStyles;
return CreateCtrl();
}
void CBrowseCtrl::SetPathName(LPCTSTR lpszPathName)
{
if (::IsWindow(m_wndEdit.m_hWnd))
m_wndEdit.SetWindowText(lpszPathName);
if (m_lpszPathNames != NULL)
{
delete [] m_lpszPathNames;
m_lpszPathNames = NULL;
}
if (lpszPathName != NULL)
m_lpszPathNames = _tcsdup(lpszPathName);
}
int CBrowseCtrl::BrowseCallbackProc(HWND hwnd, UINT nMsg, LPARAM lParam, LPARAM lpData)
{
lParam = 0; // Appeases VC6 warning level 4.
CBrowseCtrl* pCtrl = (CBrowseCtrl*)(lpData);
if (pCtrl == NULL)
return 0;
if (nMsg == BFFM_INITIALIZED)
{
if (!pCtrl->m_sDlgTitle.IsEmpty())
::SetWindowText(hwnd, pCtrl->m_sDlgTitle);
CString sPathName = pCtrl->GetPathName();
if (!sPathName.IsEmpty())
::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)(LPCTSTR)sPathName);
}
return 0;
}
void CBrowseCtrl::SetFolderFlags(UINT nFlags)
{
m_nFolderFlags = nFlags;
}
UINT CBrowseCtrl::GetFolderFlags() const
{
return m_nFolderFlags;
}
int CBrowseCtrl::FolderDoModal()
{
// Popup the folder dialog
TCHAR szPathName[MAX_PATH + 1] = _T("");
BROWSEINFO bi;
memset(&bi, 0, sizeof(BROWSEINFO));
bi.hwndOwner = ::GetParent(m_hWnd);
bi.pszDisplayName = szPathName;
bi.lpszTitle = m_sDlgBanner;
bi.ulFlags = m_nFolderFlags;
bi.lpfn = BrowseCallbackProc;
bi.lParam = (LPARAM)this;
LPITEMIDLIST pItemIDList = ::SHBrowseForFolder(&bi);
if (pItemIDList == NULL)
return IDCANCEL;
m_nSelCount = 1;
if (m_lpszPathNames != NULL)
{
delete [] m_lpszPathNames;
m_lpszPathNames = NULL;
}
m_lpszPathNames = new TCHAR[MAX_PATH + 2];
memset(m_lpszPathNames, 0, (MAX_PATH + 2) * sizeof(TCHAR));
::SHGetPathFromIDList(pItemIDList, m_lpszPathNames);
IMalloc* pMalloc = NULL;
if(SUCCEEDED(::SHGetMalloc(&pMalloc)))
{
pMalloc->Free(pItemIDList);
pMalloc->Release();
}
m_nPathNamesLen = _tcslen(m_lpszPathNames);
m_bReadOnlyRef = FALSE;
if (::IsWindow(m_wndEdit.m_hWnd))
{
m_wndEdit.SetWindowText(m_lpszPathNames);
m_wndEdit.SetSel(0, -1);
}
m_bEditChanged = FALSE; // Discard previously changes made to the edit control
m_sEditText = m_lpszPathNames;
return IDOK;
}
int CBrowseCtrl::FileDoModal()
{
CFileDialog dlg(m_bOpenFileDialog, m_sDefExt, GetPathName(), m_dwFileFlags, m_sFilter, ::IsWindow(m_hWnd) ? GetParent() : NULL);
dlg.m_ofn.lpstrTitle = m_sDlgTitle; // display dialog title
// ***** To make the buffer less likely to be too small *****
// The buffer allocates 64KB heap memory and frees it before this function ends.
// Of course 64KB is a serious overkill in most cases, but the memory usage is
// just temporary. As soon as the actual usage is determined, the wasted memory
// will be redeemed immediately.
LPTSTR pszLargeBuffer = new TCHAR[MAX_SUM_PATHNAME + 1];
ASSERT(pszLargeBuffer != NULL);
pszLargeBuffer[0] = _T('\0');
// Make the struct use our buffer instead of its own(which was allocated in the
// stack so no need to be taken care of)
dlg.m_ofn.lpstrFile = pszLargeBuffer;
dlg.m_ofn.nMaxFile = MAX_SUM_PATHNAME;
if (dlg.DoModal() != IDOK)
{
delete [] pszLargeBuffer;
return IDCANCEL;
}
if (m_lpszPathNames != NULL)
{
delete [] m_lpszPathNames;
m_lpszPathNames = NULL;
}
POSITION pos = dlg.GetStartPosition();
// determine the string length
m_nSelCount = 0;
m_nPathNamesLen = 0;
while (pos != NULL)
{
m_nSelCount++;
m_nPathNamesLen += dlg.GetNextPathName(pos).GetLength() + 1;
}
m_nPathNamesLen++;
m_lpszPathNames = new TCHAR[m_nPathNamesLen];
// copy the string
LPTSTR lpDes = m_lpszPathNames;
pos = dlg.GetStartPosition();
while (pos != NULL)
{
CString str = dlg.GetNextPathName(pos);
_tcscpy(lpDes, str);
lpDes = &lpDes[str.GetLength() + 1];
}
m_lpszPathNames[m_nPathNamesLen - 1] = _T('\0');
// Now the "ugly large buffer" is no longer useful, free it.
delete [] pszLargeBuffer;
m_bReadOnlyRef = dlg.GetReadOnlyPref();
if (::IsWindow(m_wndEdit.m_hWnd))
{
m_wndEdit.SetWindowText(m_lpszPathNames);
m_wndEdit.SetSel(0, -1);
}
m_bEditChanged = FALSE; // Discard previously changes made to the edit control
m_sEditText = m_lpszPathNames;
return IDOK;
}
void CBrowseCtrl::SetDialogTitle(LPCTSTR lpszTitle)
{
m_sDlgTitle = lpszTitle;
}
CString CBrowseCtrl::GetDialogTitle() const
{
return m_sDlgTitle;
}
void CBrowseCtrl::SetButtonText(LPCTSTR lpszText)
{
m_sButtonText = lpszText;
if ((m_dwStyle & BC_BTN_ICON) == 0 && ::IsWindow(m_hWnd))
{
RecalculateRects();
CreateEdit();
RedrawWindow();
}
}
CString CBrowseCtrl::GetButtonText() const
{
return m_sButtonText;
}
void CBrowseCtrl::DrawButtonText(CDC *pDC, COLORREF bkColor, const CRect& rect) const
{
if (m_sButtonText.IsEmpty() || rect.IsRectEmpty())
return;
CDC memDC;
CBitmap bmp;
PrepareMemDC(&memDC, &bmp, pDC, rect, bkColor);
memDC.SelectObject(GetFont());
memDC.SetBkMode(TRANSPARENT);
if (GetStyle() & WS_DISABLED)
{
memDC.SetTextColor(::GetSysColor(COLOR_3DHIGHLIGHT));
memDC.TextOut(1, 1, m_sButtonText);
memDC.SetTextColor(::GetSysColor(COLOR_3DSHADOW));
memDC.TextOut(0, 0, m_sButtonText);
}
else
{
memDC.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
memDC.TextOut(0, 0, m_sButtonText);
}
// bitblt to screen
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
// cleanup
bmp.DeleteObject();
}
void CBrowseCtrl::DrawButtonArrowFolder(CDC *pDC, COLORREF bkColor, const CRect& rect) const
{
CDC memDC;
CBitmap bmp;
PrepareMemDC(&memDC, &bmp, pDC, rect, bkColor);
CLineDraw ld(&memDC);
const BOOL DISABLED = (GetStyle() & WS_DISABLED) != 0;
int i = 0;
CPen blackPen, whitePen, yellowPen, olivePen;
blackPen.CreatePen(PS_SOLID, 1, DISABLED ? BC_COLOR_DARK : BC_COLOR_BLACK);
whitePen.CreatePen(PS_SOLID, 1, DISABLED ? BC_COLOR_WHITE : BC_COLOR_WHITE);
yellowPen.CreatePen(PS_SOLID, 1, DISABLED ? BC_COLOR_GRAY : BC_COLOR_YELLOW);
olivePen.CreatePen(PS_SOLID, 1, DISABLED ? BC_COLOR_DARK : BC_COLOR_OLIVE);
// black frame
memDC.SelectObject(&blackPen);
ld.InitOffsetMoveTo(1, 13);
ld.OffsetLineTo(10, 0);
ld.OffsetLineTo(4, -4);
ld.OffsetLineTo(0, -1);
ld.OffsetLineTo(-9, 0);
ld.OffsetLineTo(-5, 5);
ld.OffsetLineTo(0, -8);
ld.OffsetLineTo(1, -1);
ld.OffsetLineTo(2, 0);
ld.OffsetLineTo(1, 1);
ld.OffsetLineTo(6, 0);
ld.OffsetLineTo(0, 2);
// top bending arrow
ld.InitOffsetMoveTo(9, 2);
ld.OffsetLineTo(1, -1);
ld.OffsetLineTo(2, 0);
ld.OffsetLineTo(2, 2);
ld.OffsetMoveTo(1, -1);
ld.OffsetLineTo(0, 2);
ld.OffsetLineTo(-2, 0);
// Olive patterns
memDC.SelectObject(&olivePen);
ld.InitOffsetMoveTo(6, 9);
for (i = 0; i < 4; i++)
{
ld.OffsetLineTo(8, 0);
ld.OffsetMoveTo(-9, 1);
}
// yellow patterns
memDC.SelectObject(&yellowPen);
ld.InitOffsetMoveTo(2, 6);
ld.OffsetLineTo(1, -1);
ld.InitOffsetMoveTo(2, 8);
ld.OffsetLineTo(2, -2);
ld.InitOffsetMoveTo(2, 10);
ld.OffsetLineTo(4, -4);
ld.OffsetLineTo(1, 1);
ld.OffsetLineTo(1, -1);
ld.OffsetLineTo(1, 1);
ld.OffsetLineTo(1, -1);
// white patterns
memDC.SelectObject(&whitePen);
ld.InitOffsetMoveTo(2, 5);
ld.OffsetLineTo(0, 0);
ld.OffsetMoveTo(0, 2);
ld.OffsetLineTo(2, -2);
ld.InitOffsetMoveTo(2, 9);
ld.OffsetLineTo(3, -3);
ld.InitOffsetMoveTo(2, 11);
ld.OffsetLineTo(5, -5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -