Итак, для поиска видимых окон используется функция GetWindow, которая может искать все окна, включая главные и подчиненные. Идентификатор найденного окна сохраняется в переменной w.
В данном случае для хранения указателей на окна используется массив заранее определенной длины (HWND winlist[10000]). В качестве длины я взял 10 000 элементов, и этого достаточно для хранения всех запущенных программ, потому что даже больше 100 окон запускать никто не будет.
В идеальном случае надо использовать динамические массивы (массив с динамически изменяемым количеством элементов), но я не стал применять их, чтобы не усложнять пример. Наша задача — посмотреть интересные алгоритмы, а вы потом можете сами доработать их до универсального вида.
После выполнения этого кода в массиве winlist будут храниться указатели всех запущенных и видимых программ, а в переменной windowCount — количество указателей в массиве.
А теперь о самом сдвиге. Он начинается с вызова API-функции BeginDeferWindowPos. Эта функция выделяет память для нового окна рабочего стола, куда мы будем сдвигать все видимые окна. В качестве параметра нужно указать, сколько окон мы будем двигать.
Для сдвига окна в подготовленную область памяти используется функция DeferWindowPos. В данный момент не происходит никаких реальных перемещений, а изменяется только информация о позиции и размерах. У этой функции следующие параметры:
После перемещения всех окон вызывается API-функция EndDeferWindowPos. Вот тут окна реально перескакивают в новое место. Это происходит практически моментально. Если бы вы использовали простую API-функцию SetwindowPos для установки позиции каждого окна в отдельности, то отрисовка происходила бы намного медленнее.