2012-12-03 53 views
16

मैं अपने प्रोग्राम को 32x32 के अधिकतम लगाए गए माउस आकार को ओवरराइड करने में सक्षम होना चाहता हूं, जैसा चित्रित चित्र में प्रोग्राम की तरह है, चित्रित कर्सर 72x72 है । यह ProcMon से एक कैप्चर है जो कर्सर बदलते समय क्या हो रहा है।विंडोज़ में अधिकतम 32x32 माउस आकार को ओवरराइड करने के लिए कैसे करें इस प्रोग्राम की तरह

हालांकि, अगर मैं कर्सर के लिए अपने आप फ़ाइलें रजिस्ट्री मान को बदलने और उसके बाद का उपयोग कर

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

तो कर्सर बदल जाएगा परिवर्तन पुश करने के लिए प्रयास करते हैं, लेकिन यह अभी भी 32x32 अधिकतम आकार तक सीमित है। यह कार्यक्रम इस प्रतिबंध के आसपास कैसे हो सकता था? साथ ही, प्रोग्राम समाप्त होने के बाद कर्सर बने रहते हैं, इसलिए यह चलने के दौरान ऐसा कुछ नहीं हो सकता है, लेकिन कहीं भी सेटिंग को ओवरराइड करना होगा।

enter image description here

धन्यवाद आपकी मदद के लिए, मैं नेट पर इस तरह कुछ भी करने में सक्षम नहीं किया गया है, तो मैं भी नहीं जानता कि अगर किसी को भी इस सवाल का जवाब होगा।

संपादित करें: मुझे C:\Windows\SysWOW64\Imageres.dll नामक फ़ाइल में कुछ पहुंच दिखाई देती है। वे केवल पढ़ते हैं, लेकिन हो सकता है कि ये कर्सर यहां संग्रहीत हों, या उन्होंने इस फ़ाइल को किसी भी तरह संशोधित किया है। लेकिन मुझे लगा कि यह किसी को सही रास्ते पर अपने आप से अधिक अनुभव के साथ मिल सकता है।

संपादित करें 2: मेरा मानना ​​है कि आकार SM_CXCURSOR और SM_CYCURSOR चर द्वारा निर्धारित किए गए हैं। अगर मुझे इन्हें सेट करने का कोई तरीका मिल सकता है, तो मैं व्यवसाय में हो सकता हूं। प्रोग्राम चलाने और विशाल माउस कर्सर के साथ पीसी पर उन मूल्यों को प्राप्त करने के लिए एक त्वरित कार्यक्रम लिखने के लिए जा रहे हैं और देखें कि यह क्या लौटाता है ...

संपादित करें 3: कोई भाग्य नहीं; विशाल कर्सर के साथ पीसी 32x32 देता है इसके SM_CXCURSOR और SM_CYCURSOR के लिए।

+0

शायद आप अपनी स्क्रीन का आकार बदलकर 150% कर सकते हैं? यह स्क्रीन रिज़ॉल्यूशन सेटिंग –

+0

द्वारा है, लेकिन ऐसा नहीं है कि यह प्रोग्राम इसे कैसे करने में सक्षम है। माउस कर्सर को छोड़कर कुछ भी नहीं बदलेगा, जो प्रभाव है जिसे मैं प्रतिलिपि बनाने की उम्मीद कर रहा हूं। –

+1

आपको माउस पॉइंटर के आकार को बदलने का प्रयास करने की आवश्यकता होगी। –

उत्तर

6

SetSystemCursor का उपयोग करते हुए यह मानक कर्सर से भी ज्यादा बड़ा आकार की एक छवि के लिए एक कर्सर सेट करने के लिए संभव है।

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://stackoverflow.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); 
     } 

    } 
} 

यह रूप में System.Windows.Forms.Cursors में प्रदान की मौजूदा प्रणाली कर्सर हो रही है और Cursor.Draw के साथ से एक छवि बनाने के द्वारा काम करता है:

यहां कक्षा मैं प्रणाली कर्सर का आकार बदलने के लिए है। छवि को वांछित आकार में बदल दिया जाता है। इसके लिए कर्सर छवि को या तो निचले दाएं कोने में (तीर पॉइंटर्स के लिए) या बड़ी छवि (जैसे क्रॉस और आईबीएम) के अंदर कर्सर छवि को केंद्रित करने की आवश्यकता होती है।

यदि आप वांछित हैं तो कर्सर के लिए अपनी छवि का उपयोग कर सकते हैं, सभी आकार बदलने वाले कोड को छोड़कर। बस बिटमैप को SetCursor पर आपूर्ति करें।

एक बार नया कर्सर छवि तैयार हो जाने के बाद, आवश्यक डेटा का अंतिम भाग कर्सर की आईडी है जिसे हम प्रतिस्थापित करने की कोशिश कर रहे हैं। प्रत्येक System.Windows.Forms.Cursor में यह जानकारी होती है, लेकिन एक निजी चर में, इसलिए मूल्य प्राप्त करने के लिए प्रतिबिंब का उपयोग किया जाता है। यदि आप प्रतिबिंब से बचना पसंद करते हैं, तो आप इसके बजाय इन मानों की एक तालिका बना सकते हैं। मूल्यों की सूची के लिए MSDN SetSystemCursor देखें।

वर्ग का उपयोग करने के लिए बस

SystemCursors.SetSystemCursorsSize(128); 
+0

अरे, यह निश्चित रूप से सबसे नज़दीक है जिसे मैंने कभी भी प्राप्त किया है जिसे मैं ढूंढ रहा था। मैं थोड़ी देर के लिए घूमने जा रहा हूं, लेकिन इसके साथ एकमात्र मुद्दा यह है कि कर्सर के वास्तविक डिफ़ॉल्ट सेट पर वापस जाने का कोई तरीका नहीं है, और यदि आप 'SetSystemCursorSize' को कॉल करके कॉल करके आगे और आगे जाना चाहते हैं, 32 से 128 से 32 तक और उससे अधिक विकृत हो जाएंगे कि यह अंततः एक काले वर्ग के रूप में समाप्त होता है। जैसे मैंने कहा, मैं चारों ओर देखूंगा लेकिन अगर आपके पास कोई विचार था तो सिर्फ उत्सुक था! पोस्ट के लिए धन्यवाद! –

+0

यदि आप पहले से जानते हैं कि आपको किस आकार की आवश्यकता होगी, तो आप प्रत्येक कर्सर को छवि फ़ाइल के रूप में सहेज सकते हैं, और उसके बाद प्रत्येक आकार को आवश्यकतानुसार लोड कर सकते हैं। कुछ 'सेट कर्सर (नया बिटमैप (छवि.फ्रोफाइल (arrow32.png)), ...); '। 32 से बड़े चित्रों के लिए, आपको छवि को स्थानांतरित करने की आवश्यकता होगी, जैसे 'ResizeCursorBitmap' करता है। प्रोग्राम शुरू होने पर प्रत्येक कर्सर के बिटमैप की प्रतिलिपि रखना और फिर आकार बदलना और स्थानांतरित करना, या मूल को पुनर्स्थापित करना होगा। – endofzero

+0

दुर्भाग्य से यह विंडोज 10 में काम नहीं करता है। यहां तक ​​कि 'SetCursor' के साथ एक बड़ा बाहरी बिटमैप लोड करते समय भी इसे 32x32 में बदल दिया जाता है। – kwill

6

यदि आप WPF के साथ काम कर रहे हैं, तो आप अपना माउस कर्सर बना सकते हैं और इसे असाइन कर सकते हैं। लेकिन यह एक सिस्टम चौड़ा माउस कर्सर परिवर्तन नहीं है। यहां कुछ कोड है जो चाल करेगा। नीचे दिए गए कोड में मैं एक कर्सर 50x50 पिक्सल बना रहा हूं। आप 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); 
      } 
     } 
    } 

} 
+0

मदद करने में खुशी है मैं मदद और कोड नमूना की सराहना करता हूं, लेकिन दुर्भाग्यवश इसे सिस्टम-व्यापी की आवश्यकता होगी। मुझे यकीन नहीं है कि इन लोगों ने किस तरह का काला जादू काम किया है, लेकिन मैं इसे समझने के लिए दृढ़ संकल्पित हूं: पी धन्यवाद! –

0

करने पर अपने खुद के आकार आकर्षित कर सकते हैं अपने वर्ग के लिए इन आयात करें:

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

LoadImage और SetSystemCursor के बारे में पढ़ा MSDN लेख, विशेषकर मापदंडों वे उपयोग के बारे में।

फिर अपने कोड में फ़ंक्शन का उपयोग:

// "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) 
} 
0

फोन मैं intrueder के way.Supplement का उपयोग करके, एपीआई LoadImage Load.png नहीं कर सकते हैं इस समस्या को हल करें। System.drawing.BitMap का उपयोग करें। इस तरह: Bitmap bmp = new Bitmap(str, true); IntPtr p = bmp.GetHicon(); SetSystemCursor(p, OCR_NORMAL);