|
Hello Alex,
Thanks so much for your kindly reply.
The error occurs in line 1504 of ExtendedRichTextBox.cs, the last line of set property of SelectionCharStyle. As following:
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref param);
The definition of SendMessage defined in line 732:
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref CHARFORMAT2 lParam);
By the way, I tried to modify the CharSet attribute of DllImport from Auto to Unicode, it failed too.
Thanks again.
Alva
Impossible is Nothing!
|
|
|
|
|
I just found it not only doesn't work in X64 platform, but also not work properly in Windows 7, so that I decided to debug it and get rid of the bug.
The problem is caused for the structure which passed to SendMessage. To avoid this, I used the way as following:
Step 1. Modify the extern method definition
//[DllImport("user32", CharSet = CharSet.Auto)]
//private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref CHARFORMAT2 lParam);
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, Int32 wParam, ref IntPtr lParam);
Step 2. Modify the call to that method, as following:
//SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
GCHandle gch = GCHandle.Alloc(fmt);
IntPtr lParam = GCHandle.ToIntPtr(gch);
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref lParam);
gch.Free();
It works now in Windows 7 and I assume it should works fine in X64 bit as well.
BR,
Alva Chien
Impossible is Nothing!
|
|
|
|
|
Hello, guys. It seems that much time passed, after previous post was published but I think that solution to problem described before may help someone.
So, main problem in porting 32 bit code to 64 bit platform and vice versa is the size of pointers, which is 4 bytes in x86 and 8 bytes in x64. So far there is no way for native platforms (like C\C++\Delphi) to produce the code for both platforms other than recompilation with retargeting to new paltform.
In .NET world it's much easier, due to existence of IntPtr (UIntPtr) which is platform independent and changes accordingly to he underlying pointer size used in end user's system.
I have noticed that many P/Invoke declarations are written using Int32 or UInt32 instead of pointers, so did I here (this is my mistake, sorry). This will limit the usage of such code to the 32 bit platforms only as the size of Int32 and UInt32 is 4 bytes (comparing with x64 8 bytes). And of course when you'll try to execute such code you will get memory exception.
So, the solution is simple. Replace all Int32 and UInt32 parameters in P/Invoke declarations with corresponding pointers from .NET world (IntPtr, UIntPtr, SafeHandle, HandleRef and others).
Hope this info will help someone. Good luck!
Alex KraS
|
|
|
|
|
I really like it, i was just going to ask if you could make a project with ruler for VB 2008, i can not figure out how to create a ruler.
Thanks,
Charles
|
|
|
|
|
Hey,
I have a bit of a problem. When I set the ZoomFactor property in my richtextbox to anything other than 1, the ruler does not adjust to still show the indentation correctly. The ruler stays the same size while all the text in the box is zoomed correctly.
Like in openoffice, when you zoom out or in, the ruler adjusts itself. How can I achieve the same behaviour?
Thanks,
Anthony.
Check out my desktop conversion software for Windows -
www.universalconverter.net
|
|
|
|
|
Hey,
Thanks for this wonderful project. It really is a great editor, and I would love to use it in my projects.
However, I read in one of your posts some time ago that the next version will have Hunspell powered spell check. Just wondering, did I miss when you released it, or is it still in development?
Thanks in advance,
Anthony
Check out my desktop conversion software for Windows -
www.universalconverter.net
|
|
|
|
|
Hello, sory for inconvinience. I just don't have enough time to upload files (Currently very busy at work). I try to dedicate some time for upload.
I will also update an article when work will be done.
P.S. Thank you very much for your words. I am glad that this portion of code is usefull for people.
Cheers,
Alex
Alex KraS
|
|
|
|
|
Hey,
No worries, thanks for replying
Anthony
Check out my desktop conversion software for Windows -
www.universalconverter.net
|
|
|
|
|
I like your control. thanks
|
|
|
|
|
Thank you for your kind words
Alex KraS
|
|
|
|
|
I tried to make this project in VB2005 with the help of .net reflector, but i have problems i dont know how to overcome . I need the ruler interface and the extendedrichtextbox that allows full justify alignment.
Has someone translated it to VB2005? if so please send me by mail (zqlmyn@yahooo.com.ar) the project. Thanks. By the way thanks also for sharing the code!
|
|
|
|
|
i think i will use the C# files to make a dll, and then just add it in VB as a reference so i can use the methods in VB.
|
|
|
|
|
If you change the text size of a selection from the default to say 10 pt it actually changes to 7pt if you change it to 14pt it actually changes to 10 and other values for other sizes. When the text is no longer highlighted the text box reports the correct size. I have looked through the source code for ages and I cannot see what causes this. This effect occurs both in your demo project and the project in which I am using your code
brian at BCC
|
|
|
|
|
Actually this is know bug. I already fixed it. Actually I fully recoded the ExtendedRichTextBox . I think I upload it in a day or two.
New features:
- OLE dialogs and OLE features support (but currently not all)
- Spell checking as you type (Hunspell(r) powered)
- Theasaurus
- Hyperlinks with custom text
- Advanced AutoReplace
- and even more...
Alex KraS
|
|
|
|
|
Thats what I call service. The bug fixed before I reported it!! If only Microsoft could do as well.
Thanks Alex for a superb piece of work. You have saved me a lot of time.
brian at BCC
|
|
|
|
|
Hi Aleksei.
Perhaps I've missed it but is the update available? Seems that the current version still has this bug.
Cheers,
Frank
|
|
|
|
|
Hey, do you have the new version? I would like to see it.
public class SysAdmin : Employee
{
public override void DoWork(IWorkItem workItem)
{
if (workItem.User.Type == UserType.NoLearn){
throw new NoIWillNotFixYourComputerException(new Luser(workItem.User));
}else{
base.DoWork(workItem);
}
}
}
|
|
|
|
|
Hello Brian,
if you debug the code you will find out that in ExtendedRichTextBox class in a definition of property SelectionFont2 in line 1540 there is a bug: the factor for calculating yHeight attribute of CHARFORMAT2 structure should be 20 not 14.4 (which currently is represented by variable AnInch).
Quick correction solves the case.
Michal Orlik
michael.orlik@wp.pl
|
|
|
|
|
Thanks Michael,
I was also looking for the bug. Thanks very much for sharing the solution.
Brian
brian at BCC
|
|
|
|
|
Hi Aleksei.
Hyperlinks that have spaces included do not work as expected. E.g. the hyperlink
file:\\c:\documents and settings\frank\somefile.txt. The text left of the first space is highlighted but the link does not work. Any ideas? (besides removing the spaces)
Cheers,
Frank
|
|
|
|
|
Hello.
Actually, this is an issue of the RichTextBox. Well, I found a solution.
Firstly, it's easier to use arbitrary links (like, click here, instead of file://somefile).
You sould add a function to the ExtendedRichTextBox, which will instert hyperlinks. Here is what I use:
internal void InsertHyperlink(string text, string address, Color linkColor)
{
if (address == null) return; if (address == "") return;
if (text == "") text = address;
string _val = "", _val2 = "";
string s = @"{\rtf1\ansi\ansicpg1251\deff0\deflang1049" +
Environment.NewLine + @"{\colortbl ;\red" + linkColor.R.ToString() + @"\green" + linkColor.G.ToString() + @"\blue" + linkColor.B.ToString() + ";}" +
Environment.NewLine + @"{\*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1 ";
string s1 = "\\pard \\protect {\\field{\\*\\fldinst{HYPERLINK \"";
string s2 = "\" }}{\\fldrslt{\\cf1\\ul ";
string s3 = "}}}\\cf0\\ulnone\\f0 ";
_val2 = "\\uc0 ";
for (int i = 0; i < address.Length; i++)
{
_val2 += "\\u" + ((short)address[i]).ToString() + " ";
}
_val = s + s1 + _val2 + s2;
_val2 = "\\uc0 ";
for (int y = 0; y < text.Length; y++)
{
_val2 += "\\u" + ((short)text[y]).ToString() + " ";
}
_val += _val2 + s3 + Environment.NewLine + "\\protect0 " + Environment.NewLine + "}";
this.SelectedRtf = _val;
}
It's not perfect, but working. It uses MS Word style hyperlinks (it uses HYPERLINK keyword defined inside field). After adding the code above provide the link text (caption), address (this is the path to your file) and optionally the color of the link.
One more thing. On my computer there was a problem. Method above worked only if there was some text after the link. . It was somehow unexpected. Fortunatly I found the solution. You have to handle the LinkClicked event in the WndProc in the following way:
if (m.Msg == 8270)
{
NativeMethods.ENLINK lParam;
lParam = m.GetLParam(typeof(NativeMethods.ENLINK)) as NativeMethods.ENLINK;
if (lParam != null)
{
if (lParam.msg == 513)
{
string str = this.CharRangeToString(lParam.charrange);
if (!string.IsNullOrEmpty(str))
{
m.Result = (IntPtr)1;
OnLinkClicked(new LinkClickedEventArgs(str));
}
else base.WndProc(ref m);
}
else base.WndProc(ref m);
}
else base.WndProc(ref m);
}
It happens that way: user clicks the link, we handle it, than we get its address (this should be you filename) and convert it into a string. After that we rise the OnLinkClicked event and passing the address to it. All you need to do is just to decide what to do it LinkClicked proc.
Fortunately, definition for ENLINK, TEXTRANGE, NMHDR and CHARRANGE you can find in the MSDN. And here is the definitions for CharRangeToString function:
private class CharBuffer
{
internal char[] buffer;
internal int offset;
internal CharBuffer(int size)
{
if (size > 8196 || size < 0)
{
this.buffer = new char[0];
return;
}
try
{
this.buffer = new char[size];
}
catch (Exception)
{
}
}
public IntPtr AllocCoTaskMem()
{
if (this.buffer.Length == 0) return IntPtr.Zero;
IntPtr destination = Marshal.AllocCoTaskMem(this.buffer.Length * 2);
Marshal.Copy(this.buffer, 0, destination, this.buffer.Length);
return destination;
}
public string GetString()
{
int offset = this.offset;
while ((offset < this.buffer.Length) && (this.buffer[offset] != '\0'))
{
offset++;
}
string str = new string(this.buffer, this.offset, offset - this.offset);
if (offset < this.buffer.Length)
{
offset++;
}
this.offset = offset;
return str;
}
public void PutCoTaskMem(IntPtr ptr)
{
Marshal.Copy(ptr, this.buffer, 0, this.buffer.Length);
this.offset = 0;
}
public void PutString(string s)
{
int count = Math.Min(s.Length, this.buffer.Length - this.offset);
s.CopyTo(0, this.buffer, this.offset, count);
this.offset += count;
if (this.offset < this.buffer.Length)
{
this.buffer[this.offset++] = '\0';
}
}
}
private string CharRangeToString(NativeMethods.CHARRANGE c)
{
NativeMethods.TEXTRANGE lParam = new NativeMethods.TEXTRANGE();
lParam.chrg = c;
int size = (c.cpMax - c.cpMin) + 1;
CharBuffer buffer = new CharBuffer(size);
IntPtr ptr = buffer.AllocCoTaskMem();
if (ptr == IntPtr.Zero)
{
return "";
}
lParam.lpstrText = ptr;
int num1 = (int)NativeMethods.SendMessage(new HandleRef(this, this.Handle), 1099, 0, lParam);
buffer.PutCoTaskMem(ptr);
if (lParam.lpstrText != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(ptr);
}
return buffer.GetString();
}
I hope this will help you. For me this works perfect. But remember that when you insert the hyperlink that way, you mark it protected, so you can't edit it directly in the RichTextBox. And changing the hyperlinks is another topic.
Good luck.
Cheers,
Alex.
Alex KraS
|
|
|
|
|
Thanks a lot, you sure put me in the right direction . The arbitrary links looks a lot better. For those who still want to use the file://somefile, replace each space in the link with '%20', no quotes of course.
Cheers,
Frank
|
|
|
|
|
Hi Aleksei, great peice of work! but was wondering how you change the indentations on the ruler to match the page margin, let me explain in more detail
For example:
If i change the ruler margins to 1 Inch(25.4mm) each side id expect the Ruler indetation pegs to adjust to the edge of the newly set margin, however you must change the ruler indentation settings to affect these, which in turn alters the Rich Text box indentation level therefore messing with the print
So what im asking is how can i set the ruler margins and change the ruler indents posistion without changing the Rich text box's indentation level?
Any Ideas?
Thanks
modified on Sunday, December 21, 2008 3:50 AM
|
|
|
|
|
Hi
Your control is very useful for me but there is a little problem. I have some rtf formatted text and now I want to display this text in the text editor
this.ateAdditionalNote.TextEditor.Rtf = text;
Unfortunately no text is displayed in the control although the property (TextEditor.Rtf) has the right value. When I save the text in a file and open it in MS Word, the text is displayed correctly.
Do I have to call some kind of refresh method or something similar?
Thank you for your help!
Michael Hachen
|
|
|
|
|
Hm. I can't tell you exactly, what can be wrong with it. For me it works fine. What kind of text are you assigning to Rtf property (I mean formatting)?
Alex KraS
|
|
|
|
|