2010-05-14 7 views
9

J'ai un TextBox que j'autorise la rotation de mes utilisateurs. Mais ce que je voudrais pour mes utilisateurs est d'avoir leur Cursor tourner dans le même angle que le TextBox a été tourné à. Par exemple, si elles ont tourné le TextBox à 28 °, alors lorsque le Cursor entre TextBox le Cursor devrait également se tourner à 28 °.Rotation du curseur selon TextBox pivoté

Toute aide sera grandement appréciée.

Merci :)

+0

Peut-être ... Puisque le "curseur" est lui-même un contrôle réel, il pourrait être tourné de la même manière que je fais tourner mes autres contrôles. Hmmm, je vais essayer cela et republier. –

+0

Nup ... Ne fonctionnait pas! Argh! –

+0

Quand vous dites curseur, voulez-vous dire le curseur de la souris à savoir. Je me réfère au Caret qui est affiché pour indiquer où le caractère suivant sera inséré/effacé etc. Je demande seulement parce que j'entends souvent le mot curseur pour impliquer les deux. Je suppose que vous voulez dire le curseur de la souris parce que le curseur clignote, mais je pensais que je demanderais de toute façon. –

Répondre

8

Vous pouvez faire pivoter votre curseur en utilisant la classe System.Drawing.Icon de WinForms en combinaison avec la capacité de rotation bitmap de WPF. Pour ce faire, vous devez charger l'icône, la convertir en BitmapSource, utiliser Image et RenderTargetBitmap pour la faire pivoter, la convertir en icône, la sauvegarder et enfin mettre à jour les octets 2, 10 et 11 en faire un .cur au lieu d'un .ico.

Voici ce que le code ressemble à:

public Cursor GetRotatedCursor(byte[] curFileBytes, double rotationAngle) 
{ 
    // Load as Bitmap, convert to BitmapSource 
    var origStream = new MemoryStream(curFileBytes); 
    var origBitmap = new System.Drawing.Icon(origStream).ToBitmap(); 
    var origSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(origBitmap.GetHBitmap()); 

    // Construct rotated image 
    var image = new Image 
    { 
    BitmapSource = origSource, 
    RenderTransform = new RotateTransform(rotationAngle) 
    }; 

    // Render rotated image to RenderTargetBitmap 
    var width = origBitmap.Width; 
    var height = origBitmap.Height; 
    var resultSource = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); 
    resultSource.Render(image); 

    // Convert to System.Drawing.Bitmap 
    var pixels = new int[width*height]; 
    resultSource.CopyPixels(pixels, width, 0); 
    var resultBitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppPargb); 
    for(int y=0; y<height; y++) 
    for(int x=0; x<width; x++) 
     resultBitmap.SetPixel(x, y, Color.FromArgb(pixels[y*width+x])); 

    // Save to .ico format 
    var resultStream = new MemoryStream(); 
    new System.Drawing.Icon(resultBitmap.GetHIcon()).Save(resultStream); 

    // Convert saved file into .cur format 
    resultStream.Seek(2); resultStream.WriteByte(curFileBytes, 2, 1); 
    resultStream.Seek(10); resultStream.WriteByte(curFileBytes, 10, 2); 
    resultStream.Seek(0); 

    // Construct Cursor 
    return new Cursor(resultStream); 
} 

Si vous voulez éviter la boucle, vous pouvez le remplacer par un petit morceau de code USAFE pour appeler le constructeur System.Drawing.Bitmap qui prend des données d'initialisation :

fixed(int* bits = pixels) 
    { 
    resultBitmap = new System.Drawing.Bitmap(width, height, width, System.Drawing.Imaging.PixelFormat.Format32bppPargb, new IntPtr(bits)); 
    } 

Vous devrez l'appeler à chaque fois que votre rotation TextBox change. Cela peut être effectué à partir du code qui fait pivoter votre TextBox ou à partir d'un PropertyChangedCallback sur une valeur qui est liée à la rotation de la TextBox.

+0

Wow! Cela fonctionne parfaitement. Merci beaucoup d'avoir pris le temps d'écrire ceci. Brillant! –

+0

De rien. C'était un petit puzzle amusant. Je suis content que mon code ait fonctionné. –

+0

Je reçois diverses erreurs de syntaxe. – SepehrM

0

mmm Je ne suis pas sûr ... mais étant donné que le curseur est géré par Windows .. je suppose que vous devez cacher le curseur lorsqu'il pénètre dans la zone de texte et d'en tirer votre propre (ce qui serait facile à faire pivoter puisque vous faites tourner les autres contrôles).

Heh, recherche sur Google pour une façon de le faire, le premier résultat était naturellement, vous voudrez peut-être vérifier la réponse acceptée (si vous utilisez WPF):

Custom cursor in WPF?

+0

Merci pour votre aide. :-) m'a sauvé beaucoup de futre heaches et le temps lol. –