2012-12-23 33 views
0

这是一个奇怪的问题。我有兴趣在计算机上构建导航应用程序。我想在用户完成某些事情时给予用户“物理线索”。例如,点击文件夹时会出现白色晕圈。这可以用C#完成。一位用户建议我详细说明这一点,以便更具体。我想使用Kinect来允许用户浏览操作系统。但是,我希望它们能够使用双手,因此我不想只将手附着在鼠标指针上。我想给用户一些关于他们与操作系统交互的视觉反馈。我很难想到这样做的最佳方法。所以我想在操作系统上创建视觉效果,但不是在任何特定的窗口中,比如游戏窗口。OS上的C#图形编程

我看到的大多数图形教程都涉及到为该窗口构建窗口和渲染管线;或者使用WPF和Silverlight图形和动画。我需要更多的灵活性,因为这将用于操作系统而不是特定的应用程序。我无法确定从哪里开始,甚至可以使用.NET或Mono Framework。

我最好用C++来完成这个目标。请让我知道这是否太开放了一个问题。我正试图找到如何开始这样的事情。谢谢!

+0

这是一个非常普遍的问题。我认为你需要举一些例子,并且稍微填补一下。 –

回答

4

.NET WinForms,就像C++ WinForms使用GDI +一样,.NET更加抽象化。您仍然可以通过p/invoke访问本机代码,并且可以在抽象的BCL中重写受保护的成员,这意味着您仍然拥有相当程度的控制权。所以除非你正在讨论特定的图形库,我不认为.NET WinForms比C++更小。在这方面。

关于你的任务,我会研究分层的窗口。对不起,我没有任何全面的参考资料,因为我正在努力寻找他们,当我学习时,但这里有一个班级,我可以帮助你开始绘制Layered Window。而不是从Form派生出你的主窗体派生自SingleLayeredForm

public class SingleLayeredForm : Form 
{ 
    public new event PaintEventHandler Paint; 

    public SingleLayeredForm() 
    { 
     this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     this.FormBorderStyle = FormBorderStyle.FixedSingle; 
     this.StartPosition = FormStartPosition.Manual; 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      if (DesignMode) return base.CreateParams; 
      CreateParams createParams = base.CreateParams; 
      createParams.ExStyle = createParams.ExStyle | 0x80000; 
      return createParams; 
     } 
    } 

    public void SetBitmap(Bitmap bitmap) 
    { 
     if (!IsHandleCreated || DesignMode) return; 
     IntPtr oldBits = IntPtr.Zero; 
     IntPtr screenDC = WinAPI.GetDC(IntPtr.Zero); 
     IntPtr hBitmap = IntPtr.Zero; 
     IntPtr memDC = WinAPI.CreateCompatibleDC(screenDC); 
     try 
     { 
      Point topLocation = new Point(this.Left, this.Top); 
      Size bitmapSize = new Size(bitmap.Width, bitmap.Height); 
      WinAPI.BLENDFUNCTION blendFunc = new WinAPI.BLENDFUNCTION(); 
      Point sourceLocation = Point.Empty; 
      hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); 
      oldBits = WinAPI.SelectObject(memDC, hBitmap); 

      blendFunc.BlendOp = WinAPI.AC_SRC_OVER; 
      blendFunc.SourceConstantAlpha = 255; 
      blendFunc.AlphaFormat = WinAPI.AC_SRC_ALPHA; 
      blendFunc.BlendFlags = 0; 

      WinAPI.UpdateLayeredWindow(Handle, screenDC, ref topLocation, ref bitmapSize, memDC, ref sourceLocation, 0, ref blendFunc, WinAPI.ULW_ALPHA); 
     } 
     finally 
     { 
      if (hBitmap != IntPtr.Zero) 
      { 
       WinAPI.SelectObject(memDC, oldBits); 
       WinAPI.DeleteObject(hBitmap); 
      } 
      WinAPI.ReleaseDC(IntPtr.Zero, screenDC); 
      WinAPI.DeleteDC(memDC); 
     } 
    } 

    public new void Invalidate() 
    { 
     using (Bitmap bitmap = new Bitmap(this.ClientSize.Width, this.ClientSize.Height)) 
     { 
      using (Graphics graphics = Graphics.FromImage(bitmap)) 
      { 

       graphics.SmoothingMode = SmoothingMode.HighSpeed; 
       graphics.CompositingMode = CompositingMode.SourceCopy; 

       if (this.Paint != null) 
        this.Paint(this, new PaintEventArgs(graphics, Rectangle.Empty)); 
      } 
      SetBitmap(bitmap); 
     } 
    } 
} 

public sealed class WinAPI 
{ 
    [DllImport("user32.dll")] 
    public static extern bool HideCaret(IntPtr hWnd); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] 
    public static extern short GetKeyState(int keyCode); 

    [DllImport("user32.dll")] 
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); 

    [DllImport("user32.dll")] 
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id); 

    [DllImport("gdi32.dll", SetLastError = true)] 
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetDC(IntPtr hWnd); 

    [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)] 
    public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 

    [DllImport("user32.dll")] 
    public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); 

    [DllImport("gdi32.dll")] 
    public static extern bool DeleteDC(IntPtr hdc); 

    [DllImport("gdi32.dll")] 
    public static extern bool DeleteObject(IntPtr hObject); 

    [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 
    public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pptSrc, uint crKey, [In] ref BLENDFUNCTION pblend, uint dwFlags); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetDesktopWindow(); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr ptr); 

    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); 

    [DllImport("gdi32.dll")] 
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetForegroundWindow(); 

    [DllImport("user32.dll")] 
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect); 

    public const byte AC_SRC_OVER = 0; 
    public const byte AC_SRC_ALPHA = 1; 
    public const byte ULW_ALPHA = 2; 

    [StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct BLENDFUNCTION 
    { 
     public byte BlendOp; 
     public byte BlendFlags; 
     public byte SourceConstantAlpha; 
     public byte AlphaFormat; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct RECT 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 
    } 
} 
+0

哇,谢谢!这对我来说绝对是未知的领域。我会研究pinvoke和上面的例子。我很感激帮助。当我有足够的声望点时,我会高兴。 – JamWils