using System; using System.ComponentModel; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Drawing.Design; using HotelPms.Share.Windows.Component.PropertyEditor; using System.Runtime.InteropServices; using System.Text.RegularExpressions; namespace HotelPms.Share.Windows.Component { /// /// 入力スタイル /// public enum InputStyleSelection { /// /// 通常 /// [Description("通常")] Normal = 0, /// 時刻 /// [Description("時刻")] Time, [Description("日付")] Date, [Description("年月")] Month, } /// /// MMyyを入力したときの年の付与方法 /// public enum MMddInputStyle { Future = 0, //未来 Before = 1, //過去 } /// /// EnabledがFalseでも前景色、背景色が変わらないTextBox /// [ToolboxBitmap(typeof(System.Windows.Forms.TextBox))] public class CTextBox : TextBox, ITextBoxArray, IPanelEx { public enum ETitleStyle : int { /// /// なし /// [Description("なし")] None = 0, /// /// "ラベル /// [Description("ラベル")] Label, /// /// アイコン /// [Description("アイコン")] Icon, /// /// アンドロイドスタイル /// [Description("アンドロイドスタイル")] Material, } #region -------- API ------ [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Bindable(true)] public override bool AutoSize { get { return base.AutoSize; } set { base.AutoSize = value; } } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetWindowLong(IntPtr hWnd, int nIndex); private const int GWL_STYLE = -16; private const int WS_DISABLED = 0x8000000; private const int EM_SETCUEBANNER = 0x1501; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); #endregion private bool m_IsFocus = false; private static bool m_ClickSelAll = false; /// /// クリックしたら、全選択かどうか /// public static bool ClickSelAll { get { return m_ClickSelAll; } set { m_ClickSelAll = value; } } #region 拡張動作 private MMddInputStyle curMMddInputStyle = MMddInputStyle.Future; /// /// MMddで入力したら、来年 + mmddかもしくは 今年 + mmddの設定 /// [Description("MMddで入力したら、来年/今年/ホテルデート + MMddの設定"), Category("拡張動作")] public MMddInputStyle CurMMddInputStyle { get { return curMMddInputStyle; } set { curMMddInputStyle = value; } } private string tipText = string.Empty; [Description("ヒント"), Category("拡張動作")] public string TipText { get { return tipText; } set { tipText = value; SendMessage(this.Handle, EM_SETCUEBANNER, 0, value); Invalidate(); } } private bool panelExEnabled = false; [Description("親Panelを描くするかどうか"), Category("IPanelEx拡張動作")] public bool PanelExEnabled { get { return panelExEnabled; } set { panelExEnabled = value; Invalidate(); } } private ETitleStyle titleStyle = ETitleStyle.None; [Description("タイトル表示"), Category("IPanelEx拡張動作")] public ETitleStyle TitleStyle { get { return titleStyle; } set { titleStyle = value; Invalidate(); } } private int titleWidth = 50; [Description("タイトル幅(アイコンの場合無効、幅=高)"), Category("IPanelEx拡張動作")] public int TitleWidth { get { return titleWidth; } set { titleWidth = value; Invalidate(); } } private string titleText = string.Empty; [Description("タイトルの文言"), Category("IPanelEx拡張動作")] public string TitleText { get { return titleText; } set { titleText = value; Invalidate(); } } private Font titleFont = new Font("MS UI Gothic", 9F); [Description("タイトルのフォント"), Category("IPanelEx拡張動作")] public Font TitleFont { get { return titleFont; } set { titleFont = value; Invalidate(); } } private Color titleForeColor = Color.White; [Description("タイトルの文字色"), Category("IPanelEx拡張動作")] public Color TitleForeColor { get { return titleForeColor; } set { titleForeColor = value; Invalidate(); } } private Color titleBackColor = Color.FromArgb(255, 0, 64, 64); [Description("タイトルの背景色"), Category("IPanelEx拡張動作")] public Color TitleBackColor { get { return titleBackColor; } set { titleBackColor = value; Invalidate(); } } private Color shadowColor = Color.FromArgb(140, 123, 193, 247); //#7bc1f7 140, 123, 193, 247 (青) #22AC38 140, 34, 172, 56 (緑) 255,55,71,79 (濃Gray) [Description("影色"), Category("IPanelEx拡張動作")] public Color ShadowColor { get { return shadowColor; } set { shadowColor = value; Invalidate(); } } private Color borderColor = Color.FromArgb(255, 122, 122, 122); //255,0,120,215 (濃青) #7bc1f7 140, 123, 193, 247 (青) #22AC38 255, 34, 172, 56 (緑) 255,122,122,122(Gray) [Description("罫線色"), Category("IPanelEx拡張動作")] public Color BorderColor { get { return borderColor; } set { borderColor = value; Invalidate(); } } private Color borderFocusColor = Color.FromArgb(255, 0, 120, 215); //255,0,120,215 (濃青) #7bc1f7 140, 123, 193, 247 (青) #22AC38 255, 34, 172, 56 (緑) 255,122,122,122(Gray) [Description("罫線色"), Category("IPanelEx拡張動作")] public Color BorderFocusColor { get { return borderFocusColor; } set { borderFocusColor = value; Invalidate(); } } private Image foreImage = null; [Category("IPanelEx拡張動作"), Description("显示的前端的图片")] public Image ForeImage { get { return foreImage; } set { foreImage = value; Invalidate(); } } #endregion private bool enabled = true; public new bool Enabled { get { return enabled; } set { enabled = value; if (enabled) { SetWindowLong(this.Handle, GWL_STYLE, (~WS_DISABLED) & GetWindowLong(this.Handle, GWL_STYLE)); } else { SetWindowLong(this.Handle, GWL_STYLE, WS_DISABLED | GetWindowLong(this.Handle, GWL_STYLE)); } } } #region CTextBoxArray動作 private InputStyleSelection m_InputStyle = InputStyleSelection.Normal; private bool m_TextBoxArrayMember = false; private string m_ShowStyle = "0x1"; private bool m_IsChkData = false; private bool m_NotNull = false; private string m_InputType = "0x1"; private bool m_IsDate = false; private string m_In_Range = string.Empty; // '範囲: "'A','E','F'" OR "'1','2','21'" OR "[1,10]" OR "(1,10)" OR "[1,10)" OR "(1,10]" 空白の時しない private string m_DBFieldName = string.Empty; private object m_DBObject = null; private bool m_IsPrimaryKey = false; private bool m_EnableUpDownKey = false; //↑と↓キーで「enter」と「esc」同じ様にする private Control m_MstNameCtrl = null; [Description("入力モード"), Category("CTextBoxArray動作"), DefaultValue(InputStyleSelection.Normal)] public InputStyleSelection InputStyle { get { return m_InputStyle; } set { m_InputStyle = value; } } [Description("日付コントロールかどうか"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool IsDate { get { return m_IsDate; } set { m_IsDate = value; } } [Description("入力範囲を取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue("")] public string In_Range { get { return m_In_Range; } set { m_In_Range = value; } } [Description("DB項目名を取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue("")] public string DBFieldName { get { return m_DBFieldName; } set { m_DBFieldName = value; } } [Description("DBクラスを取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue(null)] public object DBObject { get { return m_DBObject; } set { m_DBObject = value; } } [Description("PrimaryKeyを取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool IsPrimaryKey { get { return m_IsPrimaryKey; } set { m_IsPrimaryKey = value; } } [Description("UpとDownFocus動作するかどうか。"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool EnableUpDownKey { get { return m_EnableUpDownKey; } set { m_EnableUpDownKey = value; } } [Description("名称コントロールを取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue("")] public Control MstNameCtrl { get { return m_MstNameCtrl; } set { m_MstNameCtrl = value; } } [Description("CTextBoxArrayの子コントロールを取得または設定します。"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool TextBoxArrayMember { get { return m_TextBoxArrayMember; } set { m_TextBoxArrayMember = value; } } [Description("チェックするかどうか"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool IsChkData { get { return m_IsChkData; } set { m_IsChkData = value; } } [Description("空白可能かどうか true:NULL不可 / false:NULL可"), Category("CTextBoxArray動作"), DefaultValue(false)] public bool NotNull { get { return m_NotNull; } set { m_NotNull = value; } } [Description("組合せ可能 例:0x2,0x8"), Category("CTextBoxArray動作"), DefaultValue(false), Editor(typeof(InputTypeEditor), typeof(UITypeEditor))] public string InputType { get { return m_InputType; } set { m_InputType = value; } } [Description(@"組合せ可能 例:0x2,0x8 0x1:特になし 0x2:桁数未満だったら「0」を頭に追加 0x4:金額時の3桁ごとの「,」 例1,000,000 0x8:ENDキーで一覧選択画面があり"), Category("CTextBoxArray動作"), DefaultValue("0x1")] public string ShowStyle { get { return m_ShowStyle; } set { m_ShowStyle = value; } } private string m_OrgText = string.Empty; public string OrgText { get { return m_OrgText; } set { m_OrgText = value; } } #endregion protected override void OnEnter(EventArgs e) { if (enabled) { base.OnEnter(e); } m_IsFocus = true; } /// /// フォッカス取得時 /// /// protected override void OnGotFocus(EventArgs e) { if (!enabled) { return; } base.OnGotFocus(e); if ((this.Text != string.Empty) && (!this.Multiline)) { this.SelectAll(); } } protected override void OnLeave(EventArgs e) { if (enabled) { base.OnLeave(e); } m_IsFocus = false; } protected override void OnClick(EventArgs e) { if (enabled) { base.OnClick(e); } } protected override void OnMouseDown(MouseEventArgs e) { if (enabled) { base.OnMouseDown(e); } } protected override void OnMouseUp(MouseEventArgs e) { if (enabled) { base.OnMouseUp(e); } if (m_ClickSelAll && m_IsFocus && e.Button == MouseButtons.Left) { if (this.Text.Length > 0) { this.SelectAll(); } m_IsFocus = false; } } protected override void OnMouseEnter(EventArgs e) { if (enabled) { base.OnMouseEnter(e); } } protected override void OnKeyDown(KeyEventArgs e) { switch (e.KeyCode) { case Keys.Return: if (m_InputStyle == InputStyleSelection.Time) { this.Text = ParseTime(); } else if (m_InputStyle == InputStyleSelection.Month) { this.Text = ParseMonth(); } else if (m_InputStyle == InputStyleSelection.Date) { this.Text = ParseDate(); } break; } base.OnKeyDown(e); } protected override void OnValidating(CancelEventArgs e) { if (m_InputStyle == InputStyleSelection.Time) { this.Text = ParseTime(); } else if (m_InputStyle == InputStyleSelection.Month) { this.Text = ParseMonth(); } else if (m_InputStyle == InputStyleSelection.Date) { this.Text = ParseDate(); } base.OnValidating(e); } /// /// 月文字列加工 /// /// public string ParseMonth() { string sbuf = ""; try { if (this.Text.Length == 2) { //月のみが入力されている場合は、当年の年を付加する if (int.Parse(this.Text) >= 1 && int.Parse(this.Text) <= 12) { sbuf = DateTime.Today.Year.ToString() + "/" + this.Text; } } else if (this.Text.Length == 6) { int pos = this.Text.LastIndexOf('/'); if (pos == -1) { if (int.Parse(this.Text.Substring(4)) >= 1 && int.Parse(this.Text.Substring(4)) <= 12) { sbuf = this.Text.Substring(0, 4) + "/" + this.Text.Substring(4); } } else if (pos == 4) { sbuf = this.Text.Substring(0, 4) + "/0" + this.Text.Substring(5); } } else if (this.Text.Length == 7 && this.Text.LastIndexOf('/') == 4) { if (int.Parse(this.Text.Substring(5)) >= 1 && int.Parse(this.Text.Substring(5)) <= 12) { sbuf = this.Text; } } if (Convert.ToInt32(sbuf.Replace("/", string.Empty)) < 190101) { return string.Empty; } return sbuf; } catch { return ""; } } /// /// 全て数字かどうか /// /// /// private bool IsWholeNumber(String strNumber) { Regex objNotPattern = new Regex("[^0-9]"); Regex objPattern = new Regex("^[0-9]+$"); return !objNotPattern.IsMatch(strNumber) && objPattern.IsMatch(strNumber); } private DateTime GetToday() { return DateTime.Today; } public string ParseDate() { string sbuf = ""; try { if (this.Text.Length == 10) { //入力された文字列が日付入力文字として正しいかをチェックする int pos = this.Text.IndexOf('/'); if (pos == 4) { pos = this.Text.LastIndexOf('/'); if (pos == 7) { if (int.Parse(this.Text.Substring(5, 2)) >= 1 && int.Parse(this.Text.Substring(5, 2)) <= 12 && int.Parse(this.Text.Substring(8)) >= 1 && int.Parse(this.Text.Substring(8)) <= 31) { DateTime result; if (DateTime.TryParse(this.Text, out result)) { sbuf = this.Text; } } } } } else if (this.Text.Length == 9) { int pos = this.Text.IndexOf('/'); if (pos == 4) { pos = this.Text.LastIndexOf('/'); if (pos == 7) { // Ex)2012/10/1 if (int.Parse(this.Text.Substring(5, 2)) >= 1 && int.Parse(this.Text.Substring(5, 2)) <= 12 && int.Parse(this.Text.Substring(8)) >= 1 && int.Parse(this.Text.Substring(8)) <= 31) { DateTime result; if (DateTime.TryParse(this.Text.Substring(0, 7) + "/0" + this.Text.Substring(8), out result)) { sbuf = this.Text.Substring(0, 7) + "/0" + this.Text.Substring(8); } } } else if (pos == 6) { //20151218 毛利 Redmine#7195 日付のチェックの桁がおかしかった。.Substring(8)→.Substring(7)に修正 // Ex)2012/1/11 if (int.Parse(this.Text.Substring(5, 1)) >= 1 && int.Parse(this.Text.Substring(5, 1)) <= 12 && int.Parse(this.Text.Substring(7)) >= 1 && int.Parse(this.Text.Substring(7)) <= 31) { DateTime result; if (DateTime.TryParse(this.Text.Substring(0, 5) + "0" + this.Text.Substring(5), out result)) { sbuf = this.Text.Substring(0, 5) + "0" + this.Text.Substring(5); } } } } } else if (this.Text.Length == 8) { int pos = this.Text.LastIndexOf('/'); if (pos == -1) { //スラッシュが入力されない場合 if (int.Parse(this.Text.Substring(4, 2)) >= 1 && int.Parse(this.Text.Substring(4, 2)) <= 12 && (int.Parse(this.Text.Substring(6, 2)) >= 1 && int.Parse(this.Text.Substring(6, 2)) <= 31)) { DateTime result; if (DateTime.TryParse(this.Text.Substring(0, 4) + "/" + this.Text.Substring(4, 2) + "/" + this.Text.Substring(6, 2), out result)) { sbuf = this.Text.Substring(0, 4) + "/" + this.Text.Substring(4, 2) + "/" + this.Text.Substring(6, 2); } } } else if (pos == 6) { //Ex)2012/1/1 pos = this.Text.IndexOf('/'); if (pos == 4) { DateTime result; if (DateTime.TryParse(this.Text.Substring(0, 4) + "/0" + this.Text.Substring(5, 1) + "/0" + this.Text.Substring(7), out result)) { sbuf = this.Text.Substring(0, 4) + "/0" + this.Text.Substring(5, 1) + "/0" + this.Text.Substring(7); } } } } else if (this.Text.Length == 6) { if (IsWholeNumber(this.Text)) { DateTime result; string dateStr = string.Format("{0}{1}/{2}/{3}", DateTime.Today.Year.ToString().Substring(0, 2), this.Text.Substring(0, 2), this.Text.Substring(2, 2), this.Text.Substring(4, 2)); if (DateTime.TryParse(dateStr, out result)) { sbuf = dateStr; } } } else if (this.Text.Length == 5) { //月日のみ入力 int pos = this.Text.LastIndexOf('/'); if (pos == 2) { DateTime result; if (DateTime.TryParse(DateTime.Today.Year.ToString() + "/" + this.Text, out result)) { sbuf = DateTime.Today.Year.ToString() + "/" + this.Text; } } } else if (this.Text.Length == 4) { //月日のみ入力 Ex)1111 int pos = this.Text.LastIndexOf('/'); if (pos == -1) { DateTime result; if (this.Text == "0229") { if (!DateTime.TryParse(this.GetToday().Year.ToString() + "/02/29", out result))//今年で変換できた { if (curMMddInputStyle == MMddInputStyle.Future)//「今年/02/29」 or 「来年/02/29」 { DateTime.TryParse(this.GetToday().Year.ToString() + "/02/28", out result);//仮に0228で日付取得 } else if (curMMddInputStyle == MMddInputStyle.Before) { DateTime.TryParse(this.GetToday().Year.ToString() + "/03/01", out result);//仮に0301で日付取得 } } if (curMMddInputStyle == MMddInputStyle.Future)//「今年/02/29」 or 「来年/02/29」 { //未来 if (DateTime.Compare(result.Date, this.GetToday().Date) < 0) { result = result.AddYears(1);//さらに未来 } } else if (curMMddInputStyle == MMddInputStyle.Before)//「今年/02/29」 or 「去年/02/29」 { //過去 if (DateTime.Compare(result.Date, this.GetToday().Date) > 0) { result = result.AddYears(-1);//さらに過去 } } if (DateTime.TryParse(result.Year.ToString() + "/02/29", out result))//最後にその年で02/29にがあるなら { sbuf = result.ToString("yyyy/MM/dd"); } } else if (DateTime.TryParse(this.GetToday().Year.ToString() + "/" + this.Text.Substring(0, 2) + "/" + this.Text.Substring(2), out result)) { if (curMMddInputStyle == MMddInputStyle.Future) { //未来 if (DateTime.Compare(new DateTime(this.GetToday().Year, int.Parse(this.Text.Substring(0, 2)), int.Parse(this.Text.Substring(2))), this.GetToday().Date) < 0) { sbuf = (this.GetToday().Year + 1).ToString() + "/" + this.Text.Substring(0, 2) + "/" + this.Text.Substring(2); } else { sbuf = this.GetToday().Year.ToString() + "/" + this.Text.Substring(0, 2) + "/" + this.Text.Substring(2); } } else { //過去 if (DateTime.Compare(new DateTime(this.GetToday().Year, int.Parse(this.Text.Substring(0, 2)), int.Parse(this.Text.Substring(2))), this.GetToday().Date) <= 0) { sbuf = this.GetToday().Year.ToString() + "/" + this.Text.Substring(0, 2) + "/" + this.Text.Substring(2); } else { sbuf = (this.GetToday().Year - 1).ToString() + "/" + this.Text.Substring(0, 2) + "/" + this.Text.Substring(2); } //-----------------------------------liu 不具合2270 ↑------------------------------------------------------- } } } else if (pos == 1) { //月日のみ入力 Ex)1/11 DateTime result; if (DateTime.TryParse(DateTime.Today.Year.ToString() + "/0" + this.Text, out result)) { sbuf = DateTime.Today.Year.ToString() + "/0" + this.Text; } } else if (pos == 2) { //月日のみ入力 Ex)11/1 DateTime result; if (DateTime.TryParse(DateTime.Today.Year.ToString() + "/" + this.Text.Substring(0, 2) + "/0" + this.Text.Substring(3), out result)) { sbuf = DateTime.Today.Year.ToString() + "/" + this.Text.Substring(0, 2) + "/0" + this.Text.Substring(3); } } } else if (this.Text.Length == 3) { //月日のみ入力 Ex)111 int pos = this.Text.LastIndexOf('/'); if (pos == 1) { //月日のみ入力 Ex)1/1 DateTime result; if (DateTime.TryParse(DateTime.Today.Year.ToString() + "/0" + this.Text, out result)) { sbuf = result.ToShortDateString(); } } } else if (this.Text.Length == 2) { //EX 01 int pos = this.Text.LastIndexOf('/'); if (pos == -1) { DateTime result; if (DateTime.TryParse(this.GetToday().Year.ToString() + "/" + this.GetToday().Month.ToString() + "/" + this.Text, out result)) { if (DateTime.Compare(this.GetToday().Date, new DateTime(this.GetToday().Year, this.GetToday().Month, int.Parse(this.Text))) <= 0) { sbuf = this.GetToday().Year.ToString() + "/" + this.GetToday().Month.ToString() + "/" + this.Text; } else { if ((this.GetToday().Month + 1) > 12) { sbuf = (this.GetToday().Year + 1).ToString() + "/01" + "/" + this.Text; } else { sbuf = this.GetToday().Year.ToString() + "/" + (this.GetToday().Month + 1).ToString() + "/" + this.Text; } } sbuf = DateTime.Parse(sbuf).ToString("yyyy/MM/dd"); } } } return sbuf; } catch { //return this.Text; return OrgText; } } /// /// 時間文字列の加工 /// /// public string ParseTime() { // 00:00 ~ 23:59 string sbuf = ""; try { if (this.Text.Length > 5) { return string.Empty; } int pos = this.Text.LastIndexOf(':'); if (this.Text.Length == 5) { if (pos == 2) { if (int.Parse(this.Text.Substring(0, 2)) >= 0 && int.Parse(this.Text.Substring(0, 2)) < 24 && int.Parse(this.Text.Substring(3)) >= 0 && int.Parse(this.Text.Substring(3)) <= 59) { sbuf = this.Text; } } } else if (this.Text.Length == 4) { if (pos >= 0) { string[] items = this.Text.Split(new char[] { ':' }); if (int.Parse(items[0]) >= 0 && int.Parse(items[0]) < 24 && int.Parse(items[1]) >= 0 && int.Parse(items[1]) <= 59) { sbuf = int.Parse(items[0]).ToString().PadLeft(2, '0') + ":" + int.Parse(items[1]).ToString().PadLeft(2, '0'); } } else { if (int.Parse(this.Text.Substring(0, 2)) >= 0 && int.Parse(this.Text.Substring(0, 2)) < 24 && int.Parse(this.Text.Substring(2)) >= 0 && int.Parse(this.Text.Substring(2)) <= 59) { sbuf = this.Text.Substring(0, 2) + ":" + this.Text.Substring(2); } } } else { if (pos >= 0) { string[] items = this.Text.Split(new char[] { ':' }); if (int.Parse(items[0]) >= 0 && int.Parse(items[0]) < 24 && int.Parse(items[1]) >= 0 && int.Parse(items[1]) <= 59) { sbuf = int.Parse(items[0]).ToString().PadLeft(2, '0') + ":" + int.Parse(items[1]).ToString().PadLeft(2, '0'); } } else if (this.Text.Length == 3) { if (int.Parse(this.Text.Substring(0, 1)) >= 0 && int.Parse(this.Text.Substring(0, 1)) < 24 && int.Parse(this.Text.Substring(1)) >= 0 && int.Parse(this.Text.Substring(1)) <= 59) { sbuf = this.Text.Substring(0, 1) + ":" + this.Text.Substring(1); } } else if (this.Text.Length == 2) { if (int.Parse(this.Text) >= 0 && int.Parse(this.Text) < 24) { sbuf = this.Text + ":00"; } } else if (this.Text.Length == 1) { sbuf = this.Text.PadLeft(2, '0') + ":00"; } } return sbuf; } catch { return ""; } } public virtual void ResetOrgText() { m_OrgText = this.Text; } } }