OSDN Git Service

互換性のないメソッドをいつか廃止した
[fooeditengine/FooEditEngine.git] / Windows / FooEditEngine / FooTextBox.cs
1 /*
2  * Copyright (C) 2013 FooProject
3  * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
5
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
10  */
11 using System;
12 using System.Text;
13 using System.Threading;
14 using System.Threading.Tasks;
15 using System.Windows.Forms;
16 using System.Drawing;
17 using System.ComponentModel;
18 using Microsoft.Win32;
19
20 namespace FooEditEngine.Windows
21 {
22     /// <summary>
23     /// タブの幅が変更されたときに呼びされるデリゲート
24     /// </summary>
25     /// <param name="sender">送り主が属するクラス</param>
26     /// <param name="e">イベントデータ</param>
27     public delegate void TabStopChangeEventHandler(object sender, EventArgs e);
28
29     /// <summary>
30     /// InsetModeが変更されたときに呼び出されるデリゲート
31     /// </summary>
32     /// <param name="sender">送り主が属するクラス</param>
33     /// <param name="e">イベントデータ</param>
34     public delegate void InsertModeChangeEventHandler(object sender, EventArgs e);
35
36     /// <summary>
37     /// FooEditEngineを表します
38     /// </summary>
39     public class FooTextBox : Control
40     {
41         EditView View;
42         Controller Controller;
43         D2DTextRender render;
44         BorderStyle _BoderStyle;
45         HScrollBar HScrollBar;
46         VScrollBar VScrollBar;
47         WinIME Ime;
48         System.Windows.Forms.Timer Timer;
49
50         const int Interval = 100;
51
52         /// <summary>
53         /// コンストラクター
54         /// </summary>
55         public FooTextBox()
56         {
57             this.VScrollBar = new VScrollBar();
58             this.VScrollBar.Scroll += new ScrollEventHandler(VScrollBar_Scroll);
59             this.VScrollBar.Dock = DockStyle.Right;
60             this.VScrollBar.Visible = true;
61             this.Controls.Add(this.VScrollBar);
62
63             this.HScrollBar = new HScrollBar();
64             this.HScrollBar.Scroll += new ScrollEventHandler(HScrollBar_Scroll);
65             this.HScrollBar.Dock = DockStyle.Bottom;
66             this.HScrollBar.Visible = true;
67             this.Controls.Add(this.HScrollBar);
68
69             this.SetStyle(ControlStyles.ResizeRedraw, true);
70             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
71             this.SetStyle(ControlStyles.UserPaint, true);
72             this.SetStyle(ControlStyles.Opaque, true);
73
74             this.render = new D2DTextRender(this);
75             this.Document = new Document();
76             this.Document.LayoutLines.Render = this.render;
77             this.Document.AutoComplete = new AutoCompleteBox(this);
78             this.Document.AutoComplete.GetPostion = (tp, doc) => {
79                 var p = this.GetPostionFromTextPoint(tp);
80                 p.Y += (int)this.render.emSize.Height;
81                 return p;
82             };
83             this.View = new EditView(this.Document, this.render, new FooEditEngine.Padding(5, 5, 5, 5));
84             this.View.SrcChanged += View_SrcChanged;
85             
86             this.Controller = new Controller(this.Document, this.View);
87             this.Document.SelectionChanged += new EventHandler(Controller_CaretMoved);
88
89             this.Ime = new WinIME(this);
90             this.Ime.ImeCompstion += new ImeCompstionEventHandeler(Ime_ImeCompstion);
91             this.Ime.StartCompstion += new StartCompstionEventHandeler(Ime_StartCompstion);
92             this.Ime.EndCompstion += new EndCompstionEventHandeler(Ime_EndCompstion);
93             this.Ime.ImeDocumentFeed += new ImeDocumentFeedEventHandler(Ime_ImeDocumentFeed);
94             this.Ime.ImeReconvert += new ImeReconvertStringEventHandler(Ime_ImeReconvert);
95             this.Ime.ImeQueryReconvert += new ImeQueryReconvertStringEventHandler(Ime_ImeQueryReconvert);
96
97             this.Timer = new System.Windows.Forms.Timer();
98             this.Timer.Tick += new EventHandler(this.Timer_Tick);
99             this.Timer.Interval = Interval;
100             this.SetSystemParamaters();
101
102             this.TabStopChange += new TabStopChangeEventHandler((s, e) => { });
103             this.InsetModeChange += new InsertModeChangeEventHandler((s, e) => { });
104             this.SelectionChanged +=new EventHandler((s,e)=>{});
105
106             this.RightToLeftChanged += FooTextBox_RightToLeftChanged;
107
108             SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
109
110         }
111
112         /// <summary>
113         /// キャレットが移動したときに通知されるイベント
114         /// </summary>
115         public event EventHandler SelectionChanged;
116
117         /// <summary>
118         /// タブの幅が変更された時に発生するイベント
119         /// </summary>
120         public event TabStopChangeEventHandler TabStopChange;
121
122         /// <summary>
123         /// InsertModeが変更されたときに呼び出されるイベント
124         /// </summary>
125         public event InsertModeChangeEventHandler InsetModeChange;
126
127         /// <summary>
128         /// インデントモードを表す
129         /// </summary>
130         [DefaultValue(IndentMode.Tab)]
131         public IndentMode IndentMode
132         {
133             get
134             {
135                 return this.Controller.IndentMode;
136             }
137             set
138             {
139                 this.Controller.IndentMode = value;
140             }
141         }
142
143         /// <summary>
144         /// テキスト描写に使用するアンチエイリアシングモードを表す
145         /// </summary>
146         [BrowsableAttribute(false)]
147         public TextAntialiasMode TextAntialiasMode
148         {
149             get
150             {
151                 return this.render.TextAntialiasMode;
152             }
153             set
154             {
155                 this.render.TextAntialiasMode = value;
156             }
157         }
158
159         /// <summary>
160         /// マーカーパターンセットを表す
161         /// </summary>
162         [BrowsableAttribute(false)]
163         public MarkerPatternSet MarkerPatternSet
164         {
165             get
166             {
167                 return this.Document.MarkerPatternSet;
168             }
169         }
170
171         /// <summary>
172         /// 保持しているドキュメント
173         /// </summary>
174         [BrowsableAttribute(false)]
175         public Document Document
176         {
177             get;
178             private set;
179         }
180
181         /// <summary>
182         /// 保持しているレイアウト行
183         /// </summary>
184         [BrowsableAttribute(false)]
185         public LineToIndexTable LayoutLines
186         {
187             get { return this.View.LayoutLines; }
188         }
189
190         /// <summary>
191         /// シンタックスハイライター
192         /// </summary>
193         [BrowsableAttribute(false)]
194         public IHilighter Hilighter
195         {
196             get { return this.View.Hilighter; }
197             set { this.View.Hilighter = value; this.View.LayoutLines.ClearLayoutCache(); }
198         }
199
200         /// <summary>
201         /// フォールティングを作成するインターフェイスを表す
202         /// </summary>
203         [BrowsableAttribute(false)]
204         public IFoldingStrategy FoldingStrategy
205         {
206             get
207             {
208                 return this.View.LayoutLines.FoldingStrategy;
209             }
210             set
211             {
212                 this.View.LayoutLines.FoldingStrategy = value;
213                 if (value == null)
214                     this.View.LayoutLines.FoldingCollection.Clear();
215             }
216         }
217
218         /// <summary>
219         /// 境界線のスタイルを指定します
220         /// </summary>
221         public BorderStyle BorderStyle
222         {
223             get { return this._BoderStyle; }
224             set { this._BoderStyle = value; this.UpdateStyles(); }
225         }
226
227
228         /// <summary>
229         /// 行番号を表示するかどうか
230         /// </summary>
231         [DefaultValue(false)]
232         public bool DrawLineNumber
233         {
234             get
235             {
236                 return this.Document.DrawLineNumber;
237             }
238             set
239             {
240                 this.Document.DrawLineNumber = value;
241             }
242         }
243         
244         /// <summary>
245         /// ルーラーを表示するかどうか
246         /// </summary>
247         [DefaultValue(false)]
248         public bool DrawRuler
249         {
250             get
251             {
252                 return !this.Document.HideRuler;
253             }
254             set
255             {
256                 this.Document.HideRuler = !value;
257                 this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);
258             }
259         }
260
261         /// <summary>
262         /// 桁折りを行う方法を指定する
263         /// </summary>
264         /// <remarks>
265         /// 反映させるためにはレイアウト行の再構築を行う必要があります
266         /// </remarks>
267         [DefaultValue(LineBreakMethod.None)]
268         public LineBreakMethod LineBreakMethod
269         {
270             get
271             {
272                 return this.Document.LineBreak;
273             }
274             set
275             {
276                 this.Document.LineBreak = value;
277             }
278         }
279
280         /// <summary>
281         /// 桁折り時の文字数を指定する。
282         /// </summary>
283         /// <remarks>
284         /// 反映させるためにはレイアウト行の再構築を行う必要があります
285         /// </remarks>
286         [DefaultValue(80)]
287         public int LineBreakCharCount
288         {
289             get
290             {
291                 return this.Document.LineBreakCharCount;
292             }
293             set
294             {
295                 this.Document.LineBreakCharCount = value;
296             }
297         }
298
299         /// <summary>
300         /// URLをマークするかどうか
301         /// </summary>
302         [DefaultValue(false)]
303         public bool UrlMark
304         {
305             get
306             {
307                 return this.Document.UrlMark;
308             }
309             set
310             {
311                 this.Document.UrlMark = value;
312             }
313         }
314
315         /// <summary>
316         /// タブストップの幅
317         /// </summary>
318         [DefaultValue(4)]
319         public int TabStops
320         {
321             get { return this.Document.TabStops; }
322             set {
323                 this.Document.TabStops = value;
324                 this.View.AdjustCaretAndSrc();
325                 this.TabStopChange(this, null);
326             }
327         }
328
329         /// <summary>
330         /// 全角スペースを表示するなら真。そうでないなら偽
331         /// </summary>
332         [DefaultValue(false)]
333         public bool ShowFullSpace
334         {
335             get
336             {
337                 return this.Document.ShowFullSpace;
338             }
339             set
340             {
341                 this.Document.ShowFullSpace = value;
342             }
343         }
344
345         /// <summary>
346         /// 半角スペースを表示するなら真。そうでないなら偽
347         /// </summary>
348         [DefaultValue(false)]
349         public bool ShowHalfSpace
350         {
351             get
352             {
353                 return this.Document.ShowHalfSpace;
354             }
355             set
356             {
357                 this.Document.ShowHalfSpace = value;
358             }
359         }
360
361         /// <summary>
362         /// タブを表示するなら真。そうでないなら偽
363         /// </summary>
364         [DefaultValue(false)]
365         public bool ShowTab
366         {
367             get
368             {
369                 return this.Document.ShowTab;
370             }
371             set
372             {
373                 this.Document.ShowTab = value;
374             }
375         }
376
377         /// <summary>
378         /// 改行マークを表示するなら真。そうでないなら偽
379         /// </summary>
380         [DefaultValue(false)]
381         public bool ShowLineBreak
382         {
383             get
384             {
385                 return this.Document.ShowLineBreak;
386             }
387             set
388             {
389                 this.Document.ShowLineBreak = value;
390             }
391         }
392
393         /// <summary>
394         /// 選択中の文字列
395         /// </summary>
396         /// <remarks>
397         /// 未選択状態で文字列を代入した場合、キャレット位置に挿入され、そうでないときは置き換えられます。
398         /// </remarks>
399         [BrowsableAttribute(false)]
400         public string SelectedText
401         {
402             get { return this.Controller.SelectedText; }
403             set { this.Controller.SelectedText = value; }
404         }
405
406         /// <summary>
407         /// キャレット位置を表す
408         /// </summary>
409         [BrowsableAttribute(false)]
410         public TextPoint CaretPostion
411         {
412             get { return this.Document.CaretPostion; }
413         }
414
415         /// <summary>
416         /// 選択範囲を表す
417         /// </summary>
418         /// <remarks>
419         /// Lengthが0の場合はキャレット位置を表します
420         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
421         /// </remarks>
422         [BrowsableAttribute(false)]
423         public TextRange Selection
424         {
425             get { return new TextRange(this.Controller.SelectionStart,this.Controller.SelectionLength); }
426             set
427             {
428                 this.Document.Select(value.Index, value.Length);
429             }
430         }
431
432         /// <summary>
433         /// 挿入モードかどうか
434         /// </summary>
435         [DefaultValue(true)]
436         public bool InsertMode
437         {
438             get { return this.View.InsertMode; }
439             set
440             {
441                 this.View.InsertMode = value;
442                 this.InsetModeChange(this, null);
443             }
444         }
445
446         /// <summary>
447         /// 矩形選択を行うかどうか
448         /// </summary>
449         [DefaultValue(false)]
450         public bool RectSelection
451         {
452             get { return this.Controller.RectSelection; }
453             set { this.Controller.RectSelection = value; }
454         }
455
456         System.Drawing.Color ForegroundColor = SystemColors.ControlText,
457             HilightForegroundColor = SystemColors.HighlightText,
458             BackgroundColor = SystemColors.Control,
459             HilightColor = System.Drawing.Color.DeepSkyBlue,
460             Keyword1Color = System.Drawing.Color.Blue,
461             Keyword2Color = System.Drawing.Color.DarkCyan,
462             LiteralColor = System.Drawing.Color.Brown,
463             UrlColor = System.Drawing.Color.Blue,
464             ControlCharColor = System.Drawing.Color.Gray,
465             CommentColor = System.Drawing.Color.Green,
466             InsertCaretColor = System.Drawing.Color.Black,
467             OverwriteCaretColor = System.Drawing.Color.Black,
468             LineMarkerColor = System.Drawing.Color.WhiteSmoke,
469             UpdateAreaColor = System.Drawing.Color.MediumSeaGreen,
470             LineNumberColor = System.Drawing.Color.DimGray;
471
472         /// <summary>
473         /// 前景色
474         /// </summary>
475         public System.Drawing.Color Foreground
476         {
477             get
478             {
479                 return this.ForegroundColor;
480             }
481             set
482             {
483                 this.render.Foreground = D2DTextRender.ToColor4(value);
484                 this.ForegroundColor = value;
485             }
486         }
487
488         /// <summary>
489         /// 選択時の前景色
490         /// </summary>
491         public System.Drawing.Color HilightForeground
492         {
493             get
494             {
495                 return this.HilightForegroundColor;
496             }
497             set
498             {
499                 this.render.HilightForeground = D2DTextRender.ToColor4(value);
500                 this.HilightForegroundColor = value;
501             }
502         }
503
504         /// <summary>
505         /// 背景色
506         /// </summary>
507         public System.Drawing.Color Background
508         {
509             get
510             {
511                 return this.BackgroundColor;
512             }
513             set
514             {
515                 this.render.Background = D2DTextRender.ToColor4(value);
516                 this.BackgroundColor = value;
517             }
518         }
519
520         /// <summary>
521         /// 挿入モード時のキャレット色
522         /// </summary>
523         public System.Drawing.Color InsertCaret
524         {
525             get
526             {
527                 return this.InsertCaretColor;
528             }
529             set
530             {
531                 this.InsertCaretColor = value;
532                 this.render.InsertCaret = D2DTextRender.ToColor4(value);
533             }
534         }
535
536         /// <summary>
537         /// 上書きモード時のキャレット色
538         /// </summary>
539         public System.Drawing.Color OverwriteCaret
540         {
541             get
542             {
543                 return this.OverwriteCaretColor;
544             }
545             set
546             {
547                 this.OverwriteCaretColor = value;
548                 this.render.OverwriteCaret = D2DTextRender.ToColor4(value);
549             }
550         }
551
552         /// <summary>
553         /// ラインマーカーの色
554         /// </summary>
555         public System.Drawing.Color LineMarker
556         {
557             get
558             {
559                 return this.LineMarkerColor;
560             }
561             set
562             {
563                 this.LineMarkerColor = value;
564                 this.render.LineMarker = D2DTextRender.ToColor4(value);
565             }
566         }
567
568         /// <summary>
569         /// コントロールの色
570         /// </summary>
571         public System.Drawing.Color ControlChar
572         {
573             get
574             {
575                 return this.ControlCharColor;
576             }
577             set
578             {
579                 this.ControlCharColor = value;
580                 this.render.ControlChar = D2DTextRender.ToColor4(value);
581             }
582         }
583
584         /// <summary>
585         /// 編集行フラグの色
586         /// </summary>
587         public System.Drawing.Color UpdateArea
588         {
589             get
590             {
591                 return this.UpdateAreaColor;
592             }
593             set
594             {
595                 this.UpdateAreaColor = value;
596                 this.render.UpdateArea = D2DTextRender.ToColor4(value);
597             }
598         }
599
600         /// <summary>
601         /// 行番号の色
602         /// </summary>
603         public System.Drawing.Color LineNumber
604         {
605             get
606             {
607                 return this.LineNumberColor;
608             }
609             set
610             {
611                 this.LineNumberColor = value;
612                 this.render.LineNumber = D2DTextRender.ToColor4(value);
613             }
614         }
615
616         /// <summary>
617         /// URLの色
618         /// </summary>
619         public System.Drawing.Color Url
620         {
621             get
622             {
623                 return this.UrlColor;
624             }
625             set
626             {
627                 this.UrlColor = value;
628                 this.render.Url = D2DTextRender.ToColor4(value);
629             }
630         }
631
632         /// <summary>
633         /// 選択領域の色
634         /// </summary>
635         public System.Drawing.Color Hilight
636         {
637             get
638             {
639                 return this.HilightColor;
640             }
641             set
642             {
643                 this.HilightColor = value;
644                 this.render.Hilight = D2DTextRender.ToColor4(value);
645             }
646         }
647
648         /// <summary>
649         /// コメントの色
650         /// </summary>
651         public System.Drawing.Color Comment
652         {
653             get
654             {
655                 return this.CommentColor;
656             }
657             set
658             {
659                 this.CommentColor = value;
660                 this.render.Comment = D2DTextRender.ToColor4(value);
661             }
662         }
663
664         /// <summary>
665         /// 文字リテラルの色
666         /// </summary>
667         public System.Drawing.Color Literal
668         {
669             get
670             {
671                 return this.LiteralColor;
672             }
673             set
674             {
675                 this.LiteralColor = value;
676                 this.render.Literal = D2DTextRender.ToColor4(value);
677             }
678         }
679
680         /// <summary>
681         /// キーワード1の色
682         /// </summary>
683         public System.Drawing.Color Keyword1
684         {
685             get
686             {
687                 return this.Keyword1Color;
688             }
689             set
690             {
691                 this.Keyword1Color = value;
692                 this.render.Keyword1 = D2DTextRender.ToColor4(value);
693             }
694         }
695
696         /// <summary>
697         /// キーワード2の色
698         /// </summary>
699         public System.Drawing.Color Keyword2
700         {
701             get
702             {
703                 return this.Keyword2Color;
704             }
705             set
706             {
707                 this.Keyword2Color = value;
708                 this.render.Keyword2 = D2DTextRender.ToColor4(value);
709             }
710         }
711
712         /// <summary>
713         /// キャレットに下線を描くかどうか
714         /// </summary>
715         [DefaultValue(false)]
716         public bool DrawCaretLine
717         {
718             get { return !this.View.HideLineMarker; }
719             set { this.View.HideLineMarker = !value; }
720         }
721
722         /// <summary>
723         /// ドキュメントを選択する
724         /// </summary>
725         /// <param name="start">開始インデックス</param>
726         /// <param name="length">長さ</param>
727         public void Select(int start, int length)
728         {
729             this.Document.Select(start, length);
730             this.HScrollBar.Value = (int)this.View.Src.X;
731             this.VScrollBar.Value = this.View.Src.Row;
732         }
733
734         /// <summary>
735         /// ドキュメント全体を選択する
736         /// </summary>
737         public void SelectAll()
738         {
739             this.Document.Select(0, this.Document.Length - 1);
740         }
741
742         /// <summary>
743         /// 選択を解除する
744         /// </summary>
745         public void DeSelectAll()
746         {
747             this.Controller.DeSelectAll();
748         }
749
750         /// <summary>
751         /// クリップボードにコピーする
752         /// </summary>
753         public void Copy()
754         {
755             string text = this.SelectedText;
756             if(text != null && text != string.Empty)
757                 Clipboard.SetText(text);
758         }
759
760         /// <summary>
761         /// クリップボードにコピーし、指定した範囲にある文字列をすべて削除します
762         /// </summary>
763         public void Cut()
764         {
765             string text = this.SelectedText;
766             if (text != null && text != string.Empty)
767             {
768                 Clipboard.SetText(text);
769                 this.Controller.SelectedText = "";
770             }
771         }
772
773         /// <summary>
774         /// クリップボードの内容をペーストします
775         /// </summary>
776         public void Paste()
777         {
778             if (Clipboard.ContainsText() == false)
779                 return;
780             this.Controller.SelectedText = Clipboard.GetText();
781         }
782
783         /// <summary>
784         /// キャレットを指定した行に移動させます
785         /// </summary>
786         /// <param name="index">インデックス</param>
787         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
788         public void JumpCaret(int index)
789         {
790             this.Controller.JumpCaret(index);
791         }
792         /// <summary>
793         /// キャレットを指定した行と桁に移動させます
794         /// </summary>
795         /// <param name="row">行番号</param>
796         /// <param name="col">桁</param>
797         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
798         public void JumpCaret(int row, int col)
799         {
800             this.Controller.JumpCaret(row, col);
801         }
802
803         /// <summary>
804         /// 再描写します
805         /// </summary>
806         public new void Refresh()
807         {
808             if (this.Document.FireUpdateEvent == false)
809                 throw new InvalidOperationException("");
810             if(this.View.CaretBlink)
811                 this.View.CaretBlink = true;
812             this.Invalidate();
813             this.Update();
814         }
815
816         /// <summary>
817         /// 行の高さを取得する
818         /// </summary>
819         /// <param name="row">行</param>
820         /// <returns>高さ</returns>
821         public double GetLineHeight(int row)
822         {
823             if (this.Document.FireUpdateEvent == false)
824                 throw new InvalidOperationException("");
825             return this.View.LayoutLines.GetLayout(row).Height;
826         }
827
828         /// <summary>
829         /// 対応する座標を返す
830         /// </summary>
831         /// <param name="tp">テキストポイント</param>
832         /// <returns>座標</returns>
833         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
834         public System.Drawing.Point GetPostionFromTextPoint(TextPoint tp)
835         {
836             if (this.Document.FireUpdateEvent == false)
837                 throw new InvalidOperationException("");
838             return this.View.GetPostionFromTextPoint(tp);
839         }
840
841         /// <summary>
842         /// 対応するテキストポイントを返す
843         /// </summary>
844         /// <param name="p">クライアント領域の原点を左上とする座標</param>
845         /// <returns>テキストポイント</returns>
846         public TextPoint GetTextPointFromPostion(System.Drawing.Point p)
847         {
848             if (this.Document.FireUpdateEvent == false)
849                 throw new InvalidOperationException("");
850             return this.View.GetTextPointFromPostion(p);
851         }
852
853         /// <summary>
854         /// インデックスに対応する座標を得ます
855         /// </summary>
856         /// <param name="index">インデックス</param>
857         /// <returns>座標を返す</returns>
858         public System.Drawing.Point GetPostionFromIndex(int index)
859         {
860             if (this.Document.FireUpdateEvent == false)
861                 throw new InvalidOperationException("");
862             TextPoint tp = this.View.GetLayoutLineFromIndex(index);
863             return this.View.GetPostionFromTextPoint(tp);
864         }
865
866         /// <summary>
867         /// 座標からインデックスに変換します
868         /// </summary>
869         /// <param name="p">座標</param>
870         /// <returns>インデックスを返す</returns>
871         public int GetIndexFromPostion(System.Drawing.Point p)
872         {
873             if (this.Document.FireUpdateEvent == false)
874                 throw new InvalidOperationException("");
875             TextPoint tp = this.View.GetTextPointFromPostion(p);
876             return this.View.GetIndexFromLayoutLine(tp);
877         }
878
879         /// <summary>
880         /// レイアウト行をすべて破棄し、再度レイアウトを行う
881         /// </summary>
882         public void PerfomLayouts()
883         {
884             this.Document.PerformLayout();
885             initScrollBars();
886         }
887
888         /// <summary>
889         /// ストリームからドキュメントを構築する
890         /// </summary>
891         /// <param name="tr">TextReader</param>
892         /// <param name="token">キャンセル用トークン</param>
893         /// <returns>Taskオブジェクト</returns>
894         public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)
895         {
896             await this.Document.LoadAsync(tr, token);
897         }
898
899         /// <summary>
900         /// ファイルからドキュメントを構築する
901         /// </summary>
902         /// <param name="filepath">ファイルパス</param>
903         /// <param name="enc">エンコード</param>
904         /// <param name="token">キャンセル用トークン</param>
905         /// <returns>Taskオブジェクト</returns>
906         public async Task LoadFileAsync(string filepath, Encoding enc, System.Threading.CancellationTokenSource token)
907         {
908             var fs = new System.IO.StreamReader(filepath, enc);
909             await this.Document.LoadAsync(fs, token);
910             fs.Close();
911         }
912
913         private void Document_LoadProgress(object sender, ProgressEventArgs e)
914         {
915             if (e.state == ProgressState.Start)
916             {
917                 this.Enabled = false;
918             }
919             else if (e.state == ProgressState.Complete)
920             {
921                 this.initScrollBars();
922                 this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, MousePosition.X, MousePosition.Y, 0));
923                 this.View.CalculateLineCountOnScreen();
924                 this.Enabled = true;
925             }
926         }
927
928         /// <summary>
929         /// ドキュメントの内容をファイルに保存する
930         /// </summary>
931         /// <param name="filepath">ファイルパス</param>
932         /// <param name="newLine">改行コード</param>
933         /// <param name="enc">エンコード</param>
934         /// <param name="token">キャンセル用トークン</param>
935         /// <returns>Taskオブジェクト</returns>
936         public async Task SaveFile(string filepath, Encoding enc, string newLine, System.Threading.CancellationTokenSource token)
937         {
938             var fs = new System.IO.StreamWriter(filepath, false, enc);
939             fs.NewLine = newLine;
940             await this.Document.SaveAsync(fs, token);
941             fs.Close();
942         }
943
944         /// <summary>
945         /// マウスカーソルを指定します
946         /// </summary>
947         public override Cursor Cursor
948         {
949             get
950             {
951                 return base.Cursor;
952             }
953             set
954             {
955                 base.Cursor = value;
956                 this.VScrollBar.Cursor = DefaultCursor;
957                 this.HScrollBar.Cursor = DefaultCursor;
958             }
959         }
960
961         private const int WS_BORDER = 0x00800000;
962         private const int WS_EX_CLIENTEDGE = 0x00000200;
963         /// <summary>
964         /// コントロールの外観を指定します
965         /// </summary>
966         protected override CreateParams CreateParams
967         {
968             get
969             {
970                 CreateParams cp = base.CreateParams;
971                 switch (this.BorderStyle)
972                 {
973                     case BorderStyle.Fixed3D:
974                         cp.ExStyle |= WS_EX_CLIENTEDGE;
975                         break;
976                     case BorderStyle.FixedSingle:
977                         cp.Style |= WS_BORDER;
978                         break;
979                 }
980                 return cp;
981             }
982         }
983
984         /// <summary>
985         /// コマンド キーを処理します
986         /// </summary>
987         /// <param name="msg">メッセージ</param>
988         /// <param name="keyData">キーデータ</param>
989         /// <returns>文字がコントロールによって処理された場合は true。それ以外の場合は false。 </returns>
990         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
991         {
992             const int WM_KEYDOWN = 0x100;
993             if (msg.Msg != WM_KEYDOWN)
994                 return base.ProcessCmdKey(ref msg, keyData);
995             switch (keyData)
996             {
997                 case Keys.Control | Keys.C:
998                     this.Copy();
999                     break;
1000                 case Keys.Control | Keys.V:
1001                     this.Paste();
1002                     this.Refresh();
1003                     break;
1004                 case Keys.Control | Keys.X:
1005                     this.Cut();
1006                     this.Refresh();
1007                     break;
1008                 case Keys.Control | Keys.Z:
1009                     this.Document.UndoManager.undo();
1010                     this.Refresh();
1011                     break;
1012                 case Keys.Control | Keys.Y:
1013                     this.Document.UndoManager.redo();
1014                     this.Refresh();
1015                     break;
1016                 case Keys.Control | Keys.B:
1017                     if (this.Controller.RectSelection)
1018                         this.Controller.RectSelection = false;
1019                     else
1020                         this.Controller.RectSelection = true;
1021                     break;
1022                 default:
1023                     return base.ProcessCmdKey(ref msg,keyData);
1024             }
1025             return true;
1026         }
1027
1028         /// <summary>
1029         /// インスタンスを破棄します
1030         /// </summary>
1031         /// <param name="disposing">マネージ リソースとアンマネージ リソースの両方を解放する場合は true。アンマネージ リソースだけを解放する場合は false。</param>
1032         protected override void Dispose(bool disposing)
1033         {
1034             SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.SystemEvents_UserPreferenceChanged);
1035             this.render.Dispose();
1036             this.Timer.Dispose();
1037             base.Dispose(disposing);
1038         }
1039
1040         /// <summary>
1041         /// 入力可能な文字かチェックします
1042         /// </summary>
1043         /// <param name="charCode">入力しようとした文字</param>
1044         /// <returns>可能なら真。そうでなければ偽</returns>
1045         protected override bool IsInputChar(char charCode)
1046         {
1047             if ((0x20 <= charCode && charCode <= 0x7e)
1048                 || charCode == '\r'
1049                 || charCode == '\n'
1050                 || charCode == ' '
1051                 || charCode == '\t'
1052                 || charCode == ' '
1053                 || 0x7f < charCode)
1054             {
1055                 return true;
1056             }
1057
1058             return false;
1059         }
1060
1061         /// <summary>
1062         /// PaddingChangedイベントを発生させます
1063         /// </summary>
1064         /// <param name="e">インベントデータ</param>
1065         protected override void OnPaddingChanged(EventArgs e)
1066         {
1067             base.OnPaddingChanged(e);
1068             this.View.Padding = new Padding(this.Padding.Left, this.Padding.Top, this.Padding.Right, this.Padding.Bottom);
1069         }
1070
1071         /// <summary>
1072         /// GotFocusイベントを発生させます
1073         /// </summary>
1074         /// <param name="e">インベントデータ</param>
1075         protected override void OnGotFocus(EventArgs e)
1076         {
1077             base.OnGotFocus(e);
1078             this.View.IsFocused = true;
1079             this.Timer.Start();
1080             this.Refresh();
1081         }
1082
1083         /// <summary>
1084         /// LostFocusイベントを発生させます
1085         /// </summary>
1086         /// <param name="e">インベントデータ</param>
1087         protected override void OnLostFocus(EventArgs e)
1088         {
1089             base.OnLostFocus(e);
1090             this.View.IsFocused = false;
1091             this.Timer.Stop();
1092             this.Refresh();
1093         }
1094
1095         /// <summary>
1096         /// FontChangedイベントを発生させます
1097         /// </summary>
1098         /// <param name="e">インベントデータ</param>
1099         protected override void OnFontChanged(EventArgs e)
1100         {
1101             if (this.DesignMode)
1102                 return;
1103             base.OnFontChanged(e);
1104             initScrollBars();
1105         }
1106
1107         /// <summary>
1108         /// MouseDownイベントを発生させます
1109         /// </summary>
1110         /// <param name="e">インベントデータ</param>
1111         protected override void OnMouseDown(MouseEventArgs e)
1112         {
1113             TextPoint tp = this.View.GetTextPointFromPostion(e.Location);
1114             if (tp == TextPoint.Null)
1115                 return;
1116             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
1117             
1118             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);
1119             
1120             base.OnMouseDown(mouseEvent);
1121             
1122             if (mouseEvent.Handled)
1123                 return;
1124
1125             if (e.Button == MouseButtons.Left)
1126             {
1127                 FoldingItem foldingData = this.View.HitFoldingData(e.Location.X, tp.row);
1128                 if (foldingData != null)
1129                 {
1130                     if (foldingData.Expand)
1131                         this.View.LayoutLines.FoldingCollection.Collapse(foldingData);
1132                     else
1133                         this.View.LayoutLines.FoldingCollection.Expand(foldingData);
1134                     this.Controller.JumpCaret(foldingData.Start, false);
1135                 }
1136                 else
1137                 {
1138                     this.Controller.JumpCaret(tp.row, tp.col, false);
1139                 }
1140                 this.View.IsFocused = true;
1141                 this.Focus();
1142                 this.Refresh();
1143             }
1144         }
1145
1146         /// <summary>
1147         /// MouseClickイベントを発生させます
1148         /// </summary>
1149         /// <param name="e">インベントデータ</param>
1150         protected override void OnMouseClick(MouseEventArgs e)
1151         {
1152             int index = this.GetIndexFromPostion(e.Location);
1153
1154             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);
1155
1156             base.OnMouseClick(mouseEvent);
1157         }
1158
1159         /// <summary>
1160         /// MouseDoubleClickイベントを発生させます
1161         /// </summary>
1162         /// <param name="e">インベントデータ</param>
1163         protected override void OnMouseDoubleClick(MouseEventArgs e)
1164         {
1165             TextPoint tp = this.View.GetTextPointFromPostion(e.Location);
1166             if (tp == TextPoint.Null)
1167                 return;
1168             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
1169
1170             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);
1171             
1172             base.OnMouseDoubleClick(mouseEvent);
1173
1174             if (mouseEvent.Handled)
1175                 return;
1176
1177             if (e.X < this.render.TextArea.X)
1178                 this.Document.SelectLine(index);
1179             else
1180                 this.Document.SelectWord(index);
1181             
1182             this.Refresh();
1183         }
1184
1185         /// <summary>
1186         /// MouseMoveイベントを発生させます
1187         /// </summary>
1188         /// <param name="e">インベントデータ</param>
1189         protected override void OnMouseMove(MouseEventArgs e)
1190         {
1191             if (this.Focused == false)
1192                 return;
1193
1194             base.OnMouseMove(e);
1195
1196             if (this.View.HitTextArea(e.Location.X, e.Location.Y))
1197             {
1198                 TextPoint tp = this.View.GetTextPointFromPostion(e.Location);
1199                 if (this.Controller.IsMarker(tp, HilightType.Url))
1200                     this.Cursor = Cursors.Hand;
1201                 else
1202                     this.Cursor = Cursors.IBeam;
1203
1204                 if (e.Button == MouseButtons.Left)
1205                 {
1206                     this.Controller.MoveCaretAndSelect(tp, ModifierKeys.HasFlag(Keys.Control));
1207                     this.Refresh();
1208                 }
1209             }
1210             else
1211             {
1212                 this.Cursor = Cursors.Arrow;
1213             }
1214         }
1215
1216         /// <summary>
1217         /// MouseWheelイベントを発生させます
1218         /// </summary>
1219         /// <param name="e">インベントデータ</param>
1220         protected override void OnMouseWheel(MouseEventArgs e)
1221         {
1222             base.OnMouseWheel(e);
1223
1224             ScrollDirection dir = e.Delta > 0 ? ScrollDirection.Up : ScrollDirection.Down;
1225             this.Controller.Scroll(dir, SystemInformation.MouseWheelScrollLines, false, false);
1226             this.Refresh();
1227         }
1228
1229         /// <summary>
1230         /// Paintイベントを発生させます
1231         /// </summary>
1232         /// <param name="e">インベントデータ</param>
1233         protected override void OnPaint(PaintEventArgs e)
1234         {
1235             if (DesignMode)
1236             {
1237                 SolidBrush brush = new SolidBrush(this.BackColor);
1238                 e.Graphics.FillRectangle(brush, this.ClientRectangle);
1239                 brush.Dispose();
1240             }else if (this.Document.FireUpdateEvent){
1241                 this.render.DrawContent(this.View, e.ClipRectangle);
1242                 this.Document.IsRequestRedraw = false;
1243             }
1244             base.OnPaint(e);
1245         }
1246
1247         /// <summary>
1248         /// PaintBackgroundイベントを発生させます
1249         /// </summary>
1250         /// <param name="e">インベントデータ</param>
1251         protected override void OnPaintBackground(PaintEventArgs e)
1252         {
1253         }
1254
1255         /// <summary>
1256         /// PreviewKeyDownイベントを発生させます
1257         /// </summary>
1258         /// <param name="e">インベントデータ</param>
1259         protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
1260         {
1261             base.OnPreviewKeyDown(e);
1262
1263             switch (e.KeyCode)
1264             {
1265                 case Keys.Up:
1266                 case Keys.Down:
1267                 case Keys.Left:
1268                 case Keys.Right:
1269                 case Keys.Tab:
1270                     e.IsInputKey = true;
1271                     break;
1272             }
1273         }
1274
1275         /// <summary>
1276         /// KeyDownイベントを発生させます
1277         /// </summary>
1278         /// <param name="e">インベントデータ</param>
1279         protected override void OnKeyDown(KeyEventArgs e)
1280         {
1281             base.OnKeyDown(e);
1282
1283             var completeBox = (AutoCompleteBox)this.Document.AutoComplete;
1284             if (completeBox.ProcessKeyDown(this, e, e.Control, e.Shift))
1285             {
1286                 e.Handled = true;
1287                 return;
1288             }
1289
1290             if (e.Handled)
1291                 return;
1292
1293             switch (e.KeyCode)
1294             {
1295                 case Keys.Up:
1296                     this.Controller.MoveCaretVertical(-1, e.Shift);
1297                     this.Refresh();
1298                     break;
1299                 case Keys.Down:
1300                     this.Controller.MoveCaretVertical(+1, e.Shift);
1301                     this.Refresh();
1302                     break;
1303                 case Keys.Left:
1304                     this.Controller.MoveCaretHorizontical(-1, e.Shift, e.Control);
1305                     this.Refresh();
1306                     break;
1307                 case Keys.Right:
1308                     this.Controller.MoveCaretHorizontical(1, e.Shift, e.Control);
1309                     this.Refresh();
1310                     break;
1311                 case Keys.PageUp:
1312                     this.Controller.Scroll(ScrollDirection.Up, this.VScrollBar.LargeChange,e.Shift,true);
1313                     this.Refresh();
1314                     break;
1315                 case Keys.PageDown:
1316                     this.Controller.Scroll(ScrollDirection.Down, this.VScrollBar.LargeChange,e.Shift,true);
1317                     this.Refresh();
1318                     break;
1319                 case Keys.Insert:
1320                     if (this.InsertMode)
1321                         this.InsertMode = false;
1322                     else
1323                         this.InsertMode = true;
1324                     break;
1325                 case Keys.Delete:
1326                     this.Controller.DoDeleteAction();
1327                     this.Refresh();
1328                     break;
1329                 case Keys.Back:
1330                     this.Controller.DoBackSpaceAction();
1331                     this.Refresh();
1332                     break;
1333                 case Keys.Home:
1334                     if (e.Control)
1335                         this.Controller.JumpToHead(e.Shift);
1336                     else
1337                         this.Controller.JumpToLineHead(this.Document.CaretPostion.row, e.Shift);
1338                     this.Refresh();
1339                     break;
1340                 case Keys.End:
1341                     if (e.Control)
1342                         this.Controller.JumpToEnd(e.Shift);
1343                     else
1344                         this.Controller.JumpToLineEnd(this.Document.CaretPostion.row, e.Shift);
1345                     this.Refresh();
1346                     break;
1347                 case Keys.Tab:
1348                     if (this.Controller.SelectionLength == 0)
1349                         this.Controller.DoInputChar('\t');
1350                     else if (e.Shift)
1351                         this.Controller.DownIndent();
1352                     else
1353                         this.Controller.UpIndent();
1354                     this.Refresh();
1355                     break;
1356             }
1357         }
1358
1359         /// <summary>
1360         /// KeyPressイベントを発生させます
1361         /// </summary>
1362         /// <param name="e">インベントデータ</param>
1363         protected override void OnKeyPress(KeyPressEventArgs e)
1364         {
1365             base.OnKeyPress(e);
1366
1367             if (e.Handled)
1368                 return;
1369
1370             var completeBox = (AutoCompleteBox)this.Document.AutoComplete;
1371             if (completeBox.ProcessKeyPress(this, e))
1372                 return;
1373
1374             switch (e.KeyChar)
1375             {
1376                 case '\r':
1377                     this.Controller.DoEnterAction();
1378                     this.Refresh();
1379                     break;
1380                 case '\t':
1381                     break;  //OnKeyDownで処理しているので不要
1382                 default:
1383                     if (IsInputChar(e.KeyChar) == false)
1384                         break;
1385                     this.Controller.DoInputChar(e.KeyChar);
1386                     this.Refresh();
1387                     break;
1388             }
1389         }
1390
1391         /// <summary>
1392         /// ClientSizeChangedイベントを発生させます
1393         /// </summary>
1394         /// <param name="e">インベントデータ</param>
1395         protected override void OnClientSizeChanged(EventArgs e)
1396         {
1397             if (this.DesignMode)
1398                 return;
1399             base.OnClientSizeChanged(e);
1400             
1401             this.View.PageBound = new Rectangle(0,
1402                 0,
1403                 Math.Max(this.ClientRectangle.Width - this.VScrollBar.Width,0),
1404                 Math.Max(this.ClientRectangle.Height - this.HScrollBar.Height, 0));
1405
1406             initScrollBars();
1407             this.Refresh();
1408         }
1409
1410         void View_SrcChanged(object sender, EventArgs e)
1411         {
1412             if (this.View.Src.Row > this.VScrollBar.Maximum)
1413                 this.VScrollBar.Maximum = this.View.Src.Row + this.View.LineCountOnScreen + 1;
1414
1415             int srcX = (int)Math.Abs(this.View.Src.X);
1416             if (srcX > this.HScrollBar.Maximum)
1417                 this.HScrollBar.Maximum = srcX + (int)this.View.PageBound.Width + 1;
1418
1419             this.HScrollBar.Value = srcX;
1420
1421             this.VScrollBar.Value = this.View.Src.Row;
1422         }
1423
1424         void FooTextBox_RightToLeftChanged(object sender, EventArgs e)
1425         {
1426             this.Document.RightToLeft = this.RightToLeft == System.Windows.Forms.RightToLeft.Yes;
1427         }
1428
1429         void VScrollBar_Scroll(object sender, ScrollEventArgs e)
1430         {
1431             this.View.TryScroll(this.View.Src.X, e.NewValue);
1432             this.Refresh();
1433         }
1434
1435         void HScrollBar_Scroll(object sender, ScrollEventArgs e)
1436         {
1437             int toX;
1438             if (this.RightToLeft == System.Windows.Forms.RightToLeft.Yes)
1439                 toX = -e.NewValue;
1440             else
1441                 toX = e.NewValue;
1442             this.View.TryScroll(toX, this.View.Src.Row);
1443             this.Refresh();
1444         }
1445
1446         void Ime_StartCompstion(object sender, StartCompstionEventArgs e)
1447         {
1448             this.Ime.Font = this.Font;
1449             System.Drawing.Point p = this.GetPostionFromIndex(this.Controller.SelectionStart);
1450             float dpi;
1451             this.render.GetDpi(out dpi, out dpi);
1452             p.X = (int)(p.X * dpi / 96);
1453             p.Y = (int)(p.Y * dpi / 96);
1454             this.Ime.Location = p;
1455             this.View.HideCaret = true;
1456         }
1457
1458         void Ime_EndCompstion(object sender, EndCompstionEventArgs e)
1459         {
1460             this.View.HideCaret = false;
1461         }
1462
1463         void Ime_ImeCompstion(object sender, ImeCompstionEventArgs e)
1464         {
1465             this.Controller.DoInputString(e.InputText);
1466             this.Refresh();
1467         }
1468
1469         void Ime_ImeDocumentFeed(object sender, ImeDocumentFeedEventArgs e)
1470         {
1471             TextPoint tp = this.CaretPostion;
1472             e.Pragraph = this.LayoutLines[tp.row];
1473             e.pos = tp.col;
1474         }
1475
1476         void Ime_ImeReconvert(object sender, ImeReconvertStringEventArgs e)
1477         {
1478             if (this.RectSelection)
1479                 return;
1480             if (this.Controller.SelectionLength == 0)
1481             {
1482                 TextPoint tp = this.LayoutLines.GetTextPointFromIndex(this.Controller.SelectionStart);
1483                 e.TargetString = this.LayoutLines[tp.row];
1484                 e.AutoAdjust = true;
1485             }
1486             else
1487             {
1488                 e.TargetString = this.SelectedText;
1489                 if (e.TargetString.Length > 40)
1490                     e.TargetString.Remove(40);
1491             }
1492             e.CaretPostion = this.View.CaretLocation;
1493         }
1494
1495         void Ime_ImeQueryReconvert(object sender, ImeQueryRecovertStringEventArgs e)
1496         {
1497             TextPoint tp = this.LayoutLines.GetTextPointFromIndex(this.Controller.SelectionStart);
1498             tp.col = e.offset;
1499
1500             int index = this.View.GetIndexFromLayoutLine(tp);
1501
1502             this.Select(index, index + e.length);
1503         }
1504
1505         void Controller_CaretMoved(object sender, EventArgs e)
1506         {
1507             this.SelectionChanged(this, null);
1508         }
1509
1510         void initScrollBars()
1511         {
1512             this.VScrollBar.SmallChange = 1;
1513             this.VScrollBar.LargeChange = this.View.LineCountOnScreen;
1514             this.VScrollBar.Maximum = this.View.LayoutLines.Count + this.View.LineCountOnScreen + 1;
1515             this.HScrollBar.SmallChange = 10;
1516             this.HScrollBar.LargeChange = (int)this.View.PageBound.Width;
1517             this.HScrollBar.Maximum = this.HScrollBar.LargeChange + 1;
1518         }
1519
1520         void Timer_Tick(object sender,EventArgs e)
1521         {
1522             if (this.Document.CaretPostion.row >= this.View.LayoutLines.Count || DesignMode)
1523                 return;
1524
1525             bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw;
1526
1527             if (updateAll)
1528                 this.Invalidate();
1529             else
1530                 this.Invalidate(new System.Drawing.Rectangle(this.View.CaretLocation, this.View.GetCurrentCaretRect().Size));
1531         }
1532
1533         void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
1534         {
1535             this.SetSystemParamaters();
1536             this.Refresh();
1537         }
1538
1539         void SetSystemParamaters()
1540         {
1541             int CaretBlinkTime = SystemInformation.CaretBlinkTime;
1542             if (CaretBlinkTime == -1)
1543             {
1544                 this.View.CaretBlink = false;
1545             }
1546             else
1547             {
1548                 this.View.CaretBlink = true;
1549                 this.View.CaretBlinkTime = CaretBlinkTime * 2;
1550             }
1551             this.View.CaretWidthOnInsertMode = SystemInformation.CaretWidth;
1552         }
1553
1554     }
1555
1556     /// <summary>
1557     /// FooEditEngineで使用するマウスイベント
1558     /// </summary>
1559     public class FooMouseEventArgs : MouseEventArgs
1560     {
1561         /// <summary>
1562         /// イベントが発生したインデックス
1563         /// </summary>
1564         public int index;
1565         /// <summary>
1566         /// 既定の処理を省略するなら真。そうでなければ偽
1567         /// </summary>
1568         public bool Handled;
1569         /// <summary>
1570         /// コンストラクター
1571         /// </summary>
1572         /// <param name="index">インデックス</param>
1573         /// <param name="button">押されているボタン</param>
1574         /// <param name="clicks">ボタンが押された回数</param>
1575         /// <param name="x">マウスカーソルがあるX座標</param>
1576         /// <param name="y">マウスカーソルがあるY座標</param>
1577         /// <param name="delta">ホイールの回転方向</param>
1578         public FooMouseEventArgs(int index, MouseButtons button, int clicks, int x, int y, int delta)
1579             : base(button, clicks, x, y, delta)
1580         {
1581             this.index = index;
1582         }
1583     }
1584
1585 }