Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.05.2010, 14:02   #1
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию Синхронизация видимости немодальной формы в надстройке

Подскажите, уважаемые профессионалы!
При синхронизации видимости немодальной формы надстройки (при открытии или активизации окон "чужих" файлов - должна скрываться), столкнулся с необходимостью вводить задержку. Причем только для случая, когда при видимой форме сворачивается окно Excel,
Демопрограмма - во вложении
Все работает, но секундная задержка лезет в глаза
Invert_Data.xla – файл надстройки
InvertData.xls – файл, из которого доступен пуск надстройки
(из меню Сервис – Надстройки – Инвертор Данных)
Логика программы:
Модуль класса WbEvents
Секция Declarations
Public WithEvents XL As Application

Модуль общего назначения (Module1)
Секция Declarations
Public X As New WbEvents

Модуль книги (надстройки)
Private Sub Workbook_Open()
……..
Set X.XL = Application
End Sub

В модуле класса WbEvents – синхронизация видимости окна формы

Private Sub XL_WindowActivate(ByVal Wb As Workbook, ByVal Wn As Window)
If Wn.Caption = "InvertData.xls" Then
If FShow = True Then
UserForm1.Show
DelMenuItem
Else
AddMenultem
End If
End If
End Sub

Private Sub XL_WindowDeactivate(ByVal Wb As Workbook, ByVal Wn As Window)
If Wn.Caption = "InvertData.xls" Then
DelMenuItem
If FShow = True Then
'без ввода задержки, если свернуть окно Excel с видимой формой _
и после этого развернуть окно другого файла Excel - _
форма остается видимой (не скрывается)

Application.Wait (Now + TimeValue("0:00:01"))
UserForm1.Hide

End If
End If
End Sub
Вложения
Тип файла: rar Set_Invert.rar (34.0 Кб, 13 просмотров)
alvazor вне форума Ответить с цитированием
Старый 13.05.2010, 14:28   #2
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Вопрос,файл не смотрел еще и не вник в суть .А управление прозрачностью формы не подойдет?
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 13.05.2010, 14:40   #3
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию

Честно говоря, не думал над этим вариантом. Боюсь, что по сути возникнет такая же проблема, т.к. без задержки команда просто игнорируется (события как-то непоследовательно срабатывают). И какая тут разница - скрыть или сделать прозрачной?
alvazor вне форума Ответить с цитированием
Старый 13.05.2010, 18:23   #4
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

разница большаяСначала делаем ее прозрачной..Работает нормально.поданные идеи надо проверять
Код:
Private Sub XL_WindowActivate(ByVal Wb As Workbook, ByVal Wn As Window)
If Wn.Caption = "InvertData.xls" Then
    If FShow = True Then
        UserForm1.Show
        SetVis FindWindow(vbNullString, UserForm1.Caption)
        DelMenuItem
    Else
        AddMenultem
    End If
End If
End Sub

Private Sub XL_WindowDeactivate(ByVal Wb As Workbook, ByVal Wn As Window)
If Wn.Caption = "InvertData.xls" Then
    DelMenuItem
    If FShow = True Then
    
          SetTransparent FindWindow(vbNullString, UserForm1.Caption)
        
        UserForm1.Hide
    End If
End If
End Sub
Код модуля .урезан,взят из работы EducatedFool
Код:
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
'Функция задаёт стиль окна
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
'Функция делает окно прозрачным

Public Const LWA_COLORKEY = &H1: Public Const LWA_ALPHA = &H3
Public Const GWL_EXSTYLE = (-20): Public Const WS_EX_LAYERED = &H80000


Public Function SetTransparent(hWnd As Long) As Boolean    'регулирует прозрачность формы
    On Error GoTo 1    'hWnd - манипулятор окна, Layered - степень прозрачности от 0 до 255
    Dim Ret As Long: Ret = GetWindowLong(hWnd, GWL_EXSTYLE)    'Определяем стиль нужного окна
    Ret = Ret Or WS_EX_LAYERED    'Задаём стиль окна как заслоённый
    SetWindowLong hWnd, GWL_EXSTYLE, Ret
    SetLayeredWindowAttributes hWnd, 1, 10, LWA_ALPHA    'Задём степень прозрачности окна
    SetTransparent = True: Exit Function
1   Exit Function
End Function
Public Function SetVis(hWnd As Long) As Boolean    'возвращает видимость форме
    On Error GoTo 1    'hWnd - манипулятор окна, Layered - степень прозрачности от 0 до 255
    SetWindowLong hWnd, GWL_EXSTYLE, 257    'Задаём стиль окна как незаслоённый (возвращаем прежнее значение)
    SetLayeredWindowAttributes hWnd, 1, 255, LWA_ALPHA    'Задём степень прозрачности окна
    SetVis = True: Exit Function
1   Exit Function
End Function
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 14.05.2010, 10:01   #5
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию for doober

Спасибо и Вам и EducatedFool, API и функции прозрачности работают и без таймаута!
Я тупо скопировал функции в отдельный модуль и вставил Ваши строчки в модули открытия-закрытия окон - см. вложение.
Но вот какая выскочила штука.
Опять-таки, если окно Excel с открытой формой свернуть, а потом открыть (или развернуть окно) любого другого файла *.xls, то хотя с видимостью формы все в порядке (прозрачна), в панели задач возникает как бы свернутое окно формы. В данном случае - UserForm1. Т.е. команда Hide не прходит.
Оно вроде как и не мешает, но у меня в рабочей надстройке м.б. одновременно открыто до 6 форм. Более того, одновременно м.б. инсталлировано и параллельно работать несколько надстроек. При этом вся панель задач будет забита "мертвыми" окнами, что не очень...
М.б. есть способ отловить этот дурной момент - сворачивание окна?
Еще раз спасибо за школу по API! Может у Вас есть ссылка на приличную библиотеку функций, а то я в своей нашел только одну из используемых
Вложения
Тип файла: rar Set_Invert1.rar (36.7 Кб, 6 просмотров)
alvazor вне форума Ответить с цитированием
Старый 14.05.2010, 10:17   #6
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию

Причем эта хня происходит только если сворачивается окно приложения вместе с рабочим файлом, в котором открыта форма. Если сворачивать окно самого рабочего файла с видимой формой - все работает, как положено
alvazor вне форума Ответить с цитированием
Старый 14.05.2010, 11:38   #7
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Посмотрите здесь
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 14.05.2010, 16:59   #8
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию for doober

Спасибо, классная лекция.
Методом тыка нашел вариант - пришлось дополнительно к "прозрачности" для скрытия окна применить тоже функцию API, а не команду vba (Hide). Причем если применить только функцию API и без задержки - эффекта нет. Sleep - вообще не дает эффекта.
Но уж очень громоздко получится для 6 окон, да и тормозить, скорее всего, начнет.
Понятно, что при сворачивании окна приложения никаких событий с окнами книг и форм не происходит, они остаются в прежнем состоянии. Но почему потом, при открытии "чужой" книги (где не должно быть формы) и появления события деактивирования основного окна не успевает срабатывать Hide???
Неужели нельзя никак отловить событие сворачивания окна приложения?
Вложения
Тип файла: rar Set_Invert2.rar (37.7 Кб, 10 просмотров)
alvazor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
область видимости Dimarik Общие вопросы .NET 5 21.02.2010 21:32
область видимости процедур Uli9 Общие вопросы Delphi 16 06.12.2008 21:09
область видимости переменных. С++ Prestigio Помощь студентам 10 07.07.2008 15:55
ошибся с областью видимости ? Иванчо Общие вопросы Delphi 8 25.10.2007 16:35
область видимости ? artem779 Общие вопросы Delphi 3 14.09.2007 09:34