1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (c) 2003 by Andreas Kapust <info@akinstaller.de>; <http://www.codeproject.com/Articles/2607/AutoComplete-without-IAutoComplete>
4 // Copyright (C) 2009,2012-2013,2015 - TortoiseGit
6 // Licensed under: The Code Project Open License (CPOL); <http://www.codeproject.com/info/cpol10.aspx>
8 // ACEdit.cpp: Implementierungsdatei
19 static char THIS_FILE
[] = __FILE__
;
25 /////////////////////////////////////////////////////////////////////////////
30 m_iMode
= _MODE_STANDARD_
;
41 /*********************************************************************/
48 /*********************************************************************/
50 BEGIN_MESSAGE_MAP(CACEdit
, CWnd
)
51 //{{AFX_MSG_MAP(CACEdit)
52 ON_CONTROL_REFLECT(EN_KILLFOCUS
, OnKillfocus
)
53 ON_CONTROL_REFLECT(CBN_KILLFOCUS
, OnKillfocus
)
55 ON_CONTROL_REFLECT(EN_CHANGE
, OnChange
)
56 ON_CONTROL_REFLECT(CBN_EDITCHANGE
, OnChange
)
57 ON_CONTROL_REFLECT(CBN_DROPDOWN
, OnCloseList
)
59 ON_MESSAGE(ENAC_UPDATE
,OnUpdateFromList
)
62 /*********************************************************************/
64 void CACEdit::SetMode(int iMode
)
73 ** NEW: _MODE_CURSOR_O_LIST_
75 if(iMode
== _MODE_CURSOR_O_LIST_
)
76 m_iMode
|= _MODE_STANDARD_
;
78 if(iMode
& _MODE_FILESYSTEM_
)
79 m_SeparationStr
= _T("\\");
82 if(iMode
& _MODE_FIND_ALL_
)
84 m_Liste
.m_lMode
|= _MODE_FIND_ALL_
;
88 /*********************************************************************/
92 CString szClassName
= AfxRegisterWndClass(CS_CLASSDC
|CS_SAVEBITS
|CS_HREDRAW
|CS_VREDRAW
,
93 0,(HBRUSH
) (COLOR_WINDOW
), 0);
97 VERIFY(m_Liste
.CreateEx(WS_EX_TOOLWINDOW
,
99 WS_THICKFRAME
| WS_CHILD
| WS_BORDER
|
100 WS_CLIPSIBLINGS
| WS_OVERLAPPED
,
101 CRect(rcWnd
.left
, rcWnd
.top
+20, rcWnd
.left
+ 200, rcWnd
.top
+200),
106 ::GetClassName(GetSafeHwnd(), m_ClassName
.GetBuffer(32), 32);
107 m_ClassName
.ReleaseBuffer();
109 if (m_ClassName
.Compare(_T("Edit")) == 0)
115 if (m_ClassName
.Compare(_T("ComboBox")) == 0)
117 m_iType
= _COMBOBOX_
;
119 m_pEdit
= (CEdit
*)GetWindow(GW_CHILD
);
121 ::GetClassName(m_pEdit
->GetSafeHwnd(), m_ClassName
.GetBuffer(32), 32);
122 m_ClassName
.ReleaseBuffer();
123 VERIFY(m_ClassName
.Compare(_T("Edit")) == 0);
136 /*********************************************************************/
138 void CACEdit::AddSearchStrings(LPCTSTR Strings
[])
142 if(m_iType
== -1) {ASSERT(0); return;}
151 m_Liste
.AddSearchString(str
);
158 m_Liste
.SortSearchList();
161 /*********************************************************************/
163 void CACEdit::AddSearchString(LPCTSTR lpszString
)
165 if(m_iType
== -1) {ASSERT(0); return;}
167 m_Liste
.AddSearchString(lpszString
);
170 /*********************************************************************/
172 void CACEdit::RemoveSearchAll()
174 if(m_iType
== -1) {ASSERT(0); return;}
179 /*********************************************************************/
181 void CACEdit::OnKillfocus()
183 if(m_Liste
.GetSafeHwnd()) // fix Vers 1.1
184 m_Liste
.ShowWindow(false);
187 /*********************************************************************/
189 void CACEdit::OnKeyDown(UINT nChar
, UINT nRepCnt
, UINT nFlags
)
191 if(!HandleKey(nChar
,false))
192 CWnd::OnKeyDown(nChar
, nRepCnt
, nFlags
);
195 /*********************************************************************/
197 bool CACEdit::HandleKey(UINT nChar
, bool m_bFromChild
)
199 if (nChar
== VK_ESCAPE
||nChar
== VK_RETURN
)
201 m_Liste
.ShowWindow(false);
205 if (nChar
== VK_DOWN
|| nChar
== VK_UP
206 || nChar
== VK_PRIOR
|| nChar
== VK_NEXT
207 || nChar
== VK_HOME
|| nChar
== VK_END
)
211 ** NEW: _MODE_CURSOR_O_LIST_
213 if(!m_Liste
.IsWindowVisible() && (m_iMode
& _MODE_CURSOR_O_LIST_
))
215 GetWindowText(m_EditText
);
216 if(m_EditText
.IsEmpty())
223 if(m_Liste
.IsWindowVisible())
228 if(m_iMode
& _MODE_STANDARD_
229 || m_iMode
& _MODE_FILESYSTEM_
230 || m_iMode
& _MODE_FS_START_DIR_
)
235 m_EditText
= m_Liste
.GetNextString(nChar
);
237 m_EditText
= m_Liste
.GetString();
239 if(m_iMode
& _MODE_FILESYSTEM_
)
241 if (m_EditText
.Right(1) == _T('\\'))
242 m_EditText
= m_EditText
.Mid(0,m_EditText
.GetLength()-1);
245 m_Liste
.SelectItem(-1);
246 SetWindowText(m_EditText
);
247 pos
= m_EditText
.GetLength();
249 if(m_iType
== _COMBOBOX_
)
251 m_pEdit
->SetSel(pos
,pos
,true);
252 m_pEdit
->SetModify(true);
255 if(m_iType
== _EDIT_
)
257 ((CEdit
*)this)->SetSel(pos
,pos
,true);
258 ((CEdit
*)this)->SetModify(true);
261 GetParent()->SendMessage(ENAC_UPDATE
, WM_KEYDOWN
, GetDlgCtrlID());
262 m_CursorMode
= false;
266 if(m_iMode
& _MODE_SEPARATION_
)
268 CString m_Text
,m_Left
,m_Right
;
269 int left
,right
,pos2
=0,len
;
273 GetWindowText(m_EditText
);
275 if(m_iType
== _EDIT_
)
276 pos2
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
278 if(m_iType
== _COMBOBOX_
)
279 pos2
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
281 left
= FindSepLeftPos(pos2
-1,true);
282 right
= FindSepRightPos(pos2
);
284 m_Text
= m_EditText
.Left(left
);
287 m_Text
+= m_Liste
.GetNextString(nChar
);
289 m_Text
+= m_Liste
.GetString();
291 m_Liste
.SelectItem(-1);
292 m_Text
+= m_EditText
.Mid(right
);
293 len
= m_Liste
.GetString().GetLength();
295 m_Text
+= this->m_SeparationStr
;
297 SetWindowText(m_Text
);
298 GetParent()->SendMessage(ENAC_UPDATE
, WM_KEYDOWN
, GetDlgCtrlID());
300 right
= FindSepLeftPos2(pos2
-1);
304 left
+=m_SeparationStr
.GetLength();
306 if(m_iType
== _EDIT_
)
308 ((CEdit
*)this)->SetModify(true);
309 ((CEdit
*)this)->SetSel(left
+len
,left
+len
,false);
312 if(m_iType
== _COMBOBOX_
)
314 m_pEdit
->SetModify(true);
315 m_pEdit
->SetSel(left
,left
+len
,true);
318 m_CursorMode
= false;
326 /*********************************************************************/
328 void CACEdit::OnChange()
336 GetWindowText(m_EditText
);
337 len
= m_EditText
.GetLength();
338 //----------------------------------------------
339 if(m_iMode
& _MODE_FILESYSTEM_
|| m_iMode
& _MODE_FS_START_DIR_
)
343 if(m_iType
== _EDIT_
)
344 pos
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
346 if(m_iType
== _COMBOBOX_
)
347 pos
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
349 if(m_iMode
& _MODE_FS_START_DIR_
)
352 m_Liste
.FindString(-1,m_EditText
);
354 m_Liste
.ShowWindow(false);
358 if(len
> 2 && pos
== len
)
360 if(_taccess(m_EditText
,0) == 0)
362 ReadDirectory(m_EditText
);
364 m_Liste
.FindString(-1,m_EditText
);
367 m_Liste
.ShowWindow(false);
371 //----------------------------------------------
372 if(m_iMode
& _MODE_SEPARATION_
)
376 if(m_iType
== _EDIT_
)
377 pos
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
379 if(m_iType
== _COMBOBOX_
)
380 pos
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
383 left
= FindSepLeftPos(pos
-1);
384 right
= FindSepRightPos(pos
);
385 m_Text
= m_EditText
.Mid(left
,right
-left
);
386 m_Liste
.FindString(-1,m_Text
);
389 //----------------------------------------------
390 if(m_iMode
& _MODE_STANDARD_
)
393 m_Liste
.FindString(-1,m_EditText
);
395 //----------------------------------------------
396 GetParent()->SendMessage(ENAC_UPDATE
, EN_UPDATE
, GetDlgCtrlID());
399 /*********************************************************************/
401 int CACEdit::FindSepLeftPos(int pos
,bool m_bIncludePrefix
)
403 int len
= m_EditText
.GetLength();
407 if(pos
>= len
&& len
!= 1)
410 for(i
= pos
; i
>= 0 ; i
--)
412 ch
= m_EditText
.GetAt(i
);
413 if(m_PrefixChar
== ch
)
414 return i
+ (m_bIncludePrefix
? 1 : 0);
415 if(m_SeparationStr
.Find(ch
) != -1)
422 /*********************************************************************/
424 int CACEdit::FindSepLeftPos2(int pos
)
426 int len
= m_EditText
.GetLength();
429 if(pos
>= len
&& len
!= 1)
435 for(int i
= pos
; i
>= 0 ; i
--)
437 ch
= m_EditText
.GetAt(i
);
438 if(m_PrefixChar
== ch
)
445 /*********************************************************************/
447 int CACEdit::FindSepRightPos(int pos
)
449 int len
= m_EditText
.GetLength();
453 for(i
= pos
; i
< len
; i
++)
455 ch
= m_EditText
.GetAt(i
);
456 if(m_SeparationStr
.Find(ch
) != -1)
463 /*********************************************************************/
464 LRESULT
CACEdit::OnUpdateFromList(WPARAM lParam
, LPARAM
/*wParam*/)
468 if(lParam
== WM_KEYDOWN
)
470 HandleKey(VK_DOWN
,true);
475 /*********************************************************************/
477 void CACEdit::OnCloseList()
479 m_Liste
.ShowWindow(false);
482 /*********************************************************************/
484 BOOL
CACEdit::PreTranslateMessage(MSG
* pMsg
)
486 if(pMsg
->message
== WM_KEYDOWN
)
488 if(m_Liste
.IsWindowVisible())
490 if(m_iType
== _COMBOBOX_
)
492 if(pMsg
->wParam
== VK_DOWN
|| pMsg
->wParam
== VK_UP
)
493 if (HandleKey((UINT
)pMsg
->wParam
, false))
497 if(pMsg
->wParam
== VK_ESCAPE
|| pMsg
->wParam
== VK_RETURN
)
498 if (HandleKey((UINT
)pMsg
->wParam
, false))
502 return CWnd::PreTranslateMessage(pMsg
);
505 /*********************************************************************/
507 void CACEdit::ReadDirectory(CString m_Dir
)
509 CFileFind FoundFiles
;
513 // Wenn mittem im Pfad,
514 // vorheriges Verzeichnis einlesen.
515 if (m_Dir
.Right(1) != _T('\\'))
517 _tsplitpath_s(m_Dir
, m_szDrive
, m_szDir
, m_szFname
, m_szExt
);
518 m_Dir
.Format(_T("%s%s"),m_szDrive
, m_szDir
);
522 ch
= (TCHAR
)towupper(m_Dir
.GetAt(0));
525 CString m_Name
,m_File
,m_Dir1
= m_Dir
;
526 if (m_Dir
.Right(1) != _T('\\'))
529 if(m_LastDirectory
.CompareNoCase(m_Dir
) == 0 && m_Liste
.m_SearchList
.GetSize())
532 m_LastDirectory
= m_Dir
;
535 BOOL bContinue
= FoundFiles
.FindFile(m_Dir
);
539 while (bContinue
== TRUE
)
541 bContinue
= FoundFiles
.FindNextFile();
542 m_File
= FoundFiles
.GetFileName();
544 if(FoundFiles
.IsHidden() || FoundFiles
.IsSystem())
546 if(FoundFiles
.IsDirectory())
548 if(m_iMode
& _MODE_ONLY_FILES
)
550 if(FoundFiles
.IsDots())
553 if (m_File
.Right(1) != _T('\\'))
557 if(!FoundFiles
.IsDirectory())
558 if(m_iMode
& _MODE_ONLY_DIRS
)
561 if(m_iMode
& _MODE_FS_START_DIR_
)
568 if (m_Name
.Right(1) != _T('\\'))
574 AddSearchString(m_Name
);
581 /*********************************************************************/
583 void CACEdit::SetStartDirectory(LPCTSTR lpszString
)
585 if(m_iType
== -1) {ASSERT(0); return;}
587 if(m_iMode
& _MODE_FS_START_DIR_
)
588 ReadDirectory(lpszString
);
591 /*********************************************************************
594 *********************************************************************/
596 int CACEdit::AddString( LPCTSTR lpszString
)
598 if(m_iType
== _COMBOBOX_
)
600 return ((CComboBox
*)this)->AddString(lpszString
);
605 /*********************************************************************/
607 int CACEdit::SetDroppedWidth( UINT nWidth
)
609 if(m_iType
== _COMBOBOX_
)
611 return ((CComboBox
*)this)->SetDroppedWidth(nWidth
);
616 /*********************************************************************/
618 int CACEdit::FindString( int nStartAfter
, LPCTSTR lpszString
)
620 if(m_iType
== _COMBOBOX_
)
622 return ((CComboBox
*)this)->FindString(nStartAfter
,lpszString
);
627 /*********************************************************************/
629 int CACEdit::SelectString( int nStartAfter
, LPCTSTR lpszString
)
631 if(m_iType
== _COMBOBOX_
)
633 return ((CComboBox
*)this)->SelectString(nStartAfter
,lpszString
);
638 /*********************************************************************/
640 void CACEdit::ShowDropDown(BOOL bShowIt
)
642 if(m_iType
== _COMBOBOX_
)
644 ((CComboBox
*)this)->ShowDropDown(bShowIt
);
648 /*********************************************************************/
650 void CACEdit::ResetContent()
652 if(m_iType
== _COMBOBOX_
)
654 ((CComboBox
*)this)->ResetContent();
658 /*********************************************************************/
660 int CACEdit::GetCurSel()
662 if(m_iType
== _COMBOBOX_
)
664 return ((CComboBox
*)this)->GetCurSel();
669 /*********************************************************************/
671 int CACEdit::GetLBText( int nIndex
, LPTSTR lpszText
)
673 if(m_iType
== _COMBOBOX_
)
675 return ((CComboBox
*)this)->GetLBText(nIndex
,lpszText
);
680 /*********************************************************************/
682 void CACEdit::GetLBText( int nIndex
, CString
& rString
)
684 if(m_iType
== _COMBOBOX_
)
686 ((CComboBox
*)this)->GetLBText(nIndex
,rString
);
690 /*********************************************************************/