Allow typing an ascii tab in a BCX_Richedit control?

Started by Quin, April 20, 2025, 05:45:13 PM

Previous topic - Next topic

Quin


MrBcx

Quote from: Quin on April 23, 2025, 03:52:17 PMHi Kevin,
Using the generated C code as a base as well as the subclassing windows controls section of the BCX help, I tried subclassing the edit control myself, like so. However, I still am unable to insert tabs. Am I missing something?
 
Thanks!

Quin,

Yes, you're code was missing a few very important things that I've inserted for you.


Gui "Test", Pixels

Dim As Control MainForm, Edit

Sub Formload
    MainForm = Bcx_Form("Test")
    Edit = Bcx_Richedit("", MainForm, 101, 5, 5, 600, 400)
    Global EditBeforeSubclass As WNDPROC                   ' Edited by MrBcx
    EditBeforeSubclass = SubclassWindow(Edit, EditFieldProc)
    Center(MainForm)
    Show(MainForm)
    SetFocus(Edit)
End Sub

Begin Events
    Select Case Cbmsg
        Case WM_CLOSE, WM_DESTROY, WM_QUIT
        DestroyWindow(MainForm)
    End Select
End Events

Callback Function EditFieldProc
    If Cbmsg = WM_KEYDOWN And Cbwparam = VK_TAB Then
        $Iprint_Off                             ' Added by MrBcx
        SendMessage(hWnd, EM_REPLACESEL, True, (LPARAM)"\t")
        $Iprint_On                             ' Added by MrBcx 
        Function = 0
    End If
    Function = CallWindowProc(EditBeforeSubclass, Cbhwnd, Cbmsg, Cbwparam, Cblparam)  ' Added by MrBcx 
End Function

Here is a slimmer version of the subclass procedure:

Callback Function EditFieldProc
    If Cbmsg = WM_KEYDOWN And Cbwparam = VK_TAB Then
        SendMessage(hWnd, EM_REPLACESEL, True, Tab$)   ' Edited by MrBcx - use the BCX builtin TAB$ constant
        Function = 0
    End If
    Function = CallWindowProc(EditBeforeSubclass, Cbhwnd, Cbmsg, Cbwparam, Cblparam);
End Function



Quin

Hi Kevin,
Using the generated C code as a base as well as the subclassing windows controls section of the BCX help, I tried subclassing the edit control myself, like so. However, I still am unable to insert tabs. Am I missing something?
Gui "Test", Pixels

Dim As Control MainForm, Edit

Sub Formload
    MainForm = Bcx_Form("Test")
    Edit = Bcx_Richedit("", MainForm, 101, 5, 5, 600, 400)
    Dim EditBeforeSubclass As WNDPROC
    EditBeforeSubclass = SubclassWindow(Edit, EditFieldProc)
    Center(MainForm)
    Show(MainForm)
    SetFocus(Edit)
End Sub

Begin Events
    Select Case Cbmsg
    Case WM_CLOSE, WM_DESTROY, WM_QUIT
        DestroyWindow(MainForm)
    End Select
End Events

Callback Function EditFieldProc
    If Msg = WM_KEYDOWN And wParam = VK_TAB Then
        SendMessage(hWnd, EM_REPLACESEL, True, (LPARAM)"\t")
        Function = 0
    End If
End Function
Thanks!

MrBcx

I shared the relevant runtime codes with ChatGpt along with your question and was given this reply:

To allow tab characters in a RichEdit, you must intercept WM_KEYDOWN and insert the \t manually, as shown in the subclassing approach below.

You could wrap this in a reusable BCX-style function or optionally subclass the RichEdit only if the user wants tab input. For instance:
🧪 Sample BCX-enhanced version:

Here's a BCX-style enhancement you could add to the BCX_RichEdit function:

WNDPROC OldRichProc;

LRESULT CALLBACK RichSubclass(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  if (Msg == WM_KEYDOWN && wParam == VK_TAB)
  {
    SendMessage(hWnd, EM_REPLACESEL, TRUE, (LPARAM)"\t");
    RETURN 0;
  }
  RETURN CallWindowProc(OldRichProc, hWnd, Msg, wParam, lParam);
}

And in BCX_RichEdit, if you want to make this optional:

if (enableTabs) // a parameter you define for optional tab input
{
  OldRichProc = (WNDPROC)SetWindowLongPtr(A, GWLP_WNDPROC, (LONG_PTR)RichSubclass);
}

🛠� So to recap:

    ✅ ModStyle is great — just not applicable here.

    🔑 You need subclassing to change key behavior like handling the TAB key.

Quin

It's currently impossible to type a tab in a Bcx_Richedit control. This also seemingly leads to better tab navigation by default, the keyboard focus doesn't get trapped by rich edit controls, which is a great thing! However, occasionally, you don't want this. Every once in a while, it's useful to have users be able to type tabs in your rich edit control. Is it possible to use modstyle or something similar to do this?
Thanks!