vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest poniedziałek, 05 maja 2025 roku.
Ustaw jako stronę startową Ulubione Napisz
PowrótPowrót do serwisu  RegulaminRegulamin rssRSS

  tytuł wątku:
Wątki dyskusji

przycisk minimalizuj i maksymalizuj na UserForm


otwartyotwarty rozpoczął: du_gy postów: 15



napisał: jalamas
postów: 316


umieszczony:
21 listopada 2006
20:19

  
Cytat:
Na razie pozostaje więc rada jottad-a. Sprawdzać wersję Excela i od niej uzależnić działanie kodu


Artik
Przecież Jottad podał rozwiązanie.Jego, czyli kontrola wersji jest standardem stosowanym w każdej aplikacji
jeśli aplikacja ma pracować w różnych wersjach….
Nie tylko środowiska (Excela), lecz także systemu operacyjnego.
Samo Win API ulega zmianie !!!!!!!!! w zależności od systemu operacyjnego.
Kontrolujemy wersję, w tym na przykład wersję VBA a nawet samego Excela ponieważ już wersja 2000 różni się od 2002 dla niektórych metod i właściwości.
Możemy korzystać z kompilacji warunkowej.

Nie widzę potrzeby uruchamiania fragmentu API dla Userform od 2000 wzwyż
Dlatego też tu na przypadku UserForm ( i nie tylko w Excelu ) dodaję do form swoje własne publiczne Property.

Wykorzystuję fakt, że formę można najpierw w ładować, ustawiać właściwości (zdarzenie Initialize jest wykonywane), a potem "pokazywać"…
Posługuję się swoją funkcją wywołania formularza, a nie np.: UserForm27267.show
I tutaj na przykładzie tego co Jottad napisał:
- formy wywołuję przez nazwę (zamykam zresztą też)
- każda z moich Userform ma kod na przykład takii:
- deklaracje pominęłam… od miejsca….
Private mvarMojeModal As Boolean    'local copy

Public Property Let MojeModal(ByVal vData As Boolean)
    mvarMojeModal = vData
End Property

Public Property Get MojeModal() As Boolean
    MojeModal = mvarMojeModal
End Property

Private Sub UserForm_Activate()
    #If VBA6 Then
        ' nic nie trzeba bo w wywolaniu
    #Else
        Dim mlHWnd As Long
        On Error Resume Next
        mlHWnd = FindWindow("XLMAIN", Application.Caption)
        If MojeModal Then
            EnableWindow mlHWnd, 0
        Else
            EnableWindow mlHWnd, 1
        End If
    #End If
End Sub

Private Sub UserForm_Initialize()
Dim hwnd As Long
Dim lngStyle As Long
    hwnd = FindWindow(vbNullString, Me.Caption)
    lngStyle = GetWindowLong(hwnd, GWL_STYLE)
    lngStyle = lngStyle Or WS_MAXIMIZEBOX
    lngStyle = lngStyle Or WS_MINIMIZEBOX

    SetWindowLong hwnd, GWL_STYLE, lngStyle
    DrawMenuBar hwnd
End Sub


Kod modułu
Sub test()
    ShowUserFormModOrLess "frm_moja", False
End Sub

Public Sub ShowUserFormModOrLess(ByVal sFormName As String, _
                                 Optional bModal As Boolean = False)
' jesli potrzebuję a zwykle tak jest wiecej parametrów
' ogólnie dla wszystkich UserForm w swoim projekcie
' mam wzornik UserForm ze zbiorem moich standardowych właściwości
 ' i jest on w każdej UseForm. Tu przykładowo Property MojeModal
Dim iFrm As Long
    With UserForms
        'Load
        .Add (sFormName)
        iFrm = .Count - 1
    End With
    #If VBA6 Then
        With UserForms
            With .Item(iFrm)
                .MojeModal = bModal
                If bModal Then
                    .Show vbModal
                Else
                    .Show vbModeless
                End If
            End With
        End With
    #Else
        With UserForms
            With .Item(iFrm)
                .MojeModal = bModal
                .Show
            End With
        End With
    #End If
End Sub

Mam nadzieję, ze się nie pomyliłam....
napisał: r_c
postów: 38


umieszczony:
21 listopada 2006
12:47

  
ARTIK.
Jeżeli wyrazisz zgodę wyślę TOBIE plik Excela 2003 w pełni niemodalny.
Testując przykład JOTTAD_a zauważyłem pewną dziwną rzecz.
W nowym pliku Excela'2003 umieściłem kody zgodnie ze wskazówkami i po uruchomieniu uzyskałem efekt, który opisujesz. Następnie ustawiłem w okienku Properties > UserForm > ShowModal > False. Zapisałem plik i bezwzględu na ustawienia w Properties ShowModal > False lub True forma jest w 100% niemodalna.?????
Pozdrawiam r_c
napisał: jalamas
postów: 316


umieszczony:
20 listopada 2006
23:30

  
Oraz
http://www.bmsltd.co.uk/Excel/SBXLPage.asp
ModelessForm.zip
dla porównania.
napisał: jalamas
postów: 316


umieszczony:
20 listopada 2006
23:26

  
Zobacz jeszcze na stronie Stephena Bullena:
http://www.oaltd.co.uk/Excel/
FormFun.zip
napisał: jottad
postów: 118


umieszczony:
20 listopada 2006
00:08

  
Cytat:

Efekt jednak nie jest zadowalający. Owszem, myszką mogę sobie klikać po arkuszu (jest także menu podręczne), jednakże całkowicie straciłem kontrolę nad klawiaturą (żaden z klawiszy nie działa).
Czy coś nie tak zrobiłem, czy to raczej niedoskonałość kodu? ;)


Kod sprawdziłem w Excel 97 i działał prawidłowo! Natomiast w wyższych wersjach Excela, faktycznie występuje problem obsługi klawiatury! Wygląda na to, że jednak kod nalezy nieco zmodyfikować. Jednak w tej chwili trudno jest mi powiedzieć w jaki sposób :(
Muszę poeksperymentować w wolnej chwili.
Prowizorycznym rozwiązaniem moze być użycie Application.Version do sprawdzanie wersji Excela, a następnie uruchamianie kodu UserForm_Activate tylko dla E97. W przypadku pozostałych wersji, można zastosować argument vbModeless przy uruchamianiu formularza.

Pozdrawiam.
napisał: r_c
postów: 38


umieszczony:
19 listopada 2006
21:55

  
Wyszperane w necie lekko modyfikowane:
Option Explicit
'// Modifications & comments by Ivan F Moala
'// Define the API's for menu's
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
Private Declare Function SetFocus Lib "user32" _
            (ByVal hwnd As Long) _
                                             As Long
Private Declare Function DrawMenuBar Lib "user32" _
            (ByVal hwnd As Long) _
                                             As Long
Private Declare Function FindWindowA Lib "user32" _
            (ByVal lpClassName As String, _
             ByVal lpWindowName As String) _
                                             As Long
'// Extended Styles
Private Const GWL_EXSTYLE = (-20)
'// Sets a new window style
Private Const GWL_STYLE As Long = (-16)
'// General Windows Styles Bits
'// Sets Min Form to task bar
Private Const WS_EX_APPWINDOW = &H40000
'// WinStyle Sys Menu
Private Const WS_SYSMENU As Long = &H80000
'// WinStyle_MaxButton
Private Const WS_MINIMIZEBOX As Long = &H20000
'// WinStyle_MinButton
Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_POPUP As Long = &H80000000
Dim lFrmWndHdl As Long
Dim lStyle As Long

Private Sub UserForm_Activate()
lFrmWndHdl = FindWindowA(vbNullString, Me.Caption)
'// The GetWindowLong function retrieves information about the window.
'// The function also retrieves the 32-bit (long) value
'// into the extra window memory of a window.
lStyle = GetWindowLong(lFrmWndHdl, GWL_STYLE)
'// lStyle is the New window style so lets set it up with the following
lStyle = lStyle Or WS_SYSMENU      '// SystemMenu
lStyle = lStyle Or WS_MINIMIZEBOX  '// With MinimizeBox
lStyle = lStyle Or WS_POPUP        ' or WS_MAXIMIZEBOX '// and MaximizeBox
'// Now lets set up our New window the SetWindowLong function changes
'// the attributes of the specified window , given as lFrmWndHdl,
'// GWL_STYLE = New windows style, and our Newly defined style = lStyle
SetWindowLong lFrmWndHdl, GWL_STYLE, (lStyle)
lStyle = GetWindowLong(lFrmWndHdl, GWL_EXSTYLE)
lStyle = lStyle Or WS_EX_APPWINDOW
'// Set the extended window style
SetWindowLong lFrmWndHdl, GWL_EXSTYLE, lStyle
DrawMenuBar lFrmWndHdl
'// Need to set this to make the Form Take
'AppActivate ("Microsoft excel")
SetFocus lFrmWndHdl
End Sub


r_c
napisał: jottad
postów: 118


umieszczony:
16 listopada 2006
23:52

  
Cytat:

A co z wersją 97? Jak wówczas rozwiązać problem dostępu do arkusza?
Jak wcześniej wspominałem na API to ja się w ogóle nie znam :|


Do poprzednio podanych w moim poscie deklaracji funkcji dodaj:
Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As Long, _
ByVal bEnable As Long) As Long



oraz tak oprogramuj zdarzenie Activate formularza:
Private Sub UserForm_Activate()

Dim mlHWnd As Long

On Error Resume Next

mlHWnd = FindWindow("XLMAIN", Application.Caption)
EnableWindow mlHWnd, 1

End Sub



i będziesz miał niemodalne okno formularza w kazdej wersji Excela ( od 97 oczywiście :) )

Pozdrawiam
napisał: jottad
postów: 118


umieszczony:
16 listopada 2006
00:30

  
Cytat:
He, he. Chciałbyś? co?
W "czystym" VBA - zapomnij.
Ale od czego to forum? Właśnie niedawno natknąłem się na takie rozwiązanie, dość klarownie napisane. Poniżej przepis.
1. Do swojego projektu wstaw moduł klasy i nazwij ten moduł clsMinMaxButton.


Istnieje nieco prostsze rozwiązanie :) Ale, oczywiście też z wykorzystaniem API. Nalezy wkleić na poczatku modułu formularza następujący kod:
Private Declare Function GetWindowLong _
                        Lib "user32" Alias _
                            "GetWindowLongA" (ByVal hwnd As Long, _
                                              ByVal nIndex As Long) As Long
Private Declare Function FindWindow _
                        Lib "user32" Alias "FindWindowA" _
                            (ByVal lpClassName As String, _
                             ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLong _
                         Lib "user32" Alias _
                         "SetWindowLongA" (ByVal hwnd As Long, _
                                          ByVal nIndex As Long, _
                                          ByVal dwNewLong As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" _
                                   (ByVal hwnd As Long) As Long

Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const GWL_STYLE As Long = (-16)


Private Sub UserForm_Initialize()
Dim hwnd As Long
Dim lngStyle As Long

  hwnd = FindWindow(vbNullString, Me.Caption)
  lngStyle = GetWindowLong(hwnd, GWL_STYLE)
  lngStyle = lngStyle Or WS_MAXIMIZEBOX
  lngStyle = lngStyle Or WS_MINIMIZEBOX

  SetWindowLong hwnd, GWL_STYLE, lngStyle
  DrawMenuBar hwnd

End Sub



Minimalizuje do krawędzi okna aplikacji.

Pozdrawiam
napisał: du_gy
postów: 22


umieszczony:
15 listopada 2006
20:55

  
czy jest mozliwosc, a jesli tak to jaka dodania do okna UserForm przycisku maksymalizuj i minimalizuj (standartowych przyciskow znajdujacych sie w prawym gornym oknie aplikacji)
tHx


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z