31 декабря 2015
Кравченко Виктор

Как упорядочить окна сторонних приложений по рабочему столу

VB.NET Полезные функции Visual Studio 2013 .NET
01

В продолжение статьи Как осуществить взаимодействие со сторонним приложением - изменение положения/размера, получение текста заголовка и т.д. предлагаю простой алгоритм автоматического распределения большого количества однотипных окон на рабочем столе. Это может пригодится, например, трейдерам, у которых может быть одновременно открыто большое количество торговых терминалов. Пример работы алгоритма показан ниже:

Синтаксис и описания функций user32.dll на VB.NET и С# можно найти на сайте Pinvoke.net
02
До запуска функции распределения
До запуска функции распределения
03
После выполнения функции распределения окон по рабочему столу
После выполнения функции распределения окон по рабочему столу
04 VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
Imports System.Runtime.InteropServices
Public Class frmMain
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim procnames As String() = {"terminal", "terminal64"} ' Указываем названия всех процессов, участвующих в распределении РасположитьОкнаПоРабочемуСтолу(procnames) End Sub
<DllImport("user32.dll")> _
Public Shared Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Boolean) As Boolean End Function
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean End Function
Private Sub РасположитьОкнаПоРабочемуСтолу(procnames As String()) 'Необходимо получить хендлы приложений, которыми нужно манипулировать - получаем все запущенные процессы Dim processes As New List(Of Process) For Each pn As String In procnames processes.AddRange(Process.GetProcessesByName(pn)) Next Dim procCount As Integer = processes.Count If procCount = 0 Then Return ' Если процессы не найдены выходим Dim screenRect As Rectangle = Screen.PrimaryScreen.Bounds ' Получаем размер рабочего стола screenRect.Height = Screen.PrimaryScreen.WorkingArea.Height ' Исключаем из него панель задач (TaskBar) Dim rowsCount As Integer = ПолучитьКоличествоРядов(procCount) 'Распределяем окна по площади экрана Dim colsCount As Integer = If(procCount Mod rowsCount = 0, procCount / rowsCount, Int(procCount / rowsCount) + 1) Dim r As Integer = 0 Dim c As Integer = -1 Dim winsize As Size = New Size(screenRect.Width / colsCount, screenRect.Height / rowsCount) ' Получаем расчетный размер всех окон Dim countInLastRow As Integer = colsCount - (rowsCount * colsCount - procCount) ' Количество окон в последнем ряду For Each proc As Process In processes c += 1 If c >= colsCount Then c = 0 : r += 1 Dim winrect As Rectangle If countInLastRow < colsCount And r = rowsCount - 1 Then ' На тот случай, если в последнем ряду количество окон меньше чем в предыдущих winsize = New Size(screenRect.Width / countInLastRow, screenRect.Height / rowsCount) End If winrect = New Rectangle(New Point(c * winsize.Width, r * winsize.Height), winsize) If SetForegroundWindow(proc.MainWindowHandle) Then MoveWindow(proc.MainWindowHandle, winrect.X, winrect.Y, winrect.Width, winrect.Height, True) End If Next End Sub
Private Function ПолучитьКоличествоРядов(count As Integer) As Integer Dim screenRect As Rectangle = Screen.PrimaryScreen.Bounds screenRect.Height = Screen.PrimaryScreen.WorkingArea.Height Dim square As Long = screenRect.Width * screenRect.Height Dim proportion As Decimal = screenRect.Width / screenRect.Height Dim winSquare As Long = square / count Dim prevSize As Size = New Size(Math.Sqrt(winSquare * proportion), Math.Sqrt(winSquare * proportion) / proportion) Dim rowsCount As Integer = 1 Dim prevProportion As Decimal = proportion
' Пробуем располагать все окна сначала в одном ряду - смотрим на пропорции. ' Если пропорции не приемлемые (width / height > 2) - то останавливаемся на предыдущем варианте ' Если пропорции приемлемые (width / height <= 2) смотрим на вариант расположения в большее количество рядов
Do Dim elemInRow As Integer = count / rowsCount ' - если количество не кратно - оно округлится до нужного значения ' Размер по ширине будет равняться ширине окна поделенного на кол-во элементов в ряду Dim w As Integer = screenRect.Width / elemInRow Dim h As Integer = screenRect.Height / rowsCount 'Смотрим на получившуюся пропорцию If w / h > 2 Then Exit Do rowsCount += 1 Loop Return rowsCount - 1 End Function
End Class
06

Похожие запросы:

  • Как программно изменить размер/переместить окно стороннего приложения
  • Change Location Another Program
  • External application window position
  • Find out Size (and position) of the taskbar
  • How can I figure out the taskbar height without using Screen.WorkingArea?
  • Obtaining External Window Handles and Window Captions
  • Set Position And Size Of An External Application
  • Set screen location of external application child window?
  • screen size without taskbar
  • Taskbar Height
comments powered by HyperComments