Disabling message beeps in EditorGadget() on Windows?
Disabling message beeps in EditorGadget() on Windows?
I found this Stack Overflow answer about how to eliminate the frankly incredibly annoying message beep that occurs when doing many actions in an EditorGadget/rich text control. However, COM in PB terrifies me and I'm frankly horrible at it, and have no idea how to do any of this. I figured one of the wizards here might have already done this and/or know how?
Thanks in advance for any help!
Thanks in advance for any help!
Re: Disabling message beeps in EditorGadget() on Windows?
The converted code.
Code: Select all
Interface ITextServices Extends IUnknown
; //@cmember Generic Send Message interface
TxSendMessage.l(msg.l, wparam, lparam, *plresult)
;
; //@cmember Rendering
TxDraw.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcBounds, *lprcWBounds, *lprcUpdate, pfnContinue, dwContinue.l, lViewId.l)
;
; //@cmember Horizontal scrollbar support
TxGetHScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled)
;
; //@cmember Horizontal scrollbar support
TxGetVScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled)
;
; //@cmember Setcursor
OnTxSetCursor.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l)
;
; //@cmember Hit-test
TxQueryHitPoint.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l, *pHitResult)
;
; //@cmember Inplace activate notification
OnTxInPlaceActivate.l(*prcClient)
;
; //@cmember Inplace deactivate notification
OnTxInPlaceDeactivate.l()
;
; //@cmember UI activate notification
OnTxUIActivate.l()
;
; //@cmember UI deactivate notification
OnTxUIDeactivate.l()
;
; //@cmember Get text in control
TxGetText.l(*pbstrText)
;
; //@cmember Set text in control
TxSetText.l(pszText.s)
;
; //@cmember Get x position of
TxGetCurTargetX.l(*result)
; //@cmember Get baseline position
TxGetBaseLinePos.l(*result)
;
; //@cmember Get Size to fit / Natural size
TxGetNaturalSize.l(dwAspect.l, hdcDraw, hicTargetDev, *ptd, dwMode.l, *psizelExtent, *pwidth, *pheight)
;
; //@cmember Drag & drop
TxGetDropTarget.l(*ppDropTarget)
;
; //@cmember Bulk bit property change notifications
OnTxPropertyBitsChange.l(dwMask.l, dwBits.l)
;
; //@cmember Fetch the cached drawing size .l(logical not physical)
TxGetCachedSize.l(*pdwWidth, *pdwHeight)
EndInterface
#TXTBIT_ALLOWBEEP = 2048
DataSection
IID_ITextServices: ; 8d33f740-cf58-11ce-a89d-00aa006cadc5
Data.l $8d33f740
Data.w $cf58, $11ce
Data.b $a8, $9d, $00, $aa, $00, $6c, $ad, $c5
EndDataSection
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 8, 8, 306, 133)
If SendMessage_(GadgetID(0), #EM_GETOLEINTERFACE, 0, @Unk.IUnknown)
If Unk
If unk\QueryInterface(?IID_ITextServices, @TxtSrv.ITextServices) = #S_OK
If TxtSrv
If TxtSrv\OnTxPropertyBitsChange(#TXTBIT_ALLOWBEEP, 0) = #S_OK
Debug "OK"
EndIf
TxtSrv\Release()
EndIf
EndIf
Unk\Release()
EndIf
EndIf
For a = 0 To 5
AddGadgetItem(0, a, "Line "+Str(a))
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: Disabling message beeps in EditorGadget() on Windows?
Nice code, as always @breeze4me
Re: Disabling message beeps in EditorGadget() on Windows?
Hi breeze4me,
This works great, thanks for sharing!
When I try to use it in an app that uses dialogs however, more specifically DynamicDialogs, the beeps stay enabled. Is this a limitation of the dialog library?
This works great, thanks for sharing!
When I try to use it in an app that uses dialogs however, more specifically DynamicDialogs, the beeps stay enabled. Is this a limitation of the dialog library?
Re: Disabling message beeps in EditorGadget() on Windows?
Nice code breeze4me but it works only for PB x64
Simple approach
Simple approach
Code: Select all
If OpenWindow(0, 0, 0, 400,300, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 8, 8, 306, 133)
For a = 0 To 5
AddGadgetItem(0, a, "Line "+Str(a))
Next
ButtonGadget(1,10,260,150,24,"Sound On/Off",#PB_Button_Toggle)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
If GetGadgetState(1) = 1
keybd_event_($AD, 0, 1, 0)
Else
keybd_event_($AD, 0, 1, 0)
EndIf
EndSelect
EndSelect
Until Quit = 1
EndIf
Egypt my love
Re: Disabling message beeps in EditorGadget() on Windows?
This does not work, the reason you think it disables the sound is because it floods you with windows message beeps for the entire time you're focused on that gadget so much that it entirely eliminates any audio coming to your soundcard.RASHAD wrote: Mon Apr 14, 2025 8:03 pm Nice code breeze4me but it works only for PB x64
Simple approachCode: Select all
If OpenWindow(0, 0, 0, 400,300, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) EditorGadget(0, 8, 8, 306, 133) For a = 0 To 5 AddGadgetItem(0, a, "Line "+Str(a)) Next ButtonGadget(1,10,260,150,24,"Sound On/Off",#PB_Button_Toggle) Repeat Select WaitWindowEvent() Case #PB_Event_CloseWindow Quit = 1 Case #PB_Event_Gadget Select EventGadget() Case 1 If GetGadgetState(1) = 1 keybd_event_($AD, 0, 1, 0) Else keybd_event_($AD, 0, 1, 0) EndIf EndSelect EndSelect Until Quit = 1 EndIf
Source: blind user, tried this and lost my screen reader and any system audio.
Re: Disabling message beeps in EditorGadget() on Windows?
Hi Quin
Don't give-up
You can use AddKeyboardShortcut()
For example delete back it will disable sound when no char to delete
But of course you need to code for the delete back
What are the error messages you want to eliminate ?
Don't give-up

You can use AddKeyboardShortcut()
For example delete back it will disable sound when no char to delete
But of course you need to code for the delete back
What are the error messages you want to eliminate ?
Egypt my love
Re: Disabling message beeps in EditorGadget() on Windows?
Hi,
I want to get rid of all of them. You hit them when hitting the edge of the field, when pressing home and already at the beginning of the line, and so on. The original StackOverflow post I linked talks about this in more detail
I want to get rid of all of them. You hit them when hitting the edge of the field, when pressing home and already at the beginning of the line, and so on. The original StackOverflow post I linked talks about this in more detail
Re: Disabling message beeps in EditorGadget() on Windows?
After analyzing it, it seems that the interface uses the "thiscall" calling convention, which causes an error when compiling in PB x86.
Therefore, to make it work properly, the method must be called with a series of assembly instructions, as shown in the code below.
I don't know how to call it in the C backend.
When using the Dialog Library, you need to specify a name in the "name" attribute of an editor gadget, and use the DialogGadget function to get the gadget number.
This is an example using the DynamicDialogs module.
Edit:
Added x86 C backend part.
Edit 2:
Added to use GCC native keyword for x86 thiscall.
https://gcc.gnu.org/onlinedocs/gcc/x86- ... 02c-x86-32
Therefore, to make it work properly, the method must be called with a series of assembly instructions, as shown in the code below.
I don't know how to call it in the C backend.

When using the Dialog Library, you need to specify a name in the "name" attribute of an editor gadget, and use the DialogGadget function to get the gadget number.
This is an example using the DynamicDialogs module.
Edit:
Added x86 C backend part.
Edit 2:
Added to use GCC native keyword for x86 thiscall.
https://gcc.gnu.org/onlinedocs/gcc/x86- ... 02c-x86-32
Code: Select all
Interface ITextServices Extends IUnknown
; //@cmember Generic Send Message interface
TxSendMessage.l(msg.l, wparam, lparam, *plresult)
;
; //@cmember Rendering
TxDraw.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcBounds, *lprcWBounds, *lprcUpdate, pfnContinue, dwContinue.l, lViewId.l)
;
; //@cmember Horizontal scrollbar support
TxGetHScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled)
;
; //@cmember Horizontal scrollbar support
TxGetVScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled)
;
; //@cmember Setcursor
OnTxSetCursor.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l)
;
; //@cmember Hit-test
TxQueryHitPoint.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l, *pHitResult)
;
; //@cmember Inplace activate notification
OnTxInPlaceActivate.l(*prcClient)
;
; //@cmember Inplace deactivate notification
OnTxInPlaceDeactivate.l()
;
; //@cmember UI activate notification
OnTxUIActivate.l()
;
; //@cmember UI deactivate notification
OnTxUIDeactivate.l()
;
; //@cmember Get text in control
TxGetText.l(*pbstrText)
;
; //@cmember Set text in control
TxSetText.l(pszText.s)
;
; //@cmember Get x position of
TxGetCurTargetX.l(*result)
;
; //@cmember Get baseline position
TxGetBaseLinePos.l(*result)
;
; //@cmember Get Size to fit / Natural size
TxGetNaturalSize.l(dwAspect.l, hdcDraw, hicTargetDev, *ptd, dwMode.l, *psizelExtent, *pwidth, *pheight)
;
; //@cmember Drag & drop
TxGetDropTarget.l(*ppDropTarget)
;
; //@cmember Bulk bit property change notifications
OnTxPropertyBitsChange.l(dwMask.l, dwBits.l)
;
; //@cmember Fetch the cached drawing size .l(logical not physical)
TxGetCachedSize.l(*pdwWidth, *pdwHeight)
EndInterface
#TXTBIT_ALLOWBEEP = 2048
DataSection
IID_ITextServices: ; 8d33f740-cf58-11ce-a89d-00aa006cadc5
Data.l $8d33f740
Data.w $cf58, $11ce
Data.b $a8, $9d, $00, $aa, $00, $6c, $ad, $c5
EndDataSection
Procedure TurnOffRichEditBeep(Gadget)
Protected Unk.IUnknown, TxtSrv.ITextServices
Protected result
If IsGadget(Gadget) And GadgetType(Gadget) = #PB_GadgetType_Editor
If SendMessage_(GadgetID(Gadget), #EM_GETOLEINTERFACE, 0, @Unk)
If Unk
If Unk\QueryInterface(?IID_ITextServices, @TxtSrv) = #S_OK
If TxtSrv
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Protected Func = @TxtSrv\OnTxPropertyBitsChange()
; thiscall
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
EnableASM
mov eax, Func
mov ecx, TxtSrv
push 0
push 2048
call eax
mov result, eax
DisableASM
CompilerElse
;! int __attribute__ ((thiscall)) (*func)(int, int, int) = v_func;
! int __thiscall (*func)(int, int, int) = v_func;
! v_result = func(v_txtsrv, 2048, 0);
; !__asm__ __volatile__ (
; !".intel_syntax noprefix;"
;
; !"mov eax, %1;"
; !"mov ecx, %2;"
; !"push 0;"
; !"push 2048;"
; !"call eax;"
; !"mov %0, eax;"
;
; !".att_syntax"
; !:"=r" (v_result)
; !:"r" (v_func), "r" (v_txtsrv)
; !:"eax", "ecx"
; !);
CompilerEndIf
result = Bool(result = #S_OK)
CompilerElse
If TxtSrv\OnTxPropertyBitsChange(#TXTBIT_ALLOWBEEP, 0) = #S_OK
result = 1
EndIf
CompilerEndIf
TxtSrv\Release()
EndIf
EndIf
Unk\Release()
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure
XIncludeFile "../DynamicDialogs_suffixed.pbi"
UseModule DynamicDialogs ; to enable the 'general' commands
UseModule DynamicDialogs_suffixed ; to enable the XML-Elements with 'suffixed' syntax
ClearXML() ; make sure, the XML-Dialog is empty before you begin a new one
; --- Create the Dialog ---
Window__(#PB_Any, "", "DynamicDialog Example", #PB_Window_SizeGadget | #PB_Window_SystemMenu) ; create a resizeable window
vBox__(1) ; create a vertical-Box, where only the first Element in the vBox will be auto-resized
Editor__(#PB_Ignore, "myEditorGadget","",0,0,180) ; create an EditorGadget() with the 'Name': "myEditorGadget"
Button__(1,"","Click me ...") ; create a Button with Gadget-Number = 1
EndVBox__() ; End-Tag for the previously opened vBox
EndWindow__() ; End-Tag for the window
UnuseModule DynamicDialogs_suffixed ; we don't need the XML-Elements any more
If OpenDialogWindow(1, GetXML()) ; Open the last created Window (or specify the Window by ID or Name$)
MyEdGadget = DialogGadget(1,"myEditorGadget")
If TurnOffRichEditBeep(MyEdGadget)
Debug "OK"
EndIf
For n = 1 To 10 ; Fill Editor-Gadget with some content. Adress the Editor-Gadget by using its Name => "myEditorGadget"
SetGadgetText(DialogGadget(1,"myEditorGadget"),GetGadgetText(DialogGadget(1,"myEditorGadget"))+"Line "+Str(n)+#LF$)
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Last edited by breeze4me on Sat Apr 19, 2025 9:06 am, edited 2 times in total.
Re: Disabling message beeps in EditorGadget() on Windows?
This works amazingly, thanks for your work! I only target x64 C-backend, so removed the ASM and it all works flawlessly!breeze4me wrote: Tue Apr 15, 2025 9:04 am After analyzing it, it seems that the interface uses the "thiscall" calling convention, which causes an error when compiling in PB x86.
Therefore, to make it work properly, the method must be called with a series of assembly instructions, as shown in the code below.
I don't know how to call it in the C backend.![]()
When using the Dialog Library, you need to specify a name in the "name" attribute of an editor gadget, and use the DialogGadget function to get the gadget number.
This is an example using the DynamicDialogs module.
Edit:
Added x86 C backend part.
Code: Select all
Interface ITextServices Extends IUnknown ; //@cmember Generic Send Message interface TxSendMessage.l(msg.l, wparam, lparam, *plresult) ; ; //@cmember Rendering TxDraw.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcBounds, *lprcWBounds, *lprcUpdate, pfnContinue, dwContinue.l, lViewId.l) ; ; //@cmember Horizontal scrollbar support TxGetHScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled) ; ; //@cmember Horizontal scrollbar support TxGetVScroll.l(*plMin, *plMax, *plPos, *plPage, *pfEnabled) ; ; //@cmember Setcursor OnTxSetCursor.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l) ; ; //@cmember Hit-test TxQueryHitPoint.l(dwDrawAspect.l, lindex.l, *pvAspect, *ptd, hdcDraw, hicTargetDev, *lprcClient, x.l, y.l, *pHitResult) ; ; //@cmember Inplace activate notification OnTxInPlaceActivate.l(*prcClient) ; ; //@cmember Inplace deactivate notification OnTxInPlaceDeactivate.l() ; ; //@cmember UI activate notification OnTxUIActivate.l() ; ; //@cmember UI deactivate notification OnTxUIDeactivate.l() ; ; //@cmember Get text in control TxGetText.l(*pbstrText) ; ; //@cmember Set text in control TxSetText.l(pszText.s) ; ; //@cmember Get x position of TxGetCurTargetX.l(*result) ; ; //@cmember Get baseline position TxGetBaseLinePos.l(*result) ; ; //@cmember Get Size to fit / Natural size TxGetNaturalSize.l(dwAspect.l, hdcDraw, hicTargetDev, *ptd, dwMode.l, *psizelExtent, *pwidth, *pheight) ; ; //@cmember Drag & drop TxGetDropTarget.l(*ppDropTarget) ; ; //@cmember Bulk bit property change notifications OnTxPropertyBitsChange.l(dwMask.l, dwBits.l) ; ; //@cmember Fetch the cached drawing size .l(logical not physical) TxGetCachedSize.l(*pdwWidth, *pdwHeight) EndInterface #TXTBIT_ALLOWBEEP = 2048 DataSection IID_ITextServices: ; 8d33f740-cf58-11ce-a89d-00aa006cadc5 Data.l $8d33f740 Data.w $cf58, $11ce Data.b $a8, $9d, $00, $aa, $00, $6c, $ad, $c5 EndDataSection Procedure TurnOffRichEditBeep(Gadget) Protected Unk.IUnknown, TxtSrv.ITextServices Protected result If IsGadget(Gadget) And GadgetType(Gadget) = #PB_GadgetType_Editor If SendMessage_(GadgetID(Gadget), #EM_GETOLEINTERFACE, 0, @Unk) If Unk If Unk\QueryInterface(?IID_ITextServices, @TxtSrv) = #S_OK If TxtSrv CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 Protected Func = @TxtSrv\OnTxPropertyBitsChange() ; thiscall CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm EnableASM mov eax, Func mov ecx, TxtSrv push 0 push 2048 call eax mov result, eax DisableASM CompilerElse !__asm__ __volatile__ ( !".intel_syntax noprefix;" !"mov eax, %1;" !"mov ecx, %2;" !"push 0;" !"push 2048;" !"call eax;" !"mov %0, eax;" !".att_syntax" !:"=r" (v_result) !:"r" (v_func), "r" (v_txtsrv) !:"eax", "ecx" !); CompilerEndIf result = Bool(result = #S_OK) CompilerElse If TxtSrv\OnTxPropertyBitsChange(#TXTBIT_ALLOWBEEP, 0) = #S_OK result = 1 EndIf CompilerEndIf TxtSrv\Release() EndIf EndIf Unk\Release() EndIf EndIf EndIf ProcedureReturn result EndProcedure XIncludeFile "../DynamicDialogs_suffixed.pbi" UseModule DynamicDialogs ; to enable the 'general' commands UseModule DynamicDialogs_suffixed ; to enable the XML-Elements with 'suffixed' syntax ClearXML() ; make sure, the XML-Dialog is empty before you begin a new one ; --- Create the Dialog --- Window__(#PB_Any, "", "DynamicDialog Example", #PB_Window_SizeGadget | #PB_Window_SystemMenu) ; create a resizeable window vBox__(1) ; create a vertical-Box, where only the first Element in the vBox will be auto-resized Editor__(#PB_Ignore, "myEditorGadget","",0,0,180) ; create an EditorGadget() with the 'Name': "myEditorGadget" Button__(1,"","Click me ...") ; create a Button with Gadget-Number = 1 EndVBox__() ; End-Tag for the previously opened vBox EndWindow__() ; End-Tag for the window UnuseModule DynamicDialogs_suffixed ; we don't need the XML-Elements any more If OpenDialogWindow(1, GetXML()) ; Open the last created Window (or specify the Window by ID or Name$) MyEdGadget = DialogGadget(1,"myEditorGadget") If TurnOffRichEditBeep(MyEdGadget) Debug "OK" EndIf For n = 1 To 10 ; Fill Editor-Gadget with some content. Adress the Editor-Gadget by using its Name => "myEditorGadget" SetGadgetText(DialogGadget(1,"myEditorGadget"),GetGadgetText(DialogGadget(1,"myEditorGadget"))+"Line "+Str(n)+#LF$) Next Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow EndIf
It works with DynamicDialogs, too
