Ответ на личное сообщение разросся до такой степени, что я решил, что это может пригодиться кому-либо ещё.
В последней версии TCFS2 есть пример команды
switch_sp, которая позволяет переключать два режима окна - распахнутое на почти весь экран и некоторое среднее по центру экрана:
Код: Выделить всё
switch_sp=move(# ? 0 : @*7/64, # ? 0 : @*7/64, @-# ? @ : @*25/32, @-1-# ? @-1 : @*25/32), , switch_sp
Так можно задать любое число позиций и переключаться между ними, но есть одна проблема. Все 4 параметра (положение окна и размеры) вычисляются независимо от других, поэтому, если перемещать или изменять размер окна между вызовами такой команды, возможна рассинхронизация. Например, если выполнить
switch_sp, чтобы окно распахнулось, а потом уменьшить его мышью за правый нижний угол (не меняя позиции окна), то последюущие вызовы
switch_sp будут работать неверно (переключать будут между маленьким окном в углу и большим в правой нижней части экрана). А возникает потому, что в описанном случае позиционирование срабатывает по схеме из точки (0, 0), а изменение размера - по схеме из маленького в большое (нельзя при изменении одной величины учитывать другую). Сдвиг окна в любую сторону на 1 пиксель решает проблему (а лучше - с изменением размера, т.е. слегка изменить размер окна с левого верхнего угла).
Среди решений, избавленных от такого недостатка, есть вариант с использованием некоторого неиспользуемого системой бита стиля окна. Посмотрим, есть ли такие.
В файле WinUser.h определены следующие числовые значения стилей (файл из Visual Studio 2010, так что самый свежий):
#define WS_OVERLAPPED 0x00000000L
#define WS_POPUP 0x80000000L
#define WS_CHILD 0x40000000L
#define WS_MINIMIZE 0x20000000L
#define WS_VISIBLE 0x10000000L
#define WS_DISABLED 0x08000000L
#define WS_CLIPSIBLINGS 0x04000000L
#define WS_CLIPCHILDREN 0x02000000L
#define WS_MAXIMIZE 0x01000000L
#define WS_CAPTION 0x00C00000L
#define WS_BORDER 0x00800000L
#define WS_DLGFRAME 0x00400000L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_GROUP 0x00020000L
#define WS_TABSTOP 0x00010000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_ACTIVECAPTION 0x0001
#define WS_EX_DLGMODALFRAME 0x00000001L
#define WS_EX_NOPARENTNOTIFY 0x00000004L
#define WS_EX_TOPMOST 0x00000008L
#define WS_EX_ACCEPTFILES 0x00000010L
#define WS_EX_TRANSPARENT 0x00000020L
#define WS_EX_MDICHILD 0x00000040L
#define WS_EX_TOOLWINDOW 0x00000080L
#define WS_EX_WINDOWEDGE 0x00000100L
#define WS_EX_CLIENTEDGE 0x00000200L
#define WS_EX_CONTEXTHELP 0x00000400L
#define WS_EX_RIGHT 0x00001000L
#define WS_EX_LEFT 0x00000000L
#define WS_EX_RTLREADING 0x00002000L
#define WS_EX_LTRREADING 0x00000000L
#define WS_EX_LEFTSCROLLBAR 0x00004000L
#define WS_EX_RIGHTSCROLLBAR 0x00000000L
#define WS_EX_CONTROLPARENT 0x00010000L
#define WS_EX_STATICEDGE 0x00020000L
#define WS_EX_APPWINDOW 0x00040000L
#define WS_EX_LAYERED 0x00080000
#define WS_EX_NOINHERITLAYOUT 0x00100000L
#define WS_EX_LAYOUTRTL 0x00400000L
#define WS_EX_COMPOSITED 0x02000000L
#define WS_EX_NOACTIVATE 0x08000000L
Оставляем только числа, сортируем, удаляем дубликаты... Regex рулит.

Вот таблица занятости битов основных стилей (HEX):
00000001 USED
00000002
00000004
00000008
00000010
00000020
00000040
00000080
00000100
00000200
00000400
00000800
00001000
00002000
00004000
00008000
00010000 USED
00020000 USED
00040000 USED
00080000 USED
00100000 USED
00200000 USED
00400000 USED
00800000 USED
01000000 USED
02000000 USED
04000000 USED
08000000 USED
10000000 USED
20000000 USED
40000000 USED
80000000 USED
А вот - расширенных (тоже HEX):
00000001 USED
00000002
00000004 USED
00000008 USED
00000010 USED
00000020 USED
00000040 USED
00000080 USED
00000100 USED
00000200 USED
00000400 USED
00000800
00001000 USED
00002000 USED
00004000 USED
00008000
00010000 USED
00020000 USED
00040000 USED
00080000 USED
00100000 USED
00200000
00400000 USED
00800000
01000000
02000000 USED
04000000
08000000 USED
10000000
20000000
40000000
80000000
Как видим, есть пока неиспользуемые биты, которые можно попробовать использовать в своих целях.

Надеюсь, система не использует их для своих целей - стоит проверить, изменится ли что-нибудь при их установке. Суммируем (удаляем строки с
USED, заменяем
\r\n на
+, копируем и вставляем строку по Ctrl+V в виндосовский калькулятор в режиме HEX, жмем Enter), для обычных стилей получаем число FFFE, для расширенных - число F5A08802. А теперь пишем команду
set_style(# | $FFFE, # | F5A08802), отходим от компа на безопасное расстояние и запускаем...

Не работает...

Почему? Забыли символ доллара перед числом F5A08802.

Повторяем эксперимент...

Обычные стили установились, расширенные - нет... При отладке в тестовой программке на Windows 7 x64 выяснилось, что изменять система позволяет лишь биты расширенного стиля, содержащиеся в маске 0A5F76F7 (видимо, фильтрует неподдерживаемые - странно, что только расширенные фильтрует) - остальные биты при их установке или снятии не изменяли значения при повторном чтении. Таким образом, имеем F5A08802 & 0A5F76F7 = 2... То есть, система позволяет изменять лишь один бит из тех, которые не указаны в файле WinUser.h, да и тот может иметь какое-то значение (возможно, Windows XP будет добрее в этом плане

). Что ж, с расширенными стилями фокус не прошел, но у нас полно неиспользуемых битов основных стилей (аж 15 штук, хватит на любое извращение).
Чтобы поставить, скажем, бит 00008000 основного стиля, нужно вызвать
set_style(# | $00008000), чтобы снять - вызвать
set_style(# & ~$00008000), а чтобы проверить, установлен ли он - вызвать
style(# & $00008000). С остальными битами - аналогично. Таким образом, составляем узкоспециализированную команду:
Код: Выделить всё
s00008000_switch_sp=set_style(# & ~$00008000) move(@*7/64, @*7/64, @*25/32, @*25/32), style(# & $00008000), s00008000_switch_sp | set_style(# | $00008000) move(0, 0, @, @-33), , s00008000_switch_sp
Работает!

Команда проверяет наличие бита стиля 00008000, если бит стоит, снимает его и позиционирует окно в середину экрана, в противном случае команда ставит бит и распахивает окно. В обоих случаях команда дописывает сама себя к строке отката.
Почему узкоспециализированную? Потому, что только эта команда должна использовать этот бит (и бит не должен использоваться системой).
Название команды я специально начал с приставки
s00008000_ - если использовать несколько команд, работающих с неиспользуемыми битами стилей, так можно легко визуально определить, какие стили уже используются (особенно если располагать такие команды подряд и в алфавитном порядке), и что команда вообще использует особый приём.