Exemplo n.º 1
0
 void Event_DisplaySettingsChanged(object sender, EventArgs e)
 {
     UpdatingDisplaySettings = true;
     Console.WriteLine("\nDisplay Settings Changed...");
     //ShowScreens ();
     SnagScreen.Init(Screen.AllScreens);
     SnagScreen.ShowAll();
     UpdatingDisplaySettings = false;
 }
Exemplo n.º 2
0
    // CheckJumpCursor() returns TRUE, ONLY if the cursor is "stuck". By "stuck" we
    // specifically mean that the user is trying to move the mouse beyond the boundaries of
    // the screen currently containing the cursor. This is determined when the *current*
    // cursor position does not equal the *previous* mouse position. If there is another
    // adjacent screen (or a "wrap around" screen), then we can consider moving the mouse
    // onto that screen.
    //
    // Note that this is ENTIRELY a *GEOMETRIC* method. Screens are "rectangles", and the
    // cursor and mouse are "points." The mouse/cursor hardware interaction (obtaining
    // current mouse and cursor information) is handled in routines further below, and any
    // Screen changes are handled by the DisplaySettingsChanged event. There are no
    // hardware or OS/Win32 references or interactions here.
    bool CheckJumpCursor(Point mouse, Point cursor, out Point NewCursor)
    {
        NewCursor = cursor; // Default is to not move cursor.

        // Gather pertinent information about cursor, mouse, screens.
        Point      Dir            = Direction(cursor, mouse);
        SnagScreen cursorScreen   = WhichScreen(cursor);
        SnagScreen mouseScreen    = WhichScreen(mouse);
        bool       IsStuck        = (cursor != LastMouse) && (mouseScreen != cursorScreen);
        Point      StuckDirection = OutsideDirection(cursorScreen.R, mouse);

        string StuckString = IsStuck ? "--STUCK--" : "         ";

//        Console.Write ($" FarOut{StuckDirection}/{OutsideDis//tance(cursorScreen.R, mouse)} " +
//            $"mouse:{mouse}  cursor:{cursor} (OnMon#{cursorScreen}/{mouseScreen}) last:{LastMouse}  " +
//            $"#UnSnags {NJumps}   {StuckString}        \r");

        Console.Write($" StuckDirection/Distance{StuckDirection}/{OutsideDistance(cursorScreen.R, mouse)} " +
                      $"cur_mouse:{mouse}  prev_mouse:{LastMouse} ==? cursor:{cursor} (OnMon#{cursorScreen}/{mouseScreen})  " +
                      $"#UnSnags {NJumps}   {StuckString}   \r");

        LastMouse = mouse;

        // Let caller know we did NOT jump the cursor.
        if (!IsStuck)
        {
            return(false);
        }

        SnagScreen jumpScreen = ScreenInDirection(StuckDirection, cursorScreen.R);

        // If the mouse "location" (which can take on a value beyond the current
        // cursor screen) has a value, then it is "within" another valid screen
        // bounds, so just jump to it!
        if (mouseScreen != null)
        {
            NewCursor = mouse;
        }
        else if (jumpScreen != null)
        {
            NewCursor = jumpScreen.R.ClosestBoundaryPoint(cursor);
        }
        else if (StuckDirection.X != 0)
        {
            NewCursor = WrapPoint(StuckDirection, cursor);
        }
        else
        {
            return(false);
        }

        ++NJumps;
        Console.Write($"\n -- JUMPED!!! --\n");
        return(true);
    }
Exemplo n.º 3
0
    // Loop through Screen.AllScreens[] array to initialize ourselves.
    public static void Init(Screen[] AllScreens)
    {
        var N = AllScreens.Length;

        TopMost    = new List <SnagScreen> ();
        BottomMost = new List <SnagScreen> ();
        LeftMost   = new List <SnagScreen> ();
        RightMost  = new List <SnagScreen> ();

        BoundingBox = new Rectangle(0, 0, 0, 0);

        // First pass, populate our All[] array with all the screens.
        All = new SnagScreen[N];
        for (int i = 0; i < N; ++i)
        {
            All[i] = new SnagScreen(Screen.AllScreens[i], i);
        }

        // Now determine their geometric relationships. Yes this is O(N^2), but
        // usually N (number of monitors) is not too large. There may be more
        // efficient approaches, but this is very simple, clear, and
        // straightforward, and it is not called often (only when program
        // starts, and after any change in monitor configuration).
        foreach (var SN in All)
        {
            // Add direction from this SN screen to each of the other screens.
            foreach (var s in All)
            {
                SN.AddDirectionTo(s);
            }

            // Where appropriate, add ourselves to the lists of outermost screens.
            if (SN.IsLeftmost)
            {
                LeftMost.Add(SN);
            }
            if (SN.IsRightmost)
            {
                RightMost.Add(SN);
            }
            if (SN.IsTopmost)
            {
                TopMost.Add(SN);
            }
            if (SN.IsBottommost)
            {
                BottomMost.Add(SN);
            }

            BoundingBox = Rectangle.Union(BoundingBox, SN.R);
        }
    }
Exemplo n.º 4
0
 // If s is immediately adjacent to (shares a border with) us, then add it to the
 // appropriate direction list. If s is not "touching" us, then it will not get added to
 // any list. s can be added to at most one list (hence use of "else if" instead of just
 // a sequence of "if's").
 public void AddDirectionTo(SnagScreen s)
 {
     if ((R.Right == s.R.Left) && OverlapY(R, s.R))
     {
         ToRight.Add(s);
     }
     else if ((R.Left == s.R.Right) && OverlapY(R, s.R))
     {
         ToLeft.Add(s);
     }
     else if ((R.Top == s.R.Bottom) && OverlapX(R, s.R))
     {
         Above.Add(s);
     }
     else if ((R.Bottom == s.R.Top) && OverlapX(R, s.R))
     {
         Below.Add(s);
     }
 }
Exemplo n.º 5
0
    private void Run(string[] args)
    {
        // DPI Awareness API is not available on older OS's, but they work in
        // physical pixels anyway, so we just ignore if the call fails.
        try
        {
            SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_Per_Monitor_DPI_Aware);
        }
        catch (System.DllNotFoundException)
        {
            Console.WriteLine("No SHCore.DLL. No problem.");
        }

        // Make sure we catch CTRL-C hard-exit of program.
        CTRL_C_handler = new ConsoleEventDelegate(ConsoleEventCallback);
        SetConsoleCtrlHandler(CTRL_C_handler, true);

        //ShowScreens ();
        SnagScreen.Init(Screen.AllScreens);
        SnagScreen.ShowAll();

        // Get notified of any screen configuration changes.
        SystemEvents.DisplaySettingsChanged += Event_DisplaySettingsChanged;

        //ShowWindow(GetConsoleWindow(), SW_HIDE);

        // Keep a reference to the delegate, so it does not get garbage collected.
        MouseHookDelegate = LLMouseHookCallback;
        LLMouse_hookhand  = SetHook(WH_MOUSE_LL, MouseHookDelegate);

        Console.WriteLine("");

        // This is the one that runs "forever" while the application is alive, and handles
        // events, etc. This application is ABSOLUTELY ENTIRELY driven by the LLMouseHook
        // and DisplaySettingsChanged events.
        Application.Run();

        Console.WriteLine("Exiting!!!");
        UnsetHook(ref LLMouse_hookhand);
    }
Exemplo n.º 6
0
    // May want to update the above routine, which arbitrarily selects the monitor that
    // happens to come first in the for() loop. We should probably do a little extra work,
    // and select the monitor that is closest to the mouse position.

    // Find the monitor that is closest to the point.
    //public static SnagScreen ScreenInDirection()
    //{
    //}

    // Find the best point to "wrap" around the cursor, either horizontally or
    // vertically. We consider only the "OuterMost" screens. For instance, if
    // the mouse is moving to the left, we consider only the screens in the
    // RightMost[] array.
    public static Point WrapPoint(Point Dir, Point Cursor)
    {
        int        DistClosest = int.MaxValue;
        SnagScreen WS          = null; // Our "wrap screen".

        if (Dir.X != 0)
        {
            // Find closest Left- or Right-most screen, in Y direction.
            foreach (var S in (Dir.X == 1 ? LeftMost : RightMost))
            {
                int dist = Math.Abs(OutsideYDistance(S.R, Cursor));
                if (dist < DistClosest)
                {
                    DistClosest = dist;
                    WS          = S;
                }
            }
            return(WS.R.ClosestBoundaryPoint(new Point(Dir.X == 1?WS.R.Left:WS.R.Right, Cursor.Y)));
        }

        // We should never get here, but if we do, just return the current
        // Cursor location.
        return(Cursor);
    }