📄 fileeditctrl.cpp
字号:
/****************************************************************************
FileEditCtrl.cpp : implementation file for the CFileEditCtrl control class
written by PJ Arends
pja@telus.net
For updates check http://www3.telus.net/pja/CFileEditCtrl.htm
-----------------------------------------------------------------------------
This code is provided as is, with no warranty as to it's suitability or usefulness
in any application in which it may be used. This code has not been tested for
UNICODE builds, nor has it been tested on a network ( with UNC paths ).
This code may be used in any way you desire. This file may be redistributed by any
means as long as it is not sold for profit, and providing that this notice and the
authors name are included.
If any bugs are found and fixed, a note to the author explaining the problem and
fix would be nice.
-----------------------------------------------------------------------------
created : October 2000
Revision History:
Some changes by : Philippe Lhoste - PhiLho@gmx.net - http://jove.prohosting.com/~philho/
Perry Rapp - PRapp@smartronix.com
Remon - Remon@Hotmail.com
November 11, 2000 - allowed the control to work with dialog templates
November 22, 2000 - register the control's window class, can now be added to dialog as custom control
January 4, 2001 - near total rewrite of the control, now derived from CEdit
- control can now be added to dialog template using an edit control
- browse button now drawn in nonclient area of control
January 5, 2001 - removed OnKillFocus(), replaced with OnDestroy()
January 15, 2001 - added DDX_ and DDV_ support
- modified GetStartPosition() and GetNextPathName()
- modified how FECOpenFile() updates the control text when multiple files are selected
- added FillBuffers()
- added support for relative paths
- added OnChange handler
- added drag and drop support
January 26, 2001 - fixed bug where SHBrowseForFolder does not like trailing slash
January 27, 2001 - fixed bug where if control is initialized with text, FillBuffers was not called.
January 28, 2001 - removed GetFindFolder() and SetFindFolder() replaced with GetFlags() and SetFlags()
- modified the DDX_ and DDV_ functions to accept these flags
- modified the Create() function to accept these flags
- allowed option for returned folder to contain trailing slash
- allowed browse button to be on the left side of the control
- added ScreenPointInButtonRect() to better tell if mouse cursor is over the button
- modified how OnDropFiles() updates the control text when multiple files are dropped
February 25, 2001 - fixed EN_CHANGE notification bug. Now parent window recieves this notification message
used ON_CONTROL_REFLECT_EX macro instead of ON_CONTROL_REFLECT
April 12, 2001 - added OnSize handler, fixed button drawing problem when control size changed
April 21, 2001 - added a tooltip for the browse button
May 12, 2001 - removed OnDestroy, replaced with PostNCDestroy
- added tooltip support to client area
- modified the FECBrowseForFolder and FECFolderProc functions
- added a one pixel neutral area between the client area and browse button when the
button is on the right hand side of the control. (looks better IMO)
May 29, 2001 - PL -- removed the filename from the m_pCFileDialog->m_ofn.lpstrInitialDir
variable, so when browsing back for file, we open the correct folder.
- used smaller (exact size) arrays for file, extension and path components.
- some cosmetic changes.
May 29, 2001 - FECFolderProc now checks for UNC path. SHBrowseForFolder can not be initialized with UNC
June 2, 2001 - modified ButtonClicked function. Now sends a WM_NOTIFY message to parent window before
showing dialog, allows parent window to cancel action by setting result to nonzero. also
sends WM_NOTIFY message to parent window after dialog closes with successful return
June 9, 2001 - added OnNcLButtonDblClk handler. Double click on button treated as two single clicks
June 23, 2001 - placed a declaration for the FECFolderProc global callback function into the header file
- fixed bug that occured when removing the filename from the
m_pCFileDialog->m_ofn.lpstrInitialDir variable when there was no file to remove
August 2, 2001 - replaced SetWindowText() with OnSetText() message handler. now correctly handles
WM_SETTEXT messages
August 12, 2001 - added GetValidFolder() function and modified FECOpenFile() function. we now start
browsing in the correct folder -- it finally works!!! {:o)
- modified SetFlags() so the button could be moved by setting the FEC_BUTTONLEFT flag
- removed the m_bCreatingControl variable
- removed the call to SetWindowPos() from the Create() and DDX_FileEditCtrl() functions.
Now done in SetFlags() function
August 14, 2001 - modified FECOpenFile(). Now sets the file name in CFileDialog to first file name in
CFileEditCtrl
August 18, 2001 - Set the tooltip font to the same font used in the CFileEditCtrl
September 2, 2001 - added the ModifyFlags() function and changed how the flags are handled
- modified the GetFlags() function
- added the FEC_MULTIPLE and FEC_MULTIPLEFILES flags
- added support for wildcards ( '*' and '?') in filenames
Involved : modifying the GetStartPosition(), GetNextPathName(), SetFlags(), and
FillBuffers() functions
adding the ExpandWildCards() function
replacing the m_lpstrFiles variable with the m_Files array
adding the FEC_WILDCARDS flag.
September 3, 2001 - added ability to dereference shortcut files (*.lnk)
- added the FEC_NODEREFERENCELINKS flag.
- added the DereferenceLink() function.
September 5, 2001 - fixed the Create() function - now destroys the control if the SetFlags() function fails
September 8, 2001 - added the AddFiles() function to be better able to handle shortcut (*.lnk) files
modified the OnDropFiles() function to be better able to handle shortcut (*.lnk) files
September 12, 2001 - PR -- added #include <shlobj.h> to the FileEditCtrl.h header file
- UNICODE fixes, added _T() macro in Create() function and in TRACE() calls.
- Perry states that the code now works perfectly with UNICODE builds and UNC paths.
{:o) {:o) {:o) {:o) {:o) {:o) {:o) {:o) {:o) {:o) {:o) {:o)
September 18, 2001 - added ability to use icons or bitmaps on the browse button
Involved : adding SetButtonImage() function.
modifying the DrawButton() function
adding the FECButtonImage class.
September 20, 2001 - fixed resource leak in FECButtonImage class
- cleaned up the FECButtonImage class code
- added ability to resize the browse button
Involved : adding m_nButtonWidth variable
adding SetButtonWidth() and GetButtonWidth() functions
modifying OnNcCalcSize() and DrawButton() functions
September 24, 2001 - fixed bug in GetNextPathName() and ExpandWildCards() where multiple files could not
start from the current drive ie \folder\file.ext as second file would give an error
September 26, 2001 - fixed bug in GetNextPathName() to allow incomplete relative paths (ie ..\..\) when
browsing for files.
October 5, 2001 - PR -- Added #include <afxcmn.h> to the CFileEditCtrl.h header file
October 14, 2001 - rewrote the FECButtonImage::DrawImage() function, it now handles disabled transparent
bitmaps better (the transparent colour can be any colour, no longer just light colours),
and now also handles pattern and bitmap background brushes
- various other touch ups (comments mostly)
November 20, 2001 - added ability to dereference *.pif (shortcut to MS-DOS) files
November 26, 2001 - added abilty to be flat, hot to mouse (FEC_FLAT flag)
Involved : adding OnKillFocus(), OnLButtonDown(), and OnNCMouseMove() message handlers
adding Redraw() and SetReadOnly() member functions
modifying OnEnable(), OnMouseMove(), OnNCPaint(), and OnSetFocus() message handlers
modifying DrawButton() and SetFlags() member functions
modifying the CFECButtonImage::DrawImage() function
December 1, 2001 - clean up code from November 26, 2001
December 5, 2001 - added the FEC_GRAYSCALE flag. Flat buttons can be drawn in full colour or grayscale.
December 8, 2001 - greatly improved the button drawing code.
December 18, 2001 - removed the CFECButtonImage class, replaced with the CPJAImage class.
- rewrote the SetButtonImage() function.
- rewrote the DrawButton() function.
January 7, 2002 - Remon -- added the FEC_NM_DROP notification. The control now sends a WM_NOTIFY message to its
parent window after a file or folder has been dropped onto it.
January 14, 2002 - fixed a bug that prevented the tooltips from displaying properly.
February 18, 2002 - replaced SetReadOnly() with OnSetReadOnly(), the control now properly handles the
EM_SETREADONLY message.
March 27, 2002 - fixed border drawing when control is drawn flat. Now the control does not appear to
change size when it switches from edit mode to readonly or disabled.
March 28, 2002 - moved the FEC_NM_POSTBROWSE notification. Now it is sent after the dialog closes,
but before the edit control's text is updated. The parent window can now return
a nonzero value to stop the edit control from updating.
Involved : modifying the ButtonClicked(), FECBrowseForFolder() and FECOpenFile() functions
adding the pNewText pointer to the FEC_NOTIFY structure
- modified FEC_NM_DROP notification. The parent window can now return a nonzero
value to stop the edit control from updating.
April 1, 2002 - Removed the CStringArray used to store file names, now using a linked list (CStringList)
Involved : modifying the AddFile(), GetStartPosition(), GetNextPathName, and FillBuffers() functions
April 2, 2002 - Added the ability for the CFECFileDialog to dynamicly manage the memory needed by the
lpstrFile member of the OPENFILENAME structure. ( thanks to Philippe Lhoste )
Involved : adding the DoModal(), OnFileNameChange() and Reset() functions to the CFECFileDialog class
modifying the FECOpenFile() function.
November 23, 2002 - The April 2, 2002 changes did not work with WinNT and above. No idea why not. I fixed it by adding
the GetStartPosition() and GetNextPathName() functions and a destructor to the CFECFileDialog class.
I also removed the Reset() function, and modified the DoModal() and FECOpenFile() functions.
December 4, 2002 - Added the FEC_FILEOPEN and FEC_FILESAVEAS flags. FEC_FILEOPEN replaces the FEC_FILE flag.
The FEC_FILESAVEAS flag causes the browse button to open the 'File Save As' dialog.
- Improved the drawing code for flat control
****************************************************************************/
#include "stdafx.h"
#include "FileEditCtrl.h"
// see http://www.codeproject.com/tools/imageviewer.asp
//#define ACTIVATE_VIEWER
//#include <ImageViewer.h>
#ifndef __ATLCONV_H__
#include <atlconv.h> // for T2COLE() macro in DereferenceLinks() function
#endif // __ATLCONV_H__
#ifndef _INC_CDERR
#include <cderr.h> // for FNERR_BUFFERTOSMALL
#endif // _INC_CDERR
// resource.h is only needed for the string table resources. If you do not put the
// FEC_IDS_* strings in a string table, you do not need to include resource.h
#include "..\..\resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// These strings should be entered into a string table resource with the
// FEC_IDS_* identifiers defined here, although this class will work
// properly if they are not.
//
// string usage:
//
// FEC_IDS_ALLFILES - default file filter for CFileDialog
// FEC_IDS_BUTTONTIP - Text for the browse button tooltip
// FEC_IDS_FILEDIALOGTITLE - default dialog caption for CFileDialog
// FEC_IDS_SEPARATOR - character used to seperate files when FEC_MULTIPLE flag is used
// FEC_IDS_NOFILE - Error message for DDV_FileEditCtrl() when no files or folders are entered
// FEC_IDS_NOTEXIST - Error message for DDV_FileEditCtrl() when the specified file or folder could not be found
// FEC_IDS_NOTFILE - Error message for DDV_FileEditCtrl() when the specified file is actually a folder
// FEC_IDS_NOTFOLDER - Error message for DDV_FileEditCtrl() when the specified folder is actually a file
// FEC_IDS_OKBUTTON - Text for the 'OK' (Open) button on CFileDialog
//
// FEC_IDS_ALLFILES will be defined in resource.h if these strings
// are in a string table resource
#if !defined FEC_IDS_ALLFILES
#define FEC_NORESOURCESTRINGS /* so this class knows how to handle these strings */
#define FEC_IDS_ALLFILES _T("所有文件 (*.*)|*.*||")
#define FEC_IDS_BUTTONTIP _T("浏览")
#define FEC_IDS_FILEDIALOGTITLE _T("浏览文件")
#define FEC_IDS_SEPARATOR _T(";")
#define FEC_IDS_NOFILE _T("Enter an existing file.")
#define FEC_IDS_NOTEXIST _T("%s does not exist.")
#define FEC_IDS_NOTFILE _T("%s is not a file.")
#define FEC_IDS_NOTFOLDER _T("%s is not a folder.")
#define FEC_IDS_OKBUTTON _T("OK")
#endif
/////////////////////////////////////////////////////////////////////////////
// Button states
#define BTN_UP 0x01
#define BTN_DOWN 0x02
#define BTN_DISABLED 0x04
#define BTN_FLAT 0x08
/////////////////////////////////////////////////////////////////////////////
// ToolTip IDs
#define ID_BUTTONTIP 1
#define ID_CLIENTTIP 2
/////////////////////////////////////////////////////////////////////////////
// Brush sizes for drawing the button background
#define BRUSHWIDTH 8
#define BRUSHHEIGHT 8
/////////////////////////////////////////////////////////////////////////////
// Helper functions
/////////////////////////////////////////////////////////////////////////////
//
// IsWindow (Global function)
// Checks if the given window is active
//
// Parameters :
// pWnd [in] - points to the CWnd object to check
//
// Returns :
// TRUE if the window is active
// FALSE if not
//
/////////////////////////////////////////////////////////////////////////////
BOOL IsWindow(CWnd *pWnd)
{
if (!pWnd)
return FALSE;
return ::IsWindow(pWnd->m_hWnd);
}
/////////////////////////////////////////////////////////////////////////////
// CFileEditCtrl
IMPLEMENT_DYNAMIC(CFileEditCtrl, CEdit)
/////////////////////////////////////////////////////////////////////////////
//
// CFileEditCtrl constructor (public member function)
// Initializes all the internal variables
//
// Parameters :
// bAutoDelete [in] - Auto delete flag
//
// Returns :
// Nothing
//
// Note :
// If bAutoDelete is TRUE, this class object will be deleted
// when it's window is destroyed (in CFileEditCtrl::PostNCDestroy).
// The only time this should be used is when the control is
// created dynamicly in the
// DDX_FileEditCtrl(CDataExchange*,int,CString&,DWORD) function.
//
/////////////////////////////////////////////////////////////////////////////
CFileEditCtrl::CFileEditCtrl(BOOL bAutoDelete /* = FALSE */)
{
m_bAutoDelete = bAutoDelete;
m_bButtonLeft = (DWORD)~0; // 0xFFFFFFFF
m_bMouseCaptured = FALSE;
m_bTextChanged = TRUE;
m_dwFlags = 0;
m_dwImageDrawFlags = 0;
m_Files.RemoveAll();
m_nButtonState = BTN_UP;
m_nButtonWidth = -1;
m_pBROWSEINFO = NULL;
m_rcButtonRect.SetRectEmpty();
m_szCaption.Empty();
m_szClientTip.Empty();
m_szFolder.Empty();
m_bIsFocused = FALSE;
m_bIsMouseOver = FALSE;
m_strFilter = FEC_IDS_ALLFILES;
#ifdef AFX_PJAIMAGE_H__F15965B0_B05A_11D4_B625_A1459D96AB20__INCLUDED_
m_pButtonImage = NULL;
#endif
}
/////////////////////////////////////////////////////////////////////////////
//
// CFileEditCtrl destructor (public member function)
// cleans up internal data variables
//
// Parameters :
// None
//
// Returns :
// Nothing
//
/////////////////////////////////////////////////////////////////////////////
CFileEditCtrl::~CFileEditCtrl()
{
if (m_pBROWSEINFO)
delete m_pBROWSEINFO;
#ifdef AFX_PJAIMAGE_H__F15965B0_B05A_11D4_B625_A1459D96AB20__INCLUDED_
if (m_pButtonImage)
delete m_pButtonImage;
#endif
}
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -