Page 1 of 1
How to detect that some text is selected in a StringGadget ?
Posted: Fri Jun 21, 2024 1:20 pm
by Blue
Imagine a string gadget with some text in it.
The user selects some of the text.
I'd like to...
1. detect that a selection process is underway
2. copy the selected text so that i can do something with it
Is such a thing even possible in Windows ???
Re: How to detect that some text is selected in a StringGadget ?
Posted: Fri Jun 21, 2024 4:09 pm
by Axolotl
maybe this can be a start...
IMHO the EditorGadget is better than a StringGadget, but see yourself
Code: Select all
EnableExplicit
Enumeration EWindow
#WINDOW_Main
EndEnumeration
Enumeration EGadget
#GADGET_lblResult
#GADGET_edtValues
#GADGET_strValues
EndEnumeration
Global g_Text$ = "One sinlge line text with a String and RichEdit Gadget... "
Procedure MainWindow_Callback(hWnd, uMsg, WParam, LParam)
Protected *sc.SELCHANGE
Select uMsg
Case #WM_NOTIFY ; signal any kind of mouse or keyborad activity
*sc = LParam
Select *sc\nmhdr\code
Case #EN_SELCHANGE ; : Debug "Notify SelChange on Editor "
; maybe check for
If *sc\nmhdr\idFrom = #GADGET_edtValues
If *sc\seltyp = #SEL_EMPTY
SetGadgetText(#GADGET_lblResult, "RichEdit Caret Pos: " + *sc\chrg\cpMin + " (" + *sc\chrg\cpMax + ")")
ElseIf *sc\seltyp & #SEL_TEXT
SetGadgetText(#GADGET_lblResult, "RichEdit Selection: " + *sc\chrg\cpMin + ", " + *sc\chrg\cpMax)
; ElseIf *sc\seltyp & #SEL_MULTICHAR
Else : Debug "Notify SelChange other stuff " + *sc\seltyp
EndIf
EndIf
EndSelect
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; ---------------------------------------------------------------------------
Procedure main()
Protected hwnd, flags, wW, wH
Protected result
Protected startpos, endpos
wW = 800
wH = 400
hwnd = OpenWindow(#WINDOW_Main, 0, 0, wW, wH, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If hwnd
TextGadget(#GADGET_lblResult, 4, 8, wW-8, 18, "Result: ")
EditorGadget(#GADGET_edtValues, 8, 32, wW-16, 24)
flags = SendMessage_(GadgetID(#GADGET_edtValues), #EM_GETEVENTMASK, 0, 0) ; too long for one line
SendMessage_(GadgetID(#GADGET_edtValues), #EM_SETEVENTMASK, 0, flags | #ENM_SELCHANGE)
StringGadget(#GADGET_strValues, 8, 64, wW-16, 24, g_Text$)
SetWindowCallback(@MainWindow_Callback(), #WINDOW_Main)
SetGadgetText(#GADGET_edtValues, g_Text$)
AddWindowTimer(#WINDOW_Main, 1, 10) ; as fast as windows can
Repeat ; modal loop
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; say good bye, return nothing changed signal
Case #PB_Event_Timer
If EventTimer() = 1 And GetActiveGadget() = #GADGET_strValues
SendMessage_(GadgetID(#GADGET_strValues), #EM_GETSEL, @startpos, @endpos)
If startpos = endpos
SetGadgetText(#GADGET_lblResult, "STRING Caret Pos: " + startpos + " (" + endpos + ")")
Else
SetGadgetText(#GADGET_lblResult, "STRING Selection: " + startpos + ", " + endpos)
EndIf
EndIf
EndSelect ; WaitWindowEvent()
ForEver
EndIf ; hwnd
ProcedureReturn result
EndProcedure
End main()
; BoF
Re: How to detect that some text is selected in a StringGadget ?
Posted: Fri Jun 21, 2024 5:01 pm
by Blue
Axolotl wrote: Fri Jun 21, 2024 4:09 pm
maybe this can be a start...
IMHO the EditorGadget is better than a StringGadget, but see yourself
Code: Select all
EnableExplicit
; ... etc ...
Procedure MainWindow_Callback(hWnd, uMsg, WParam, LParam)
Protected *sc.SELCHANGE
; ... etc ...
EndProcedure
; ---------------------------------------------------------------------------
Procedure main()
; ... etc ...
EndProcedure
End main()
; BoF
Thank you, Axolotl
That's a lot more than just a start. It's the whole McCoy,
with a fully operational example to boot, which does exactly what I wanted to achieve.
Fabulous !
I studied and dissected your code carefully.
As a small bonus, it made me feel good to discover that I was looking in the right direction... although i was going nowhere !
Your code made me see that i was missing the wheels...
Who knew such a simple operation for a human could be so complex to put into code.
I now see why you suggested that an
Editor Gadget would be better. Much cleaner indeed, once you figure out how to work the complex structure holding the selection information, of course.
I must point out that your idea of running a timer operation on the
String Gadget is brilliant ! That never occurred to me. No wonder i wasn't going anywhere.
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 11:36 am
by Axolotl
Hi Blue,
thank you very much for your kind reply.
I must say that I was very pleased. I like to help as much as I can, so it's even better when comments like this come back.
Good to know: EditorGadget and StringGadget work differently with regard to the TAB key.
BTW: To process the windows messages, the used structures are important. The description can be found on 'msdn' (old style|new learn/microsoft). Use the inet search such as "msdn <message> or <structure>" i.e. msdn WM_NOTIFY and you will find all further information. The principle is always the same for many messages.
wm_timer is a very helpful and easy to use message. Because of the low priority, there are some limits. for example timers stopped while menu or window moving/sizing. So the next level of doing this is using threads.... but there are other disadvantages.
Happy coding and stay healthy.
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 1:02 pm
by BarryG
Blue wrote: Fri Jun 21, 2024 1:20 pm
Imagine a string gadget with some text in it.
The user selects some of the text.
I'd like to...
1. detect that a selection process is underway
2. copy the selected text so that i can do something with it
Is such a thing even possible in Windows ???
Do you mean like this?
Code: Select all
If OpenWindow(0, 0, 0, 322, 50, "StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 8, 10, 306, 20, "Select some text here to copy it to the clipboard")
Repeat
ev=WaitWindowEvent()
If ev=#WM_LBUTTONUP And GetActiveGadget()=0
SendMessage_(GadgetID(0),#WM_COPY,0,0)
Debug "Copied: "+GetClipboardText()
EndIf
Until ev=#PB_Event_CloseWindow
EndIf
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 2:53 pm
by Blue
Hello BarryG. Nice to have you interested.
Many thanks for your input, but, no, that's not quite what I need. But it’s close.
Copying selected text to the Windows clipboard is the easy part. Which is EXACTLY what I was (frustatingly!) stuck doing until Axolotl provided the solution : only detecting that some text is in the process of being selected, and NOT interfering at all with the selection process. It's that step #1 in my query that was eluding me.
If you try Axolotl's code, you'll see immediately what I mean.
After tweaking Axolotl's code to fit my requirements, I now have everything working like a charm.
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 2:55 pm
by ebs
@BarryG,
That's really simple and clever, but it will be incorrect when no text is selected.
For example, if you first select/copy some text, then double-click (no text selected), the previous text, which is still in the clipboard, is shown.
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 2:59 pm
by Blue
ebs wrote: Mon Jun 24, 2024 2:55 pm
@BarryG,
That's really simple and clever, but it will be incorrect when no text is selected.
[...]
Right on,
ebs !
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 3:15 pm
by RASHAD
Thumps up for BarryG
Code: Select all
If OpenWindow(0, 0, 0, 322, 50, "StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 8, 10, 306, 20, "Select some text here to copy it to the clipboard")
Repeat
ev=WaitWindowEvent()
If ev=#WM_LBUTTONUP And GetActiveGadget()=0
ClearClipboard()
SendMessage_(GadgetID(0),#WM_COPY,0,0)
If GetClipboardText()
Debug "Copied: "+GetClipboardText()
EndIf
EndIf
Until ev=#PB_Event_CloseWindow
EndIf
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 3:53 pm
by Blue
Axolotl wrote: Mon Jun 24, 2024 11:36 am
[...]
Use the inet search such as "msdn <message> or <structure>" i.e. msdn WM_NOTIFY and you will find all further information. The principle is always the same for many messages.
[...]
Happy coding and stay healthy.
MSDN... Ahhhh, the nightmare !
That's where i go looking for how-tos on Windows API.
However, I quickly get dizzy simply reading a paragraph or two of their stuff

.
I usually have to rely, like now, on enlightened souls like you to interpret that material and translate it into edible PB code

.
I guess I'm missing that little propeller that's likely spinning on top of your head

. I'll buy one. It may help...
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 9:15 pm
by Blue
Great to come across you, again,
Rashad.
As usual, when you show up, everything takes a turn for the better.
RASHAD wrote: Mon Jun 24, 2024 3:15 pm
Thumps up for BarryG
Code: Select all
[...]
ClearClipboard()
SendMessage_(GadgetID(0),#WM_COPY,0,0)
If GetClipboardText()
...
EndIf
[...]
Well thumbs up

for
Rashad as well, who provided the wheels missing from
BarryG's good idea.
Now, I've got the simplest of working solutions.
Thank you Rashad, thank you BarryG
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 9:53 pm
by boddhi
Slight modification of BarryG and Rashad codes for keyboard selection support:
Code: Select all
Define.s ClipboardString
Define.s MemoryString ; or Static.s in a procedure
If OpenWindow(0, 0, 0, 322, 50, "StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 8, 10, 306, 20, "Select some text here to copy it to the clipboard")
Repeat
ev=WaitWindowEvent()
If (ev=#WM_LBUTTONUP Or ev=#WM_KEYUP) And GetActiveGadget()=0
ClearClipboard()
SendMessage_(GadgetID(0),#WM_COPY,0,0)
ClipboardString=GetClipboardText()
If ClipboardString And ClipboardString<>MemoryString ; To prevent double keyboard release events (e.g.: Ctrl+A, Shift+Left, Shift+Right,...)
MemoryString=ClipboardString
Debug "Copied: "+ClipboardString
EndIf
EndIf
Until ev=#PB_Event_CloseWindow
EndIf
Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 10:03 pm
by BarryG
ebs wrote: Mon Jun 24, 2024 2:55 pmit will be incorrect when no text is selected
You have to add extra checks for that. It was just to show a smaller way of doing it.

Re: How to detect that some text is selected in a StringGadget ?
Posted: Mon Jun 24, 2024 10:24 pm
by Blue
Very good thinking,
boddhi.
Before trying your modified code, I hadn't realized that selection by keyboard was not working.
Adding your "slight modification"
Code: Select all
If (ev=#WM_LBUTTONUP Or ev=#WM_KEYUP)
[...]
EndIf
makes a major difference : everything now works as expected.
Thanks boddhi