EditBoxの動的な右端の折返しについて

[戻る]
ぴょぴょ 2008/07/28(月) 13:08:52
お世話になります。

簡単なメモソフトを作っています。
それでエディットボックスのスタイルの ES_AUTOHSCROLL を使って
右端の折返しを有効/無効にする部分を作成中です。
まずソースを載せます。

// 右端折返状態を取得
BOOL GetRightTurn( HWND hEdit )
{
 LONG lStyle = GetWindowLong(hEdit,GWL_STYLE);
 
 return (lStyle & ES_AUTOHSCROLL) ? FALSE : TRUE;
}

// 右端折返状態を設定
BOOL SetRightTurn( HWND hEdit, BOOL bRightTurn )
{
 BOOL bRight = GetRightTurn(hEdit);
 LONG lStyle = GetWindowLong(hEdit,GWL_STYLE);
 
 if ( bRightTurn ){
  lStyle &= ~(WS_HSCROLL | ES_AUTOHSCROLL);
 }
 else{
  lStyle |= (WS_HSCROLL | ES_AUTOHSCROLL);
 }
 SetWindowLong( hEdit, GWL_STYLE, lStyle );
 SetWindowPos( hEdit, NULL, 0, 0, 0, 0, 
(SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED) );
 return bRight;
}

このソースで SetRightTurn( hEdit, !GetRightTurn(m_hEdit) ); とすることで
右端の折返し状態を切り替えています。そして実行するとエディットボックスに
水平スクロールバーが出たり、消えたりします。しかし、水平スクロールバーが
ない状態の時に文字を入力しても右端で折り返さず自動的に水平スクロールされます。

なお、エディットボックスはダイアログで次のようになっています。(スタイル部のみ)
ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL | 
ES_AUTOHSCROLL
このスタイルで水平スクロールバーがない時なぜ右端で折り返せないのでしょうか?

試しにエディットボックスのスタイルの初期値を
ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL
とすると右端で折り返しますが、水平スクロールバーが出ているときに今度は
ずっと折り返されてしまいます。本当なら自動的に水平スクロールされずはずだが…。

原因など分かりますか?
よろしくお願い致します。

かもねぎ 2008/07/28(月) 15:48:59
SetWindowLongPtr -- GWL_STYLE で
切り替えのときにウィンドウスタイルも
変更してはどうでしょうか?

subaru 2008/07/28(月) 16:39:02
日本語での記述は見つけられませんでしたが、
こちらにエディットコントロールのスタイルは
動的に変更できないとの記述があります。
http://msdn.microsoft.com/en-us/library/bb775464.aspx

かもねぎ 2008/07/28(月) 17:16:56
変更できないのならウィンドウを2つ用意して
表示を切り替えますか?
イカサマ?

ぴょぴょ 2008/07/28(月) 17:46:23
かもねぎさん。
subaruさん。
レスありがとう。

> 切り替えのときにウィンドウスタイルも
> 変更してはどうでしょうか?
これはどのウインドウスタイルですか?
WS_HSCROLL は ES_AUTOHSCROLL とペアでフラグ操作をしています。

> こちらにエディットコントロールのスタイルは
> 動的に変更できないとの記述があります。
どの部分ですか?
ES_AUTOHSCROLL の場所ですか?
試しに ES_RIGHT スタイルで切り替えると正常に左寄せ/右寄せが動的に
切り替えられました。

> 変更できないのならウィンドウを2つ用意して
> 表示を切り替えますか?
> イカサマ?
これも考えましたがスマートでない気がします。
実現可能にするにはこの方法が有効なのでしょうがテキストの量が多いと
コピーに時間がかかります。数100KBでも数秒もかかる。

いろいろ考えエディットボックスの内部の管理上で動的に右端で折返しは
難しいのかもしれませんね。今は標準のGUI部品を使っていますが、実用な
エディタをそのうちに作ろうと思い内部の構造を考えていて動的に折返しを
実現するのがかなり難しい気がします。もちろん僕の推測ですがスタイルで
ES_AUTOHSCROLL、ES_AUTOVSCROLLは動的には変化できそうにないというのが
答えなのでしょうね。

でもいろいろと試行錯誤してみます。
他に情報があればお待ちしています。

(エディットボックスで右端の折返しを動的には絶対に無理ならあきらめます)
ちなみに作成中のメモソフトは付箋メモのような小さいサイズです。
普通にメモる程度なら右端の折返しが便利でCソースのような折り返されると
見づらい場合に動的に右端の折返しを無効にしたかったのです。

neko 2008/07/29(火) 07:08:55
Windowsのメモ帳は、メニューから
[書式]→[右端を折り返す] で動的に折り返しのON/OFFができるので、
絶対に無理ということはないと思いますが・・・

subaru 2008/07/29(火) 10:06:03
>> こちらにエディットコントロールのスタイルは
>> 動的に変更できないとの記述があります。
>どの部分ですか?
>ES_AUTOHSCROLL の場所ですか?
>試しに ES_RIGHT スタイルで切り替えると正常に左寄せ/右寄せが動的に
>切り替えられました。

Edit Control Stylesというタイトルのすぐ下です。
>After the control has been created, these styles cannot be modified, except as
noted.

ES_RIGHTも古い環境では適用されなかったかもしれません。


>nekoさん
Windowsのメモ帳の[右端を折り返す]で折り返しのON/OFFができました。
ただ折り返しのON/OFFの度にエディットコントロールのハンドルが
変わってしまうようで、コントロールを再作成していると推測します。

rin 2008/07/29(火) 12:37:30
Spy++でみると、メモ帳のEditには
設定変更のたびに、Destoroyメッセージを最後にハンドルが無効になってます
当然のことながら、サイズのでかいテキストで試すと切り替えに時間がかかります

ワードパッドだと、リッチエディットで破棄・作成することなく
切り替えが行われてるようです。

ぴょぴょ 2008/07/29(火) 12:39:37
[[解決]]
subaruさんありがとうございます。

> ES_RIGHTも古い環境では適用されなかったかもしれません。
確かにこのスタイルは新しい XP なら使えるようです。
今頃ですがこちらの環境は Windows XP で開発しています。
ただし利用は Windows 95以降でもと考えていましたので
バージョンをチェックして機能の有無をつける必要がありそうです。

nekoさん情報提供ありがとうございます。
確かにメモ帳で[右端で折り返す]があってON/OFFできますね。

ちょっと実験。
メモ帳に約140KBのテキストを読み込みキャレット位置を中央に移動。
右端で折返しすると約3秒してエディットボックスに文字が出てくる。
このときキャレット位置が先頭行に初期化された。

subaruさんのレスよりコントロールのハンドルが変化してキャレット位置も
初期化されるなら僕もコントロールが再作成されているのだと考える。

でもこの方法なら一通り動的に切り替えが出来ますね。
いろいろと実験して見慣れないEM_GETHANDLE、EM_SETHANDLEも試しましたが
再読み込みと同じく約3秒して文字が表示されるため意味がないようです。

とりあえず今回は右端で折返しを実行するたびにエディットボックスを
作成してテキストを移動する方法で我慢しようとお思います。
この方法で一通り解決です。

皆様いろいろとありがとうございました。

ぴょぴょ 2008/07/29(火) 12:41:44
[[解決]]
おっと rin さんの書き込みを見逃してしまった。

リッチエディットならできるのですか?
それなら置き換えてみようと思います。
またいろいろと実験してみます。

古いスレッドには追加発言できません。