OSDN Git Service

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