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