Автоматически отображать вертикальную полосу прокрутки в многострочном текстовом редакторе - PullRequest
0 голосов
/ 18 февраля 2009

На мобильном устройстве с Windows у меня есть элемент управления редактирования текста, который настроен только для чтения и отображает некоторый статический текст в течение всего времени его отображения. Я хотел бы отображать вертикальную полосу прокрутки только тогда, когда она действительно полезна (т. Е. Текст больше, чем дисплей).

Я не могу понять, слишком ли большой текст для отображения по двум причинам.

  1. Горизонтальная полоса прокрутки не отображается, поэтому текст переносится.
  2. В Windows Mobile подпрограммы win32 для расчета размера отображаемого текста работают некорректно. Они возвращают неправильный прямоугольник.

Элемент управления редактирования должен сообщить полосе прокрутки, какой диапазон прокрутки находится в некоторой точке. Мне было интересно, смогу ли я попасть между ними и спрятать полосу прокрутки, если она не будет использоваться.

Ответы [ 2 ]

1 голос
/ 26 февраля 2009

Вот как я решил эту проблему.

Сначала:

  • Он работает только в режиме «только чтение» элемента управления редактированием (поскольку вы не хотите, чтобы текст часто менялся).
  • Я думаю, что это специфично для Windows Mobile MFC, большие окна могут справиться с этим намного лучше.
  • Решение очень и очень хакерское.

Решение:

  • У меня есть стандартный CEdit, связанный с элементом управления.

    CEdit m_Message;

    DDX_Control (pDX, IDC_MESSAGE, m_Message);

  • Во время вызовов InitDialog и OnSize включите отображение полосы прокрутки и настройте сообщение таймера.

    m_Message.ShowScrollBar (SB_VERT, TRUE);

    SetTimer (DO_ADJUST_DISPLAY_STATE, 50, 0); * * тысячу тридцать-два

  • В коде обработки таймера используйте информацию прокрутки, чтобы определить, должна ли отображаться полоса прокрутки.

  • Если не отображается, выключите полосу прокрутки и выведите окно к повторному отображению.

 void CMessageDlg::OnTimer( UINT_PTR nIDEvent )
  {
    switch(nIDEvent)
    {
    case DO_ADJUST_DISPLAY_STATE:
        KillTimer(nIDEvent);
        // deselect all text
        m_Message.SetSel(0, 0);
        SCROLLINFO info;
        m_Message.GetScrollInfo(SB_VERT, &info);

        if(info.nPage > (UINT)info.nMax)
        {
            // need to re-display the non scroll bar version
            m_Message.ShowScrollBar(SB_VERT, FALSE);

            // I could not find any other way to force a redisplay 
            // correctly without display problems...

            // first move the window to a know invisible area
            // then wait (using a timer) for the window to move
            // then move the window back to it's original position     
            RECT rt;
            rt.left = 0;
            rt.right = 5;
            rt.top = 0;
            rt.bottom = 5;
            m_Message.MoveWindow(&rt);

            SetTimer(DO_REDISPLAY_MESSAGE, 50, 0);
        }
        break;

    case DO_REDISPLAY_MESSAGE:
        KillTimer(nIDEvent);
        // m_MessagePosition holds the original position
        // worked out dynamically during the WM_SIZE
        // processing
        m_Message.MoveWindow(&m_MessagePosition);
        break;
    }
}

Я надеюсь, что это поможет другим людям, которые могут иметь схожие требования.

0 голосов
/ 18 февраля 2009

Мне было интересно, смогу ли я встать между ними и спрятать полосу прокрутки, если она не будет использоваться.

Я очень сомневаюсь в этом. Но держу пари, что вы можете позвонить SetScrollInfo через некоторое время после создания текстового поля и отправить свои параметры прокрутки.

РЕДАКТИРОВАТЬ: Неправильная ссылка, мой плохой. Здесь для Windows CE

...