Click here to Skip to main content
13,044,705 members (51,799 online)
Rate this:
Please Sign up or sign in to vote.
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:

private extern static int GetCaretPos(out Point p);
private extern static int SetCaretPos(int x, int y);
private extern static bool ShowCaret(IntPtr hwnd);
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);

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!

Posted 8-Mar-13 18:00pm
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

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.
PIEBALDconsult 9-Mar-13 16:55pm
"it doesn't work properly (returns an inexact position)."

Is not clear.
supernorb 9-Mar-13 17:36pm
How clearer do you want? It should work by its name (GetCaretPos) but it doesn't work correctly. Please review my original post. I mentioned that "the more lines the textbox has, the more different it is between the Position of the real caret and the position obtained by using GetCaretPos. As I said, the X-coordinate is OK but the Y-coordinate obtained by using GetCaretPos is always greater the the real Y-coordinate. (the two are equal when the textbox has only 1 line). Please read it carefully. Thanks!
PIEBALDconsult 9-Mar-13 18:31pm
You may think you are being clear, but you are not.

"is always greater"

Lacks detail. How much greater? Examples would be great.
supernorb 10-Mar-13 9:49am
greater or equal (equal only when the textbox has 1 line), I forgot saying that the caret is supposed to be at the end of the text in textbox. I don't know how to express how greater it is between a line and another right before it, just a little, but if the textbox has about 4 lines, the difference between the first line and the fourth is about 2/5 of font height. Why don't you try my code above to see it in action? the code needs only a textbox defined. I think GetCaretPos may not wrong but if so, SetCaretPos will be the wrong one. Thanks!
PIEBALDconsult 10-Mar-13 13:57pm
"the caret is supposed to be at the end of the text in textbox"

It isn't always.

"font height"

Measured how? And Why?

"Why don't you try my code"

Homey don't play dat.

Why are you using SetCaretPos anyway? What is you are trying to do?
supernorb 10-Mar-13 15:10pm
It isn't always but that's the case I want to test, why? because that's the case the differnce is maximum. All the measurement you were asking for is by eyes and intuitive feeling, not exact but nearly so. Again, if you don't understand my problem. I'll rephrase it as the following, I have a textbox with some lines (in fact not real lines, because it has no return characters but it's wrapped), the real caret is currently at the end of the text in the textbox. Now by someway, let's get the position of that caret, save somewhere, hide the textbox (the real caret is also hidden), Now, let's create a new caret using CreateCaret, by default its position is (0,0), then please help me how to locate that new caret at the same postion of the hidden caret???? By using any possible. Whereas GetCaretPos and SetCaretPos seems to the most suitable API functions for this but somehow I can't make them work, my code has already been posted for seeing, I've done everything to help others understand my problem. I hope this explanation of mine will help you understand the problem well, if not I have to surrender, this is also asked in stackoverflow and there is currently no reply. Thanks.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

If I ignore your rather bizarre test and use something simpler I can't see anything wrong.

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.

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
PIEBALDconsult 10-Mar-13 21:27pm
Uh huh. Why? What is the purpose of the "fake" TextBox? What are you trying to do?
supernorb 10-Mar-13 21:36pm
That's what I want, for example, when user holds left mouse down on the textbox, it is hidden and the fake starts working, the user can move the fake like as move the real textbox with a higher performance (especially when the textbox has a transparent background), then after the user releases the mouse, the fake is hidden and the real textbox shows again. Thanks.
PIEBALDconsult 10-Mar-13 22:06pm
If it's just to improve dragging the TextBox, then why bother with the caret at all?
supernorb 12-Mar-13 19:18pm
As I said, that's a solution I could think of, I have no other choice, please notice that it's a Transparent textbox, if you have another solution better, I would like to see how it is (some link is OK), thanks.
PIEBALDconsult 12-Mar-13 19:54pm
"that's a solution"

But to what? What purpose will the caret serve? Why go to all this trouble?

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

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web02 | 2.8.170713.1 | Last Updated 10 Mar 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100