MDI child окна - в таскбар?

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

MDI child окна - в таскбар?

Сообщение ZlydenGL » 13.08.2004 (Пт) 10:52

Всем добрый день!!!

Занимаюсь разработкой своей программы, в двух словах это проект с MDI родительским окном и произвольным числом дочерних окон. С родительским все понятно - оно отображается в таскбаре. А вот можно ли сделать, чтобы и дочерние окна тоже отображались в таскбаре и при щелчке по ним в таскбаре происходил переход на соответствующее окно?

Подобная задача реализована в M$ Office 2000/XP, если в настройках не указано обратное.

Заранее спасибо за советы!!!

Среда разработки - VB6
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.08.2004 (Пт) 12:31

Первое, что приходит в голову - насоздавать невидимых top-level окон, и чтобы при их активации вылезало нужное дочернее окно. Говорят, где-то (в IDE Делфи, что ли?) так и сделано.

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 13.08.2004 (Пт) 12:55

Семен Семеныч!!!

Воистину, все гениальное - просто :-) Попробую воплотить!

А других вариантов нет?

Похоже не получится :( Когда пользователь щелкает по таблице - ответственная кнопка в тулбаре гаснет, а кнопка основной программы - подсвечивается :cry:
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

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

Сообщение Ennor » 13.08.2004 (Пт) 15:16

Я бы попробовал изменить оконный стиль через SetWindowLong(). Правда, лично меня дико бесит как раз этот стиль 2000-го офиса, и я предпочитаю классический MDI...

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 13.08.2004 (Пт) 15:20

[quote="Ennor"][/quote]
Дык меня тоже!!! Но с заказчиком как известно не спорят :-) А если подробней - как воспользоваться этой функцией для достижения моей цели?
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

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

Сообщение Ennor » 13.08.2004 (Пт) 17:52

Ну, стоит почитать в MSDN разделы Window Styles, Extended Window Styles, а также хелп по самой функции. Там много всяких фишек, но главное, что надо знать - нельзя так просто установить стиль окна, надо сначала вытянуть его текущий, через GetWindowLong(), после чего установить/снять в нем нужные тебе флаги, и только тогда устанавливать его через SetWindowLong(). И еще такая фишка: если ты просто возьмешь hWnd формы и будешь работать с ним, то может ничего не получиться. Надо сделать так: для формы получить указатель на ее владельца через GetOwnerWindow() и уже с его hWnd проделывать все манипуляции. В свое время, когда я пытался свое окно отображаться в таскбаре, мне именно так работать и пришлось. Код, правда, пропал, к сожалению, но он довольно простой - сплошняком API, никаких заморочек...

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 8:41

Может быть все же у кого-нибудь остался исходник? А то у меня похоже лыжи не едутъ :-(

Пишу в коде:
Код: Выделить всё
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Const WS_EX_APPWINDOW = &H40000
Const GWL_EXSTYLE = (-20)
Const SW_HIDE = 0
Const SW_NORMAL = 1
Dim ret&
....

Private Sub Command1_Click()
ShowWindow frmNew.hwnd, SW_HIDE
ret = GetWindowLong(frmNew.hwnd, GWL_EXSTYLE)
SetWindowLong frmNew.hwnd, GWL_EXSTYLE, ret Or S_EX_APPWINDOW
ShowWindow frmNew.hwnd, SW_NORMAL
End Sub


Код выполняется без единой ошибки - но окно не становится таким, какое мне нужно :? PLEASE, HELP!!!
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 16.08.2004 (Пн) 10:53

Некоторые стили можно задать только при создании окна...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 11:53

Да вроде эти стили можно менять онлайн - как утверждает автор примера на VB.
Автор похожей статьи на Дельфях говорит о том же:
Для показа окна:
Old:=GetWindowLong(Application.Handle,GWL_EXSTYLE);
SetWindowLong (Application.Handle,GWL_EXSTYLE,Old or WS_EX_APPWINDOW)
Это можно сделать в любом!!! месте программы. Для любых!!! форм.
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 16.08.2004 (Пн) 12:10

ZlydenGL писал(а):Может быть все же у кого-нибудь остался исходник? А то у меня похоже лыжи не едутъ :-(

Пишу в коде:
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Const WS_EX_APPWINDOW = &H40000
Const GWL_EXSTYLE = (-20)
Const SW_HIDE = 0
Const SW_NORMAL = 1
Dim ret&
....

Private Sub Command1_Click()
ShowWindow frmNew.hwnd, SW_HIDE
ret = GetWindowLong(frmNew.hwnd, GWL_EXSTYLE)
SetWindowLong frmNew.hwnd, GWL_EXSTYLE, ret Or S_EX_APPWINDOW
ShowWindow frmNew.hwnd, SW_NORMAL
End Sub


Код выполняется без единой ошибки - но окно не становится таким, какое мне нужно :? PLEASE, HELP!!!

Option Explicit поставь - сразу все ошибки сам увидишь...
Последний раз редактировалось tyomitch 16.08.2004 (Пн) 12:19, всего редактировалось 1 раз.

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 12:15

С самого начала стоит...
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 16.08.2004 (Пн) 12:20

Тогда как объяснишь выделенное жирным?
([b] внутри [code] не работало, я поменял [code] на [quote])

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 12:33

В чем конфликт-то получился? Вроде же нет ошибки в описании...

Вот реальный код, начало модуля:

Код: Выделить всё
Option Explicit
...
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Const WS_EX_APPWINDOW = &H40000
...
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 16.08.2004 (Пн) 13:03

В твоём сообщении ты используешь необъявленную константу S_EX_APPWINDOW.
Или нет?

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 13:08

Сорри, это я похоже Del'ом лишний раз сработал :-) в коде используется строка
Код: Выделить всё
SetWindowLong frmEditNew.hWnd, GWL_EXSTYLE, ret Or WS_EX_APPWINDOW

В общем, использовался пример, написанный здесь
Последний раз редактировалось ZlydenGL 16.08.2004 (Пн) 13:22, всего редактировалось 1 раз.
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 16.08.2004 (Пн) 13:18

А, тогда сорри :-)
Щас попробую сам.
[прошло 10 минут]
Хз, у меня не вышло. Наверное, и правда в рантайме так нельзя.

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 16.08.2004 (Пн) 15:51

Ни у кого больше нет идей? У меня тоже не получилось :-(
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 16.08.2004 (Пн) 16:18

Как последнее средство попробуй setwindowpos с флагом SWP_FRAMECHANGED и с запретом на изменение всего остального :roll:
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 11:48

А опять-таки можно хотя бы простейший исходничек увидеть? С API почти не сталкивался, к сожалению бОльшая часть фразы - непонятки :-(
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.08.2004 (Вт) 12:07

Код: Выделить всё
Option Explicit

Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Private Const SWP_FRAMECHANGED As Long = &H20
Private Const SWP_NOACTIVATE As Long = &H10
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOOWNERZORDER As Long = &H200
Private Const SWP_NOSIZE As Long = &H1
Private Const SWP_NOZORDER As Long = &H4

Private Sub Command1_Click()
  SetWindowPos Me.hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED Or SWP_NOACTIVATE Or SWP_NOMOVE Or SWP_NOOWNERZORDER Or SWP_NOSIZE
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 12:43

Бесполезно...

Сорри...
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 13:49

Так, похоже, лыжи все же не едутъ...

Новые данные: после отработки команды ShowWindow Me.hwnd, SW_NORMAL команда GetWindowLong(Me.hwnd, GWL_EXSTYLE) возвращает значение 262400. Так и должно быть?

Самое странное, участок кода сейчас такой:
Код: Выделить всё
ShowWindow Me.hwnd, SW_HIDE
Ret = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
SetWindowLong Me.hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW 'Ret Or WS_EX_APPWINDOW
ShowWindow Me.hwnd, SW_NORMAL


Если же использовать оригинальную строку

Код: Выделить всё
SetWindowLong Me.hwnd, GWL_EXSTYLE, Ret Or WS_EX_APPWINDOW


то GetWindowLong(Me.hwnd, GWL_EXSTYLE) возвращает 262464
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.08.2004 (Вт) 13:57

Не надо напрямую делать. Надо делать через Or.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 13:58

А почему тогда в результате получается то же значение, что и до команды SetWindowLong?

P.S. Do... Loop рулит! ;)
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.08.2004 (Вт) 14:02

Видимо, вызов проходит неудачно ввиду неверной комбинации флагов, вернее, отсутствия таковой вообще :)

ЗЫ: Ага... 8)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 14:06

А подробней можно?
1. Почему он вообще проходит неудачно? Можно это как-то оттрассировать?
2. Что подразумевается под флагами (я правильно понимаю что это например GWL_EXSTYLE)?

В принципе в проге используется некий тулбар и ребар, широко использующие в своем коде именно APIшные штуки (из-за чего невозможно нормально дебажить!!!). Может это мешать?
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.08.2004 (Вт) 14:15

Трассируется просто - что возвращает сама функция setwindowlong и чему после неё равно err.lastdllerror?
Неудачно потому, что у окна уже есть некоторые стили, а ты их игноришь и ставишь только один. В то время как нужно взять то, что уже есть, и поставить ещё биты (через or).
А компоненты если написаны хорошо, так проблем не вызовут :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 17.08.2004 (Вт) 14:22

Ышшо раз прогнал - результат следующий.

В оригинале кода стили задаются именно через Or - c ним и оставлю.
Результат: после выполнения команды ShowWindow Me.hwnd, SW_NORMAL возвращается значение таки 262464 - то же, что и было до выполнения SetWindowLong. Err.LastDLLError возвращает 0. SetWindowLong также возвращает 262464.

Караул. :evil:
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

ZlydenGL
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 148
Зарегистрирован: 13.08.2004 (Пт) 10:02

Сообщение ZlydenGL » 01.09.2004 (Ср) 11:49

Продолжение истории. Делаю свой независимый от Виндовозного таскбар прямо в MDI окне (TabStrip). Проблема следующая - как заставить по нажатию кнопки в этом таскбаре окно, привязанное к данной кнопке, отобразиться поверх всех? пробовал следующие конструкции:
Код: Выделить всё
Application.Windows(TaskButtons.SelectedItem.Index - 1).Activate

SetForegroundWindow ReportWindows(TaskButtons.SelectedItem.Index)

ShowWindow ReportWindows(TaskButtons.SelectedItem.Index), 10

Forms(TaskButtons.SelectedItem.Index + 1).Show


Естественно, пробовал не все подряд, а поочередно. Не рабтает. :evil: Переменная ReportWindows - одномерный массив с хэндлами новых окон (добавляются по факту загрузки новых окон). Массив заполняется корректно.

Что еще можно использовать?
Покой нам только снится!!! И то редко. Поскольку нет в мире совершенства, а есть только стремление к оному.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.09.2004 (Ср) 12:05

Forms().SetFocus
Lasciate ogni speranza, voi ch'entrate.

След.

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

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

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

    TopList