Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?

Persistent Window Selector

Description
This script displays a persistent window listing all open windows, categorized by monitor (limited to two monitors). It allows the user to move any window between the two monitors by double-clicking on it. The list updates automatically every 3 seconds to reflect real-time window changes.
Language
C#.net
Minimum Version
Created By
ADJADI
Contributors
-
Date Created
3d ago
Date Last Modified
3d ago

Scripted Function (Macro) Code

using System;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;

public class PersistentWindowSelector : Form
{
    private SplitContainer splitContainer;
    private ListView lvMonitor1;
    private ListView lvMonitor2;
    private Timer refreshTimer;

    public PersistentWindowSelector()
    {
        this.Text = "Sélectionnez la fenêtre à déplacer...";
        this.Size = new Size(600, 600);

        splitContainer = new SplitContainer();
        splitContainer.Dock = DockStyle.Fill;
        splitContainer.Orientation = Orientation.Horizontal;
        this.Controls.Add(splitContainer);

        lvMonitor1 = new ListView { View = View.List, Dock = DockStyle.Fill, FullRowSelect = true };
        lvMonitor1.DoubleClick += ListView_DoubleClick;
        
        lvMonitor2 = new ListView { View = View.List, Dock = DockStyle.Fill, FullRowSelect = true };
        lvMonitor2.DoubleClick += ListView_DoubleClick;

        splitContainer.Panel1.Controls.Add(lvMonitor1);
        splitContainer.Panel2.Controls.Add(lvMonitor2);

        refreshTimer = new Timer { Interval = 3000 };
        refreshTimer.Tick += RefreshTimer_Tick;
        refreshTimer.Start();
    }

    private void RefreshTimer_Tick(object sender, EventArgs e)
    {
        string currentSelection = (lvMonitor1.SelectedItems.Count > 0) ? lvMonitor1.SelectedItems[0].Text :
                                  (lvMonitor2.SelectedItems.Count > 0) ? lvMonitor2.SelectedItems[0].Text : null;

        lvMonitor1.BeginUpdate();
        lvMonitor2.BeginUpdate();
        lvMonitor1.Items.Clear();
        lvMonitor2.Items.Clear();

        IntPtr[] windows = BFS.Window.GetVisibleAndMinimizedWindowHandles();
        uint[] monitors = BFS.Monitor.GetMonitorIDs();
        if (monitors.Length < 2)
        {
            lvMonitor1.Items.Add("Il n'y a pas 2 moniteurs disponibles.");
            lvMonitor1.EndUpdate();
            lvMonitor2.EndUpdate();
            return;
        }
        uint monitor1 = monitors[0], monitor2 = monitors[1];

        foreach (IntPtr window in windows)
        {
            string title = BFS.Window.GetText(window);
            if (string.IsNullOrEmpty(title)) continue;

            uint windowMonitorID = BFS.Monitor.GetMonitorIDByWindow(window);
            ListView targetList = (windowMonitorID == monitor1) ? lvMonitor1 :
                                  (windowMonitorID == monitor2) ? lvMonitor2 : null;

            targetList?.Items.Add(title);
        }

        lvMonitor1.EndUpdate();
        lvMonitor2.EndUpdate();
        
        RestoreSelection(lvMonitor1, currentSelection);
        RestoreSelection(lvMonitor2, currentSelection);
    }

    private void RestoreSelection(ListView listView, string selection)
    {
        if (!string.IsNullOrEmpty(selection))
        {
            foreach (ListViewItem item in listView.Items)
            {
                if (item.Text == selection)
                {
                    item.Selected = true;
                    break;
                }
            }
        }
    }

    private void ListView_DoubleClick(object sender, EventArgs e)
    {
        ListView lv = sender as ListView;
        if (lv.SelectedItems.Count == 0) return;

        string selectedTitle = lv.SelectedItems[0].Text;
        IntPtr windowToMove = BFS.Window.GetWindowByTextExact(selectedTitle);
        if (windowToMove == IntPtr.Zero) return;

        uint[] monitors = BFS.Monitor.GetMonitorIDs();
        if (monitors.Length < 2) return;
        uint monitor1 = monitors[0], monitor2 = monitors[1];

        uint currentMonitorID = BFS.Monitor.GetMonitorIDByWindow(windowToMove);
        uint targetMonitorID = (currentMonitorID == monitor1) ? monitor2 : monitor1;

        BFS.Window.MoveToMonitor(targetMonitorID, windowToMove);
    }
}

public static class DisplayFusionFunction
{
    public static void Run(IntPtr windowHandle)
    {
        using (PersistentWindowSelector selector = new PersistentWindowSelector())
        {
            selector.ShowDialog();
        }
    }
}