1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
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.
14 
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
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.Diagnostics;
23 using System.Text;
24 using System.Windows.Forms;
25 
26 using KeePass.Native;
27 using KeePass.Util;
28 
29 using NativeLib = KeePassLib.Native.NativeLib;
30 
31 namespace KeePass.UI
32 {
33 	// public delegate string QueryToolTipDelegate(TreeNode tn);
34 
35 	public sealed class CustomTreeViewEx : TreeView
36 	{
37 		// private TreeNode m_tnReadyForLabelEdit = null;
38 
39 		// private QueryToolTipDelegate m_fnQueryToolTip = null;
40 		// /// <summary>
41 		// /// This handler will be used to dynamically query tooltip
42 		// /// texts for tree nodes.
43 		// /// </summary>
44 		// public QueryToolTipDelegate QueryToolTip
45 		// {
46 		//	get { return m_fnQueryToolTip; }
47 		//	set { m_fnQueryToolTip = value; }
48 		// }
49 
CustomTreeViewEx()50 		public CustomTreeViewEx() : base()
51 		{
52 			if(Program.DesignMode) return;
53 
54 			// Enable default double buffering (must be combined with
55 			// TVS_EX_DOUBLEBUFFER, see OnHandleCreated)
56 			try { this.DoubleBuffered = true; }
57 			catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindowsVista); }
58 
59 			// try
60 			// {
61 			//	IntPtr hWnd = this.Handle;
62 			//	if((hWnd != IntPtr.Zero) && (this.ItemHeight == 16))
63 			//	{
64 			//		int nStyle = NativeMethods.GetWindowStyle(hWnd);
65 			//		nStyle |= (int)NativeMethods.TVS_NONEVENHEIGHT;
66 			//		NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_STYLE, nStyle);
67 			//		this.ItemHeight = 17;
68 			//	}
69 			// }
70 			// catch(Exception) { }
71 
72 			// this.ItemHeight = 18;
73 
74 			// try
75 			// {
76 			//	IntPtr hWnd = this.Handle;
77 			//	if((hWnd != IntPtr.Zero) && UIUtil.VistaStyleListsSupported)
78 			//	{
79 			//		int nStyle = NativeMethods.GetWindowStyle(hWnd);
80 			//		nStyle |= (int)NativeMethods.TVS_FULLROWSELECT;
81 			//		NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_STYLE, nStyle);
82 			//		nStyle = NativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE);
83 			//		nStyle |= (int)NativeMethods.TVS_EX_FADEINOUTEXPANDOS;
84 			//		NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE, nStyle);
85 			//	}
86 			// }
87 			// catch(Exception) { }
88 
89 			ApplyOptions();
90 		}
91 
ApplyOptions()92 		internal void ApplyOptions()
93 		{
94 			this.ShowLines = Program.Config.UI.TreeViewShowLines;
95 		}
96 
97 		// protected override void WndProc(ref Message m)
98 		// {
99 		//	if(m.Msg == NativeMethods.WM_NOTIFY)
100 		//	{
101 		//		NativeMethods.NMHDR nm = (NativeMethods.NMHDR)m.GetLParam(
102 		//			typeof(NativeMethods.NMHDR));
103 		//		if((nm.code == NativeMethods.TTN_NEEDTEXTA) ||
104 		//			(nm.code == NativeMethods.TTN_NEEDTEXTW))
105 		//			DynamicAssignNodeToolTip();
106 		//	}
107 		//	base.WndProc(ref m);
108 		// }
109 
110 		// private void DynamicAssignNodeToolTip()
111 		// {
112 		//	if(m_fnQueryToolTip == null) return;
113 		//	TreeViewHitTestInfo hti = HitTest(PointToClient(Cursor.Position));
114 		//	if(hti == null) { Debug.Assert(false); return; }
115 		//	TreeNode tn = hti.Node;
116 		//	if(tn == null) return;
117 		//	tn.ToolTipText = (m_fnQueryToolTip(tn) ?? string.Empty);
118 		// }
119 
120 		/* protected override void OnAfterSelect(TreeViewEventArgs e)
121 		{
122 			base.OnAfterSelect(e);
123 
124 			if(!this.Focused) m_tnReadyForLabelEdit = null;
125 			else m_tnReadyForLabelEdit = this.SelectedNode;
126 		}
127 
128 		protected override void OnLeave(EventArgs e)
129 		{
130 			m_tnReadyForLabelEdit = null;
131 
132 			base.OnLeave(e);
133 		}
134 
135 		protected override void OnBeforeLabelEdit(NodeLabelEditEventArgs e)
136 		{
137 			if(e != null)
138 			{
139 				if((m_tnReadyForLabelEdit == null) || (e.Node !=
140 					m_tnReadyForLabelEdit))
141 				{
142 					e.CancelEdit = true;
143 					return;
144 				}
145 			}
146 			else { Debug.Assert(false); }
147 
148 			base.OnBeforeLabelEdit(e); // Call BeforeLabelEdit event
149 		} */
150 
OnHandleCreated(EventArgs e)151 		protected override void OnHandleCreated(EventArgs e)
152 		{
153 			base.OnHandleCreated(e);
154 			if(Program.DesignMode) return;
155 
156 			try
157 			{
158 				if(this.DoubleBuffered && !NativeLib.IsUnix())
159 				{
160 					IntPtr p = new IntPtr((int)NativeMethods.TVS_EX_DOUBLEBUFFER);
161 					NativeMethods.SendMessage(this.Handle,
162 						NativeMethods.TVM_SETEXTENDEDSTYLE, p, p);
163 				}
164 				else { Debug.Assert(!WinUtil.IsAtLeastWindowsVista); }
165 			}
166 			catch(Exception) { Debug.Assert(false); }
167 
168 			// Display tooltips for a longer time;
169 			// https://sourceforge.net/p/keepass/feature-requests/2038/
170 			UIUtil.ConfigureToolTip(this);
171 		}
172 
173 		/* [Browsable(false)]
174 		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
175 		protected override CreateParams CreateParams
176 		{
177 			get
178 			{
179 				CreateParams cp = base.CreateParams;
180 				cp.ExStyle |= NativeMethods.WS_EX_COMPOSITED;
181 				return cp;
182 			}
183 		} */
184 
185 		/* protected override void WndProc(ref Message m)
186 		{
187 			if(m.Msg == NativeMethods.WM_ERASEBKGND)
188 			{
189 				m.Result = IntPtr.Zero;
190 				return;
191 			}
192 
193 			base.WndProc(ref m);
194 		} */
195 
OnKeyDown(KeyEventArgs e)196 		protected override void OnKeyDown(KeyEventArgs e)
197 		{
198 			if(UIUtil.HandleCommonKeyEvent(e, true, this)) return;
199 
200 			base.OnKeyDown(e);
201 		}
202 
OnKeyUp(KeyEventArgs e)203 		protected override void OnKeyUp(KeyEventArgs e)
204 		{
205 			if(UIUtil.HandleCommonKeyEvent(e, false, this)) return;
206 
207 			base.OnKeyUp(e);
208 		}
209 
OnBeforeCollapse(TreeViewCancelEventArgs e)210 		protected override void OnBeforeCollapse(TreeViewCancelEventArgs e)
211 		{
212 			TreeNode tn = ((e != null) ? e.Node : null);
213 			if(tn != null)
214 			{
215 				if((tn.Parent == null) && !this.ShowRootLines)
216 				{
217 					// This should only occur due to a user action (e.g.
218 					// double-click on the node), not programmatically
219 					Debug.Assert(false);
220 
221 					e.Cancel = true;
222 					return;
223 				}
224 			}
225 			else { Debug.Assert(false); }
226 
227 			base.OnBeforeCollapse(e);
228 		}
229 	}
230 }
231