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-2016 - 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)
113 if (m_ClassName
.Compare(_T("ComboBox")) == 0)
115 m_iType
= _COMBOBOX_
;
117 m_pEdit
= (CEdit
*)GetWindow(GW_CHILD
);
119 ::GetClassName(m_pEdit
->GetSafeHwnd(), m_ClassName
.GetBuffer(32), 32);
120 m_ClassName
.ReleaseBuffer();
121 VERIFY(m_ClassName
.Compare(_T("Edit")) == 0);
134 /*********************************************************************/
136 void CACEdit::AddSearchStrings(LPCTSTR Strings
[])
140 if(m_iType
== -1) {ASSERT(0); return;}
149 m_Liste
.AddSearchString(str
);
156 m_Liste
.SortSearchList();
159 /*********************************************************************/
161 void CACEdit::AddSearchString(LPCTSTR lpszString
)
163 if(m_iType
== -1) {ASSERT(0); return;}
165 m_Liste
.AddSearchString(lpszString
);
168 /*********************************************************************/
170 void CACEdit::RemoveSearchAll()
172 if(m_iType
== -1) {ASSERT(0); return;}
177 /*********************************************************************/
179 void CACEdit::OnKillfocus()
181 if(m_Liste
.GetSafeHwnd()) // fix Vers 1.1
182 m_Liste
.ShowWindow(false);
185 /*********************************************************************/
187 void CACEdit::OnKeyDown(UINT nChar
, UINT nRepCnt
, UINT nFlags
)
189 if(!HandleKey(nChar
,false))
190 CWnd::OnKeyDown(nChar
, nRepCnt
, nFlags
);
193 /*********************************************************************/
195 bool CACEdit::HandleKey(UINT nChar
, bool m_bFromChild
)
197 if (nChar
== VK_ESCAPE
||nChar
== VK_RETURN
)
199 m_Liste
.ShowWindow(false);
203 if (nChar
== VK_DOWN
|| nChar
== VK_UP
204 || nChar
== VK_PRIOR
|| nChar
== VK_NEXT
205 || nChar
== VK_HOME
|| nChar
== VK_END
)
209 ** NEW: _MODE_CURSOR_O_LIST_
211 if(!m_Liste
.IsWindowVisible() && (m_iMode
& _MODE_CURSOR_O_LIST_
))
213 GetWindowText(m_EditText
);
214 if(m_EditText
.IsEmpty())
221 if(m_Liste
.IsWindowVisible())
226 if(m_iMode
& _MODE_STANDARD_
227 || m_iMode
& _MODE_FILESYSTEM_
228 || m_iMode
& _MODE_FS_START_DIR_
)
233 m_EditText
= m_Liste
.GetNextString(nChar
);
235 m_EditText
= m_Liste
.GetString();
237 if(m_iMode
& _MODE_FILESYSTEM_
)
239 if (m_EditText
.Right(1) == _T('\\'))
240 m_EditText
= m_EditText
.Mid(0,m_EditText
.GetLength()-1);
243 m_Liste
.SelectItem(-1);
244 SetWindowText(m_EditText
);
245 pos
= m_EditText
.GetLength();
247 if(m_iType
== _COMBOBOX_
)
249 m_pEdit
->SetSel(pos
,pos
,true);
250 m_pEdit
->SetModify(true);
253 if(m_iType
== _EDIT_
)
255 ((CEdit
*)this)->SetSel(pos
,pos
,true);
256 ((CEdit
*)this)->SetModify(true);
259 GetParent()->SendMessage(ENAC_UPDATE
, WM_KEYDOWN
, GetDlgCtrlID());
260 m_CursorMode
= false;
264 if(m_iMode
& _MODE_SEPARATION_
)
266 CString m_Text
,m_Left
,m_Right
;
267 int left
,right
,pos2
=0,len
;
271 GetWindowText(m_EditText
);
273 if(m_iType
== _EDIT_
)
274 pos2
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
276 if(m_iType
== _COMBOBOX_
)
277 pos2
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
279 left
= FindSepLeftPos(pos2
-1,true);
280 right
= FindSepRightPos(pos2
);
282 m_Text
= m_EditText
.Left(left
);
285 m_Text
+= m_Liste
.GetNextString(nChar
);
287 m_Text
+= m_Liste
.GetString();
289 m_Liste
.SelectItem(-1);
290 m_Text
+= m_EditText
.Mid(right
);
291 len
= m_Liste
.GetString().GetLength();
293 m_Text
+= this->m_SeparationStr
;
295 SetWindowText(m_Text
);
296 GetParent()->SendMessage(ENAC_UPDATE
, WM_KEYDOWN
, GetDlgCtrlID());
298 right
= FindSepLeftPos2(pos2
-1);
302 left
+=m_SeparationStr
.GetLength();
304 if(m_iType
== _EDIT_
)
306 ((CEdit
*)this)->SetModify(true);
307 ((CEdit
*)this)->SetSel(left
+len
,left
+len
,false);
310 if(m_iType
== _COMBOBOX_
)
312 m_pEdit
->SetModify(true);
313 m_pEdit
->SetSel(left
,left
+len
,true);
316 m_CursorMode
= false;
324 /*********************************************************************/
326 void CACEdit::OnChange()
334 GetWindowText(m_EditText
);
335 len
= m_EditText
.GetLength();
336 //----------------------------------------------
337 if(m_iMode
& _MODE_FILESYSTEM_
|| m_iMode
& _MODE_FS_START_DIR_
)
341 if(m_iType
== _EDIT_
)
342 pos
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
344 if(m_iType
== _COMBOBOX_
)
345 pos
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
347 if(m_iMode
& _MODE_FS_START_DIR_
)
350 m_Liste
.FindString(-1,m_EditText
);
352 m_Liste
.ShowWindow(false);
356 if(len
> 2 && pos
== len
)
358 if(_taccess(m_EditText
,0) == 0)
360 ReadDirectory(m_EditText
);
362 m_Liste
.FindString(-1,m_EditText
);
365 m_Liste
.ShowWindow(false);
369 //----------------------------------------------
370 if(m_iMode
& _MODE_SEPARATION_
)
374 if(m_iType
== _EDIT_
)
375 pos
= LOWORD(((CEdit
*)this)->CharFromPos(GetCaretPos()));
377 if(m_iType
== _COMBOBOX_
)
378 pos
= m_pEdit
->CharFromPos(m_pEdit
->GetCaretPos());
381 left
= FindSepLeftPos(pos
-1);
382 right
= FindSepRightPos(pos
);
383 m_Text
= m_EditText
.Mid(left
,right
-left
);
384 m_Liste
.FindString(-1,m_Text
);
387 //----------------------------------------------
388 if(m_iMode
& _MODE_STANDARD_
)
391 m_Liste
.FindString(-1,m_EditText
);
393 //----------------------------------------------
394 GetParent()->SendMessage(ENAC_UPDATE
, EN_UPDATE
, GetDlgCtrlID());
397 /*********************************************************************/
399 int CACEdit::FindSepLeftPos(int pos
,bool m_bIncludePrefix
)
401 int len
= m_EditText
.GetLength();
405 if(pos
>= len
&& len
!= 1)
408 for(i
= pos
; i
>= 0 ; i
--)
410 ch
= m_EditText
.GetAt(i
);
411 if(m_PrefixChar
== ch
)
412 return i
+ (m_bIncludePrefix
? 1 : 0);
413 if(m_SeparationStr
.Find(ch
) != -1)
420 /*********************************************************************/
422 int CACEdit::FindSepLeftPos2(int pos
)
424 int len
= m_EditText
.GetLength();
427 if(pos
>= len
&& len
!= 1)
433 for(int i
= pos
; i
>= 0 ; i
--)
435 ch
= m_EditText
.GetAt(i
);
436 if(m_PrefixChar
== ch
)
443 /*********************************************************************/
445 int CACEdit::FindSepRightPos(int pos
)
447 int len
= m_EditText
.GetLength();
451 for(i
= pos
; i
< len
; i
++)
453 ch
= m_EditText
.GetAt(i
);
454 if(m_SeparationStr
.Find(ch
) != -1)
461 /*********************************************************************/
462 LRESULT
CACEdit::OnUpdateFromList(WPARAM lParam
, LPARAM
/*wParam*/)
466 if(lParam
== WM_KEYDOWN
)
467 HandleKey(VK_DOWN
,true);
471 /*********************************************************************/
473 void CACEdit::OnCloseList()
475 m_Liste
.ShowWindow(false);
478 /*********************************************************************/
480 BOOL
CACEdit::PreTranslateMessage(MSG
* pMsg
)
482 if(pMsg
->message
== WM_KEYDOWN
)
484 if(m_Liste
.IsWindowVisible())
486 if(m_iType
== _COMBOBOX_
)
488 if(pMsg
->wParam
== VK_DOWN
|| pMsg
->wParam
== VK_UP
)
489 if (HandleKey((UINT
)pMsg
->wParam
, false))
493 if(pMsg
->wParam
== VK_ESCAPE
|| pMsg
->wParam
== VK_RETURN
)
494 if (HandleKey((UINT
)pMsg
->wParam
, false))
498 return CWnd::PreTranslateMessage(pMsg
);
501 /*********************************************************************/
503 void CACEdit::ReadDirectory(CString m_Dir
)
505 CFileFind FoundFiles
;
509 // Wenn mittem im Pfad,
510 // vorheriges Verzeichnis einlesen.
511 if (m_Dir
.Right(1) != _T('\\'))
513 _tsplitpath_s(m_Dir
, m_szDrive
, m_szDir
, m_szFname
, m_szExt
);
514 m_Dir
.Format(_T("%s%s"),m_szDrive
, m_szDir
);
518 ch
= (TCHAR
)towupper(m_Dir
.GetAt(0));
521 CString m_Name
,m_File
,m_Dir1
= m_Dir
;
522 if (m_Dir
.Right(1) != _T('\\'))
525 if(m_LastDirectory
.CompareNoCase(m_Dir
) == 0 && m_Liste
.m_SearchList
.GetSize())
528 m_LastDirectory
= m_Dir
;
531 BOOL bContinue
= FoundFiles
.FindFile(m_Dir
);
535 while (bContinue
== TRUE
)
537 bContinue
= FoundFiles
.FindNextFile();
538 m_File
= FoundFiles
.GetFileName();
540 if(FoundFiles
.IsHidden() || FoundFiles
.IsSystem())
542 if(FoundFiles
.IsDirectory())
544 if(m_iMode
& _MODE_ONLY_FILES
)
546 if(FoundFiles
.IsDots())
549 if (m_File
.Right(1) != _T('\\'))
553 if(!FoundFiles
.IsDirectory())
554 if(m_iMode
& _MODE_ONLY_DIRS
)
557 if(m_iMode
& _MODE_FS_START_DIR_
)
564 if (m_Name
.Right(1) != _T('\\'))
570 AddSearchString(m_Name
);
576 /*********************************************************************/
578 void CACEdit::SetStartDirectory(LPCTSTR lpszString
)
580 if(m_iType
== -1) {ASSERT(0); return;}
582 if(m_iMode
& _MODE_FS_START_DIR_
)
583 ReadDirectory(lpszString
);
586 /*********************************************************************
589 *********************************************************************/
591 int CACEdit::AddString( LPCTSTR lpszString
)
593 if(m_iType
== _COMBOBOX_
)
595 return ((CComboBox
*)this)->AddString(lpszString
);
600 /*********************************************************************/
602 int CACEdit::SetDroppedWidth( UINT nWidth
)
604 if(m_iType
== _COMBOBOX_
)
606 return ((CComboBox
*)this)->SetDroppedWidth(nWidth
);
611 /*********************************************************************/
613 int CACEdit::FindString( int nStartAfter
, LPCTSTR lpszString
)
615 if(m_iType
== _COMBOBOX_
)
617 return ((CComboBox
*)this)->FindString(nStartAfter
,lpszString
);
622 /*********************************************************************/
624 int CACEdit::SelectString( int nStartAfter
, LPCTSTR lpszString
)
626 if(m_iType
== _COMBOBOX_
)
628 return ((CComboBox
*)this)->SelectString(nStartAfter
,lpszString
);
633 /*********************************************************************/
635 void CACEdit::ShowDropDown(BOOL bShowIt
)
637 if(m_iType
== _COMBOBOX_
)
639 ((CComboBox
*)this)->ShowDropDown(bShowIt
);
643 /*********************************************************************/
645 void CACEdit::ResetContent()
647 if(m_iType
== _COMBOBOX_
)
649 ((CComboBox
*)this)->ResetContent();
653 /*********************************************************************/
655 int CACEdit::GetCurSel()
657 if(m_iType
== _COMBOBOX_
)
659 return ((CComboBox
*)this)->GetCurSel();
664 /*********************************************************************/
666 int CACEdit::GetLBText( int nIndex
, LPTSTR lpszText
)
668 if(m_iType
== _COMBOBOX_
)
670 return ((CComboBox
*)this)->GetLBText(nIndex
,lpszText
);
675 /*********************************************************************/
677 void CACEdit::GetLBText( int nIndex
, CString
& rString
)
679 if(m_iType
== _COMBOBOX_
)
681 ((CComboBox
*)this)->GetLBText(nIndex
,rString
);
685 /*********************************************************************/