Jump to content

Need help with _GUICtrlRichEdit_SetEventMask


Go to solution Solved by Melba23,

Recommended Posts

Posted

I'm attempting to implement an automatic process for text that's dropped into a RichEdit control.  The help file seems to describe a straightforward method.  But my simple test implementation isn't working.  The control accepts text, but I never receive the corresponding notification.

;
;       Simple Text Drag and Drop  ... attempt
;
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Drag Drop", 400, 300, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUISetFont(12, 400, 0, "Arial")
$hEdit = _GUICtrlRichEdit_Create($hGui, "", 20, 30, 360, 120, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)              ; this didn't help
_GUICtrlRichEdit_SetFont($hEdit, 14, "Arial")
_GUICtrlRichEdit_SetEventMask ($hEdit, $ENM_DRAGDROPDONE)
GUICtrlCreateLabel("Drop text into above field", 24, 170, 200, 24)
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            MsgBox(0, "Close", "... detected", 0, $hGui)
               _GUICtrlRichEdit_Destroy($hEdit) ; needed unless script crashes
            Exit
        Case $EN_DRAGDROPDONE
            MsgBox(0, "Edit/Change", "... detected", 0, $hGui)
    EndSwitch
    Sleep(20)
WEnd

I'll guess that I've left something out.  But I can't spot it.

Thanks in advance for any help.

 

Posted

Your example is not complete.

Where is your 

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) 

declared ?

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted (edited)

Short answer: sitting right there in the help file for _GUICtrlRichEdit_SetEventMask!

Longer answer:  I thought it was only needed in OnEvent mode.  Nonetheless, here's my example with WM_NOTIFY included:

;
;       Simple Text Drag and Drop  ... attempt
;
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Drag Drop", 400, 300, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUISetFont(12, 400, 0, "Arial")
$hEdit = _GUICtrlRichEdit_Create($hGui, "", 20, 30, 360, 120, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)                          ; this didn't help
_GUICtrlRichEdit_SetFont($hEdit, 14, "Arial")
_GUICtrlRichEdit_SetEventMask ($hEdit, $ENM_DRAGDROPDONE)
GUICtrlCreateLabel("Drop text into above field", 24, 170, 200, 24)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            MsgBox(0, "Close", "... detected", 0, $hGui)
               _GUICtrlRichEdit_Destroy($hEdit) ; needed unless script crashes
            Exit
        Case $EN_DRAGDROPDONE
            MsgBox(0, "Edit/Change", "... detected", 0, $hGui)
    EndSwitch
    Sleep(20)
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hEdit
            MsgBox(0, "Notify", "... detected", 0, $hGui)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

It has no effect.  Obviously, just including it isn't enough.  In any event, I don't understand why GUIGetMsg() doesn't receive the $EN_DRAGDROPDONE if it has occurred.  It receives the $GUI_EVENT_CLOSE just fine.  This all serves to highligh a rather significant point:

AutoIt users appear to operate in a general vacuum of understanding of WM_NOTIFY ... only that "it's needed" ... as exemplified by this thread from last year: 

It's an honest and well-researched attempt at determining an answer, but the answer isn't there.  The issue was left hanging ... with an example script that still didn't work.

Would someone who actually knows please write a paragraph on WM_NOTIFY from an AutoIt perspective?  A search of the help file brings up over 100 references and not one of them explains the function.  Yet, WM_NOTIFY occurs throughout the examples.

As a point of reference, here's msdn's offering:  "Sent by a common control to its parent window when an event has occurred or the control requires some information."  It's not the kind of explanation you can go build a script around.

Edited by qwert
Posted

OK ... I've made a little headway ... after looking at code for hours, code that looked the same as code in examples, but that just sat there without doing anything.

 

First, I’ve found an overview of WM_NOTIFY in the AutoIt Wiki.

https://www.autoitscript.com/wiki/Tutorial_GUIRegisterMsg

But it doesn’t explain the crossover relationship between the realms of GUIGetMsg and WM_COMMAND/WM_NOTIFY, for example. I’ve read elsewhere that “WM_NOTIFY is WM_COMMAND on steriods!” But it’s difficult to appreciate that meaning without a foundation understanding.

 

And I found this nugget in the help file regarding $GUI_DROPACCEPTED and $GUI_EVENT_DROPPED

Only dragging a ListviewItem will start the drag & drop process. The @GUI_DragId will be the ListView controlID.

 

But I've yet to see anything close to “the ins and outs of drag and drop methods for GUIs—an overview”.

 

My test script now works (with WM_NOTIFY registered ... and with _GUICtrlRichEdit_SetEventMask ($hEdit, $ENM_DRAGDROPDONE))

 ... but only for dragging/dropping text within the richedit control.

 

;
;       Simple Text Drag and Drop (within RichEdit control)
;
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Drag Drop", 400, 300, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUISetFont(12, 400, 0, "Arial")
$hEdit = _GUICtrlRichEdit_Create($hGui, "", 20, 30, 360, 120, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)                          ; this didn't help
_GUICtrlRichEdit_SetFont($hEdit, 14, "Arial")
_GUICtrlRichEdit_SetEventMask ($hEdit, $ENM_DRAGDROPDONE)
;_GUICtrlRichEdit_SetEventMask ($hEdit, $ENM_CHANGE)            ; << didn't help
;_GUICtrlRichEdit_SetEventMask($hEdit, BitOR($ENM_MOUSEEVENTS)  ; << didn't help
GUICtrlCreateLabel("Drop text into above field", 24, 170, 200, 24)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE                                       ; this works
            MsgBox(0, "Close", "... detected", 0, $hGui)
               _GUICtrlRichEdit_Destroy($hEdit) ; needed unless script crashes
            Exit
        Case $GUI_EVENT_SECONDARYUP                             ; this works
            MsgBox(0, "Click", "... detected", 0, $hGui)
        Case $EN_CHANGE                                         ; these didn't
            MsgBox(0, "Change", "... detected", 0, $hGui)       ;
        Case $GUI_EVENT_DROPPED                                 ;
            MsgBox(0, "Drop", "... detected", 0, $hGui)         ;
        Case $EN_DRAGDROPDONE                                   ;
            MsgBox(0, "Edit/Change", "... detected", 0, $hGui)
    EndSwitch
    Sleep(20)
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hEdit
            MsgBox(0, "Notify", $iCode & " ... detected", 0, $hGui)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

.

I'm still lacking a way to know that text has been dropped in from a source outside the GUI. And when I enable mouse events ($ENM_MOUSEEVENTS), I get “1792” for the code any time the edit field is touched.  (Notifications Edit Control ... EN_ALIGN_LTR_EC = 1792

Sent when the user has changed the edit control direction to left-to-right. )

 

Any suggestions will be appreciated.

 

  • Moderators
  • Solution
Posted (edited)

qwert,

You need to register WM_COMMAND, not WM_NOTIFY - then you get a response whenever the content is changed: :)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiRichEdit.au3>

$hGui = GUICreate("Drag Drop", 400, 300, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUISetFont(12, 400, 0, "Arial")

$hEdit = _GUICtrlRichEdit_Create($hGui, "", 20, 30, 360, 120, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))

_GUICtrlRichEdit_SetFont($hEdit, 14, "Arial")
_GUICtrlRichEdit_SetEventMask($hEdit, $ENM_CHANGE)
GUICtrlCreateLabel("Drop text into above field", 24, 170, 200, 24)

GUISetState()

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE ;
            ConsoleWrite("Close" & @CRLF)
            _GUICtrlRichEdit_Destroy($hEdit) ;
            Exit
    EndSwitch
WEnd

Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    If $lParam = $hEdit And _WinAPI_HiWord($wParam) = $EN_CHANGE Then
        ConsoleWrite("Edit content changed" & @CRLF)
    EndIf
EndFunc
I am sorry that you find the GUIRegisterMsg tutorial in the Wiki less than satisfactory. It was only ever intended as a brief overview - if you want the full explanation of how Windows messaging works, I recommend MSDN, although it is very detailed. ;)

As to the crossover between GUIGetMsg and needing to register the Windows messages directly - look at the Help file pages <GUI Reference - MessageLoop/OnEvent Mode>. You will see that GUIGetMsg and GUI/GUICtrlSetOnEvent only have a limited set of messages to which they will respond, plus the controls created by AutoIt's native functions. Anything over and above that limited set (such as looking for a change in a UDF-created control as here) requires you to intercept the relevant message yourself. To do that you need to look in MSDN (or search the forum for a suitable crib ;)) and determine which message is sent and how to intercept it - I looked on MSDN and found this page from which I devised the above code. :)

Does that make it any clearer? :huh:

M23

Edited by Melba23
Code modified - see below

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

  • Moderators
Posted

kylomas,

Thanks - not sure how that happened as it appears in the version which I was running in SciTE. :wacko:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

Posted

@Melba23,

Excellent. I can’t believe I was completely off track by something right in front of me. I recall trying it both ways, but I’ll suppose my ducks weren’t aligned (a technical term).

 

But even with your working example, it took me several tries to get the same result with mine. The difference is that I was expecting $hWndFrom = $hEdit, while you were using $iParam = $hEdit.  At this moment, I can’t fathom why that is so or where I got the idea. I’ll add it to my (long list) of “things to figure out why”. For now, it’s working and I’m glad to be unstuck.

 

The Wiki (you wrote?) is excellent at covering the topics it does. Its style is flowing and understandable ... sort of the opposite of msdn. My “disappointment” was only that it didn’t carry on and on. I always hope to find those clay tablets that will spell things out for me ... like travel guides written by someone who’s actually been there.

 

Thanks very much for helping me out with this.

 

 

 

 

  • Moderators
Posted

qwert,

Glad I could help.

 

  Quote

Its style is flowing and understandable ... sort of the opposite of msdn

Delighted you think so - although being less turgid than MSDN is not exactly hard! :D

 

  Quote

“things to figure out why"

When it comes to Windows messaging it is sometimes best just accept that is the way things are - trying to understand WHY MS did things the way they did is just too much for any one brain. I suspect a lot of it has to do with backwards compatibility - we have enough problems in AutoIt with that, so heaven knows what it must be like for Windows itself! :ohmy:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...