|
OK I'll start from the beginning again...
Is this true?
xPixel = (textColumnNumber - horizontalScrollCount) * textCharacterWidth;
yPixel = (textLineNumber - verticalScrollCount) * textLineHeight;
______/\______ ___________/\__________
Unknown Vars Unknown Var(S)?
|
|
|
|
|
You choose a font size, hence you get a charwidth and a charheight; you choose a textLineHeight equal to or slightly larger than the charheight.
On (mouse) input you know xPixel and yPixel and want to know textLineNumber and textColumnNumber
on (display) output you know textLineNumber and textColumnNumber and want to know xPixel and yPixel.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Luc, can't you please, please help me? The closest I could come was this, and it's still pathetic:
colNum = (Cursor.Position.X - this.stormParent.HorizontalScroll.Value) / charWidth - charWidth;
lineNum = (Cursor.Position.Y - this.stormParent.VerticalScroll.Value) / (int)this.Font.Size - (int)this.Font.Size;
I tried for nearly 9 hours :s
|
|
|
|
|
Hi,
I gave you
xPixel=(textColumnNumber-horizontalScrollCount)*textCharacterWidth;
and you now want textColumnNumber=a*xPixel+b right?
The only problem is determining the coefficients a and b. Take the recipe I gave earlier, make the factors and terms on the textColumnNumber disappear by adding/subtracting/multiplying/dividing both sides of thee equation appropriately.
The first thing to go is "*textCharacterWidth" because that is what you perform last in the original equation;
then the remaining "-horizontalScrollCount"
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Is it something like this? It's the closest I can get. (And this time I even got help, lol, I suck at math)
colNum = (Cursor.Position.X / charWidth) + this.stormParent.HorizontalScroll.Value;
|
|
|
|
|
Congratulations are in order.
When a formula is correct, you can read it and see it makes sense, in this case, using horizontal character positions as a unit of measure, it says:
the column you're at equals your cursor position (in pixels) divided by the width of a character (in pixels, we divide to get rid of those pixels), plus whatever number of characters that have been scrolled away.
So now you have two ways to come up with a formula:
- start from an existing one and invert it, by moving annoying terms and factors to the other side (undoing multiplication by a division, addition by a subtraction);
- or write down a logical statement, as in the above example.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Yay, I did something correct!
However, it still seems a little off, for example what should have given me char 1, line 1, give sme char 18, line 24. This is what I have:
colNum = (Cursor.Position.X / charWidth) + this.stormParent.VerticalScroll.Value;
lineNum = (Cursor.Position.Y / (int)this.stormParent.Font.Size) + this.stormParent.HorizontalScroll.Value;
As I said, math isn't my strongest side xD I'm more at app design and such.
|
|
|
|
|
Hi,
Cursor.Position gives a location in screen coordinates, i.e. relative to the top left corner of the screen (as it doesn't take any Control parameter, all it can do is return absolutes).
You probably want relative to your control; there is a PointToClient() method to transform them.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hey dude, thanks! It seems like it gives the totally perfect coords (increases correctly and so on), however now it says char 15, line 18 instead of char 1, line 1. :s
Point p = this.PointToClient(Cursor.Position);
colNum = (p.X / charWidth) + this.stormParent.VerticalScroll.Value;
lineNum = (p.Y / (int)this.stormParent.Font.Size) + this.stormParent.HorizontalScroll.Value;
Btw: can you tell if this is correct?:
The original RichTextBox redraws the whole text every time a color has changed, so if I have 5000 words it redraws 5000 times every time I edit the text. Now, the reason this is more efficient, is because the text natively is given the intended colors instead of changing it when it has been drawn already. Now, to highlight a line, I'd use a code somewhat like this:
namespace Storm.TextBox
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
#region Keyword class
public class Keyword
{
private string _kword = "";
private Color _kcol = SystemColors.ControlText;
private Font _kfont = new Font(new Font("Courier New", 10), FontStyle.Regular);
public Keyword(string keyword, Color color, Font font)
{
_kword = keyword;
_kcol = color;
_kfont = font;
}
public string Keyword
{
get { return _kword; }
set { _kword = value; }
}
public Color KeywordColor
{
get { return _kcol; }
set { _kcol = value; }
}
public Font KeywordFont
{
get { return _kfont; }
set { _kfont = value; }
}
}
#endregion
public class HighlightingSetup
{
#region Members
private TextEditor stormParent = null;
private Dictionary<string, Keyword> keywordDic;
#endregion
#region Methods
public void Add(string keyword, Color color, FontStyle fontstyle)
{
keywordDic.Add(keyword, new Keyword(keyword, color,
new Font(stormParent.Font, fontstyle)));
}
public Keyword KeywordFromString(string keyword)
{
if (keywordDic.ContainsKey(keyword))
return keywordDic[keyword];
return null;
}
public void Remove(string keyword)
{
if (keywordDic.ContainsKey(keyword))
keywordDic.Remove(keyword);
}
#endregion
public HighlightingSetup(TextEditor parent)
{
stormParent = parent;
keywordDic = new Dictionary<string, Keyword>();
}
}
}
private Color[] kColors;
private Font[] kFonts;
private char[] Splitters = { ' ', '(', ')', '[', ']', '{', '}', '!', '"',
'#', '$', '%', '&', '/', '=', '?', '+', '-',
'*', '^', '_', ':', ';', '<', '>', '\\'};
private string tempLine = "";
private int maxKeywordCount = 0;
private void HighlightLine(int lineNum)
{
string splitString = doc.GetLineFromIndex(lineNum);
string[] keywords = splitString.Split(Splitters);
int keywordCount = 0;
foreach (string keyword in keywords)
{
Keyword kw = setup.KeywordFromString(keyword);
kColors[keywordCount] = kw.KeywordColor;
kFonts[keywordCount] = kw.KeywordFont;
tempLine += keyword + "+";
keywordCount++;
}
maxKeywordCount = keywordCount;
tempLine = tempLine.Substring(0, tempLine.Length - 1);
this.Invalidate();
}
private void onRepaint(object sender, PaintEventArgs e)
{
string splitString = tempLine;
string[] keywords = splitString.Split('+');
int keywordCount = 0;
foreach (string keyword in keywords)
{
Keyword kw = setup.KeywordFromString(keyword);
Color kcolor = kw.KeywordColor;
Font kfont = kw.KeywordFont;
StringFormat strFormat = new StringFormat(StringFormatFlags.NoWrap);
Rectangle posRect = new Rectangle(0, 0, 0, 0);
ControlPaint.DrawStringDisabled(e.Graphics, keyword, kfont, kcolor,
posRect, strFormat);
ControlPaint.DrawStringDisabled(e.Graphics, " ", this.Font, kcolor,
posRect, strFormat);
keywordCount++;
}
}
|
|
|
|
|
Hi,
I haven't read all that in detail, here are some comments for you:
1. you seem to create a new Font for each new keyword; that is a waste, most of those fonts would be identical (maybe there is a regular and a bold, but not dozens of variations)
2. your "parser" seems to split a line by all kinds of special symbols, which will chop a line in many parts, e.g. two-character operators will be split, which isn't necessary (and maybe not what you want, you probably will end up coloring operators too)
3. your "parser" seems ignorant about digits. Not sure that will work well.
4. you are parsing and storing results in arrays. Why? Arrays are trouble, since you must declare them (you forgot that part) and set an arbitrary size. Sooner or later someone will enter a line that exceeds your parsing capabilities. If you must store an unknown number of items, use a List. However there is no need to store the data, you can paint line parts as you go, while parsing! Yes my parser sits inside my Paint handler, however it only parses the visible lines.
I'm sure the list isn't complete however you have to come up with ideas and critical thinking yourself.
One advice: don't keep adding code while existing code isn't compiling/running/running almost correctly. It may soon grow well above your head and become unmanageable.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, thanks for those tips
I'm going on vacation today, and I'll be home in 3 weeks or so. So I won't reply in that time, sorry.
When I get back I'll update my code
|
|
|
|
|
Hey Luc,
I'm back! I'm going to update my parser tomorrow, but that was simply a demo
Now, could you please tell me why this:
Point p = this.PointToClient(Cursor.Position);
colNum = (p.X / charWidth) + this.stormParent.VerticalScroll.Value;
lineNum = (p.Y / (int)this.stormParent.Font.Size) + this.stormParent.HorizontalScroll.Value;
Gives me wrong X and Y locations? It increases and decreases the X and Y locations correctly, however it gives me 15x and 18y when it should've given me 1x and 1y.
Thanks
|
|
|
|
|
Vestras wrote: Gives me wrong X and Y locations
Then you did something wrong. Learn to debug, i.e. observe the details, formulate a hypothesis, check its correctness, and act on it.
When wrong, try again.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Is it possible to get a copy of your syntax coloring control?
Everything makes sense in someone's mind
|
|
|
|
|
I would really like to take a look at your source if you could post it or send me an email i would really appreciate it.
|
|
|
|
|
I'm passing an array of structs to an unmanaged method and just want to make sure that what I'm doing is correct.
Let's assume I have a struct defined as
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyStruct
{
public MyStruct(string Name, uint Index, MyEnum flag)
{
}
[MarshalAs(UnmanagedType.LPTStr)]
public string mName;
public uint sIndex;
[MarshalAs(UnmanagedType.U4)]
public MyEnum mflag;
}
where MyEnum is some enum deriving from uint.
The calling code creates an array of these structs like this:
MyStruct [] structs =
{
new MyStruct("BEN", 0, MyEnum.FIRST),
new MyStruct("VAL", 1, MyEnum.FOURTH),
new MyStruct("ROG", 2, MyEnum.SECOND)
};
I then pass this array to the managed function which looks like this:
public static extern int SetMyStructs([MarshalAs(UnmanagedType.LPArray)] MyStruct [] structs)
which is supposed to map to the unmanaged function of:
int SetMyStructs(MyStruct * structs)
SetMyStructs is returning values indicating that the function is not executing correctly. Is passing an array of structs containing strings and integers possible and if so am I using the correct marshalling attributes? I just want to eliminate this array of structs as a possible reason for the failing function.
|
|
|
|
|
I have a ToolStripTextBox, I'd like to customize such that when there's no text in it, it draws some background text, in different color that's not editable. Once the user starts typing this goes away. The OnPaint method doesn't cut it, further looking shows that the ToolStripTextBox apparently hosts an internal TextBox control. The ToolStripTextBox.Paint handler (unsurprisingly) does nothing. The docs for the TextBox class claim that the Paint handler is not to be used. Is it not possible to do this in .Net?
|
|
|
|
|
Not that it helps you, but someone asked pretty much the same question on MSDN[^] in 2005.
He's still waiting for an answer!
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
Sigh. What a bunch of dolts. I have the nasty suspicion that I'll have to resort to creating my own custom ToolStrip control and create a custom TextBox with WM message hooks to defeat the idiocy of Redmond's brain dead developers.
This was actually relatively *EASY* to do in MFC. Double fail for .Net.
|
|
|
|
|
The .NET TextBox isn't .NETified. It's just a .NET wrapper around the standard TextBox.
Trying to do anything with it is a PITA. Alot of the stuff you can do with many controls, although the properties/methods are there, they just don't work as expected. Can't give specifics to back this up because I've blocked my last experience of this out of my brain as it was painful!
Someone (MS?) really needs to make a proper .NET TextBox, I did start myself - but it was bloody hard work and I gave up!
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Hi Devs,
I am trying to return a string which goes out of scope.
public static string test(Guid ID)
{
if (a == n )
{
string abc = x.group;
}
return abc
}
What would be the best way to return the abc string because as it is declared in bracket, it gets out of scope.
Thank You
|
|
|
|
|
Either by returning from inside the if statement like this:
public static string test(Guid ID)
{
if (a == n )
{
string abc = x.group;
return abc;
}
else
{
return String.Empty;
}
}
Or by creating the string and setting a default value first:
public static string test(Guid ID)
{
string abc = String.Empty;
if (a == n )
{
abc = x.group;
}
return abc;
}
Simon
|
|
|
|
|
|
Hi,
if that poses a problem, do yourself a favor: go to a bookstore, look at some tutorials on C#, buy one and study it.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
I don't agree with you here Lucy.
You learn more when you do stuff rather than reading it. So practical plus theory is a good way.
|
|
|
|
|