Оба ответа здесь хороши, но не учли того, что я считаю действительно интересными (включая пару, которую вы не спрашивали напрямую, но вы могли бы найти интерес в любом случае), так что вот мой 2c:
Рисование элементов управления
В идеале, вы просто идете вперед и создаете обычный экземпляр элемента управления. Вы хотите что-то похожее на кнопку? Создать настоящую кнопку. Хитрость заключается в том, что он перестает вести себя как кнопка: вы хотите, чтобы щелчки активировали его для перемещения, а не «нажимали» на него.
Один из способов справиться с этим - предполагая, что рассматриваемые элементы управления «основаны на HWND» (например, стандартный набор окон для кнопки, редактирования, статики, списка, древовидного отображения и т. Д.) - это создать элемент управления, а затем подкласс это - т.е. переопределите wndproc с помощью SetWindowLongPtr (GWLP_WNDPROC, ...), чтобы код конструктора мог перехватывать ввод с помощью мыши и клавиатуры и использовать его, например, для инициирования перемещения, вместо того, чтобы ввод мыши осуществлялся до действительного кода кнопки, который вместо этого будет интерпретировать его как событие «щелчка».
Альтернативный подход к созданию подклассов заключается в размещении невидимого окна над кнопкой для ввода ввода. Та же идея перехвата ввода, просто другая реализация.
Вышесказанное относится как к управляемым (VB.Net, C #), так и к неуправляемым (C / C ++) элементам управления; они оба по сути стоковые окна HWND; у управляемых версий просто есть код управляемой оболочки, передаваемый базовому неуправляемому элементу управления.
Старые элементы управления ActiveX (с предварительно заданным кодом), используемые в pre-.Net VB, представляли собой совершенно другую игру с мячом. Существует довольно сложная взаимосвязь между контейнером ActiveX и элементами управления ActiveX внутри него, причем многие COM-интерфейсы обрабатывают такие вещи, как согласование свойств, события, рисование и т. Д. (Существует набор интерфейсов, который позволяет элементу управления ActiveX получать входные данные и рисовать себя, не имея собственного HWND.) Однако одно преимущество, которое вы получаете от этой сложности, заключается в том, что элементы управления ActiveX имеют явный «режим разработки»; поэтому элемент управления знает, как правильно реагировать в этом случае, и может взаимодействовать со всей процедурой.
Сама форма ...
Так что в основном элементы управления - это обычные элементы управления. Таким образом, вы ожидаете, что сама форма будет обычной формой? - Почти. Насколько я знаю, это просто еще одно окно, основанное на HWND, это дочерний элемент дизайнера (поэтому оно обрезается и может прокручиваться внутри него); но я думаю, что дизайнер немного обманывает, потому что обычно Windows рисует только такие кадры, как - с заголовками кнопок и мин / макс, которые используются для реальных окон верхнего уровня. Я не знаю от руки точную технику, которую они используют здесь, но некоторые варианты могли бы включать: нарисовать это вручную, чтобы подражать взгляду Windows; использование «тематических» API-интерфейсов Windows, которые позволяют получить доступ к графическим элементам, используемым для фрагментов заголовков и рисовать их там, где вы хотите; или, возможно, менее вероятно, что окно будет настроено как «дочернее окно MDI» - это один из исключительных случаев, когда окна рисуют рамку вокруг вложенного окна.
Перетаскиваемые ручки
Простейший подход здесь для дизайнера - создать восемь маленьких квадратных всплывающих окон без строки заголовка, которые располагаются над всеми остальными элементами - которые инициируют соответствующий код изменения размера при нажатии. Когда пользователь щелкает от элемента управления к элементу управления, просто переместите окна маркера перетаскивания в текущий активный элемент управления. (Обратите внимание, что во всем вышеперечисленном Windows сама выясняет, на кого нажали, вам никогда не придется сравнивать координаты мыши с координатами прямоугольника элемента и самостоятельно их обрабатывать.)
Сохранение и воссоздание
Для системных элементов управления с обычными окнами, которые используются неуправляемым C / C ++, это относительно просто: существует хорошо известный текстовый формат файла - .rc -, который описывает элементы управления и местоположения. Пусть дизайнер выплюнет это (и, вероятно, также файл resource.h), и все готово: любой проект C / C ++ может взять эти файлы и скомпилировать их. Управляемый код (C #, VB.Net) имеет несколько больше сложная схема, но это все та же основная идея: напишите описание в стиле, которого ожидают управляемые инструменты, и они с радостью скомпилируют его и будут его использовать.
(Элементы управления ActiveX - как вы уже догадались - целая другая история. Мне не известен стандартный формат, поэтому редактор форм и среда выполнения, в которой используются данные, будут тесно связаны друг с другом - например, редактор форм из pre- .Net VB6 создает формы, которые может использовать только VB. - Я думаю. Это было некоторое время назад ...)
Что касается воссоздания формы: если у вас есть файл .rc, он компилируется в ресурс диалога, в Windows имеется встроенная поддержка для его воссоздания. Аналогично, библиотеки поддержки управляемого кода знают, как воссоздать форму из ее определенного формата. Оба в основном анализируют описание, и для каждого элемента создают элементы соответствующих классов и задают соответствующий стиль, текст и другие свойства, как указано. Он не делает ничего, что вы не можете сделать сам, это всего лишь вспомогательный служебный код.
Обработка фокуса
Для набора HWND в любом контейнере, будь то в «тестовом» режиме или фактически работающем в реальном приложении, и независимо от того, позволяете ли вы Windows или Winforms обрабатывать создание формы или вы сами создали каждый HWND, вы можете добавить поддержка табуляции путем вызова IsDialogMessage в цикле сообщений: подробности см. в разделе замечаний на странице MSDN. (Хотя WinForms может это сделать, я думаю на самом деле выполняет свою собственную обработку фокуса, так что он может иметь порядок табуляции независимо от визуального стекового Z-порядка.)
Другие вещи для изучения ...
Подружитесь с приложением Spy ++ (входит в состав SDK, устанавливается вместе с Visual Studio). Если вы собираетесь что-то делать с HWND, управляемыми или неуправляемыми, очень полезно знать, как использовать этот инструмент: вы можете указать его на любой элемент пользовательского интерфейса в Windows и посмотреть, как он построен из дерева различные типы HWND. Направьте его на дизайнера VB и посмотрите, что на самом деле происходит для вас. (Щелкните значок «бинокль» на панели инструментов, затем перетащите перекрестие в интересующее вас окно.)
Также взгляните на файлы ресурсов, которые выкладывает дизайнер. Все, что можно настроить, переместить или отредактировать в конструкторе форм, соответствует некоторому элементу в одном из этих файлов ресурсов. Сделайте их копию, настройте некоторые параметры, а затем сравните файлы двух наборов и посмотрите, что изменилось. Попробуйте изменить некоторые вещи в файлах вручную (я думаю, что они почти все текстовые), перезагрузите компьютер и посмотрите, подхватил ли дизайнер ваши изменения.
Другие замечания ...
Многое из вышеперечисленного относится только к Windows, в частности к тому, что, поскольку мы используем собственные строительные блоки Window - HWND, - мы можем заставить саму Windows выполнить некоторую тяжелую работу за нас: это дает нам возможность повторно использовать сами элементы управления во время разработки, поэтому нам не нужно рисовать макеты; перехватывать ввод данных в других элементах управления, чтобы мы могли превратить щелчок в движение или в любое другое действие, которое мы хотим, или выяснить, по какому элементу управления выполняется щелчок, без необходимости самостоятельно определять местоположение. Если бы это был дизайнер для какой-то другой инфраструктуры пользовательского интерфейса - скажем, Flash - которая не использует HWND для внутреннего использования, скорее всего вместо этого она использовала бы
собственных внутренних средств платформы для выполнения аналогичной работы.
Кроме того, гораздо проще, если вы ограничите количество элементов управления в палитре небольшим конечным набором, по крайней мере, сначала. Если вы хотите разрешить перетаскивание любого элемента управления, например. сторонний или тот, который вы использовали в другом проекте; Обычно вам сначала нужно каким-то образом зарегистрировать этот элемент управления, чтобы разработчик знал, что он доступен в первую очередь. Также вам может понадобиться какой-то способ узнать, какой значок он использует на панели инструментов, как его имя, какие свойства он поддерживает - и так далее.
Веселитесь, исследуя!