Как запретить сворачивать форму?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как запретить сворачивать форму?

Сообщение bon818 » 06.12.2016 (Вт) 11:31

Что это за стандартные системные механизмы, для создания каких-угодно боковых панелей?
Это, это AppBar ?
Код: Выделить всё
ABM_NEW      Register a new AppBar to the system
ABM_REMOVE      Remove a previously created AppBar from the system
ABM_QUERYPOS      Query the AppBar position
ABM_SETPOS      Set the AppBar position
........

И причем здесь workarea(рабочая область) , где про это можно прочитать?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как запретить сворачивать форму?

Сообщение ger_kar » 06.12.2016 (Вт) 14:17

bon818 писал(а):И причем здесь workarea(рабочая область) , где про это можно прочитать?
Я кстати тоже ничего на эту тему не нашел, а было бы интересно узнать, что это за зверь такой :)
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как запретить сворачивать форму?

Сообщение The trick » 06.12.2016 (Вт) 14:23

SPI_SETWORKAREA
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как запретить сворачивать форму?

Сообщение Хакер » 07.12.2016 (Ср) 6:19

bon818 писал(а):Что это за стандартные системные механизмы, для создания каких-угодно боковых панелей?

Стандартный механизм следующий: панель задач в нижней строке «Пуска», языковая панель (там, где выбор раскладки), панель быстро запуска (у тех, кто её не выключил), и создаваемые пользователями панели с ярлыками — всё это живёт внутри контрола ReBar, так же известного как CoolBar. Желающие могут посмотреть с помощью Spy++ или другого вьювера оконной иерархии — всё лежит внутри контейнеров класса ReBarWindow32.

Для тех, кто не знает: ReBar (он же CoolBar) — этот тот самый контрол, который позволяет положить в него другие контролы (как правило — ToolBar-контролы), а он любезно предоставит вам готовый функционал в виде возможности двигать «полоски», менять их порядок следования, размеры, одним словом — компоновку.


Так вот, по крайней мере, каждый пользователь может создать свою собственную панель на основе произвольной папке (предполагается, что в ней лежат ярлыки на нужные программы или файлы или веб-ресурсы или шелл-команды). Лично я, например, сто лет пользуюсь вот такой панелью, которая у меня прилеплена к верхней границе экрана:
my_top_panel.png
my_top_panel.png (42.75 Кб) Просмотров: 1516


Но речь вовсе не о том, что пользователь может сам себе создать такую панель на базе папки!
Речь о том, что сама архитектура оболочки Windows позволяет любому программисту написать свою собственную панель (содержащую произвольную начинку, будь то какие-то контролы или график загрузки процессора или график стоимости акций на бирже или отображение анекдотов, а может быть отображение температур дисков и т.п.).

Эту custom-панель (написанную кем-то со стороны) можно будет помещать в нижнюю панель Пуска или прикреплять к боковой грани экрана (верхней, левой, правой), либо иметь в виде ни к чему не прилепленного попап-окна. Эта custom-панель будет жить рядом с панелью задач, рядом с языковой панелью — их порядок и взаиморасположение можно будет менять произвольно.

Вот я свою верхнюю панель перетащил и прилепил к левой границе экрана и включил ещё пару панелей, которыми я никогда не пользовался:
my_top_panel_on_left_edge.png
my_top_panel_on_left_edge.png (34.98 Кб) Просмотров: 1516
Обращаю внимание на обведённый красным указатель мыши, который в момент скришота тащит за «корешок» ReBar-а — как раз за возможность произвольной компоновки и отвечает контрол ReBar.

А вот я это сборище вернул обратно наверх, поменял визуальную компоновку (мышкой) и добавил к ним ещё и языковую панель:
my_top_panel_2.png
my_top_panel_2.png (52.94 Кб) Просмотров: 1516


Ладно, довольно примеров.

Суть, ещё раз, в том, что Windows позволяет кому угодно взять и написать свою произвольную панель.

При этом, программисту не нужно беспокоиться за следующие вещи, потому что Windows берёт ответственность за них на себя:
  • За создание контейнера для собственной панели
  • За реализацию логики авто-скрытия панели (если надо), за то, чтобы обычные окна не перекрывлаи собой панели, когда развёрнуты на весь экран.
  • За механизм перетаскивания панелей, перегруппировки, за возможность менять их взаимное расположение
  • За запоминание (для каждого пользователя), где, в каком месте и как пользователь поместил каждую панель, чтобы при следующем входе в систему расположить всё снова так, как было раньше.

То есть, система предоставляет программисту готовый контейнер, внутри которого он может делать что угодно (хоть на голове плясать). Этот контейнер будет помещён в ReBar-контрол, то есть юзер сможет двигать панели, менять расположение, включать режим «Закрепить панели инструментов», а система всё это запомнит.

Так как же, в конце-концов, программисту написать свою собственную произвольную панель с произвольной начинкой?

Для этого, в лучших традициях ООП и COM, программисту нужно написать класс, поддерживающий интерфейс IDeskBand (или IDeskBand2, в котором добавлено несколько методов для поддержки «полупрозрачных» панелей).

Далее ActiveX-библиотека (DLL), реализующая этот класс, регистрируется в реестре в специальном месте.

Вот так совпадение, из всех языков программирования, написать ActiveX-библиотеку с классом, реализующим некий системный интерфейс, проще всего на VB6 — он как раз создан для этих задач, он единственный, где классы это априори COM-классы, а объекты — априори COM-объекты. Всего-то написать Implements IDeskBand в теле класса первой строчкой (вернее второй — после Option Explicit). На самом деле, конечно, тут есть своя масса сложностей.

Когда проводник (explorer.exe) запускается, он идёт в реестр и проверяет специальный раздел, чтобы найти список зарегистрированных в системе custom-панелей. Если одну из таких панелей нужно отображать (потому что пользователь уже включил её отображение в меню, которое можно было увидеть на скриншотах выше), то проводник порождает экземпляр класса (олицетворяющего панель), создаёт для панели контейнер и взаимодействует через методы этого класса с кодом, который и реализует произвольную панель.

Кстати говоря, абсолютно тем же методом реализуются панели для окна проводника (того окна, в котором отображаются файлы и папки) и для Internet Explorer-а, разница только в разделе реестра, где такие панели регистрируются.

___________

На самом деле, помимо IDeskBand нужно проимплементировать (реализовать) ещё парочку интерфейсов:
  • IObjectWithSite — через метод которого оболочка передаёт нам указатель на объект-контейнер, внутри которого мы (мы = панель) должны осуществлять жизнедеятельность.
  • IPersistStreamInit — через который осуществляется сохранение/загрузка специфичных для панели данных, например данных о её состоянии.

Если вкратце, то процесс создания и встраивания панели в оконную иерархию оболочки происходит по следующему сценарию:
  • Хост (так я дальше буду называть процесс explorer.exe или процесс Internet Explorer-а) создаёт экземпляр нашего класса.
  • Хост вызывает у нашего объекта метод IDeskBand::GetBandInfo с целью получить информацию о нашей панели. Мы внутри этого метода должны заполнить структуру DESKBANDINFO, на которую будет смотреть хост. В этой структуре не так много полей: название панели, максимальные габариты, минимальные габариты, текущие габариты, минимальный шаг изменения размеров по вертикальной оси (например, для панели со значками имеет смысл сделать в качестве шага размер значка, чтобы размер панели изменялся кратно размеру значка), задний цвет фона, флаги.
  • Хост, в соответствии с полученной от предыдущего шага информацией, порождает контейнер для будущей панели.
  • Хост вызывает метод IObjectWithSite::SetSite нашего объекта и передаёт нам ссылку на другой объект, олицетворяющий контейнер, в которой мы (как панель) должны быть встроены. У этого объекта мы должны запросить интерфейс IOleWindow и вызвать метод GetWindow — тут мы получил хендл (HWND) окна-контейнера.
  • Дальше, имея хендл окна контейнера, мы можем в нём порождать другие дочерние контролы (например ToolBar или какие угодно другие), либо рисовать в нём что-то. Можно, с другой стороны, если кому-то в тягость порождать дочерние контролы или рисовать что-то вручную, попробовать строить готовый VB-шный UserControl в область контейнера, используя OLE-шные способы встраивания.

Разумеется, нужно реализовать и другие методы IDeskBand (который унаследован от IDockingWindow) — ShowDW, ResizeBorderDW, CloseDW.

Второй момент состоит в том, что в Windows 7 этот прекрасный механизм изничтожили. Это ещё одна из причин, почему я не перехожу на Windows 7. Но и там на замену (вроде бы как) предложили другой встроенный системный механизм, которым следует пользоваться.

bon818 писал(а):И причем здесь workarea(рабочая область) , где про это можно прочитать?

Руководствуясь соображениями, что пользователю понадобится прилеплять различные панели и окна к боковым граням экрана, что такие приложения рано или поздно появятся, и что как минимум сам механизм, который я описал выше, тоже даёт возможность прилеплять панели к боковым граням, люди в Microsoft создали понятие «work area» — это область, которую занимают обычные окна при максимизации (разворачивании «на весь экран»), и область, до которой ужимается рабочий стол, а вернее все значки на рабочем столе.

Моя мысль была в том, что если не использовать системный механизм с IDeskBand, который я описал выше, а делать всё вручную, то чтобы наша импровизированная боковая панель не страдала от того, что её постоянно накрывают какие-то окна, есть смысл переустановить область work area (SPI_SETWORKAREA) так, чтобы наша боковая панель оказалась вне work area.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как запретить сворачивать форму?

Сообщение bon818 » 07.12.2016 (Ср) 19:42

Хакер писал(а):Второй момент состоит в том, что в Windows 7 этот прекрасный механизм изничтожили. Это ещё одна из причин, почему я не перехожу на Windows 7. Но и там на замену (вроде бы как) предложили другой встроенный системный механизм, которым следует пользоваться.

Большое спасибо за столь подробное объяснение этой темы.
Аж жаль, что эта статья, а это статья, оказалась не на своем месте, а именно в теме "Как запретить сворачивать форму?"
Возможно, нужно создать новую тему, чисто по проблеме реализации этих самых боковых панелей.
Я даже сам готов взяться за реализацию, при условии, что найду на это время.

Но вот, что понял Я:
Что реализовывать боковые панели, нужно исключительно стандартными ф-ми WINAPI,
и слава Билу, что они не меняются(ну или почти и слегка) десятками лет.

Отдельное спасибо за напоминание о (SystemParametersInfo SPI_SETWORKAREA) , конечно все равно пришлось бы дойти до этого самому,
но теперь все намного понятнее, как это делать, к тому-же придется учитывать и мультидисплейность.

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

    TopList