2010-05-07 6 views
2

Je crée un contrôle WinForms en C# (en utilisant VS2008, .net 3.5) qui permet la saisie de texte. J'ai importé les fonctions de l'API Win32 nécessaires de User32.dll pour afficher le signe d'insertion de Windows normal et tout cela fonctionne très bien, mais il n'affiche pas exactement comment je l'aimerais.Couper le curseur dans un programme C#

Le texte est affiché sur le contrôle avec une bordure vierge et j'utilise Graphics.SetClip() pour laisser cette marge libre. Je veux que le caret soit découpé dans la même région, mais comme je ne le peins pas et qu'il n'y a pas de fonction API évidente pour définir une région de découpage, je ne vois aucun moyen de le faire. Ai-je manqué quelque chose d'évident?

Le curseur est clipsé à l'intérieur de la commande dans laquelle il est dessiné. Je suis donc conscient qu'une solution pourrait être de placer le texte dans un sous-contrôle séparé sans bordure. Cependant, s'il y a un moyen plus simple que de redéfinir cette partie du contrôle, j'aimerais d'abord le chercher.

Merci d'avance pour toute aide!

+0

Avez-vous dérivé votre contrôle de TextBox ou dessinez-vous tout vous-même? –

+0

C'est tiré à partir de zéro. Malheureusement, Textbox est un wrapper raisonnablement mince autour du contrôle Win32 non managé afin que les modifications que vous pouvez apporter à la fonctionnalité sont un peu limitées. –

Répondre

0

Alors, ai-je bien compris que votre problème est que le curseur par défaut "saigne" dans votre zone de marge?

Je pense que votre meilleure option est de placer le texte sur un secondaire ou un sous-contrôle comme vous l'avez mentionné. Deux autres options que vous pourriez envisager, qui pourraient répondre à vos besoins

1- Utilisez CreateCaret pour créer un curseur plus petit que celui qui vous convient dans la région écrêtée. Bien sûr, vous devez toujours vous assurer que vous ne placez pas le curseur dans l'espace frontalier.

[DllImport("user32", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
private extern static bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight); 

// Create a caret which is 2 pixels wide by 8 high 
CreateCaret(theControl.Handle, IntPtr.Zero, 2, 8); 

2- Une autre option qui est probablement moins utile, mais qui va couper le curseur, donc je vais le mentionner. Utilisez Control.Region pour découper toute la fenêtre dans la zone de découpe dont vous avez besoin. Bien sûr, cela va également couper votre zone frontalière qui pourrait ou ne pourrait pas être un problème pour vous. Cela dépend si l'arrière-plan est d'une telle nature qu'il n'introduit pas sur la frontière, fondamentalement la frontière sera transparente. Mais à la fin de la journée, je pense que l'option d'utiliser un sous-contrôle fournirait le plus de contrôle.

+0

Merci pour vos suggestions. Je pense que le sous-contrôle sera l'option la plus simple pour le moment. –

1

Que diriez-vous de définir la zone que vous utilisez actuellement avec SetClip() en tant que zone client vrai Windows? (en remplaçant WM_NCCALCSIZE).

+0

C'est une idée intéressante. Mais je ne peux pas faire ressortir de la documentation que j'ai lu exactement ce que la sortie de cette fonction est utilisée. Par exemple, si j'exclus la partie du contrôle sur laquelle se trouve la barre de défilement, sera-t-elle encore redessinée si nécessaire? –

+1

Vous devez répondre à NC_PAINT et dessiner quelque chose en dehors de la zone client de la fenêtre pour laquelle vous remplacez WM_NCCALCSIZE. (http://www.codeproject.com/KB/edit/PaddedRichTextBox.aspx) –

+0

@AlexK., c'était vraiment utile, merci! – nekavally

Questions connexes