Jump to content

RichTextBox image problem

Recommended Posts


When I run the example script of _GUICtrlRichEdit_Create in my windows 10 machine, i can drag & drop an image and it appears in the richtextbox, but if I do the same on windows 7, the image is converted to an object and the richtextbox only shows the icon for images.

How can i replicate the windows 10 behavior on windows 7? Is it posible?

Here is the code:

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


Func Example()
    Local $hGui, $hRichEdit, $iMsg
    $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", 320, 350, -1, -1)
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "DROP AN IMAGE HERE!"&@CRLF, 10, 10, 300, 220, _

    While True
        $iMsg = GUIGetMsg()
            Case $iMsg = $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes
                ; GUIDelete()   ; is OK too
EndFunc   ;==>Example

I attached some screenshots to show what i say, Imagen1 is in windows 10 and Imagen2 in windows 7.

Sorry for my english, it's not my native lenguaje :/



Link to post
Share on other sites

Very interesting.  I'm not an expert but I'd imagine it's a new feature in Windows 10 to convert an image file into a compatible graphic (bitmap?) for the RichEdit control.  I'd be interested if there is an easy way to tweak the control on Windows 7 to produce the same behavior.  

I assume you are looking to add an image to a GUI "at will" (during run-time).  If you don't need the fancy edit control like functionality (being able to type and paste data into the control) you could use alternative means to display the graphic (i.e. graphics control, GDI+).  Just wanted to offer alternatives and better understand what you are looking to accomplish.

Link to post
Share on other sites

Thanks for your response, i need this to happen in run-time :/
I discovered that windows 8 have the same behavior that windows 10 (maybe you are right, and it's a new feature).
Also, if you open the image in paint, select it all, copy to the clipboard, and paste in the richedit, it will show the image (like windows 10), but in its real size (windows 8/10 resize it a little, see new screenshot)


Link to post
Share on other sites

I'm on Windows 7 as well and get the icon when dropping the image. I converted the exact image to bmp (in paint) and it loaded it properly.

Only thing I can think of is intercept whatever windows message you're getting to load the picture and convert to a bmp before loading in richedit. Unfortunately, I don't know what the message is or how to load an image on richedit (I actually didn't even know richedit could do that! lol)

Link to post
Share on other sites

I keep investigating, in https://msdn.microsoft.com/en-us/library/windows/desktop/bb774325(v=vs.85).aspx appears the definition of  __RichCom_Object_QueryAcceptData , but can't read the LPDATAOBJECT ($pDataobj), there should be the image binary (I think).


Also, I tried to put Win10/Office 2016 MSFTEDIT.DLL and RICHED20.DLL files in the script's dir, but I think the script doesn't recognize the files.

Edited by Gianfranco_753
More Info
Link to post
Share on other sites

If someone need it, I made a workaround:

First, I add the following code the beginning of the project, before i created the GUICtrlRichEdit

Global $bAcceptData = False
If @OSBuild < 9600 Then ;If it's older than Windows 8
    ;Change the callback of the UDF to a new one
    Global $__g_pRichCom_Object_QueryAcceptData = DllCallbackRegister("__RichCom_Object_QueryAcceptDataWIN7", "long", "ptr;ptr;dword;dword;dword;ptr")
;The new callback function
Func __RichCom_Object_QueryAcceptDataWIN7($pObject, $pDataobj, $pCfFormat, $vReco, $bReally, $hMetaPict)
    #forceref $pObject, $pDataobj, $pCfFormat, $vReco, $bReally, $hMetaPict
    If $bAcceptData Then
        Return $_GCR_S_OK ;Accept objects (and images)
        If Not $bReally Then MsgBox($MB_ICONWARNING,"", "If you wish to add an image on Windows 7 or older, you must do a right click and select add image.")
        Return $_GCR_E_INVALIDARG ;Don't add the object to the richedit.
EndFunc   ;==>__RichCom_Object_QueryAcceptData

Then created a context menu:

$Dummy1context = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$InsertarImagen = GUICtrlCreateMenuItem("Add image", $Dummy1context)
GUICtrlSetOnEvent($InsertarImagen, "InsertarImagenClick")
Func InsertarImagenClick()
    Local $sTipoImagen
    Local $sImagen = FileOpenDialog("Select the image that you want to add", @ScriptDir & "\", "Images (*.png;*.jpg;*.jpeg;*.bmp)", $FD_FILEMUSTEXIST)
    If Not @error Then
        Local $vClipBoardBackup = _ClipBoard_GetData()
        If _ClipBoard_Open($RegistroDiarioDeActividades) Then
            Local $fFactor = 0.5669 ;Or the image will be too big for my control
            Local $hImg2 = _GDIPlus_ImageLoadFromFile($sImagen)
            Local $iW = _GDIPlus_ImageGetWidth($hImg2)*$fFactor
            Local $iH = _GDIPlus_ImageGetHeight($hImg2)*$fFactor
            $hImg = _GDIPlus_ImageResize($hImg2, $iW, $iH)
            Local $hBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImg)
            Local $hBitmap = _WinAPI_CopyImage($hBitmap2,0,0,0,$LR_COPYDELETEORG+$LR_COPYRETURNORG)
            _ClipBoard_SetDataEx($hBitmap, $CF_BITMAP)
            $bAcceptData = True
            $bAcceptData = False
            MsgBox(0,'',"_ClipBoard_Open failed")
    Return True

And finaly, create the RichEdit and add

_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_MOUSEEVENTS)
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 $hRichEdit
                Case $iCode = $EN_MSGFILTER
                    $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
                    If DllStructGetData($tMsgFilter, "msg") = $WM_RBUTTONUP Then
                        $hMenu = GUICtrlGetHandle($Dummy1context)
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd)
EndFunc   ;==>WM_NOTIFY

That way, i can add images in all the systems (drag&drop in windows >= 8 and add with the button on windows < 8)

I hope this could help someone in the future.

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

    No registered users viewing this page.

  • Create New...