visual studio eventos evento derecho c# registry mouse accessibility

c# - studio - Cómo anular el tamaño máximo del mouse de 32x32 en Windows como este programa puede



mouse click c# (4)

Agregue estas importaciones a su clase:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad); [DllImport("user32.dll")] static extern bool SetSystemCursor(IntPtr hcur, uint id);

lea los artículos de LoadImage sobre LoadImage y SetSystemCursor , especialmente sobre los parámetros que utilizan.

Luego usa las funciones en tu código:

// "cursor.cur" - cursor image of any size you want // 2 == IMAGE_CURSOR (from Winuser.h) // cxDesired = 0 and cyDesired = 0, using original image size // 0x8010 == LR_DEFAULTCOLOR | LR_SHARED | LR_LOADFROMFILE (from Winuser.h) var ptr = LoadImage(IntPtr.Zero, "cursor.cur", 2, 0, 0, 0x8010); if(ptr != IntPtr.Zero) { SetSystemCursor(ptr, 32512); // 32512 == OCR_NORMAL (from Winuser.h) }

Me gustaría que mi programa pueda anular el tamaño máximo de mouse impuesto de 32x32, al igual que el programa en la imagen adjunta, el cursor que se muestra es 72x72. Esta es una captura de ProcMon muestra lo que sucede cuando cambian los cursores.

Sin embargo, si intento cambiar los valores de registro para los archivos del cursor y luego presionar los cambios con

SystemParametersInfo(SPI.SPI_SETCURSORS, 0, IntPtr.Zero, SPIF.SPIF_SENDCHANGE);

entonces el cursor cambiará, pero todavía está limitado al tamaño máximo de 32x32. ¿Cómo pudo este programa sortear esa restricción? Además, los cursores permanecen una vez que finaliza el programa, por lo que no puede ser algo que esté haciendo mientras se ejecuta, pero debe anular una configuración en algún lugar.

Gracias por su ayuda, no he podido encontrar NADA como esta en la red, así que ni siquiera sé si alguien tendrá la respuesta.

EDITAR: veo algún acceso a un archivo llamado C:/Windows/SysWOW64/Imageres.dll . Solo son lecturas, pero tal vez estos cursores estén almacenados aquí, o modifiquen este archivo de alguna manera. Pero pensé que podría hacer que alguien con más experiencia que yo vaya por el camino correcto.

EDIT 2: creo que los tamaños son dictados por las variables SM_CXCURSOR y SM_CYCURSOR. Si pudiera encontrar una manera de establecer esto, podría estar en el negocio. Voy a escribir un programa rápido para obtener esos valores en la PC con el programa en ejecución y el cursor del mouse enorme y ver qué devuelve ...

EDIT 3: no hay suerte; la PC con el cursor enorme devuelve 32x32 para SM_CXCURSOR y SM_CYCURSOR.


Resuelvo este problema usando el modo de intrueder. Suplemento, el API LoadImage no puede cargar.png. Use System.drawing.BitMap. Le gusta esto: Bitmap bmp = new Bitmap(str, true); IntPtr p = bmp.GetHicon(); SetSystemCursor(p, OCR_NORMAL); Bitmap bmp = new Bitmap(str, true); IntPtr p = bmp.GetHicon(); SetSystemCursor(p, OCR_NORMAL);


Si está trabajando con WPF, puede crear su propio cursor del mouse y asignarlo. Pero esto no es un cambio de cursor del mouse en todo el sistema. Aquí hay un código que haría el truco. En el siguiente código estoy creando un cursor de 50x50 píxeles. Puedes dibujar tu propia forma en RenderTargetBitmap

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Mouse.OverrideCursor = CreateCursor(50,50, Brushes.Gold, null); } Cursor CreateCursor(double rx, double ry, SolidColorBrush brush, Pen pen) { var vis = new DrawingVisual(); using (var dc = vis.RenderOpen()) { dc.DrawRectangle(brush, new Pen(Brushes.Black, 0.1), new Rect(0, 0, rx, ry)); dc.Close(); } var rtb = new RenderTargetBitmap(64, 64, 96, 96, PixelFormats.Pbgra32); rtb.Render(vis); using (var ms1 = new MemoryStream()) { var penc = new PngBitmapEncoder(); penc.Frames.Add(BitmapFrame.Create(rtb)); penc.Save(ms1); var pngBytes = ms1.ToArray(); var size = pngBytes.GetLength(0); //.cur format spec http://en.wikipedia.org/wiki/ICO_(file_format) using (var ms = new MemoryStream()) { {//ICONDIR Structure ms.Write(BitConverter.GetBytes((Int16)0), 0, 2);//Reserved must be zero; 2 bytes ms.Write(BitConverter.GetBytes((Int16)2), 0, 2);//image type 1 = ico 2 = cur; 2 bytes ms.Write(BitConverter.GetBytes((Int16)1), 0, 2);//number of images; 2 bytes } {//ICONDIRENTRY structure ms.WriteByte(32); //image width in pixels ms.WriteByte(32); //image height in pixels ms.WriteByte(0); //Number of Colors in the color palette. Should be 0 if the image doesn''t use a color palette ms.WriteByte(0); //reserved must be 0 ms.Write(BitConverter.GetBytes((Int16)(rx / 2.0)), 0, 2);//2 bytes. In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left. ms.Write(BitConverter.GetBytes((Int16)(ry / 2.0)), 0, 2);//2 bytes. In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top. ms.Write(BitConverter.GetBytes(size), 0, 4);//Specifies the size of the image''s data in bytes ms.Write(BitConverter.GetBytes((Int32)22), 0, 4);//Specifies the offset of BMP or PNG data from the beginning of the ICO/CUR file } ms.Write(pngBytes, 0, size);//write the png data. ms.Seek(0, SeekOrigin.Begin); return new Cursor(ms); } } } }


Usando SetSystemCursor es posible establecer un cursor en una imagen de un tamaño mucho más grande que el cursor estándar.

Aquí hay una clase que tengo para cambiar el tamaño de los cursores del sistema:

using System; using System.Drawing; using System.Reflection; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { class SystemCursors { [DllImport("user32.dll")] static extern bool SetSystemCursor(IntPtr hcur, uint id); enum CursorShift { Centered, LowerRight, } public static void SetSystemCursorsSize(int newSize) { ResizeCursor(System.Windows.Forms.Cursors.AppStarting, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.Arrow, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.Cross, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.Hand, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.Help, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.HSplit, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.IBeam, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.No, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.NoMove2D, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.NoMoveHoriz, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.NoMoveVert, newSize, CursorShift.LowerRight); ResizeCursor(System.Windows.Forms.Cursors.PanEast, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanNE, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanNorth, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanNW, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanSE, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanSouth, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanSW, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.PanWest, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.SizeAll, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.SizeNESW, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.SizeNS, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.SizeNWSE, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.SizeWE, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.UpArrow, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.VSplit, newSize, CursorShift.Centered); ResizeCursor(System.Windows.Forms.Cursors.WaitCursor, newSize, CursorShift.LowerRight); } private static void ResizeCursor(System.Windows.Forms.Cursor cursor, int newSize, CursorShift cursorShift) { Bitmap cursorImage = GetSystemCursorBitmap(cursor); cursorImage = ResizeCursorBitmap(cursorImage, new Size(newSize, newSize), cursorShift); SetCursor(cursorImage, getResourceId(cursor)); } public static Bitmap GetSystemCursorBitmap(System.Windows.Forms.Cursor cursor) { Bitmap bitmap = new Bitmap( cursor.Size.Width, cursor.Size.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(bitmap); cursor.Draw(graphics, new Rectangle(new Point(0, 0), cursor.Size)); bitmap = Crop(bitmap); return bitmap; } private static Bitmap Crop(Bitmap bmp) { //code from http://.com/a/10392379/935052 int w = bmp.Width; int h = bmp.Height; Func<int, bool> allWhiteRow = row => { for (int i = 0; i < w; ++i) if (bmp.GetPixel(i, row).A != 0) return false; return true; }; Func<int, bool> allWhiteColumn = col => { for (int i = 0; i < h; ++i) if (bmp.GetPixel(col, i).A != 0) return false; return true; }; int topmost = 0; for (int row = 0; row < h; ++row) { if (allWhiteRow(row)) topmost = row; else break; } int bottommost = 0; for (int row = h - 1; row >= 0; --row) { if (allWhiteRow(row)) bottommost = row; else break; } int leftmost = 0, rightmost = 0; for (int col = 0; col < w; ++col) { if (allWhiteColumn(col)) leftmost = col; else break; } for (int col = w - 1; col >= 0; --col) { if (allWhiteColumn(col)) rightmost = col; else break; } if (rightmost == 0) rightmost = w; // As reached left if (bottommost == 0) bottommost = h; // As reached top. int croppedWidth = rightmost - leftmost; int croppedHeight = bottommost - topmost; if (croppedWidth == 0) // No border on left or right { leftmost = 0; croppedWidth = w; } if (croppedHeight == 0) // No border on top or bottom { topmost = 0; croppedHeight = h; } try { var target = new Bitmap(croppedWidth, croppedHeight); using (Graphics g = Graphics.FromImage(target)) { g.DrawImage(bmp, new RectangleF(0, 0, croppedWidth, croppedHeight), new RectangleF(leftmost, topmost, croppedWidth, croppedHeight), GraphicsUnit.Pixel); } return target; } catch (Exception ex) { throw new Exception( string.Format("Values are topmost={0} btm={1} left={2} right={3} croppedWidth={4} croppedHeight={5}", topmost, bottommost, leftmost, rightmost, croppedWidth, croppedHeight), ex); } } private static Bitmap ResizeCursorBitmap(Bitmap bitmap, Size size, CursorShift cursorShift) { if (size.Width > 32) { //shifting must occur Bitmap intermediateBitmap = new Bitmap(64, 64); Graphics intermediateGraphics = Graphics.FromImage(intermediateBitmap); if (cursorShift == CursorShift.LowerRight) //place the mouse cursor in the lower right hand quadrant of the bitmap intermediateGraphics.DrawImage(bitmap, intermediateBitmap.Width / 2, intermediateBitmap.Height / 2); else if (cursorShift == CursorShift.Centered) intermediateGraphics.DrawImage(bitmap, intermediateBitmap.Width / 2 - bitmap.Width / 2, intermediateBitmap.Height / 2 - bitmap.Height / 2); //now we have a shifted bitmap; use it to draw the resized cursor //Bitmap finalBitmap = new Bitmap(intermediateBitmap, size); //normal quality Bitmap finalBitmap = new Bitmap(size.Width, size.Height); Graphics finalGraphics = Graphics.FromImage(finalBitmap); finalGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; finalGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; finalGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; finalGraphics.DrawImage(intermediateBitmap, 0, 0, finalBitmap.Width, finalBitmap.Height); return finalBitmap; } else { Bitmap newBitmap = new Bitmap(bitmap, size); return newBitmap; } } private static uint getResourceId(System.Windows.Forms.Cursor cursor) { FieldInfo fi = typeof(System.Windows.Forms.Cursor).GetField( "resourceId", BindingFlags.NonPublic | BindingFlags.Instance); object obj = fi.GetValue(cursor); return Convert.ToUInt32((int)obj); } private static void SetCursor(Bitmap bitmap, uint whichCursor) { IntPtr ptr = bitmap.GetHicon(); bool retval = SetSystemCursor(ptr, whichCursor); } } }

Funciona obteniendo el cursor del sistema actual tal como se proporciona en los System.Windows.Forms.Cursors y haciendo una imagen con Cursor.Draw . La imagen se redimensiona al tamaño deseado. Esto requiere desplazar la imagen del cursor, ya sea a la esquina inferior derecha (como para los punteros de flecha) o centrar la imagen del cursor dentro de la imagen más grande (como para Cruz y IBeam).

Puede usar su propia imagen para el cursor si lo desea, omitiendo todo el código de cambio de tamaño. Simplemente suministre el mapa de bits a SetCursor .

Una vez que la nueva imagen del cursor está lista, la última parte de los datos necesarios es la ID del cursor que estamos tratando de reemplazar. Cada System.Windows.Forms.Cursor contiene esta información, pero en una variable privada, por lo que la reflexión se utiliza para obtener el valor. Si prefiere evitar la reflexión, podría construir una tabla de estos valores en su lugar. Consulte MSDN SetSystemCursor para obtener una lista de valores.

Para usar la clase solo llama

SystemCursors.SetSystemCursorsSize(128);