views:

1479

answers:

2

On a windows mobile device I have a mutliline text edit control that is set to read-only and has some static text displayed during it's display lifetime. I would like to only display a vertical scrollbar when it's actually useful (i.e. the text is larger than the display).

I can't easily figure out if the text is to large to display because of two reasons.

  1. There is no horizontal scroll bar displayed so the text wraps.
  2. Under windows mobile, the win32 routines to calculate the size of what text will display does not work correctly. They return a incorrect rectangle.

The edit control must tell the scroll bar what it's scroll range is at some point. I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.

A: 

I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.

I highly doubt it. But I bet you could call SetScrollInfo some time after the text box is created, and send your own scroll parameters.

EDIT: Wrong link, my bad. Here's the one for the Windows CE

zildjohn01
A: 

This is how I solved this problem.

First off:

  • It only works with read-only mode of a edit control (as you don't want the text to change often).
  • I think is specific to Windows Mobile MFC, big windows can handle this a lot better.
  • The solution is very very hacky.

Solution:

  • I have a standard CEdit bound to the control.

    CEdit m_Message;

    DDX_Control(pDX, IDC_MESSAGE, m_Message);

  • During the InitDialog and OnSize calls, turn on the display of the scroll bar and setup a timer message.

    m_Message.ShowScrollBar(SB_VERT, TRUE);

    SetTimer(DO_ADJUST_DISPLAY_STATE, 50, 0);

  • In the timer handling code, use the scroll information to determine if the scroll bar needs to be displayed.

  • If not being displayed, turn off the scroll bar and force the window to redisplay.

    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; }

    }

I hope that helps out other people who may have similar requirements.

Shane Powell