VC++ SDK でエディットにスクロールバーを関連付けするには?

解決


つぶマン  2007-04-20 23:06:35  No: 64954

はじめまして!
VC++はじめて1ヶ月も経たない初心者です。
今、VS2005 VC++ win32 SDK(API?)で
テキストを読み込んで、画面に表示する。
という画面を作成中です。
タッチパネルで運用する予定なので、
ボタンなどを押しやすいように大きくしないといけません。
なので、テキストを表示するエディットコントロールに、
スクロールバーを連動させたいのですが、どうにもうまくいきません;
MSDNやネットでも散々調べたのですが、
なかなかサンプルなども見つからなくて。
困り果てております。
どなたか詳しい方、教えてください(>_<)!


YuO  2007-04-21 01:11:36  No: 64955

WS_VSCROLLを付けてEDITを生成するのではだめですか?


つぶマン  2007-04-21 01:23:48  No: 64956

コメントありがとうございます。

>WS_VSCROLLを付けてEDITを生成するのではだめですか?
・・・申し訳ありません;
私にはYuOさんのおっしゃっている意味をちゃんと
理解する知識がないようです;
これは・・・フォームアプリのお話でしょうか?
言い忘れていました!ダイアログベースで作成しております。


つぶマン  2007-04-21 01:23:50  No: 64957

コメントありがとうございます。

>WS_VSCROLLを付けてEDITを生成するのではだめですか?
・・・申し訳ありません;
私にはYuOさんのおっしゃっている意味をちゃんと
理解する知識がないようです;
これは・・・フォームアプリのお話でしょうか?
言い忘れていました!ダイアログベースで作成しております。


つぶマン  2007-04-21 01:23:54  No: 64958

コメントありがとうございます。

>WS_VSCROLLを付けてEDITを生成するのではだめですか?
・・・申し訳ありません;
私にはYuOさんのおっしゃっている意味をちゃんと
理解する知識がないようです;
これは・・・フォームアプリのお話でしょうか?
言い忘れていました!ダイアログベースで作成しております。


つぶマン  2007-04-21 01:25:44  No: 64959

ボタン押しすぎました;失礼しました;;


夏みかん  2007-04-21 03:18:41  No: 64960

エディットコントロールのスタイルに WS_VSCROLL を追加すればよい。

ちなみにダイアログは VC++ のダイアログ・エディタで作っていますか?
もし、そうならばエディットコントロールのプロパティで WS_VSCROLL の項目を TRUE にすれば簡単ですけど…。

なお、エディットコントロールを WM_INITDIALOG の場所で CreateWindow などで作成している場合は、
CreateWindow の第3引数の dwStyle に WS_VSCROLL の定数をビットORすれば良い。

http://wisdom.sakura.ne.jp/system/winapi/win32/win66.html
上記のページに詳しく載っていますよ。
このサイトを参考にして下さい。


つぶマン  2007-04-21 04:06:16  No: 64961

夏みかんさん。コメントありがとうございます。
はい、ダイアログ・エディタで作成しています。

夏みかんさんの言う方法では、
「細いスクロールバーがくっつく」という感じになってしまいました。
最初にも述べましたが、タッチパネルで操作することになりますので、
太くないとダメなのです;
なので私は、エディットコントロールの隣に
スクロールバーコントロール(?)を配置して、
その二つのコントロールを連動させたいのです。

しかし、昨日の夜からずっと考えていますが、全然わかりません。
・・・無理なのでしょうか;


wclrp ( 'o')  URL  2007-04-21 05:02:46  No: 64962

スクロールバーのメッセージを受け取って
エディットコントロールのスクロールすればいいのだが、
今エディットコントロールが何行のテキストなのかによって
スクロールバーの設定も変えなきゃいけないから面倒だな。
スクロールバーが太ければいいんだな。

デスクトップで右クリックしてメニューからプロパティを選び、
デザインを変えてしまうか、
設定でDPIを変えてしまうか。
全てのアプリケーションのスクロールバーが太くなるけどね。
ボタンも大きくなるし。


wclrp ( 'o')  2007-04-21 05:43:06  No: 64963

連動させるとしたら
地道にたくさんの処理を連動するように作らないといけないし
そんな面倒なことしても上手く行くかわからないな。
がんばれば出来るけどって感じだな。


夏みかん  2007-04-22 01:38:31  No: 64964

つぶマンさんへ。
エディットコントロールの隣にスクロールバーをダイアログエディタで貼り付けて下さい。
そして、WM_HSCROLL(水平) や WM_VSCROLL(垂直) のメッセージを処理して下さい。
このメッセージを処理してエディットコントロールの水平、または垂直のスクロールを
SendMessage() 関数などで制御して下さい。

エディットコントロールのスクロール制御は、
EM_GETFIRSTVISIBLELINE トップに表示されている行番号を取得する
EM_GETLINECOUNT 複数行TextBoxにおいて、テキストの行数を取得する
EM_GETTHUMB 複数行TextBoxにおいて、スクロールバーの位置を取得する
EM_LINESCROLL 複数行TextBoxにおいて、テキストをスクロールする
EM_SCROLL 複数行テキストボックスにおいて、テキストのスクロールを行う
を駆使して制御します。
別々に用意したスクロールバーでエディットコントロールのスクロールを制御するのは
とても大変です。頑張って下さい。
下に参考になるリンクを貼っておきます。

http://wisdom.sakura.ne.jp/system/winapi/win32/win63.html
http://www.winapi-database.com/Message/EM/index.html


つぶマン  2007-04-23 20:59:25  No: 64965

解決しました!!
wclrp ( 'o')さん、夏みかんさん、ありがとうございました!
wclrp ( 'o')さんのおっしゃった
「地道にたくさんの処理を連動するように作らないといけない」
という言葉の意味が、すべてできあがってから理解できましたw

実際のソースを・・・※必要ないと思われる部分は省いています

INT_PTR CALLBACK Disp(HWND hDlg, UINT message, 
                          WPARAM wParam, LPARAM lParam)
{
      static SCROLLINFO si_v, si_h;
      static int dispno_v,dispno_h,pos_v,pos_h;
      static RECT rc;

      switch (message)
      {
  case WM_INITDIALOG:
    // 初期処理
    InitDialog_LogDisp(hDlg, message, wParam, lParam);
    
    GetWindowRect(GetDlgItem(hDlg,IDC_EDIT1), &rc);
    // 垂直スクロールバー
    dispno_v = (rc.bottom - rc.top) / LINEHEIGHT;
    si_v.cbSize = sizeof(SCROLLINFO);
    si_v.fMask = SIF_ALL;
    si_v.nMin = 0;
    si_v.nMax = MaxLine;
    si_v.nPage = dispno_v;
    si_v.nPos = pos_v;
    SetScrollInfo(GetDlgItem(hDlg,IDC_SCROLLBAR2),
                                       SB_CTL, &si_v, TRUE);
  case WM_VSCROLL:

    switch (LOWORD(wParam)) {
                case SB_LINEUP:
                    dy = -1;
                    break;
                case SB_LINEDOWN:
                    dy = 1;
                    break;
                case SB_PAGEUP:
                    dy = -1 * si_v.nPage;  
                    break;
                case SB_PAGEDOWN:
                    dy = si_v.nPage;
                    break;
                //case SB_THUMBPOSITION:
                case SB_THUMBTRACK:
      dy = HIWORD(wParam) - si_v.nPos;    
                    break;
                default:
                    dy = 0;
                    break;
    }
        dy = max(-1 * si_v.nPos, min(dy, si_v.nMax - si_v.nPos));
        if (dy != 0)
        {
            si_v.nPos += dy;
    //  テキストのスクロール
    switch (LOWORD(wParam)) {
             case SB_LINEUP:
         SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                                 EM_SCROLL, SB_LINEUP, 0L);
                    break;
             case SB_LINEDOWN:
         SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                                 EM_SCROLL, SB_LINEDOWN, 0L);
                    break;
             case SB_PAGEUP:        
         SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                                 EM_SCROLL, SB_PAGEUP, 0L);
                    break;
             case SB_PAGEDOWN:    
         SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                                 EM_SCROLL, SB_PAGEDOWN, 0L);
                    break;
             case SB_THUMBTRACK:
         SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                                 EM_LINESCROLL, 0L, dy);
                    break;
             default:
                break;
          }
        // スクロールバーのつまみの移動
        SetScrollInfo(GetDlgItem(hDlg,IDC_SCROLLBAR2),
                                SB_CTL, &si_v, TRUE);
        UpdateWindow(GetDlgItem(hDlg,IDC_EDIT1));
        UpdateWindow(GetDlgItem(hDlg,IDC_SCROLLBAR2));
        }
        break;
     }

こんな感じになりました。
SendMessageの使い方がよくわからず、最初はSB_THUMBTRACKの場所でも

if(dy > 0)
   SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                     EM_SCROLL,SB_LINEUP, 0L);
else
   SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                     EM_SCROLL, SB_LINEDOWN, 0L);

としていて、ものすごく動きの遅いスクロールバーでしたw
(しかも位置が合わない;)

とにもかくにも、なんとかなりました。
みなさん、ありがとうございました!!!
壁にぶち当たったらまた書き込ませていただくこともあると思いますので、
そのときはどうかよろしくお願いいたします。


つぶマン  2007-04-23 21:02:10  No: 64966

if(dy < 0)
   SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                     EM_SCROLL,SB_LINEUP, 0L);
else
   SendMessage(GetDlgItem(hDlg, IDC_EDIT1),
                     EM_SCROLL, SB_LINEDOWN, 0L);

↑不等号が逆でした!w


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加