DropEdit.cpp
上传用户:abc_ningbo
上传日期:2007-01-02
资源大小:13k
文件大小:5k
源码类别:

编辑框

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // CDropEdit
  4. // Copyright 1997 Chris Losinger
  5. //
  6. // This code is freely distributable and modifiable, as long as credit
  7. // is given to where it's due. Watch, I'll demonstrate :
  8. //
  9. // shortcut expansion code modified from :
  10. // CShortcut, 1996 Rob Warner
  11. //
  12. ////
  13. //
  14. // To use this in an app, you'll need to :
  15. //
  16. // 1) #include <afxole.h> in stdafx.h
  17. //
  18. // 2) in your CWinApp-derived class *::InitInstance, you'll need to call
  19. // ::CoInitialize(NULL);
  20. //
  21. // 3) in your CWinApp-derived class *::ExitInstance, you'll need to call
  22. // ::CoUninitialize();
  23. //
  24. // 4) Place a normal edit control on your dialog. 
  25. // 5) Check the "Accept Files" property.
  26. //
  27. // 6) In your dialog class, declare a member variable of type CDropEdit
  28. // (be sure to #include "CDropEdit.h")
  29. // ex. CDropEdit m_dropEdit;
  30. //
  31. // 7) In your dialog's OnInitDialog, call
  32. // m_dropEdit.SubclassDlgItem(IDC_YOUR_EDIT_ID, this);
  33. //
  34. // 8) if you want the edit control to handle directories, call
  35. // m_dropEdit.SetUseDir(TRUE);
  36. //
  37. // 9) if you want the edit control to handle files, call
  38. // m_dropEdit.SetUseDir(FALSE);
  39. //
  40. // that's it!
  41. //
  42. // This will behave exactly like a normal edit-control but with the 
  43. // ability to accept drag-n-dropped files (or directories).
  44. //
  45. //
  46. #include "stdafx.h"
  47. #include "resource.h"
  48. #include "DropEdit.h"
  49. #include <sys/types.h>
  50. #include <sys/stat.h>
  51. #ifdef _DEBUG
  52. #define new DEBUG_NEW
  53. #undef THIS_FILE
  54. static char THIS_FILE[] = __FILE__;
  55. #endif
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CDropEdit
  58. CDropEdit::CDropEdit()
  59. {
  60. m_bUseDir=FALSE;
  61. }
  62. CDropEdit::~CDropEdit()
  63. {
  64. }
  65. BEGIN_MESSAGE_MAP(CDropEdit, CEdit)
  66. //{{AFX_MSG_MAP(CDropEdit)
  67. ON_WM_CREATE()
  68. ON_WM_DROPFILES()
  69. //}}AFX_MSG_MAP
  70. END_MESSAGE_MAP()
  71. /////////////////////////////////////////////////////////////////////////////
  72. // CDropEdit message handlers
  73. int CDropEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  74. {
  75. if (CEdit::OnCreate(lpCreateStruct) == -1)
  76. return -1;
  77. DragAcceptFiles(TRUE);
  78. return 0;
  79. }
  80. //
  81. // handle WM_DROPFILES
  82. //
  83. void CDropEdit::OnDropFiles(HDROP dropInfo)
  84. {
  85. // Get the number of pathnames that have been dropped
  86. WORD wNumFilesDropped = DragQueryFile(dropInfo, -1, NULL, 0);
  87. CString firstFile="";
  88. // get all file names. but we'll only need the first one.
  89. for (WORD x = 0 ; x < wNumFilesDropped; x++) {
  90. // Get the number of bytes required by the file's full pathname
  91. WORD wPathnameSize = DragQueryFile(dropInfo, x, NULL, 0);
  92. // Allocate memory to contain full pathname & zero byte
  93. char * npszFile = (char *) LocalAlloc(LPTR, wPathnameSize += 1);
  94. // If not enough memory, skip this one
  95. if (npszFile == NULL) continue;
  96. // Copy the pathname into the buffer
  97. DragQueryFile(dropInfo, x, npszFile, wPathnameSize);
  98. // we only care about the first
  99. if (firstFile=="")
  100. firstFile=npszFile;
  101. // clean up
  102. LocalFree(npszFile);
  103. }
  104. // Free the memory block containing the dropped-file information
  105. DragFinish(dropInfo);
  106. // if this was a shortcut, we need to expand it to the target path
  107. CString expandedFile = ExpandShortcut(firstFile);
  108. // if that worked, we should have a real file name
  109. if (expandedFile!="") 
  110. firstFile=expandedFile;
  111. struct _stat buf;
  112. // get some info about that file
  113. int result = _stat( firstFile, &buf );
  114. if( result == 0 ) {
  115. // verify that we have a dir (if we want dirs)
  116. if ((buf.st_mode & _S_IFDIR) == _S_IFDIR) {
  117. if (m_bUseDir)
  118. SetWindowText(firstFile);
  119. // verify that we have a file (if we want files)
  120. } else if ((buf.st_mode & _S_IFREG) == _S_IFREG) {
  121. if (!m_bUseDir)
  122. SetWindowText(firstFile);
  123. }
  124. }
  125. }
  126. //////////////////////////////////////////////////////////////////
  127. // use IShellLink to expand the shortcut
  128. // returns the expanded file, or "" on error
  129. //
  130. // original code was part of CShortcut 
  131. // 1996 by Rob Warner
  132. // rhwarner@southeast.net
  133. // http://users.southeast.net/~rhwarner
  134. CString CDropEdit::ExpandShortcut(CString &inFile)
  135. {
  136. CString outFile = "";
  137.     // Make sure we have a path
  138.     ASSERT(inFile != _T(""));
  139.     IShellLink* psl;
  140.     HRESULT hres;
  141.     LPTSTR lpsz = inFile.GetBuffer(MAX_PATH);
  142.     // Create instance for shell link
  143.     hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  144.         IID_IShellLink, (LPVOID*) &psl);
  145.     if (SUCCEEDED(hres))
  146.     {
  147.         // Get a pointer to the persist file interface
  148.         IPersistFile* ppf;
  149.         hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) &ppf);
  150.         if (SUCCEEDED(hres))
  151.         {
  152.             // Make sure it's ANSI
  153.             WORD wsz[MAX_PATH];
  154.             ::MultiByteToWideChar(CP_ACP, 0, lpsz, -1, wsz, MAX_PATH);
  155.             // Load shortcut
  156.             hres = ppf->Load(wsz, STGM_READ);
  157.             if (SUCCEEDED(hres)) {
  158. WIN32_FIND_DATA wfd;
  159. // find the path from that
  160. HRESULT hres = psl->GetPath(outFile.GetBuffer(MAX_PATH), 
  161. MAX_PATH,
  162. &wfd, 
  163. SLGP_UNCPRIORITY);
  164. outFile.ReleaseBuffer();
  165.             }
  166.             ppf->Release();
  167.         }
  168.         psl->Release();
  169.     }
  170. inFile.ReleaseBuffer();
  171. // if this fails, outFile == ""
  172.     return outFile;
  173. }