Jump to content

Richedit : drag/drop .txt files and display content


Recommended Posts

Hello

I was used to drag and drop .txt files in Edit controls and then display the text at once
But I got problems when trying to do the same with a Richedit control
I could laboriously manage this using a kind of dirty workaround as shown in the code below

Could someone please provide a cleaner solution ?  (I'm running XP SP3 and could get neither $EN_DROPFILES nor $WM_DROPFILES to work)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#Include <Array.au3>
#include <GuiEdit.au3>
#include <GuiRichEdit.au3>


$gui = GUICreate("test", 600, 400, -1, 100, -1, $WS_EX_ACCEPTFILES)
$edit = GUICtrlCreateEdit("", 10, 10, 580, 180, BitOr($ES_MULTILINE, $ES_WANTRETURN, $WS_VSCROLL) )
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$hRichEdit = _GUICtrlRichEdit_Create($gui, "", 10, 200, 580, 180, BitOr($ES_MULTILINE, $ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL) )
_GUICtrlRichEdit_SetLimitOnText($hRichEdit, 100000)
GUISetState()

_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_MOUSEEVENTS )
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")


While 1
  $nMsg = GUIGetMsg()
  Switch $nMsg
    Case $GUI_EVENT_CLOSE
             Exit
    Case $GUI_EVENT_DROPPED
        $dropped = @GUI_DragFile
        If StringRight($dropped, 4) <> ".txt" Then ContinueLoop
        GuiCtrlSetData($edit, FileRead($dropped))
  EndSwitch
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hRichEdit
            Select
              Case $iCode = $EN_MSGFILTER
                  $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
                  If DllStructGetData($tMsgFilter, "msg") = $WM_MOUSEMOVE  Then
                          If _SendMessage($hRichEdit, $EM_GETMODIFY) <> 0 Then 
                               $modified = _GUICtrlRichEdit_StreamToVar($hRichEdit)
                               If StringInStr($modified, "objemb") Then _Drop($modified)
                               _SendMessage($hRichEdit, $EM_SETMODIFY, false)
                         EndIf     
                   EndIf
            EndSelect
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Func _Drop($txt)
   _GUICtrlRichEdit_Undo($hRichEdit)
   $res = StringRegExp($txt, '[[:xdigit:]]{9,}', 3)
   Local $str
   For $i = 1 to 5
      $str &= $res[$i]
   Next
   $str = StringRegExpReplace($str, '(?s)[[:xdigit:]]+?0{4,}[[:xdigit:]]+?0{4,}([[:xdigit:]]+?)0{2,}.*', "$1")
   $filepath = FileGetLongName(BinaryToString("0x" & $str) )
   If StringRight($filepath, 4) <> ".txt" Then Return
   _NewFile($filepath)
EndFunc


Func _NewFile($newfile)
  GUIRegisterMsg($WM_NOTIFY, "")
  $filetxt = FileRead($newfile)
  _GUICtrlRichEdit_SetText($hRichEdit, "")
  _GUICtrlRichEdit_AppendText($hRichEdit, $filetxt)
  _GUICtrlRichEdit_SetSel($hRichEdit, 0, 0)
  GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
EndFunc

 

Edit
I was wrong about $EN_DROPFILES   :)

Edited by mikell
Link to comment
Share on other sites

Found it finally. Much much cleaner. I post the solution in case of someone could need it  
Too bad the $ES_NOOLEDRAGDROP constant was not documented  :)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#Include <Array.au3>
#include <GuiEdit.au3>
#include <GuiRichEdit.au3>
#include <WinAPISys.au3>

Global Const $ES_NOOLEDRAGDROP = 0x08
Global Const $tagDROPFILES  = $tagNMHDR & ";handle hDrop;long cp;bool fProtected"


$gui = GUICreate("test", 600, 400, -1, 100, -1, $WS_EX_ACCEPTFILES)
$edit = GUICtrlCreateEdit("", 10, 10, 580, 180, BitOr($ES_MULTILINE, $ES_WANTRETURN, $WS_VSCROLL) )
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$hRichEdit = _GUICtrlRichEdit_Create($gui, "", 10, 200, 580, 180, BitOr($ES_NOOLEDRAGDROP, $ES_MULTILINE, $ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL))
_GUICtrlRichEdit_SetLimitOnText($hRichEdit, 100000)
GUISetState()

_WinAPI_DragAcceptFiles ($hRichEdit)
_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_DROPFILES)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
  $nMsg = GUIGetMsg()
  Switch $nMsg
    Case $GUI_EVENT_CLOSE
             Exit
    Case $GUI_EVENT_DROPPED
        $dropped = @GUI_DragFile
        If StringRight($dropped, 4) <> ".txt" Then ContinueLoop
        GuiCtrlSetData($edit, FileRead($dropped))
  EndSwitch
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tDropFiles, $hDrop, $aFileList
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hRichEdit
            Select
              Case $iCode = $EN_DROPFILES
                  $tDropFiles = DllStructCreate($tagDROPFILES, $lParam)
                  $hDrop = DllStructGetData($tDropFiles, "hDrop")
                  $aFileList = _WinAPI_DragQueryFileEx($hDrop, 1)  ; files only
                  If @error OR $aFileList[0] > 1 OR StringRight($aFileList[1], 4) <> ".txt" Then _ 
                                Return _GUICtrlRichEdit_SetText($hRichEdit, "")
                  _NewFile($aFileList[1])
                  _WinAPI_DragFinish($hDrop)
            EndSelect
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Func _NewFile($newfile)
  $filetxt = FileRead($newfile)
  _GUICtrlRichEdit_SetText($hRichEdit, "")
  _GUICtrlRichEdit_AppendText($hRichEdit, $filetxt)
  _GUICtrlRichEdit_SetSel($hRichEdit, 0, 0)
EndFunc

 

Link to comment
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
 Share

  • Recently Browsing   0 members

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