- PR -

C#での独自コンポーネントへのIMEからの文字入力の方法

投稿者投稿内容
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-12-12 17:28
.NET 2.0で仕様が変わったのかバグかは分かりませんが、ContainerControl以下のクラスを代表とした一部のコントロールでIMEが自動的に無効になるようになっているようですね。
例えばScrollableControlの派生クラスなら問題なくIMEを使えるはずです。
ちなみに、IMEを操作すると言うことになると、WndProcで直接メッセージを処理する必要が必ず出てくると思います。

個人的には別に入力系だからといってTextBoxBaseに拘らなくてもいいと思います。特殊な描画が多く要求されるなら逆に遠回りになることも多いし。
ただ、派生元としてUserControlなんかを使うのは不自然だとも思います。UserControlはほかのコントロール群のコンテナとして用意されているクラスだと思いますから。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-12 17:38
すいません、こちらのレスを読んでおりませんでした。
(連続返信だったもので、その後の 1 つしか拝見していませんでした)

引用:

冬星さんの書き込み (2005-12-11 15:50) より:

どのような仕様のテキストエディタを作ろうとしているかですが:
・文法を別途定義して、文法に従って'<','>',識別子などの構文上の強調表示。
・括弧入力時、対応する括弧の点滅表示。
・改行コード、EOFマークの画像表示。
・折り返し、非折り返し表示。
・行番号、行ルーラー、桁ルーラー表示。
・無限回数の Undo/Redo への対応。(その際、強調色分け表示処理に Undo/Redo 処理が影響されないこと。)
・xml, xhtml, html の対応するノードレベルの Expand, Collapse 表示。( C# の IDE がもっているような、エディタの左側の +,- ボタンでの開閉。)


これだと、全部自前で描画した方が良いです。
RichTextBox ならば CreateGraphic でいけないこともないですが、非常につらいです。

ただ、UserControl ではなく、1 からコントロールを作成することになりますね。

冬星さんのおっしゃるとおり、プログラム内部でエディタの文字列情報をすべて持ち、
表示されている範囲内のみ、自前で描画で大正解です。

本当に申し訳ありませんでした。(*_ _)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
冬星
会議室デビュー日: 2005/12/11
投稿数: 6
投稿日時: 2005-12-12 21:32
最初に結論:解決しました。ありがとうございます。

Hongliangさん:
引用:

Hongliangさんの書き込み (2005-12-12 17:28) より:
.NET 2.0で仕様が変わったのかバグかは分かりませんが、ContainerControl以下のクラスを代表とした一部のコントロールでIMEが自動的に無効になるようになっているようですね。

例えばScrollableControlの派生クラスなら問題なくIMEを使えるはずです。
(snipped...)
ただ、派生元としてUserControlなんかを使うのは不自然だとも思います。UserControlはほかのコントロール群のコンテナとして用意されているクラスだと思いますから。


UserControl から派生するのをやめて、ScrollableControl から派生させたところ .Net2.0+Corsavy で IME から全角入力ができるようになりました。

ということは Corsavy(#develop2.0) のIDEのエディタで現状全角文字が入力できない問題も、開発元にフィードバックすれば解決しそうですね。postしてみます。(うまく説明できるかわからないけど…。) Hongliang さんズバリな情報ありがとうございます。助かりました。


じゃんぬさん:
引用:

冬星さんのおっしゃるとおり、プログラム内部でエディタの文字列情報をすべて持ち、
表示されている範囲内のみ、自前で描画で大正解です。


こちらこそ、あまりにスキル不足な課題のため自分で見えていない部分をじゃんぬさんの方では見えている状態で発言されているのはわかるのですが、それが何かわからず足を引っ張ってしまいましたが、おかげさまで解決できそうです。全角半角混じりの文字入力が正常に動作するところまで完成しました。(サンプルでスクラッチしたはずなのですが、このまま書き上げてみます。)

あとは周辺の気づいた点ですが、現状IMEの変換窓が常にコントロールの矩形左上に表示されるようですので、これをなおすのに caret の移動時にImmSetCompositionWindow()を呼ぶか、それでダメならImmGetDefaultIMEWnd()でとってきたhWndにSendMessage()でIMC_SETCOMPOSITIONWINDOWを送ってみて…と思いやってみたのですが、前者は機能せず、後者はトレース実行したときだけ成功するという微妙な結果に…。(^^; 何らかのタイミングの問題があるのだと思います。(関数を呼び出すべきタイミング or 呼び出したときの処理の仕方のタイミング etc.)もう少し調べてみます。

引用:

ちなみに、IMEを操作すると言うことになると、WndProcで直接メッセージを処理する必要が必ず出てくると思います。


基本的に IME 制御をしない方向でおりますが、 WndProc については、変換が確定した直後に変換窓のあった矩形の下が真っ白になってしまうのが確認されましたので、WndProc() と this.OnPaint() を override して、this.OnPaint() では必要な場所を再描画する処理を用意してやり、WndProc() で WM_IME_ENDCOMPOSITION を補足して this.Invaridate(); を呼び出す必要が出てきました。(その方法で解決しました。)

引用:

個人的には別に入力系だからといってTextBoxBaseに拘らなくてもいいと思います。特殊な描画が多く要求されるなら逆に遠回りになることも多いし。
ただ、派生元としてUserControlなんかを使うのは不自然だとも思います。UserControlはほかのコントロール群のコンテナとして用意されているクラスだと思いますから。


コンテナですか。.Net2.0だとToolStripとかがそうですね。
このへんの話(.Netコントロールの系統・働き)については、かなり研究不足を感じました。ネットで HOW TO を公開して下さっているところでも、このあたりの視点と方針立てについては見かけたことがないような気がします。MFC のとき手元においていた(VCを買ったら付いてきた)クラス構成の図みたいなものを、コントロールの分だけでもつくってみます。
CHN#
常連さん
会議室デビュー日: 2004/11/07
投稿数: 31
投稿日時: 2005-12-12 22:08
作り始めのようですので、今のうちに経験者として
余計なお世話をよかったら聞いてください。

こういうものはNativeコードで作るべきです。
将来性を考えて.NETを選んだなら、それは大きな
大きな間違いです。(特に理由がないまたはほかの理由ならごめんなさい)
今の.NETは中途半端ですので、APIのラッパーでしかない.NETでつくったからといって
将来性はないです。将来成熟しきったときAPIを呼びまくっている今の.NETアプリは
ほとんどごみ同然です。だったらNativeコードでやったほうがパフォーマンスという
大きなメリットがあります。
どうしても.NETやる必要があるのであれば、
APIを呼び出しているところを自分で完全にラップし純粋なマネージコードになっても
問題ないようにうまく逃げ道をつくっておいたほうがいいです。

余計なお世話でした
masas
常連さん
会議室デビュー日: 2002/05/23
投稿数: 25
投稿日時: 2005-12-15 23:04
引用:

CHN#さんの書き込み (2005-12-12 22:08) より:
こういうものはNativeコードで作るべきです。
お世話でした[/b]。



私も同感です。C++で作りますね。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2005-12-16 00:03
.net的なコンポーネントとしての価値はあるね。利用しやすいという点で。
全部マネージでなくとも、なるべくマネージにしとくっていうのもよい点。

スキルアップ/キャリアアップ(JOB@IT)