⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browsectrl.cpp

📁 《MFC窗口程序设计》书籍源码 详细讲解MFC框架程序设计
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -