qwert Posted April 2, 2017 Share Posted April 2, 2017 I've looking for a simple way to grab a word that a user highlights (by double-clicking) in a RichEdit control, as soon as it's highlighted. Based on a script from these forums, I built the following script that can pick up the highlighted word when you double-click on a different field. I half way thought that it could process a double-click from the RichEdit, as well. It doesn't. expandcollapse popup; ; Process a double click ; #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <ButtonConstants.au3> #include <GuiRichEdit.au3> Global $Flag $hGui = GUICreate("", 150, 100) $hLabel = GUICtrlCreateLabel("DOUBLE_CLICK", 20, 20, 100, 20) $hText = _GUICtrlRichEdit_Create($hGui, "Text in field", 10, 50, 120, 24, $ES_READONLY) GUICtrlSetState($hLabel, $GUI_FOCUS) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_COMMAND, "TEST_WM_COMMAND") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $Flag = True Then $cur = _GUICtrlRichEdit_GetSelText($hText) MsgBox(0, "Double click", $cur) $Flag = False EndIf WEnd Func TEST_WM_COMMAND($hWnd, $MsgID, $wParam, $lParam) Local Const $STN_DBLCLK = 1 Local $nID = BitAND($wParam, 0xFFFF) Local $nCode = BitShift($wParam, 16) If $nID = $hLabel And $nCode = $STN_DBLCLK Then $Flag = True ; this works If $nID = $hText And $nCode = $STN_DBLCLK Then $Flag = True ; this doesn't Return $GUI_RUNDEFMSG EndFunc ;==>TEST_WM_COMMAND Can someone suggest a different direction ... and point me to an example? Thanks in advance for any help. Link to comment Share on other sites More sharing options...
benners Posted April 2, 2017 Share Posted April 2, 2017 It's probably not much help and i'm still trying to understand GUIRegisterMsg and control messages but GUICtrlCreateLabel returns an Id for the control (3) and _GUICtrlRichEdit_Create returns a handle. Using $nID the richedit returns 10000 which doesn't match the handle for $hText. The $nCode value doesn't match $STN_DBLCLK either. It seems to return either 256 or 1024 (this seems to be when its highlighted). As a bodge job if you replace If $nID = $hText And $nCode = $STN_DBLCLK Then $Flag = True ; this doesn't with If $lParam = $hText And $nCode = 1024 Then $Flag = True ; this mostly you can at least get it to register a dbl click. It is flakey as it sometimes shows the msgbox when it hasn't been double clicked. Hopefully it might help a bit, especially if you can sort the dbl click value out. I'm sure someone will come along with the correct code to sort it. I normally copy and paste from my old projects but nothing seemed to work with this. Link to comment Share on other sites More sharing options...
benners Posted April 3, 2017 Share Posted April 3, 2017 Looking in the EditConstants.au3 file it seems that the Richedit fires the $EN_UPDATE value and doesn't register the double click, or so I think. So the msgbox is fired if you double click or highlight the text. There is a post from PhoenixXL here that might be of use. You could probably strip the thing out you don't need. Link to comment Share on other sites More sharing options...
qwert Posted April 3, 2017 Author Share Posted April 3, 2017 (edited) Thanks for your two responses. I've confirmed everything you described in your first post ... and will investigate your second suggestion. This is the first time I've had cause to "look under the hood" of the RichText UDF. The very first thing I found was that RichEdits are actually individual windows, which, as you pointed out, causes the create operation to return a window handle and not a control ID. This gives me other ideas of things to look at. (But I'll still hope that someone has solved this, before!) I appreciate your help. Edited April 3, 2017 by qwert Link to comment Share on other sites More sharing options...
qwert Posted April 4, 2017 Author Share Posted April 4, 2017 Quote To receive EN_SELCHANGE notification codes, specify ENM_SELCHANGE in the mask sent with the EM_SETEVENTMASK message. For a minute, I thought I'd found the answer. I was able to receive an $EN_UPDATE notification, but it requires a pause to allow the RichEdit to refresh to show a selected word. The above msdn note led me to believe that $EN_SELCHANGE was the answer. But I don't receive a notification with the following statements: expandcollapse popup; ; Process a double click ; #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <ButtonConstants.au3> #include <GuiRichEdit.au3> Global $Flag $hGui = GUICreate("Double Click Test", 200, 100) $hLabel = GUICtrlCreateLabel("Double click on any word:", 10, 20, 180, 20) Global $hText = _GUICtrlRichEdit_Create($hGui, "Text in field", 10, 40, 180, 24, $ES_READONLY) GUICtrlSetState($hLabel, $GUI_FOCUS) GUISetState(@SW_SHOW) _GUICtrlRichEdit_SetEventMask($hText, $ENM_SELCHANGE) ; << SET EVENT MASK GUIRegisterMsg($WM_COMMAND, "TEST_WM_COMMAND") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $Flag = True Then $cur = _GUICtrlRichEdit_GetSelText($hText) If $cur <> -1 Then MsgBox(0, "Double click", $cur) $Flag = False EndIf WEnd _GUICtrlRichEdit_Destroy($hText) Func TEST_WM_COMMAND($hWnd, $MsgID, $wParam, $lParam) Local $iCode = _WinAPI_HiWord($wParam) ; If $lParam = $hText And $iCode = $EN_UPDATE Then $Flag = True ; THIS WORKED If $lParam = $hText And $iCode = $EN_SELCHANGE Then $Flag = True ; THIS DOESN'T Return $GUI_RUNDEFMSG EndFunc ;==>TEST_WM_COMMAND Would anyone happen to know why? (You can swap over to the $EN_UPDATE method and watch it work.) Link to comment Share on other sites More sharing options...
benners Posted April 7, 2017 Share Posted April 7, 2017 I had a play with some examples from the help file and cobbled together this. It seems to work. I also added checks for blank selection and stripped any leading\trailing white space. Figured if RichEdits are windows as you mentioned, they should, at times, return different values than controls. expandcollapse popup#include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <StringConstants.au3> #include <WindowsConstants.au3> Global $Flag = False Global $hGui = GUICreate("Double Click Test", 200, 100) Global $hLabel = GUICtrlCreateLabel("Double click on any word:", 10, 20, 180, 20) Global $h_Text = _GUICtrlRichEdit_Create($hGui, "Text in field", 10, 40, 180, 24, $ES_READONLY) _GUICtrlRichEdit_SetEventMask($h_Text, $ENM_MOUSEEVENTS) GUICtrlSetState($hLabel, $GUI_FOCUS) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $Flag = True Then $cur = _GUICtrlRichEdit_GetSelText($h_Text) If $cur <> -1 And $cur <> '' Then MsgBox(0, "Double click", StringStripWS($cur, BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING))) $Flag = False EndIf WEnd _GUICtrlRichEdit_Destroy($h_Text) Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam Local $tMsgFilter Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $h_Text Select Case $iCode = $EN_MSGFILTER $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam) If DllStructGetData($tMsgFilter, "msg") = $WM_LBUTTONDBLCLK Then $Flag = True EndSelect EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Link to comment Share on other sites More sharing options...
qwert Posted April 11, 2017 Author Share Posted April 11, 2017 I want to thank you for providing this method. It works a you've indicated. (It did take me a bit to get it operating in my full script, largely due to the fact that I mis-placed the _GUICtrlRichEdit_SetEventMask($h_Text, $ENM_MOUSEEVENTS) statement.) The one enhancement I made was in the way I respond to the $Flag. I detect it in the main While...Wend loop and pause for a half second so the user gets the benefit of a momentary highlight of the Rich Text word before other processing takes over. It's the "natural" effect I was hoping for. I appreciate your help. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now