Вращающийся курсор в соответствии с повернутым TextBox - PullRequest
10 голосов
/ 14 мая 2010

У меня есть TextBox, который я позволяю своим пользователям вращаться. Но то, что я ЛЮБЛЮ для своих пользователей, это чтобы их Cursor поворачивались на тот же угол, что и TextBox. Например, если они повернули TextBox на 28 °, то, когда Cursor входит, TextBox, Cursor также должен повернуться на 28 °.

Любая помощь будет принята с благодарностью.

Спасибо:)

Ответы [ 2 ]

9 голосов
/ 14 мая 2010

Вы можете вращать курсор, используя класс System.Drawing.Icon из WinForms в сочетании с возможностью поворота растрового изображения в WPF.

Способ сделать это - загрузить значок, преобразовать его в BitmapSource, использовать Image и RenderTargetBitmap, чтобы повернуть его, преобразовать обратно в Icon, сохранить его и, наконец, обновить байты 2, 10 и 11, которые делают это .cur вместо .ico.

Вот как выглядит код:

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

Если вы хотите избежать цикла, вы можете заменить его небольшим кусочком удобного кода, чтобы вызвать конструктор System.Drawing.Bitmap, который принимает данные инициализации:

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

Вам нужно будет вызывать это каждый раз, когда меняется ваш оборот TextBox. Это можно сделать либо из кода, который вращает ваш TextBox, либо из PropertyChangedCallback для значения, которое связано с вращением TextBox.

0 голосов
/ 14 мая 2010

ммм Я не уверен ... но так как курсор управляется Windows .. Я думаю, вам нужно будет скрыть курсор, когда он входит в текстовое поле, и нарисовать свой собственный (который будет легко вращаться, так как вы вращая другие элементы управления).

Хех, погуглил, как это сделать, первый результат был естественно от SO, вы могли бы проверить принятый ответ (если вы используете wpf):

Пользовательский курсор в WPF?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...