スポンサーサイト

--年--月--日 --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

てきすとえでぃた 4

2006年06月30日 23:29

何回かすっ飛ばしてましたけど、てきすとえでぃたモドキ完成しました~。

無限リドゥアンドゥもあの後(ワードブレイク処理を入れた後)は特に難しいこともなくサクサクと実装した後バグ修正も含めて1日ほどで終わりました。
それでこの前リストアップした欲しい機能リストを実現したヤツだけチェックしてみると、、、

 ●コピーアンドペースト
 ○強調表示機能
 ●無限アンドゥ、リドゥ
 ○検索
 ○置換
 ○行数表示
 ○インテリジェンスな補足機能(VC++でやってる単語補完機能)

 ● が出来てます。
 ○ は出来てません。


エディットコントロールを使ってる分には無理な機能は、、、強調表示かな。
時間的に無理なのはインテリジェンスな補足機能。これやるとなったらかなり大掛かりに組みなおした後でしょう。

検索や置換はすぐ出来るだろうけど、UI作るのが・・・('A`)



とりあえず、編集は今のままでも出来るので、これで突っ走りますw
っていうのもこのエディタもどきを使ったアプリケーションを完成させなきゃいけないわけですよ。
7月5日までには完成させなきゃ( ・`ω・´)



完成させた後にエディタは修正しようかな?と。
エディットコントロールを使ってる分では、タブサイズを変更することもままなりません。
これじゃ使いにくいことこの上なしです。

結局自前で描画する感じになっちゃいそうですね(´・ω・`)
うーん、、、自前で描画するとなるとデータ構造とかも考えないとなー。。

別に50MBとかあるテキストを扱わなければ適当に作っても問題ないんですけどねw
シーンファイルとかをテキストフォーマットで出すと割と20MBとか軽く行っちゃうのが悩みの種です。


あ、今現在、アンドゥやリドゥ実行時の文字の置換は EM_SETRECT と EM_REPLACESEL とかでやってます。
文字列の取得とかは EM_GETHANDLE で文字列のバッファのメモリハンドル(HLOCAL)を取得した後、LocalLock と LocalUnlock を使ったりして速度を稼ごうとしてます。
なんか適当な処理ですけど特に重い感じはしません。


自前で文字を描画したときとかって速度大丈夫なのかいな('A`)
IMEを使うことはそんなに難しくなさそうだけど・・・。
ちょっと心配。


とりあえず、アプリケーションを完成させます。



blog_rank
スポンサーサイト

シザー領域とビューポート領域

2006年06月27日 23:14

GL のことでちょっとはまったので..._〆(゚▽゚*) メモメモ代わりに残しておきやす。


シザーは Viewport 変換した後のどの部分を持ってくるか?の設定です。
Viewport 変換後のピクセルの位置がシザー領域外だった場合、そこは書き込まれないわけです。
当然、レンダーバッファ(描画領域)以上の設定をしても無意味です。
それに対して Viewport はレンダーバッファのどの領域に書き込むのか?の設定です。
別にレンダーバッファ以上の設定にしてもOKですけど、領域外のピクセルはどうせシザーテストで落ちるので書き込まれません。


わかりにくいので汚いですけど図にたとえます。


Viewport 0, 0, 640, 480
Scissor 0, 0, 640, 480

なら

test1.jpg


こんな感じに絵が出てるとすると、、、




Viewport 0, 0, 640, 480
Scissor 0, 0, 320, 240

に変更すると

test2.jpg


こんな感じに絵が出るわけです。



逆に

Viewport 0, 0, 320, 240
Scissor 0, 0, 640, 480

に変更すると

test3.jpg


こんな感じに絵が出ます。



glScissor で設定する「領域」はカレントのレンダーバッファのどの部分は書き込んでいいのか?の設定、glViewport は描画領域を特定するための処理ということはお分かりいただいたと思います。
これを踏まえて話をします。


それじゃ何が問題なの?ってことですよね。
実はハマった場所はテクスチャに描画した後、そのテクスチャを使う時はまりました。

glBindFramebufferEXT、glFramebufferTexture2DEXT などでテクスチャに書き込む設定をした場合、当たり前ですけど上記のルールが厳密に適応されます。
あるけ は Scissor は何故か一番最後(SwapBuffers 時)に適応されるもんだと思ってました orz
なので、シザーの設定をテクスチャに書き込むときには設定してなかったんですね。
ですから、ウィンドウズのサイズで設定されていたシザーがそのまま適応されてしまい、おかしな具合になってたわけです(´・ω・`)





blog_rank

is系関数 追加(マルチバイト対応編)

2006年06月25日 01:31

テキストエディタを作ってて、ちょっとわからなかった時に調べてメモった内容を残しておきます。
誰かの役に立つかもしれないしね(・∀・)



ってことで、表題の通りマルチバイト対応の is系関数を書いておきます。
全て条件に当てはまれば 0 以外が返ります。

  _ismbchira
    「ひらがな」かどうか調べる
  _ismbckata
    「カタカナ」かどうか調べる
  _ismbclegal
    マルチバイト文字かどうか調べる
  _ismbcl0
    漢字以外の全角文字(ひらがな、カタカナ、英数字含む)
  _ismbcl1
    JIS 第一水準
  _ismbcl2
    JIS 第二水準
  _ismbcsymbol
    記号などの全角のシンボル(■とか○とか)


また、 isprint や isalpha などはマルチバイト文字を渡すと assert する場合があるのでそれを起こさないようにマルチバイト文字に対応している関数を呼ぶ必要があります。
なので、それ系の関数も ..._〆(゚▽゚*) メモメモ。

 _ismbcalnum
  英数字 (A ~ Z、a ~ z、または 0 ~ 9)。
 _ismbcalpha
  英字 (A ~ Z または a ~ z)。
 iswascii
  ASCII 文字 (0x00 ~ 0x7F)。
 iswcntrl
  制御文字 (0x00 ~ 0x1F または 0x7F)。
 _ismbcdigit
  10 進数 (0 ~ 9)。
 _ismbcgraph
  空白 ( ) を除く印字可能な文字。
 _ismbclower
  英小文字 (a ~ z)。
 _ismbcprint
  空白を含む印字可能な文字 (0x20 ~ 0x7E)。
 _ismbcpunct
  区切り記号。
 _ismbcspace
  空白文字 (0x09 ~ 0x0D または 0x20)。
 _ismbcupper
  英大文字 (A ~ Z)。
 iswxdigit
  16 進数 (A ~ F、a ~ f、または 0 ~ 9)。



blog_rank

てきすとえでぃた 3

2006年06月25日 01:09

今回もまたテキストエディタの続きです。


さて、前回予告したとおり無制限のリドゥとアンドゥの実装に入りました。
まぁ、こんなもんはセオリーがあるので、実装処理自体はサクっと終わりました。

簡単に説明すると、、、
入力が来た時に書き込まれたバッファの位置と書き終えたバッファの位置を保存。
削除が来た時は削除された領域の開始位置と終了位置、それに消された内容を保存すればいいだけです。

後は自前のテンプレートのリストとかスタッククラスを併用して現在のアンドゥ位置を覚えておけば終了。

簡単ですね。


当たり前ですけど、全てのバッファを保存するような真似はしません。
そんなことやったら何メガあっても足りませんから。


実装処理自体は単純でもインターフェースとくっつけると厄介になるのがウィンドウズのいいところw
上の処理、実はそのまま乗せようとすると問題があるんですね。



コピー&ペーストやカット、DELETE キーでの削除なら何も問題ありません。
削除される場合(CUT や CLEAR などで)はEM_GETSEL とかで選択領域を取得、文が挿入される場合(PASTE など)は WM_CHAR をクラックしてコピー後の領域を保存すればいいだけです。


ここで WM_CHAR を捕まえるのは WM_KEYDOWN とかで捕まえるより効率がいいからです。
WM_KEYDOWN では IME が変換処理中にもメッセージが飛んできちゃうからですね。

あ、DELETE キーだけは WM_KEYDOWN じゃないと処理できないので、こっちで処理します。
押されてるかどうかの処理は GetKeyState(VK_DELETE) などで取得できます。


さて、それじゃ何が問題なのか?
当たり前ですけど、入力中に毎回リドゥとアンドゥ用のバッファを作成するのでは処理が重過ぎます。
(もっとも、今のPCならあまり気にするレベルじゃないかもしれませんけどね)


それではどうするか?
 ・一定時間入力が行われない
 ・改行した
 ・コピー&ペーストなど行った
 ・フォーカスを失った
など、区切りのいいところでバッファを作るのがいいでしょう。



入力はひとまずこの考えでOKです。

それじゃ削除は?
削除も基本的に入力と同じ処理でOKですね。
・・・んが!ここで問題が。


適当なテキストエディタでテキストファイルを開いて CTRL キー+ DELETE キーを押してみてください。
適当な単語単位で削除できますね。


そうです。この処理をアンドゥ出来るようにするのが一番骨が折れるのです( ´Д⊂ヽ


はじめ、何かAPIで選択領域を絞れるのか調べてみました。。
・・・特に見当たりません( ;Д⊂ヽ

ちょっと調べてみると、CTRL + カーソルキーの左 or 右 などの単語単位での移動や単語単位での削除などでどうやって単語を特定しているのか?は EditWordBreakProc というコールバックプロシージャでやってるみたいです。
これは EM_SETWORDBREAKPROC や EM_GETWORDBREAKPROC で設定や取得できるみたいです。
んが、ここでも問題が。。・・・デフォルトの WordBreakProg が無いんです( ;Д⊂ヽ


嘆いててもしょうがないので、結局全て自作してみました。
もちろん、マルチバイト文字や半角カタカナにも対応しないと意味がないので対応しました。
結構面倒でしたよこれ。。


けど、単語取得処理は後々色換えや検索で使用すると思うので作っていても損はないと思うので良かったのかもしれません(´ー` )


とりあえず、自前の EditWordBreakProc が出来たので次回はコレを利用して無制限リドゥとアンドゥを完璧に処理したいと思います。


blog_rank

てきすとえでぃた 2

2006年06月21日 16:51

テキストエディタの続きです。


前回書いたとおり大体やりたいことが決まったので次は「どうやって実現するか?」を考えます。
一番簡単なのはエディットコントロールを使うことでしょう。
最終的に強調表示などを組み入れたい場合、リッチエディットコントロールにしないといけないとは思いますが、そこまで気合入れてやっちゃうと時間がかかりそうなので強調表示は次のステップにします。

念のため、他の代表的なエディタを VS に標準でついてるツール SPY++ で軽く調べます。
・・・秀丸は独自形式でやってるみたいですね。
notepad や wordpad などはエディットコントロールやリッチエディットコントロールを使ってました。

うーん、やっぱり細かい設定をやるのなら自前で DrawText とかのAPIを使って書くのがいいんでしょうね。
けど、折角在るのなら使った方がいいかなーってことで、やっぱりエディットコントロールを使って組みます。



さて、実現方法なんですけど、CreateWindowEx とかで "EDIT" 指定してウィンドウを作成、その後 SetWindowLong と GetWindowLong を使ってサブクラス化するっていうきわめてオーソドックスなやり方でクラス化しました。
あとはメッセージ捕まえて処理するだけですね。

ってことで、今日はエディットコントロール系のメッセージを全部ラッピングして終わりです。
ここはそんなに重要じゃないのでさらっと流しますw
(・・・そのくせ面倒なんだよね、ラップって)

ラップしたメッセージは

  EM_SETLIMITTEXT
  EM_GETLIMITTEXT
  EM_SETRECT
  EM_SETRECTNP
  EM_GETRECT
  EM_SETSEL
  EM_GETSEL
  EM_REPLACESEL
  EM_SETMARGINS
  EM_GETMARGINS
  EM_SETPASSWORDCHAR
  EM_GETPASSWORDCHAR
  EM_LINESCROLL
  EM_SCROLL
  EM_SCROLLCARET
  EM_FMTLINES
  EM_SETREADONLY
  EM_GETFIRSTVISIBLELINE
  EM_GETLINECOUNT
  EM_GETLINE
  EM_LINELENGTH
  EM_LINEINDEX
  EM_LINEFROMCHAR
  EM_GETTHUMB
  EM_CHARFROMPOS
  EM_POSFROMCHAR
  WM_CUT
  WM_PASTE
  WM_COPY
  WM_CLEAR
  
ってとこでしょうか。

あ、そうそう。
WM_CUT を CallWindowProc(GetWindowLong で取得したエディットコントロールのプロシージャで処理)で処理した場合に送られる WM_COPY は戻り値を返さないと WM_CLEAR などは呼ばれませんw
VC++ についてる WM_COPY のヘルプでは No return Value などと書かれていましたが、ここで戻り値を返さないと WM_CUT を呼んでるのに字が消えないことになります。

あるけ は自前のウィンドウズライブラリで全てのウィンドウズメッセージをトラップしているのですが、WM_COPY の処理関数 OnCopy でヘルプどおりに戻り値に S_OK を返していたら字が消えず嵌りました( ´Д⊂ヽ


ってことで、誰にも役に立たないであろう Tips でしたw
次回は無限アンドゥリドゥを実装して行きたいと思います。


blog_rank

てきすとえでぃた 1

2006年06月20日 15:47

ちょっと諸種の事情でテキストエディタを作ることになったのでそれの開発日記なんぞを書こうかと思います。


ちなみに、以前作ってた株ソフト、実はスクリーニング処理もハードコードしたら出来る段階まで来てるんですけど、フレキシブルに計算式を作るなどのUI部分をまだ作ってません。
んが!!アーティストハウスショック以来、ボロ負けしてる現状では他の株を買うことも出来ず(ただいま塩漬け中ヽ(`Д´)ノウワーン)これ以上何か出来る段階ではないので一旦開発を中止してます。
必要に差し迫ったらまた開発再開すると思うけど、今はやることも多いので。



ってことで、テキストエディタを作ることになりました。
なんでテキストエディタを作るのか?
それは自前のアプリケーション(自前のツール)に組み込むためですね。
自前のアプリケーション上でテキストを扱う必要が出てきた時に、いちいち外部エディッタを呼び出して結果だけ貰うのは面倒だしアホらしい!ってことで、どうせなら作っちまおうってことになりました。
本当はいいオープンソースでも参考にしながら作りたかったんですけど、微妙なオープンソースしか見つかりませんでした( ;Д⊂ヽ


折角なんで後々でも使えるように高機能なものを作っちゃおうかな?と思ってます。
検索を早くしたり色分けをできるようにしたり、もちろん無限アンドゥとリドゥも。

とりあえず、まずは欲しい機能を列挙します
 ・コピーアンドペースト
 ・強調表示機能
 ・無限アンドゥ、リドゥ
 ・検索
 ・置換
 ・行数表示
 ・インテリジェンスな補足機能(VC++でやってる単語補完機能)
 
コレぐらい出来ると最高ですね。

どうせなら一つのクラスで全部出来るようにしちゃって後々公開できたりとかすると楽しそうです。

んでは、がんばって作りますか(´<_ ` )



blog_rank


最近の記事


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。