Сделать форму MDIchild-ом во время работы программы

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Mongoose
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 29.03.2004 (Пн) 17:03
Откуда: Московский зоопарк

Сделать форму MDIchild-ом во время работы программы

Сообщение Mongoose » 09.01.2006 (Пн) 15:50

Как с помощью API изменять свойство mdichild окна? Через стандартные свойства только во время разработки работает...
I Wish I Had An Angel For One Moment Of Love.

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 09.01.2006 (Пн) 16:20

Создавай окно через CreateWindow со стилем WS_CHILD. После создания окна изменить его "принадлежность" нельзя.
Моду создают модоки, а распространяют модозвоны.

Mongoose
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 29.03.2004 (Пн) 17:03
Откуда: Московский зоопарк

Сообщение Mongoose » 09.01.2006 (Пн) 17:02

У меня уже есть, скажем, Form1 с некоторым набором контролов и т.д. Как её сделать child-ом с помощью CreateWindow?
I Wish I Had An Angel For One Moment Of Love.

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 09.01.2006 (Пн) 17:17

Нельзя. Нужно создать новое окошко с нужным стилем. Вручную. Кстати, в .NET Framework это делается автоматически - убивается окно со старым стилем и создается точно такое же новое.

Может быть, нужного тебе эффекта можно добиться, эмулируя поведение child-окна, ну, например, функцией SetParent?
Моду создают модоки, а распространяют модозвоны.

Mongoose
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 29.03.2004 (Пн) 17:03
Откуда: Московский зоопарк

Сообщение Mongoose » 09.01.2006 (Пн) 17:25

SetParent уже сделал... В принципе и меню-список Child-окон вручную сделать можно... А как сделать чтобы при перемещении окна за границы родительского появлялись полосы прокрутки? Для обычных childов работает, а для полученных с помощью SetParent - нет!
I Wish I Had An Angel For One Moment Of Love.

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 09.01.2006 (Пн) 18:51

Блин. А сделать два одинаковых окна, одно из которых MDIChild, а другое - нет, не судьба? Ибо в данном случае это ограничение со стороны архитектуры Windows. Бу дезигн.

Один из тех редких случаев, когда самое топорное решение оказывается самым эффективным по количеству затраченных усилий (в т.ч. умственных).

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 09.01.2006 (Пн) 19:08

2hCORe: Почтие все окна имеют стиль WS_CHILD, так как являются "детьми" десктопа. Твой способ ему совсем не поможет.
Боюсь, что это вообще не возможно... Но попытаться можно.

2Mongoose: У MDI-формы есть потомок класса MDIClient, попробуй установить его как родителя.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Mongoose
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 29.03.2004 (Пн) 17:03
Откуда: Московский зоопарк

Сообщение Mongoose » 10.01.2006 (Вт) 2:56

2Ennor: Таких окон около 15-20 будет... Соответственно делать 30-40? Не слишком ли?
2ANDLL: Так и делал... Не помогло =(
I Wish I Had An Angel For One Moment Of Love.

Naked
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 207
Зарегистрирован: 27.10.2004 (Ср) 3:16
Откуда: Дальнегорск столица мира

Сообщение Naked » 10.01.2006 (Вт) 4:01

Можно и возможно.

Создаем новый проэкт (по умолчанию создается форма, назовем Form1 и в свойствах ставим MDIChild = Да), добавляем MDIForm обзываем MDIForm1, добавляем еще одну форму с названием tmpChild.

в модуле формы MDIForm1 пишем
Private Sub MDIForm_Load()
tmpChild.Show
End Sub

Private Sub MDIForm_Unload(Cancel As Integer)
End
End Sub


в модуле формы tmpChild пишем
Private Sub Form_Click()
Call HookChildForm(hWnd)
End Sub

Private Sub Form_Unload(Cancel As Integer)
Call UnHookChildForm(hWnd)
End Sub


пишем в модуле Module1
Option Explicit

Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function DefMDIChildProc Lib "user32" Alias "DefMDIChildProcA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const GWL_EXSTYLE = (-20)
Public Const GWL_STYLE = (-16)
Public Const WS_EX_MDICHILD = &H40
Public Const WS_CHILD = &H40000000
Public Const GWL_WNDPROC = (-4)

Public ChildWndProc As Long
Dim MDIClient As Long
Dim GWL As Long

Sub HookChildForm(hWnd As Long)
MDIClient = GetWindow(MDIForm1.hWnd, 5)
Call SetParent(hWnd, MDIClient)

GWL = GetWindowLong(hWnd, GWL_STYLE)
Call SetWindowLong(hWnd, GWL_STYLE, GWL Or WS_CHILD)

GWL = GetWindowLong(hWnd, GWL_EXSTYLE)
Call SetWindowLong(hWnd, GWL_EXSTYLE, GWL Or WS_EX_MDICHILD)

ChildWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf ChildWindowProc)
End Sub

Sub UnHookChildForm(hWnd As Long)
Call SetWindowLong(hWnd, GWL_WNDPROC, ChildWndProc)
End Sub

Function ChildWindowProc(ByVal hWnd As Long, ByVal message As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case message

Case Else
ChildWindowProc = DefMDIChildProc(hWnd, message, wParam, lParam)
End Select
End Function

Конец.

Naked
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 207
Зарегистрирован: 27.10.2004 (Ср) 3:16
Откуда: Дальнегорск столица мира

Сообщение Naked » 10.01.2006 (Вт) 13:21

а говорили что невозможно, ограничения винды...

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 10.01.2006 (Вт) 16:18

Интересно, кто такое говорил? Процетируй. Особенно на счет ограничения винды :)
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 10.01.2006 (Вт) 17:44

ANDLL
Ennor писал(а):Ибо в данном случае это ограничение со стороны архитектуры Windows. Бу дезигн.
Изображение

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 10.01.2006 (Вт) 18:35

Совершенно верно, это был я. И я это говорил не просто так.

Наличие стиля класса окна WS_EX_MDICHILD в природе еще не означает, что этот стиль можно изменить в рантайме у уже созданного окна. Слегка причесав код твоего примера (из-за обилия форм приходится некоторое время колдовать со свойством Startup Object, ну и оконная процедура там ни к чему) и запустив его, можно увидеть, что некоторая степень подобия достигается, но - не более того. Один из найденных косяков: после "смены" стиля окна на дочернее максимизировать дочернее окно, после чего максимизировать MDI-окно. Инвольтировать на увиденное одну минуту.

Аналогичный пример - свойство Style контрола Listbox. Если контрол создан со стилем Checkbox, то убрать чеки невозможно, иначе как задестроив окно и создав его заново с нужным стилем. Таких мест в Windows - считанные единицы, но они есть.

Mongoose
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 29.03.2004 (Пн) 17:03
Откуда: Московский зоопарк

Сообщение Mongoose » 12.01.2006 (Чт) 17:49

2Ennor: У меня ничего противоестественного не возникает, если максимизировать дочернее окно, после чего максимизировать MDI-окно. :-/

2Naked: У меня работает твой код, но он в принципе не завершается корректно =) Всегда убивает IDE =) Возможно это из-за "end" в "MDIForm_Unload" Сейчас не хватает времени, чтобы разобраться... Но спасибо! =)

Хотя есть пара минусов всё-таки... Это окно не попадает в список child-окон и в его меню отсутствует пункт "следующее окно".. Поэтому мне больше подойдёт наверное простой setparent + не давать окнам выходить за пределы родителя =) А максимизировать мне и не надо, все окна имеют стиль toolwindow =)
I Wish I Had An Angel For One Moment Of Love.


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

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

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

    TopList