3 * $Date: 2006-08-17 16:26:11 +0900 (木, 17 8 2006) $
7 using System.Collections.Generic;
8 using System.ComponentModel;
12 using System.Windows.Forms;
13 using System.Runtime.InteropServices;
14 using System.Diagnostics;
18 namespace Lugens.Components
20 public partial class AutoCompleteTextBox : TextBox, IComparer<IconListBoxItem>
22 [DllImport("Imm32.dll")]
23 private static extern IntPtr ImmGetContext(IntPtr hWnd);
25 [DllImport("Imm32.dll")]
26 private static extern int ImmGetCompositionString(
27 IntPtr hIMC, int dwIndex, byte[] buf, int dwBufLen);
29 [DllImport("Imm32.dll")]
30 private static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
32 // IME入力中文字取得に使用する値(ひらがな)
33 private const int GCS_COMPSTR = 0x0008;
36 /// オートコンプリートドロップダウンリスト表示の最大件数
38 private int maxDropdownCount = 3;
40 /// オートコンプリートドロップダウンリスト表示の最大件数
42 public int MaxDropdownCount { get { return this.maxDropdownCount; } set { this.maxDropdownCount = value; } }
45 /// オートコンプリートドロップダウンリストのアイテム
47 private List<IconListBoxItem> items = new List<IconListBoxItem>();
48 public List<IconListBoxItem> Items { get { return this.items; } }
50 private DropdownListForm dropdownForm = new DropdownListForm();
51 public DropdownListForm DropdownForm { get { return this.dropdownForm; } }
53 private bool showableDropdownList = true;
54 public bool ShowableDropdownList { get { return this.showableDropdownList; } set { this.showableDropdownList = value; } }
59 /// <param name="type"></param>
60 public delegate void ComplementEventHandler(IconListBoxType type);
61 public event ComplementEventHandler Complement;
66 /// <param name="type"></param>
67 public delegate void ImeCompositionEventHandler(int type, string text);
68 public event ImeCompositionEventHandler ImeComposition;
70 private bool complemented = false;
71 public bool Complemented
73 get { return complemented; }
74 set { complemented = value; }
77 private string imeText;
80 get { return imeText; }
81 set { imeText = value; }
84 protected override void Dispose(bool disposing)
86 base.Dispose(disposing);
89 #region コンポーネント デザイナで生成されたコード
92 /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
93 /// コード エディタで変更しないでください。
95 private void InitializeComponent()
99 // AutoCompleteTextBox
101 this.SizeChanged += new System.EventHandler(this.AutoCompleteTextBox_SizeChanged);
102 this.ResumeLayout(false);
108 public AutoCompleteTextBox() : base()
110 InitializeComponent();
111 dropdownForm.ParentTextBox = this;
112 dropdownForm.SetBounds(-1, -1, 1, 1);
115 protected override void OnTextChanged(EventArgs e)
117 base.OnTextChanged(e);
120 protected override void OnKeyDown(KeyEventArgs e)
125 Size t = TextRenderer.MeasureText(this.Text, this.Font);
127 IconListBox listBox = this.dropdownForm.DropdownListBox;
131 if (this.dropdownForm.Visible && this.dropdownForm.DropdownListBox.SelectedIndex >= 0)
134 this.complemented = true;
135 IconListBoxItem item = (IconListBoxItem)this.dropdownForm.DropdownListBox.SelectedItem;
138 case IconListBoxType.Directory:
139 case IconListBoxType.Command:
140 case IconListBoxType.File:
141 case IconListBoxType.History:
142 case IconListBoxType.SysCommand:
143 case IconListBoxType.SearchEngine:
144 this.Text = item.Text;
145 this.SelectionStart = this.Text.Length;
146 this.dropdownForm.DoVisibleChange(false);
147 this.Complement(item.Type);
155 if ((Keys.Control & Control.ModifierKeys) == Keys.Control || Keys.Home == e.KeyCode)
163 if (listBox.Items.Count > 0)
165 if ((Keys.Control & Control.ModifierKeys) == Keys.Control || Keys.Home == e.KeyCode)
168 index = listBox.SelectedIndex - 1;
169 index = Math.Max(index, 0);
170 listBox.SelectedIndex = Math.Max(index, 0);
175 if (listBox.Items.Count > 0)
177 if ((Control.ModifierKeys & Keys.Control) == Keys.Control || Keys.End == e.KeyCode)
178 index = listBox.Items.Count - 1;
180 index = listBox.SelectedIndex + 1;
181 listBox.SelectedIndex = Math.Min(index, listBox.Items.Count - 1);
186 if (this.dropdownForm.Visible)
188 index = listBox.SelectedIndex - maxDropdownCount + 1;
191 listBox.SelectedIndex = index;
196 if (this.dropdownForm.Visible)
198 index = listBox.SelectedIndex + maxDropdownCount - 1;
199 if (index > listBox.Items.Count - 1)
200 index = listBox.Items.Count - 1;
201 listBox.SelectedIndex = index;
206 if (this.dropdownForm.Visible)
208 if (Keys.Control == (Keys.Control & Control.ModifierKeys))
210 listBox.SelectedIndex = 0;
217 if (this.dropdownForm.Visible)
219 if (Keys.Control == (Keys.Control & Control.ModifierKeys))
221 listBox.SelectedIndex = listBox.Items.Count - 1;
230 protected override void OnKeyPress(KeyPressEventArgs e)
232 switch ((Keys)e.KeyChar)
235 if (this.dropdownForm.Visible)
237 if (this.dropdownForm.DropdownListBox.SelectedIndex >= 0)
239 this.Text = this.dropdownForm.DropdownListBox.Text;
240 this.SelectionStart = this.Text.Length;
242 this.dropdownForm.DoVisibleChange(false);
248 if (this.dropdownForm.Visible)
251 this.complemented = true;
252 IconListViewItem item = (IconListViewItem)this.dropdownForm.DropdownListView.SelectedItems[0];
255 case IconListViewType.Directory:
256 case IconListViewType.Command:
257 case IconListViewType.File:
258 case IconListViewType.SysCommand:
259 this.Text = item.Text;
260 this.SelectionStart = this.Text.Length;
261 this.dropdownForm.DoVisibleChange(false);
262 this.Complement(item.Type);
273 si = this.SelectionStart;
279 char c = this.Text[i];
280 if (c == '\\' || c == ' ')
287 if (this.Text.Length == si)
288 this.Text = this.Text.Substring(0, i);
290 this.Text = this.Text.Substring(0, i) + this.Text.Substring(si);
291 this.SelectionStart = i;
297 this.complemented = false;
303 /// <param name="keyData"></param>
304 /// <returns></returns>
305 protected override bool IsInputKey(Keys keyData)
315 return base.IsInputKey(keyData);
318 public void SetDropdownFormLocation()
320 if (this.Parent == null || this.Parent.Parent == null)
322 int count = Math.Min(this.maxDropdownCount, this.dropdownForm.DropdownListBox.Items.Count);
323 Rectangle r = this.Parent.Parent.RectangleToScreen(this.Parent.Bounds);
326 Size size = new Size(this.Parent.Width, this.dropdownForm.DropdownListBox.ItemHeight + 4 + ((count - 1) * this.dropdownForm.DropdownListBox.ItemHeight));
327 this.dropdownForm.Size = size;
328 this.dropdownForm.Location = Util.CalcWindowLocate(r, size, Util.Locate.Down);
330 if (this.Parent == null)
332 int count = Math.Min(this.maxDropdownCount, this.dropdownForm.DropdownListBox.Items.Count);
333 Rectangle r = this.Parent.RectangleToScreen(this.Bounds);
336 Size size = new Size(this.Width, this.dropdownForm.DropdownListBox.ItemHeight + 4 + ((count - 1) * this.dropdownForm.DropdownListBox.ItemHeight));
337 this.dropdownForm.Size = size;
338 this.dropdownForm.Location = Util.CalcWindowLocate(r, size, Util.Locate.Down);*/
341 public void SortItems()
343 this.items.Sort(this);
346 public int Compare(IconListBoxItem item1, IconListBoxItem item2)
348 return item1.Text.CompareTo(item2.Text);
351 private void AutoCompleteTextBox_SizeChanged(object sender, EventArgs e)
353 this.SetDropdownFormLocation();
356 protected override void WndProc(ref Message m)
360 case 0x010F: //WM_IME_COMPOSITION
361 //if (((int)m.LParam & GCS_COMPSTR) == GCS_COMPSTR)
363 IntPtr hIMC = ImmGetContext(this.Handle);
364 StringBuilder sb = new StringBuilder(1024);
365 byte[] buffer = new byte[1024];
366 int length = ImmGetCompositionString(hIMC, GCS_COMPSTR, buffer, 1024);
367 ImmReleaseContext(this.Handle, hIMC);
368 string str = Encoding.GetEncoding("Shift_JIS").GetString(buffer);
369 str = str.TrimEnd('\0');
370 this.ImeComposition((int)m.LParam, str);