如何计算屏幕上2个像素之间的高度(宽度)?

时间:2014-10-02 16:08:30

标签: c# position pixel graphic

我被要求做一个能够做这样的事情的应用程序(最好用C#):

  1. 我运行应用程序(例如:它在我的活动监视器上处于活动状态)
  2. 然后我点击2个像素(不一定是像素,epsilon将是+ -3px)
  3. 程序会在底部计算或显示它们之间的高度(宽度)
  4. 像" positionShower"在一个简单的绘画中,除了我在整个显示屏上选择2个像素(如果它在活动窗口中或完全不在它之外并不重要)但它不需要运行任何其他程序在同一时间。

    有任何帮助吗?我真的无法搜索任何类似的东西。

2 个答案:

答案 0 :(得分:0)

    int distance;
    Point location = new Point(); 
    Point location2 = new Point();
    private void FormClick(object sender, EventArgs e)
    {

        if(location == new Point())
        {
            location = Form.MousePosition;
        }
        else if (location2 == new Point())
        {
            location2 = Form.MousePosition;
            distance = location2.X - location.X;
            location = new Point();
            location2 = new Point();
        }
    }

答案 1 :(得分:0)

要执行此操作,您需要将低级鼠标事件全局挂钩,请参阅示例代码中的LowLevelMouseProcSetWindowsHookEx和其他函数。

要测试示例,请创建一个新的Windows窗体项目,并在主窗体上添加三个标签,如下所示:

form design

并使用以下内容替换Form1.cs中的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _proc = HookCallback;

            _hookID = SetHook(_proc);

        }

        // This method is called for each global mouse event
        private IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 &&
                MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                if (isFirstClick)
                {
                    firstClickMouseStruct = hookStruct;
                    label1.Text = "First click: " + hookStruct.pt.x + ", " + hookStruct.pt.y;
                }
                else
                {
                    secondClickMouseStruct = hookStruct;
                    label2.Text = "Second click: " + secondClickMouseStruct.pt.x + ", " + secondClickMouseStruct.pt.y;
                    label3.Text = "Height: " + Math.Abs(secondClickMouseStruct.pt.y - firstClickMouseStruct.pt.y)
                        + ", Width: " + Math.Abs(secondClickMouseStruct.pt.x - firstClickMouseStruct.pt.x);
                }
                isFirstClick = !isFirstClick;
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private MSLLHOOKSTRUCT firstClickMouseStruct;
        private MSLLHOOKSTRUCT secondClickMouseStruct;
        private bool isFirstClick = true;

        private LowLevelMouseProc _proc = null;
        private IntPtr _hookID = IntPtr.Zero;

        private IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        private const int WH_MOUSE_LL = 14;

        private enum MouseMessages
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_MOUSEMOVE = 0x0200,
            WM_MOUSEWHEEL = 0x020A,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            UnhookWindowsHookEx(_hookID);
        }
    }
}

现在,您可以在表单内部或外部(桌面或其他窗口)上单击鼠标左键,应用程序将挂钩点击,检查鼠标位置并根据需要计算高度和宽度:

result