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.ComponentModel;
23 using System.Diagnostics;
24 using System.Drawing;
25 using System.Text;
26 using System.Windows.Forms;
27 
28 using KeePass.Native;
29 using KeePass.Util;
30 
31 using NativeLib = KeePassLib.Native.NativeLib;
32 
33 namespace KeePass.UI
34 {
35 	public sealed class SplitButtonEx : Button
36 	{
37 		private const int BS_SPLITBUTTON = 0x0000000C;
38 		// private const int BS_LEFTTEXT = 0x00000020;
39 		// private const int BS_RIGHT = 0x00000200;
40 
41 		private const uint BCN_FIRST = unchecked((uint)(-1250));
42 		private const uint BCN_DROPDOWN = (BCN_FIRST + 0x0002);
43 
44 		private readonly bool m_bSupported;
45 
46 		private CustomContextMenuStripEx m_ctx = null;
47 		[Browsable(false)]
48 		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
49 		public CustomContextMenuStripEx SplitDropDownMenu
50 		{
51 			get { return m_ctx; }
52 			set { m_ctx = value; }
53 		}
ShouldSerializeSplitDropDownMenu()54 		public bool ShouldSerializeSplitDropDownMenu() { return false; }
55 
56 		[Browsable(false)]
57 		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
58 		protected override CreateParams CreateParams
59 		{
60 			get
61 			{
62 				CreateParams cp = base.CreateParams;
63 
64 				if(m_bSupported)
65 				{
66 					int fAdd = BS_SPLITBUTTON;
67 					// if(this.RightToLeft == RightToLeft.Yes)
68 					//	fAdd |= (BS_LEFTTEXT | BS_RIGHT);
69 
70 					cp.Style |= fAdd;
71 				}
72 
73 				return cp;
74 			}
75 		}
76 
SplitButtonEx()77 		public SplitButtonEx() : base()
78 		{
79 			m_bSupported = (WinUtil.IsAtLeastWindowsVista &&
80 				!NativeLib.IsUnix() && !Program.DesignMode);
81 
82 			if(m_bSupported) this.FlatStyle = FlatStyle.System;
83 		}
84 
WndProc(ref Message m)85 		protected override void WndProc(ref Message m)
86 		{
87 			if((m.Msg == NativeMethods.WM_NOTIFY_REFLECT) && m_bSupported)
88 			{
89 				try
90 				{
91 					NativeMethods.NMHDR nm = (NativeMethods.NMHDR)m.GetLParam(
92 						typeof(NativeMethods.NMHDR));
93 					if(nm.code == BCN_DROPDOWN)
94 					{
95 						if(m_ctx != null)
96 						{
97 							m_ctx.ShowEx(this);
98 							return; // We handled it
99 						}
100 						else { Debug.Assert(false); }
101 					}
102 				}
103 				catch(Exception) { Debug.Assert(false); }
104 			}
105 
106 			base.WndProc(ref m);
107 		}
108 	}
109 }
110