The following code avoids the Richtextbox of being focused. So the user can not edit the text or select it. To avoid the Cursor of changing to IBeam I also also catch the SETCURSOR message. But the Problem is, the richtextbox also contains links and I want the cursor to change to Hand, if I move the mouse over a link. So I have to distinguish between IBeam and Hand. For this I could not find a solution, altough I think this can not be so difficult.
Const WM_SETFOCUS = &H0007
Const WM_KILLFOCUS = &H0008
Const WM_SETCURSOR = &H0020
Const WM_NULL = &H0000
Protected Overrides Sub WndProc(ByRef _M As Message)
Select Case _M.Msg
Case WM_SETFOCUS, WM_KILLFOCUS
_M.Msg = WM_NULL
Case WM_SETCURSOR
'Here I need your help: How can I check the cursor?
'If Cursor is IBeam Then
' _M.Msg = WM_NULL
'End If
End Select
MyBase.WndProc(_M)
End Sub
This is for C# but you should be able to convert it:
protected override void OnMouseMove(MouseEventArgs e)
{
if (SelectionLength > 0)
{
int position = GetCharIndexFromPosition(e.Location);
if (position > SelectionStart && position < SelectionStart+SelectionLength)
this.Cursor = Cursors.Arrow;
else
this.Cursor = Cursors.IBeam;
}
base.OnMouseMove(e);
}
Related
I have a program that loads a checked list box, then the user selects the items they want and selects a button to say they are done. The checked items are read in a contiguous string with a newline "\n" at the end of each string added. My problem is everything works ok except the newline "\n", and I don't know why.
Code
private: System::Void bntSelected_Click(System::Object^ sender, System::EventArgs^ e) {
int numSelected = this->checkedListBox1->CheckedItems->Count;
if (numSelected != 0)
{
// Set input focus to the list box.
//SetFocus(lstReceiver);
String^ listBoxStr = "";
// If so, loop through all checked items and print results.
for (int x = 0; x < numSelected; x++)
{
listBoxStr = listBoxStr + (x + 1).ToString() + " = " + this->checkedListBox1->CheckedItems[x]->ToString() + "\n";
}
lstReceiver->Items->Add(listBoxStr);
}
}
The string is being formed correctly, but the ListBox control doesn't show newlines in its list items - each item is pushed onto a single line. You can see this by debugging, or by adding a Label to the form with AutoSize set to false - the label will show the newline(s) in the string properly.
Related (C#): How to put a \n(new line) inside a list box?
Instead of ā\nā, try ā\r\nā. This may be a windows thing.
I'm using Settings feature of Visual Studio with string type and user scope.
I try to list last used recent files on my menu item but i think my approach not seems good for coding approach too much if else statement i used.
Is there any way to get it with better approach ?
Public Sub addRecentUsedFiles(recentFile As String)
If recentFile <> My.Settings.recent1 Then
If recentFile <> My.Settings.recent2 Then
If recentFile <> My.Settings.recent3 Then
If recentFile <> My.Settings.recent4 Then
My.Settings.recent5 = My.Settings.recent4
My.Settings.recent4 = My.Settings.recent3
My.Settings.recent3 = My.Settings.recent2
My.Settings.recent2 = My.Settings.recent1
My.Settings.recent1 = recentFile
Else
My.Settings.recent4 = My.Settings.recent3
My.Settings.recent3 = My.Settings.recent2
My.Settings.recent2 = My.Settings.recent1
My.Settings.recent1 = recentFile
End If
Else
My.Settings.recent3 = My.Settings.recent2
My.Settings.recent2 = My.Settings.recent1
My.Settings.recent1 = recentFile
End If
Else
My.Settings.recent2 = My.Settings.recent1
My.Settings.recent1 = recentFile
End If
End If
I recommend a queue of fixed size for this approach. See the data structure defined here. I have it below but made a lot of changes to it.
Fixed size queue which automatically dequeues old values upon new enques
In your case, you would the data type of String and set the limit to 5.
I've included the base code, removed the concurrency, and added a Contains method. Also added an enumerator so you can access the data.
[Serializable()]
public class FixedSizedQueue<T>
{
System.Collections.Generic.Queue<T> q = new System.Collections.Generic.Queue<T>();
public int Limit { get; set; }
public void Enqueue(T obj)
{
q.Enqueue(obj);
while (q.Count > Limit) q.Dequeue() ;
}
public bool Contains(T obj)
{
return q.Contains(obj);
}
public Queue<T>.Enumerator GetEnumerator()
{
return q.GetEnumerator();
}
}
Then how you would use it, assuming My.Settings.Recent was of this type of String, you assigned the limit of 5 and the My.Settings.Recent was not null.
if ( ! My.Settings.Recent.Contains(recentFile) )
My.Settings.Recent.Enqueue(recentFile);
Here's another example of writing data to the object, that only after the code has "6" to "10".
FixedSizedQueue<string> t = new FixedSizedQueue<string>();
t.Limit = 5;
for (int i = 0; i <= 10; i++)
if (! t.Contains(i.ToString()))
t.Enqueue(i.ToString());
Your easiest approach will be to write the Recently used files(file names) to a text file.Sample code :
File.WriteAllText("C:\test.txt","last file name")
Now, if you use the WriteAllText method,it will rewrite(or create) the text file.If you want to write to the text file from different places,you can simply use File.AppendText method :
File.AppendText("C:\test.txt","last file name" + Environment.NewLine)
Then, if you want to retrieve the file names from the text file,you can simply create a List(of String) which will read(and store data from) the text file :
Dim readFile As New List(Of String)(File.ReadAllLines("C:\test.txt")
Now you have a list which has successfully stored each line from the text file as a separate item.You easily iterate through the list and do whatever you want with it,such as :
For Each Item In readFile
ComboBox1.Items.Add(Item)
Next
Hope this helps to enrich your knowledge :)
I am trying to animate an image based on the select pivoted items position.
I am currently using the ManipulationDelta event to try and see which direction the user is swiping so that I can fade out or fade in an animated image based on the position of the pivot item.
My problem is with the ManipulationDelta event, this event is only ever called once on a pivot item, regardless of how much manipulation of the pivot control is occurring.
Does anyone know a way to make it so the pivot items ManpulationDelta event is constantly called when it is being manipulated?
Probably your Pivot is intercepting further events. You may try to do such a thing - disable Pivot (then your Manipulations should work) and change PivotItems manually for example using TouchPanel and Touch.FrameReported. Sample code:
public MainPage()
{
InitializeComponent();
myPivot.IsHitTestVisible = false; // disable your Pivot
Touch.FrameReported += Touch_FrameReported;
TouchPanel.EnabledGestures = GestureType.HorizontalDrag;
}
TouchPoint first;
private const int detectRightGesture = 20;
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
TouchPoint mainTouch = e.GetPrimaryTouchPoint(this);
if (mainTouch.Action == TouchAction.Down)
first = mainTouch;
else if (mainTouch.Action == TouchAction.Up && TouchPanel.IsGestureAvailable)
{
if (mainTouch.Position.X - first.Position.X < -detectRightGesture)
{
if (myPivot.SelectedIndex < myPivot.Items.Count - 1) myPivot.SelectedIndex++;
else myPivot.SelectedIndex = 0;
}
else if (mainTouch.Position.X - first.Position.X > detectRightGesture)
{
if (myPivot.SelectedIndex > 0) myPivot.SelectedIndex--;
else myPivot.SelectedIndex = myPivot.Items.Count - 1;
}
}
}
In the Winforms RichTextBox control I have previously used the GetLineFromCharIndex method and the GetFirstCharIndexOfCurrentLine to work out the start and end points of the typed text on he current line.
I am struggling with the new RichTextBox control in Silverlight 4 as there doesn't appear to be equivalent methods. GetPositionFromPoint is available but seems a but clunky.
Cheers.
Updated...I have gone someway to making this work but this requires me to use the Select method of the control, this feels very wrong...
private string GetCurrentLine()
{
TextPointer prevSelStart = richTextBox1.Selection.Start;
Point lineStart = new Point(0, prevSelStart.GetCharacterRect(LogicalDirection.Forward).Y);
TextPointer prevSelEnd = richTextBox1.Selection.End;
TextPointer currentLineStart = richTextBox1.GetPositionFromPoint(lineStart);
//need to find a way to get the text between two textpointers
//other than performing a temporary selection in the rtb
richTextBox1.Selection.Select(currentLineStart, prevSelStart);
string text = richTextBox1.Selection.Text;
//revert back to previous selection
richTextBox1.Selection.Select(prevSelStart, prevSelEnd);
return text;
}
I don't think you can't avoid the selection, it's a proper way to do it (the "selection" is just a logical one), but you can avoid GetPositionFromPoint with TextPointer.GetNextInsertionPosition(LogicalDirection ): Start from richTextBox1.Selection.Start and move towards the beginning of the line (char != '\n')
I've needed to figure out when I was on the top line or bottom line of the RTB. To do this I used the GetCharacterRect methods then compared the tops to see if it was on the last line or first line.
You could do the same and use a text pointer to move through the text and number of times the tops don't match.
Here's code to see if the cursor is on the first or last lines:
private bool IsCursorOnFirstLine()
{
TextPointer contentStart = this.ContentStart;
TextPointer selection = this.Selection.End;
Rect startRect = contentStart.GetCharacterRect(LogicalDirection.Forward);
Rect endRect = selection.GetCharacterRect(LogicalDirection.Forward);
return startRect.Top == endRect.Top;
}
private bool IsCursorOnLastLine()
{
TextPointer start = this.Selection.Start;
TextPointer end = this.ContentEnd;
Rect startRect = start.GetCharacterRect(LogicalDirection.Forward);
Rect endRect = end.GetCharacterRect(LogicalDirection.Backward);
return startRect.Top == endRect.Top;
}
I have a textArea and a list. When a user double clicks a list item, the label of the selected item should be inserted into the textarea. When a text is selected in the textArea, it should be replaced, otherwise the text just needs to be inserted into the existing text at the caret point.
I've managed to get the text and everything, I just can't manage to insert it at the caret point. Does anyone know how to do this?
It's actually not JavaScript but Adobe Flex 3. Thanks for the help though, it did push me in the right direction. This is the way its done in Flex 3:
var caretStart:int = textArea.selectionBeginIndex;
var caretEnd:int = textArea.selectionEndIndex;
textArea.text = textArea.text.substring(0,caretStart)
+ newText
+ textArea.text.substr(caretEnd);
The accepted answer works great if you do not have existing HTML formatting. In my case, I inserted a new button into the editor that the user could click to put in a key word. I kept losing all HTML formatting until I dug around in the actual class and sided with a TextRange object:
public function keyWord_Click(event:Event) : void
{
var caretStart:int = txtEditor.textArea.selectionBeginIndex;
var caretEnd:int = txtEditor.textArea.selectionEndIndex;
var newText : String = "[[[KEYWORD]]]";
var tf:TextRange = new TextRange(txtEditor,true,caretStart,caretEnd);
tf.text = newText;
}
The nice thing about this approach is, you can also apply conditional formatting to that TextRange object as needed.
You can use txtarea.selectionStart and txtarea.selectionEnd to get Selected text position.
After that, You delete txt and add new selected text.
I don't known much about Javascript, so I wrote it for U.
You can search on google with keywords:
"Javascript Selected Text TextArea"
"Javascript add text at position"
Sample code:
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA/NETSCAPE support
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
caretPos = doGetCaretPosition(myField);
alert(caretPos);
setCaretPosition(myField,caretPos-3);
}