Click here to Skip to main content
15,886,095 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to use GetCaretPos() Win32 Api to get the position of the caret of a TextBox (even when it's invisble), it seems to work OK if the TextBox has only 1 line. But the more lines it has, the more different the Y-coordinate of the caret (which is got from GetCaretPos()) is.
The Y-coordinate of the caret getting from GetCaretPos() is always great than the actual Y-coordinate of the caret (the more lines the TextBox has, the greater it is).

Could you please give me any solution for this?

Here is the code:

C#
[DllImport("user32")]
private extern static int GetCaretPos(out Point p);
[DllImport("user32")]
private extern static int SetCaretPos(int x, int y);
[DllImport("user32")]
private extern static bool ShowCaret(IntPtr hwnd);
[DllImport("user32")]
private extern static int CreateCaret(IntPtr hwnd, IntPtr hBitmap, int width, int height);
//Suppose I have a TextBox with a few lines already input.
//And I'll make it invisible to hide the real caret, create a new caret and set its position to see how the difference between them is.

private void TestCaret(){
   textBox1.Visible = false;//textBox1 is the only Control on the Form and has been focused.
   CreateCaret(Handle, IntPtr.Zero, 2, 20);
   Point p;
   GetCaretPos(out p);//Retrieve Location of the real caret (calculated in textBox1's coordinates)
   SetCaretPos(p.X + textBox1.Left, p.Y + textBox1.Top);
   ShowCaret(Handle);
}


As I said, anywhere the textBox1 is on the Form, when it's invisible, calling the method above will show a faked caret at the exact position of the real (hidden) caret, it works OK when textBox1 has only 1 line, but ... (I mentioned above).

Your help would be highly appreciated... Thanks!

VipHaLong
Posted

 
Share this answer
 
v2
Comments
supernorb 9-Mar-13 3:32am    
I'm sorry but the code from your link is almost the same to mine, except the Attribute for a user-defined structure of Point. And I have also tried that code but it couldn't help (the same to what the code of mine can do). Thanks!
PIEBALDconsult 9-Mar-13 10:39am    
Did the comments help any?
And you haven't explained your problem very well.
supernorb 9-Mar-13 12:55pm    
I think my problem was well explained, the code from the first link of yours is almost the same to my code, and the code from the second link seems to calculate the location of caret as indices (horizontal index and vertical index) not a Point structure as I want. Thanks!
PIEBALDconsult 9-Mar-13 13:55pm    
"I think my problem was well explained"

I don't; you don't say what you get or what you expect.
supernorb 9-Mar-13 15:06pm    
The first sentence of my question stated clearly, I want to use GetCaretPos to get the location/position of the real caret, but it doesn't work properly (returns an inexact position). In fact any other solution (without using GetCaretPos) is of course OK, I also post my code to help others understand the problem thoroughly.
If I ignore your rather bizarre test and use something simpler I can't see anything wrong.

C#
tbx.Click += new EventHandler(WhereIsTheCaret_Click);

private void WhereIsTheCaret_Click(object sender, EventArgs e) {
  Point p;
  GetCaretPos(out p);
  Debug.Print("Caret {0}, Index {1} IndexPos {2}",
    p, tbx.SelectionStart, tbx.GetPositionFromCharIndex(tbx.SelectionStart));
}


Wherever I click in a multiline TextBox the value of the Point obtained either from GetCaretPos or from the Selection are the same.

Alan.
 
Share this answer
 
Comments
supernorb 10-Mar-13 14:57pm    
The results from the both methods are the same doesn't mean it works properly. If possible, please help me create a new caret, get the position of the real caret and set that position for new caret, if the new caret is positioned exactly at the same position of the real caret, it works. As I said, we suppose to set the real caret at the end of the text in TextBox with about more 4 lines. Thanks.
Alan N 10-Mar-13 15:53pm    
I can't agree with that at all and would say that independent confirmation of the caret position is very good evidence of correct operation. What you haven't given is your code for calculating the required caret position. You could avoid your own calculation and the use of SetCaretPos by using Select(charIndex, 0) to do the actual setting. I think Select(TextLength, 0) would position the caret at the end of the text.
It doesn't seem to make any sense to set a caret position in a hidden textbox which cannot have input focus. Like Piebald said, what is it is that you are trying to do?
Oh, yes and check the returns from all of the window API calls that you use as all the caret method return a boolean value for success/failure.
supernorb 10-Mar-13 19:29pm    
The code I posted is clear that I used GetCaretPos to calculate the position at which I want to locate the new caret. I think any window has only 1 caret, it can have many textboxes but there is only 1 caret at a time (the caret will belong to the focused textbox), that's why some the Win32 api functions related to Caret such as GetCaretPos, SetCaretPos, GetCaretBlinkTime... don't have a Handle as an argument, the Handle here is understood as of the current process which calls the functions. So the caret here is of the form as well as of the textbox (if the textbox is focused), and that means hiding the textbox doesn't matter creating a new caret, this new caret is not of the hidden textbox, it is of the form. I'll try using some methods of TextBox instead, however as you said your code seems to show that GetCaretPos works like as using some methods of TextBox, I'm sure it doesn't work. There is something I can't understant here. I have thought of DPI problem, yes my computer is set to a high DPI (the normal is 96, but it's now 125). I'll try this then. Now, I'm very tired! Thanks.
PIEBALDconsult 10-Mar-13 20:49pm    
"calculate the position at which I want to locate the new caret"

But why?
supernorb 10-Mar-13 21:21pm    
You can imagine this context, there is a textbox on a form, it has a blinking caret of course, but now I want to create a faked textbox image when the textbox is invisible, however it doesn't have a caret blinking at the end, and that's why I have to create a new caret for the fake (of course also for the form), the new caret should be located at the exact position of the hidden caret. I hope now you understand. Thanks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900