Opened 4 years ago

Last modified 4 years ago

#17379 confirmed defect

wxTextCtrl doesn't display value for strings longer than 32767 pixels

Reported by: sentry42 Owned by:
Priority: low Milestone:
Component: wxMSW Version: 3.0.0
Keywords: wxTextCtrl raymond-chen-needed Cc:
Blocked By: Blocking:
Patch: no

Description

Trying to set the value of a wx.TextCtrl object to a string larger than 6150 bytes using either SetValue method or typing via the keyboard causes the text control to become blank.

The contents of the 'blank' text control can still be selected and copied elsewhere as normally expected - it is just not visible on screen.

First experienced on Windows 10 with Python 2.7 and wxPython v3.0.0. Apparently it's been reproduced by someone else on Windows 7 with Python 2.7 and wxPython v3.0.2. Apparently using the wx.TE_RICH style for the text control bypasses this issue.

First reported at https://stackoverflow.com/questions/35462050/wx-textctrl-is-blank-for-very-long-strings

To reproduce simply use a wx.TextCtrl with default style.

Apologies for not supplying a patch - just don't have the expertise with wxWidgets or wxPython.

Change History (12)

comment:1 follow-up: Changed 4 years ago by awi

It seems that this is a duplicate of #15980.

comment:2 Changed 4 years ago by sentry42

Last edited 4 years ago by sentry42 (previous) (diff)

comment:3 in reply to: ↑ 1 Changed 4 years ago by sentry42

Issue 15980 seems to concern truncated text. The issue here is not that the text is truncated - it's that the entire text control appears blank but still actually has a value which is a non-empty string. The value of the text control can be copy/pasted in full to another text editor (e.g. Notepad++) - it is not truncated.
I'm not familiar enough with the necessary components to identify whether these two issues are related. However they appear to me to be slightly different issues.

Replying to awi:

It seems that this is a duplicate of #15980.

comment:4 Changed 4 years ago by vadz

  • Component changed from wxPython to wxMSW
  • Status changed from new to confirmed

It is indeed a different issue and I can reproduce it easily using just:

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    index 27aabd7..771a3c8 100644
    a b bool MyApp::OnInit() 
    171171    CreateStatusBar(2);
    172172    SetStatusText("Welcome to wxWidgets!");
    173173#endif // wxUSE_STATUSBAR
     174
     175    new wxStaticText(this, wxID_ANY, "Label");
     176    new wxTextCtrl(this, wxID_ANY, wxString('y', 7000), wxPoint(5, 20), wxSize(300, -1));
    174177}
    175178
    176179

@awi: are you looking at this by chance or should I? Right now I have no idea where does this come from, but it looks rather bad, so I'd like to at least try to fix this for 3.1.0. TIA!

comment:5 Changed 4 years ago by MaartenB

It seems to depends on the width of the text. I can only add 5459 y, but double the number of i (10919). Probably related to EM_SETMARGINS?

comment:6 Changed 4 years ago by awi

It looks that this issue occurs if size (width) of displayed text (plus padding and margins) exceeds 32767 pixels.
You can examine this with following code:

wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxPoint(5, 20), wxSize(300, -1));
wxString s = wxString('y', 6000);
text->SetValue(s);
wxSize size = text->GetTextExtent(s);

Unfortunately, it seems that this is a system limit since e.g. WM_SIZE message operates on 16-bit width/height values.

A workaround could be to create wxTextCtrl as a multiline control (with wxTE_MULTILINE flag).

comment:7 Changed 4 years ago by vadz

The problem is that the bug doesn't happen in raw Win32 code, i.e. if I do something like this:

    static const int BUF_SIZE = 7000;
    TCHAR buf[BUF_SIZE];
    wmemset(buf, L'y', BUF_SIZE);
    buf[BUF_SIZE - 1] = L'\0';

    HWND hwndEdit = CreateWindowW(L"EDIT",
                                  buf,
                                  WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_BORDER,
                                  150, 200, 200, 20, hwnd, 0,
                                  g_hInstance, NULL);

it works just fine. So it must be something that we're doing, now if I only knew what...

comment:8 Changed 4 years ago by MaartenB

Once you use the normal font, e.g. adding:

        NONCLIENTMETRICS ncm;
        ncm.cbSize = sizeof(ncm);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
        HFONT fnt = CreateFontIndirect(&ncm.lfMessageFont);
        SendMessage(hwndEdit, WM_SETFONT, (WPARAM)fnt, 0);

it goes wrong.

comment:9 Changed 4 years ago by vadz

  • Keywords raymon-chen-needed added
  • Summary changed from wxTextCtrl doesn't display value for large strings (>6150 bytes) to wxTextCtrl doesn't display value for strings longer than 32767 pixels

Ah, you're right, thanks, I didn't realize it was font dependent.

But I still wonder why does the edit control containing the file name in the "File properties" standard dialog doesn't seem to have any trouble with this -- if I copy and paste the invisible string of 7000 "y"s into it, it displays it just fine. And this in spite of using exactly the same style (if you add ES_AUTOHSCROLL to CreateWindow()). It seems to use the same font too (although I was too lazy to really check it, so maybe it only looks the same but actually isn't?), so there still seems to be something we're missing here.

Even if this is undoubtedly a Windows bug...

comment:10 Changed 4 years ago by vadz

  • Keywords raymond-chen-needed added; raymon-chen-needed removed

comment:11 Changed 4 years ago by MaartenB

The Windows File Properties dialog truncates the string to 223 characters. Try copying it from there...

comment:12 Changed 4 years ago by vadz

  • Priority changed from normal to low

Oh, this would explain it, indeed. Thanks again!

Well, there is really nothing we can do about it then unfortunately (I don't think automatically switching to richedit is feasible). We'll just have to document this as a platform limitation.

Note: See TracTickets for help on using tickets.