ScintillaNET icon indicating copy to clipboard operation
ScintillaNET copied to clipboard

Display binary data

Open jvkaam opened this issue 7 years ago • 5 comments

Hi,

When I read a file in Notepad++ the representation sometimes shows some NUL, SCH or SUB (white letters on a black background) codes of characters that cannot be shown. In Scintilla the representation stops at the first character (that has an ASCII 0). Is there a setting that can change this behavior?

jvkaam avatar Apr 29 '18 15:04 jvkaam

Yes, this is supported, but I can't recall what API it is off the top of my head.

jacobslusser avatar Sep 21 '18 19:09 jacobslusser

I have been struggling to find the answer to this question as well. I cannot tell from the source code of Notepadd ++ and Scintilla.NET which is the API that makes this happen. @jacobslusser, if you have recalled in the meantime, can you please share? Thank you.

craiovea avatar Sep 02 '20 07:09 craiovea

Use Scintilla.AppendText instead assigning Scintilla.Text. You can try the following snipped code:

var scintilla = new ScintillaNET.Scintilla();
byte[] buffer = null;
using (FileStream fs = File.OpenRead("YourFileName"))
{
    long size = fs.Length;
    buffer = new byte[size];
    size = fs.Read(buffer, 0, (int)size);
}
// Do not use: scintilla.Text = Encoding.Default.GetString(buffer); 
// Use instead:
scintilla.Text = "";
scintilla.AppendText(Encoding.Default.GetString(buffer));

AlbertBecker avatar Dec 03 '20 18:12 AlbertBecker

The AppendText method that AlbertBecker mentioned works properly since SCI_APPENDTEXT does not take a null terminated string whereas SCI_SETTEXT does. The Text property should be overridden to support this by adding a simple else if statement in the setter. VPKSoft can you please merge this fix into your unofficial.ScintillaNET fork?

public unsafe override string Text
{
    get
    {
        var length = DirectMessage(NativeMethods.SCI_GETTEXTLENGTH).ToInt32();
        var ptr = DirectMessage(NativeMethods.SCI_GETRANGEPOINTER, new IntPtr(0), new IntPtr(length));
        if (ptr == IntPtr.Zero)
            return string.Empty;

        // Assumption is that moving the gap will always be equal to or less expensive
        // than using one of the APIs which requires an intermediate buffer.
        var text = new string((sbyte*)ptr, 0, length, Encoding);
        return text;
    }
    set
    {
        if (string.IsNullOrEmpty(value))
        {
            DirectMessage(NativeMethods.SCI_CLEARALL);
        }
        else if (value.Contains('\0'))
        {
            DirectMessage(NativeMethods.SCI_CLEARALL);
            AppendText(value);
        }
        else
        {
            
            fixed (byte* bp = Helpers.GetBytes(value, Encoding, zeroTerminated: true))
                DirectMessage(NativeMethods.SCI_SETTEXT, IntPtr.Zero, new IntPtr(bp));
        }
    }
}

cyber960 avatar Mar 01 '21 23:03 cyber960

Version 3.8.5 should now include the change - thank you 👍

VPKSoft avatar Mar 02 '21 15:03 VPKSoft