qwert

RichEdit processes double-click. Can I get it, too?

7 posts in this topic

#1 ·  Posted

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.

;
;       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.

Share this post


Link to post
Share on other sites



#2 ·  Posted

 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.

Share this post


Link to post
Share on other sites

#3 ·  Posted

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.

Share this post


Link to post
Share on other sites

#4 ·  Posted (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 by qwert

Share this post


Link to post
Share on other sites

#5 ·  Posted

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:

;
;       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.)

Share this post


Link to post
Share on other sites

#6 ·  Posted

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.

#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

 

Share this post


Link to post
Share on other sites

#7 ·  Posted

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.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now