2010-05-14 14 views
9

Ho un TextBox che consente ai miei utenti di ruotare. Ma quello che mi piacerebbe per i miei utenti è di far ruotare il loro Cursor allo stesso angolo su cui è stato ruotato il TextBox. Ad esempio, se ruotano il valore da a 28 °, quando lo Cursor immette lo Cursor, lo Cursor deve ruotare anch'esso su 28 °.Cursore rotante in base a TextBox ruotato

Qualsiasi aiuto sarà molto apprezzato.

Grazie :)

+0

Forse ... Poiché il "Cursore" è di per sé un controllo effettivo, potrebbe essere ruotato nello stesso modo in cui sto ruotando gli altri controlli. Hmmm, proverò e riposto. –

+0

Nup ... Non ha funzionato! Argh! –

+0

Quando dici Cursore intendi il cursore del mouse, ad esempio. l'I Beam o stai facendo riferimento al Caret che viene visualizzato per indicare dove verrà inserito/cancellato il prossimo carattere, ecc. Chiedo solo perché io di dieci sento la parola cursore usata per implicare entrambi. Immagino tu intenda il cursore del mouse perché il cursore lampeggiante ruota, ma ho pensato di chiedere comunque. –

risposta

8

È possibile ruotare il vostro cursore usando la classe System.Drawing.Icon da WinForms in combinazione con la capacità di rotazione bitmap di WPF.

Il modo per fare ciò è caricare l'icona, convertirla in BitmapSource, utilizzare Image e RenderTargetBitmap per ruotarlo, convertirlo in un'icona, salvarlo e infine aggiornare i byte 2, 10 e 11 che rendilo un .cur invece di un .ico.

Ecco ciò che il codice è simile:

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); 
} 

Se si vuole evitare il loop, è possibile sostituirlo con un piccola porzione di codice USAFE chiamare il costruttore System.Drawing.Bitmap che prende i dati di inizializzazione :

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

Avrete bisogno di chiamare questo ogni volta che la rotazione del vostro TextBox cambia. Questo può essere fatto sia dal codice che ruota il tuo TextBox, o da un PropertyChangedCallback su un valore che è associato alla rotazione del TextBox.

+0

Wow! Funziona perfettamente. Grazie mille per aver dedicato del tempo a scrivere questo. Brillante! –

+0

Prego. E 'stato un piccolo puzzle divertente. Sono contento che il mio codice abbia funzionato davvero. –

+0

Ricevo vari errori di sintassi. – SepehrM

0

mmm non sono sicuro ... ma dal momento che il cursore è gestito da Windows .. Credo che si avrebbe bisogno di nascondere il cursore quando si entra nella casella di testo e disegnare il proprio (che sarebbe facile da ruotare poiché ruotate gli altri controlli).

Eh, Googling di un modo per fare questo, il primo risultato è stato naturalmente da SO, si potrebbe desiderare di controllare la risposta accettata (se si utilizza WPF):

Custom cursor in WPF?

+0

Grazie per questo. :-) Mi ha salvato un sacco di futre heaches e time lol. –