1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "../DragDropImpl.h"
22 #include "../UnicodeUtils.h"
26 * helper class to turn a control into a file drop target
28 class CFileDropTarget
: public CIDropTarget
31 CFileDropTarget(HWND hTargetWnd
):CIDropTarget(hTargetWnd
){}
32 virtual bool OnDrop(FORMATETC
* pFmtEtc
, STGMEDIUM
& medium
, DWORD
* /*pdwEffect*/, POINTL
/*pt*/)
34 if(pFmtEtc
->cfFormat
== CF_TEXT
&& medium
.tymed
== TYMED_ISTREAM
)
36 if(medium
.pstm
!= NULL
)
38 const int BUF_SIZE
= 10000;
39 char buff
[BUF_SIZE
+1];
41 HRESULT hr
= medium
.pstm
->Read(buff
, BUF_SIZE
, &cbRead
);
42 if( SUCCEEDED(hr
) && cbRead
> 0 && cbRead
< BUF_SIZE
)
45 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
46 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
47 std::wstring str
= CUnicodeUtils::StdGetUnicode(std::string(buff
));
48 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)str
.c_str());
51 for(;(hr
==S_OK
&& cbRead
>0) && SUCCEEDED(hr
) ;)
54 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
55 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
56 std::wstring str
= CUnicodeUtils::StdGetUnicode(std::string(buff
));
57 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)str
.c_str());
59 hr
= medium
.pstm
->Read(buff
, BUF_SIZE
, &cbRead
);
63 if(pFmtEtc
->cfFormat
== CF_UNICODETEXT
&& medium
.tymed
== TYMED_ISTREAM
)
65 if(medium
.pstm
!= NULL
)
67 const int BUF_SIZE
= 10000;
68 TCHAR buff
[BUF_SIZE
+1];
70 HRESULT hr
= medium
.pstm
->Read(buff
, BUF_SIZE
, &cbRead
);
71 if( SUCCEEDED(hr
) && cbRead
> 0 && cbRead
< BUF_SIZE
)
74 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
75 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
76 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)buff
);
79 for(;(hr
==S_OK
&& cbRead
>0) && SUCCEEDED(hr
) ;)
82 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
83 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
84 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)buff
);
86 hr
= medium
.pstm
->Read(buff
, BUF_SIZE
, &cbRead
);
90 if(pFmtEtc
->cfFormat
== CF_TEXT
&& medium
.tymed
== TYMED_HGLOBAL
)
92 char* pStr
= (char*)GlobalLock(medium
.hGlobal
);
95 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
96 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
97 std::wstring str
= CUnicodeUtils::StdGetUnicode(std::string(pStr
));
98 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)str
.c_str());
100 GlobalUnlock(medium
.hGlobal
);
102 if(pFmtEtc
->cfFormat
== CF_UNICODETEXT
&& medium
.tymed
== TYMED_HGLOBAL
)
104 WCHAR
* pStr
= (WCHAR
*)GlobalLock(medium
.hGlobal
);
107 LRESULT nLen
= ::SendMessage(m_hTargetWnd
, WM_GETTEXTLENGTH
, 0, 0);
108 ::SendMessage(m_hTargetWnd
, EM_SETSEL
, nLen
, -1);
109 ::SendMessage(m_hTargetWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)pStr
);
111 GlobalUnlock(medium
.hGlobal
);
113 if(pFmtEtc
->cfFormat
== CF_HDROP
&& medium
.tymed
== TYMED_HGLOBAL
)
115 HDROP hDrop
= (HDROP
)GlobalLock(medium
.hGlobal
);
118 TCHAR szFileName
[MAX_PATH
];
120 UINT cFiles
= DragQueryFile(hDrop
, 0xFFFFFFFF, NULL
, 0);
121 for(UINT i
= 0; i
< cFiles
; ++i
)
123 DragQueryFile(hDrop
, i
, szFileName
, sizeof(szFileName
));
124 ::SendMessage(m_hTargetWnd
, WM_SETTEXT
, 0, (LPARAM
)szFileName
);
126 //DragFinish(hDrop); // base class calls ReleaseStgMedium
128 GlobalUnlock(medium
.hGlobal
);
130 return true; //let base free the medium
138 * Enhancement for a CEdit control which allows the edit control to have files
139 * dropped onto it and fill in the path of that dropped file.
141 class CFileDropEdit
: public CEdit
143 DECLARE_DYNAMIC(CFileDropEdit
)
147 virtual ~CFileDropEdit();
150 DECLARE_MESSAGE_MAP()
152 CFileDropTarget
* m_pDropTarget
;
153 virtual void PreSubclassWindow();