いくつかのアイテムを固定させたまま画面をスクロール?

[戻る]
WWE 2002/11/18(月) 14:08:45
 はじめまして。初めて質問させていただきます、よろしくお願いします。
VC++6.0のCFormViewを使って入力画面の設計をしているのですが、
入力項目が多くて画面の右側にスクロールバーが発生します。
それを動かすと当然、画面が上下にスクロールするのですが、そのとき、
画面の左にある、ツリービューはスクロールさせないでおきたいのですが、
どのようにすればいいのでしょうか?

wood 2002/11/18(月) 15:32:13
発想だけですけど、スプリッターウィンドウつかえませんか

ku 2002/11/18(月) 15:32:32
> 右側にスクロールバーが発生します
ウィンドウを横方向に小さくしたら下にもスクロールバーがでますか?

OnVScroll()とOnHScroll()を追加してから下記のようなコードに修正します
(IDC_BUTTON2は移動させたくないコントロールのIDに変更すること)
下記のコードはOnVScroll()の場合です
    CWnd* pItem = GetDlgItem(IDC_BUTTON2);
    CRect rcItem;
    pItem->GetWindowRect(rcItem);
    CFormView::OnVScroll(nSBCode, nPos, pScrollBar);
    ScreenToClient(rcItem);
    pItem->MoveWindow(rcItem);

移動させないと縦スクロールか横スクロールのどちらかで
コントロールが重なることがあるような気がするけど
僕の方が質問を勘違いしてるかもしれません

タブコントロールを使うって方法も考えられますね

WWE 2002/11/18(月) 16:13:49
woodさん、tuさん
お返事ありがとうございます。

tuさんのプログラムをそのまま書いたらできました。これからこのコードが
何をしようとしているのか調べてみたいと思います。

ただ、まことに申し訳ないのですが、スクロールするとやけに固定したい
アイテム(ツリービュー)がぶれます。
入力画面の参考として、VBで作ったものがあるのですが、ぶれはありません。
VBでは表示されている画面のある1部分だけをスクロールの対象にすることが
できるみたいです。

もしもぶれを抑えるアイデアをお持ちでしたらその道しるべ的なヒントでも
教えていただけないでしょうか?(MDIで複数のウィンドウを作ってひとつを
スクロールの対象にする方法も考えたのですが、できれば一つの
ウィンドウ(フォームビュー)でやりたいです)
よろしくお願いします。

tuさん :
> ウィンドウを横方向に小さくしたら下にもスクロールバーがでますか?
でました。それを出して、そのスクロールバーを動かそうとするとエラーに
なっちゃいました。でも本番ではフレームを固定するつもりなので大丈夫だと
おもいます。

長くなってすみません。

WWE 2002/11/18(月) 16:16:33
たびたび、すみません。
woodさんのスプリッターウィンドウや、
tuさんのタブコントロールを試してみないで質問しちゃいました。
もし、それでぶれがなくなるようでしたらごめんなさい。

ku 2002/11/19(火) 12:25:54
前回示したのは簡単にできる方法だったので
1.動かさないコントロールの位置を得る
2.全てのコントロール(1のコントロールも含む)をスクロールする
3.1のコントロールを1で得た位置に移動する
とやっていたので2→3と2回の移動があり、ちらつきます

スクロールさせないコントロール以外を全て手動で移動させる方法を書いておきます
スタティックコントロールにもIDを振る必要があります
なおSB_LINEDOWNとSB_LINEUPしか作っておりませんので
それ以外のものはご自身で追加してください
OnVScroll()を作って下記のコードをまねて、追加してください
CFormView::OnVScroll()は参考になるので、困ったら見てください

// 移動量を得る
int nMapMode;
SIZE sizeTotal;
SIZE sizePage;
SIZE sizeLine;
GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);
// 垂直スクロールボックスの現在位置と最大位置を得る
CScrollBar* pVBar = GetScrollBarCtrl(SB_VERT);
int nOldYPos = GetScrollPos(SB_VERT);
int nMaxYPos = GetScrollLimit(SB_VERT);
bool fMove = false;
int nMoveQuant;
// 1行下へスクロールと上へスクロールだけ処理する
switch (nSBCode) {
case SB_LINEDOWN:
    if (nOldYPos < nMaxYPos) {
        fMove = true;
        nMoveQuant = sizeLine.cy;
    }
    break;
case SB_LINEUP:
    if (nOldYPos > 0) {
        fMove = true;
        nMoveQuant = -sizeLine.cy;
    }
    break;
default:
    break;
}
// スクロールすべき場合
if (fMove) {
    int anMoveCtrls[] = {IDC_BUTTON1, IDC_BUTTON3, IDC_STATIC_1};
    int n;
    for (n = 0; n < sizeof(anMoveCtrls) / sizeof(int); n++) {
        CWnd* pItem = GetDlgItem(anMoveCtrls[n]);
        CRect rcItem;
        pItem->GetWindowRect(rcItem);
        ScreenToClient(rcItem);
        pItem->SetWindowPos(NULL, rcItem.left, rcItem.top - nMoveQuant,
            0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER | 
SWP_SHOWWINDOW);
    }
    SetScrollPos(SB_VERT, nOldYPos + nMoveQuant);
}

WWE 2002/11/19(火) 14:47:33
[[解決]]
kuさん :
いままで、名前間違えていたのに。丁寧に教えていただいて
ありがとうございました。いま気づきました。すみません。
ボタンが2つあるだけのサンプルでですが、無事ひとつを固定させることができました。
本当にありがとうございました。
まわりにだれもCをできるひとがいなくて独学でやってるので大変です。

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