キーワードの色分け(2)

返信する


答えを正確に入力してください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: キーワードの色分け(2)

返信@yu0627

by yu0627 » 2006年4月16日(日) 12:41

 結局、あまりうまくいかなかったので、ストリームを使用した無限アンドゥに
切り替えました。そして、アンドゥ・リドゥともにうまく実装できました。
仕組みは、ソフトと同じフォルダに「Undo」というフォルダを作成し、そこに書き込んでいってます。
色分けをしている関係上、やはりストリームを使ったほうがさくさくと行きます。
~URL削除~
ということで、問題解決です。あとは自分で改良してやっていきたいとおもいます。
 最後に、ノッチさんにはアンドゥ機能開発の為に多大な時間を使っていただいたことに、感謝をしています。
一部、その技術を使わせていただきました。ありがとうございました。

近況報告

by yu0627 » 2006年4月07日(金) 14:33

 こんにちは。yu0627です。
今のところ、以下のところまで来ました。

○日本語入力への対応
→とりやえず実装。ただし二文字以上でゴミが入る。
○BackSpaceとDeleteへの対応
→とりあえず実装。ただし日本語入力で文字化けしたり、ゴミが入る。
 また、英字でゴミが入る。
○切り取りへの対応
→暫定実装。データが大きいサイズを処理するとバグが出る
○貼り付けへの対応
→実装。まだ改良余地あり
○REDOへの対応
→未実装
○その他
・UNDO後のpNewNextポインタの開放でHEAPが起きる

追記:BackSpace、Deleteキーの英字のごみ問題は解決しました。
   しかし、Edit上で日本語と英字のサイズは同じなのに変数上で1バイトと2バイトに分かれるので難しいです。

以下がコードです。
リッチエディット仕様に書き換えてある箇所もあるので、そちらでなんとかしてください(爆)
リッチエディットのハンドル:hEdit
あと、「SetKeywordColor」はコメントアウトで。
大変...。

返信@yu0627

by yu0627 » 2006年4月04日(火) 21:49

 確認してみました。しっかりと動いています。
 日本語入力については、IMEの変換状態を取得することでなんとかなりそうです。
あと、リドゥについて考えてみました。


1,通常入力時いつもの入力時はアンドゥを記録する
②アンドゥ時
1,現在の状態をリドゥバッファに記録する
2,アンドゥ時、記録したバッファを適用する。
③リドゥ時
1)リドゥ→アンドゥ
 1,最新のリドゥをリッチエディットに適用
 2,最新のリドゥを破棄
2)リドゥ→リドゥ
 1,最新のリドゥを適用
 2,最新のリドゥを破棄
3)リドゥ→通常入力
 1,リドゥバッファを全て破棄

こんな感じです。
これらはREDO用のコードです。
現在アンドゥの改良をしています。
 では。

Re: 返信@yu0627

by ノッチ » 2006年4月04日(火) 15:14

会社からどうどうと(!?)投稿です。 この前と同じように空のプロジェクトのMainWndにEditを追加してMainWnd.sbpの
中身を丸ごと入れ替えて下さい。
上記コードでは中にいろいろコメントしてますが、0~9、A~Zの入力と
そのアンドゥのみ実装しています。
上記条件を満たしていれば文字入力、文字を選択状態での文字入力にも
完璧に対応しています(のはずです)。
これを元にyu0627さんの力でがんばってみて下さい。
僕にやらせると完成が数ヶ月(もしかしたら数年)かかるかもしれません。

返信@yu0627

by yu0627 » 2006年4月03日(月) 17:50

 こちらの勘違いでした。
リッチエディットのアンドゥ機能を一時的に無効にすることなどできませんでした^^;
というわけで、どうやってアンドゥを呼び出すかです。
とりあえず、やり方はCtrl+Zが押されたことを検出(アクセラレータ使ってるか
WM_KEYDOWN wParam=Zの時にAsyncKeyState(VK_CONTROL)してるか)し、
それを奪い取って(CallWindowProcに渡さずExit Functionで抜ける)、
バッファから文字を追加、削除する。といった感じです。
削除をアンドゥする時はnStart~nEndの文字列をszTextに変換する。
文字追加をアンドゥする時は追加された文字をnStartの位置から削除する。
追加の場合、前のコードは考慮されていませんでしたが、文字選択状態で
"A"なんかを押すと選択部分を削除して文字追加になるのでその部分も
考えなければいけませんでした。
 だいたいは理解できます。
しかし、コードにするのはつらいです...。

返信@yu0627

by yu0627 » 2006年4月02日(日) 21:51

 ちょっと色々やっていて返信が遅れました。

 アクセラレータキーについては実装できます。

 今は、RichEdit標準のアンドゥ機能をどうやって生かすかを
考えています。置き換え機能のアンドゥ機能に記録させない設定が
あるので、コードを読み取ってやっていけばよいかと...。
すみません。

Re: 返信@yu0627

by ノッチ » 2006年3月31日(金) 00:52

この部分で
If GetWindowTextLength(hEdit)=nStart Then
としてるのはカーソルがエディットの最後にある時はDeleteを押しても
なにもしないよ。ということです。
ですので、BackSpaceの場合はカーソルが先頭にあって何も選択してない時に
何もしない、となります。

で、投げっぱなしのようになってしまうのですが、僕の家にはネット環境が
ありません。今は出張でネット付のホテルに泊まっていたのでコメントできたの
ですが、出張が終わるので時々会社から覗く(それと簡単なコメント)に
なってしまいます。

とりあえず、やり方はCtrl+Zが押されたことを検出(アクセラレータ使ってるか
WM_KEYDOWN wParam=Zの時にAsyncKeyState(VK_CONTROL)してるか)し、
それを奪い取って(CallWindowProcに渡さずExit Functionで抜ける)、
バッファから文字を追加、削除する。といった感じです。
削除をアンドゥする時はnStart~nEndの文字列をszTextに変換する。
文字追加をアンドゥする時は追加された文字をnStartの位置から削除する。
追加の場合、前のコードは考慮されていませんでしたが、文字選択状態で
"A"なんかを押すと選択部分を削除して文字追加になるのでその部分も
考えなければいけませんでした。
あまり役に立たずにいなくなります。すみません。
どなたかサポートをお願いします。

返信@yu0627

by yu0627 » 2006年3月30日(木) 21:42

 ノッチさん、ありがとうございます。
しっかりとサブクラス化も成功しています。
コードを見ると、現在はUNDOバッファを追加していくところまでのようですが。
少し僕も改造してみました。追加箇所は、スペースキー・エンターキー・バックスペースキーへの
対応です。少し、追加位置を間違っているかも知りませんが。
どうやってバッファを呼び出すのか分かりませんが...。

by ノッチ » 2006年3月30日(木) 01:17

>
今回の場合だとmallocで確保した配列よりも、リスト構造の方が向いているんじゃないでしょうか?
とあるように数日前からリスト構造でのアンドゥバッファ作成をしていました。
まだ作成途中ですが、ABの記述方法がよくわからず(メモリ操作系)
ちょっと挫折気味です。 新規プロジェクトにエディットボックスを配置してMainWnd.sbpに
上記コードをコピペしてみてください。
途中にdebugを入れたりして、こんな方法かというのを感じてもらえればと。
まだA~Zキーを押した時とDeleteキーのみですが。
まだバグもあると思いますし、AddUndoで未知の文字列が開放されます。
&リドゥは未実装です。
ほんとにイメージとして捉えて下さい。

by hira » 2006年3月29日(水) 20:14

自分なりに解釈してコード化してみました。
あってるでしょうか?
あのわかりにくい説明を解釈していただいてありがとうございますm(_ _)m
そういう感じです。
デメリットはどうしてもコードが読みにくくなることですね…(^^;
今回の場合だとmallocで確保した配列よりも、リスト構造の方が向いているんじゃないでしょうか?
どうなんでしょう。リスト構造の方が処理が高速な感じはしますが…。
※それ以前に、コードの読みにくさを改善するというメリットが(何

Re: 返信@yu0627

by Tomorrow » 2006年3月29日(水) 19:28

ちょっとうまく理解できませんが...。
例えばどうするのでしょうか。
自分なりに解釈してコード化してみました。
あってるでしょうか? >> hiraさん
>> yu0627さん
このコードを見ると、「FUndoMemory: array[0..UndoCount] of TRichUndoMemory;」って
書いてあります。よく分からないのですが、配列を途中で拡大しているようです
と書いてらっしゃいますが、"配列を途中で拡大している"とは先のDelphiのソースのどのあたりでしょう?
私には見つかりませんでした。

P.S.
今回の場合だとmallocで確保した配列よりも、リスト構造の方が向いているんじゃないでしょうか?

返信@yu0627

by yu0627 » 2006年3月29日(水) 10:54

 hiraさん、ノッチさん、ありがとうございます。
ポインタのポインタ(現在の所うまく処理できませんが)を1つ定義し、要素数分のポインタを格納する領域を用意します(mallocやcallocを使用すること)。
それぞれのポインタは、いったんクラスのポインタの変数にNewで作成したものを各要素に代入して保存します(ポインタのポインタをうまく処理できないため)。
ポインタを使ってクラスを呼び出すときは、クラスのポインタの変数に保存しておいたポインタを代入して呼び出します。
解放するときもやはりクラスのポインタの変数に代入してDeleteです。
 ちょっとうまく理解できませんが...。
例えばどうするのでしょうか。
さらっと見ただけですので間違ってるかも知れませんが、内容的には独自で
アンドゥ、リドゥ処理を実装しているようです。
やはり既存のアンドゥ、リドゥは拡張性のないものなのか、ただ情報があまり
出てないだけなのか。
ですので、リッチエディットをサブクラス化してWM_KEYDOWN、WM_COPY、
WM_PASTEあたり(?)を独自で処理すればOKです。

やり方は、WM_KEYDOWN時やペースト時にmallocでメモリを確保。
確保したメモリに入力したどの文字位置から何文字削除した、どの文字位置に
なんという文字列を追加した等を書き込み、その作業が行われるたびに
メモリを確保->メモリに情報を書き込む->メモリに前のメモリのアドレスを追加する
を繰り返し、Ctrl+Zでその作業を巻き戻す、ついでにリドゥバッファに反対の
作業を(削除した場合は追加)を書き込み・・・。

と、書くのは簡単ですが実装は大変そうです。
 確かに難しそうですね...。
あと、ストリームをやろうとしたのですが、「dwCookie」の部分に何を代入しようか迷っています。
ファイルの読み込みと保存ならファイルハンドルを指定すればよいのですが、
ただのバッファへの格納にどの値を代入すればよいのでしょうか...。

by ノッチ » 2006年3月27日(月) 22:02

さらっと見ただけですので間違ってるかも知れませんが、内容的には独自で
アンドゥ、リドゥ処理を実装しているようです。
やはり既存のアンドゥ、リドゥは拡張性のないものなのか、ただ情報があまり
出てないだけなのか。
ですので、リッチエディットをサブクラス化してWM_KEYDOWN、WM_COPY、
WM_PASTEあたり(?)を独自で処理すればOKです。

やり方は、WM_KEYDOWN時やペースト時にmallocでメモリを確保。
確保したメモリに入力したどの文字位置から何文字削除した、どの文字位置に
なんという文字列を追加した等を書き込み、その作業が行われるたびに
メモリを確保->メモリに情報を書き込む->メモリに前のメモリのアドレスを追加する
を繰り返し、Ctrl+Zでその作業を巻き戻す、ついでにリドゥバッファに反対の
作業を(削除した場合は追加)を書き込み・・・。

と、書くのは簡単ですが実装は大変そうです。

by hira » 2006年3月27日(月) 19:57

このコードを見ると、「FUndoMemory: array[0..UndoCount] of TRichUndoMemory;」って
書いてあります。よく分からないのですが、配列を途中で拡大しているようです。
こんなことABで可能でしたっけ...。
TRichUndoMemoryという名前からすればクラスですよね(多分)。
私の場合、こういうときは無理矢理実装する派です(^^;;

ポインタのポインタ(現在の所うまく処理できませんが)を1つ定義し、要素数分のポインタを格納する領域を用意します(mallocやcallocを使用すること)。
それぞれのポインタは、いったんクラスのポインタの変数にNewで作成したものを各要素に代入して保存します(ポインタのポインタをうまく処理できないため)。
ポインタを使ってクラスを呼び出すときは、クラスのポインタの変数に保存しておいたポインタを代入して呼び出します。
解放するときもやはりクラスのポインタの変数に代入してDeleteです。

※こうなると、

コード: 全て選択

p As *Class->func()
のような書き方ができるか、ポインタのポインタに対応していただけるとありがたいということになります(^^;;

返信@yu0627

by yu0627 » 2006年3月27日(月) 19:15

お久しぶりノッチです。
家にネット環境がないので出張でネット付のホテルに泊まるか会社から(!?)しか
ネットができません。

ということでリンク先を見たのですが、lzhファイルが見つからないですね。
アンドゥ処理は興味があったので残念です。
 どうやら、FTPサイトでファイル要求を送信中にタイムアウトになるようです。
ですので、こちらをご覧ください。
http://www.exfiction.net/~yu0627/temp/RichEditVx.Pas
このコードを見ると、「FUndoMemory: array[0..UndoCount] of TRichUndoMemory;」って
書いてあります。よく分からないのですが、配列を途中で拡大しているようです。
こんなことABで可能でしたっけ...。

ページトップ