Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# Win32 WinForm
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:
 
[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 8-Mar-13 19:00pm
supernorb2.6K
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

  Permalink  
v2
Comments
supernorb at 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 at 9-Mar-13 10:39am
   
Did the comments help any?
And you haven't explained your problem very well.
supernorb at 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 at 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 at 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 at 9-Mar-13 16:55pm
   
"it doesn't work properly (returns an inexact position)."
 
Is not clear.
supernorb at 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 at 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 at 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 at 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 at 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
good
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.
 
Alan.
  Permalink  
Comments
supernorb at 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 at 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 at 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 at 10-Mar-13 20:49pm
   
"calculate the position at which I want to locate the new caret"
 
But why?
supernorb at 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 at 10-Mar-13 21:27pm
   
Uh huh. Why? What is the purpose of the "fake" TextBox? What are you trying to do?
supernorb at 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 at 10-Mar-13 22:06pm
   
If it's just to improve dragging the TextBox, then why bother with the caret at all?
supernorb at 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 at 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
0 OriginalGriff 515
1 Maciej Los 349
2 Richard MacCutchan 220
3 BillWoodruff 209
4 Mathew Soji 160
0 OriginalGriff 8,654
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,639
3 Maciej Los 5,229
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 10 Mar 2013
Copyright © CodeProject, 1999-2014
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