操作系统上的c#图形编程

本文关键字:图形 编程 操作系统 | 更新日期: 2023-09-27 17:49:25

这是一个奇怪的问题。我对在计算机上构建一个导航应用程序很感兴趣。当用户完成某件事时,我想给他们"物理提示"。例如,当单击文件夹时,白色的光环会展开。这可以用c#实现吗?一位用户建议我用更多的细节来扩展它,使其更具体。我想用Kinect让用户在操作系统中导航。然而,我希望他们能够使用双手,所以我不想只是将手连接到鼠标指针。我想给用户一些视觉反馈,他们与操作系统的互动。我想不出最好的方法来做这件事。所以我想在操作系统上创造视觉效果,但不是在任何特定的窗口,如游戏窗口。

我看到的大多数图形教程要么涉及构建窗口并为该窗口渲染管道;或者使用WPF和Silverlight图形和动画。我需要更多的灵活性,因为这将是针对操作系统的,而不是针对特定的应用程序。我不知道从哪里开始,如果它甚至可能使用。net或Mono框架。

我用c++来完成这个目标是不是更好?如果这是一个开放式的问题,请让我知道。我正在努力寻找如何开始做这样的事情。谢谢!

操作系统上的c#图形编程

。.NET WinForms,像c++ WinForms使用GDI+一样,.NET只是更加抽象。您仍然可以通过p/invoke访问本机代码,并且能够在抽象的BCL中覆盖受保护的成员,这意味着您仍然具有相当程度的控制。所以,除非你谈论的是一个特定的图形库,否则我认为。net WinForms并不比c++差。在这种情况下。

关于你的任务,我将研究分层窗口。对不起,我没有任何全面的参考资料,因为我在学习的时候很难找到它们,但这里有一个我聚集在一起的课程,可以帮助你开始在分层窗口上画画。而不是从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;
    }
}