0

I was just wondering if it is possible to find the size (in pixels) of the autocompletion control shown by the wxStyledTextCtrl.

My goal is to show a help window associated with the entry when a selection happens. Therefore, I need the location and also the width of the autocompletion control. It seems location can be found from m_STC->AutoCompPosStart() but there seems to be no way of finding the width. I am using the following code:

auto StartPos = m_STC->ToPhys(m_STC->PointFromPosition(m_STC->AutoCompPosStart()));
    
int MaxChars = m_STC->AutoCompGetMaxWidth(); //returns 0 unless set to a fixed value
int w, h;
m_STC->GetTextExtent(wxString("A", MaxChars), &w, &h);

return wxPoint(StartPos.x + w, StartPos.y);

I am using Windows and wxWidgets 3.2.

macroland
  • 973
  • 9
  • 27
  • What is `m_STC`? – kiner_shah Sep 16 '22 at 10:56
  • May help: https://docs.wxwidgets.org/3.0/overview_windowsizing.html – kiner_shah Sep 16 '22 at 10:57
  • @kiner_shah, AutoComp is shown and hidden and is part of another control (wxStyledTextCtrl which is based on Scintilla). So it has nothing to do with the sizers. – macroland Sep 16 '22 at 11:09
  • @macroland, what does autocompletion have to do with the selection? – Igor Sep 16 '22 at 14:24
  • 1
    @Igor: AutoCompletion shows a list and you can make selection from that list (similar to code completion assistance by other IDEs). Once user selects an item from AutoCompletion, then I would like to show the help associated with that item. I have done similar thing using a list control but I want to switch to the AutoCompletion provided by wxStyledTextCtrl. – macroland Sep 16 '22 at 14:45

1 Answers1

2

There is no way to get this information from the styled text control because the autocomp window is completely managed by Scintilla. And unfortunately, Scintilla doesn't make any methods available for getting this info.

As a hack-around, the popup is currently implemented as a child window of the styled text control. So you could do something like this:

const wxWindowList& childred = m_stc->GetChildren();

for ( auto it = childred.begin() ; it != childred.end() ; ++it )
{
    // We're assuming the styled text control has at most 1 child - 
    // namely the autocomp popup. It might be better to check that
    // the window found is in fact the auto comp popup somehow.

    // win->GetPosition() will return screen coordinates, so to get client
    // coordinates, ScreenToClient must be called.
    wxPoint psn = m_stc->ScreenToClient(win->GetPosition());
    wxSize sz = win->GetSize();

    // Do something with size and position here.
}

However, this isn't guaranteed to always work. If in the future, the auto comp popup implementation is changed to use a top level window instead of a child of the control, this method will fail.

New Pagodi
  • 3,484
  • 1
  • 14
  • 24
  • Many thanks for the complete answers you provide! Just one question: If there are more than 1 child window in the window list, is there a way to check which one is AutoComp? The debug info of wxWindow does not give any clue. – macroland Sep 17 '22 at 13:10
  • 1
    I think the best that can be done to see if the child is actually the autocomp popup is to check if that child has its own child named "AutoCompListBox". Unfortunately, that is also based on the current implementation. So if someone edits the stc code and renames that listbox, this test will stop working. I wish there was a better answer here. – New Pagodi Sep 17 '22 at 15:14
  • Thanks for that, I hope sooner or later Scintilla will provide a simple function to access at least the size of AutoComp. Currently I am assuming that it will be the last child in the list when it pops up. – macroland Sep 17 '22 at 16:46