Witam Wszyscy mamy komputery z 2 ekranami i w makrze mam formularz użytkownika, który ma irytującą tendencję do otwierania się na niewłaściwym ekranie (na przykład Solidworks na lewym ekranie i formularz użytkownika na prawym ekranie) Na Excelu miałem taki kod, który działa bardzo dobrze:
Private Sub UserForm_Initialize()
'-------------------------------------------------------- Positionnement UserForm
Me.StartUpPosition = 0 'Déclarer position MANUAL
Me.Left = Application.Left + Application.Width / 2 - Me.Width / 2
Me.Top = Application.Top + Application.Height / 2 - Me.Height / 2
End Sub
Ale ten kod powoduje błąd 438 Jedynym znalezionym tematem, który jest zbliżony do tego, jest ten, a strona odpowiedzi nie jest już dostępna. (Formularz użytkownika Prb - #7 przez jfaradon) Jeśli ktoś wie, jak rozwiązać ten problem.
StartUpPosition modyfikujesz go bezpośrednio w oknie właściwości, nie musisz tego robić w VBA
przykład
UserForm1.Move 100, 100 'Uniquement pour déplacer à gauche et en haut.
UserForm1.left = 100 'pour déplacer latéralement
UserForm1.Top = 100 ' pour déplacer verticalement
UserForm1.Move 100, 100, 250, 190 'pour tout modifier
Private Sub UserForm_Initialize()
UserForm1.Move 100, 100, 250, 190
End Sub
Tak w . Move to co mam teraz, ale jest problem z 2 ekranami. Aktualny kod:
Private Sub UserForm_Initialize()
With Me
.StartUpPosition = 3
.Move 100, 100
End With
End Sub
Problem polega jednak na tym, że jeśli okno solidworks znajduje się na lewym ekranie (2 ekrany), nie ma obaw, że formularz użytkownika jest znacznie powyżej SW. Ale jeśli użytkownik umieścił Solidworks na swoim prawym ekranie, formularz użytkownika znajduje się na lewym ekranie, naprzeciwko SW. Dlatego szukam alternatywy jak w Excelu (kod 1 wiadomości, ale nie działający w SW.
Witam Odpowiedź z @Lynkoa15 wydaje się dobra, z drugiej strony testowałem i zwrócone wartości są dość dziwne. Daje mi to następujące wartości dla podwójnego ekranu ustawionego na ten, w którym SW jest otwarty w 1680x1050: Lewo = 897 Szerokość = 1024 Góra = 0 Wysokość = 768 Powoduje to, że formularz użytkownika jest umieszczany pośrodku dwóch ekranów. Aby utrzymać go na lewym ekranie (u mnie SW znajduje się po lewej stronie ekranu głównego) usunąłem Swapp.FramLeft z obliczeń dla Me.Left. Umieścił formularz użytkownika na lewym ekranie, nie do końca wyśrodkowany w oknie na szerokość, wysokość jest dobra, nawet jeśli wysokość nie ma nic wspólnego z rozdzielczością mojego wyświetlacza.
Cyrille, to dziwne, nie mam podwójnego ekranu i nie testowałem, ale jeśli pozwala przełączyć okno na drugi ekran, to analiza rozbieżności z wymiarami tego ostatniego musi być możliwa, może różnica między rozdzielczością ekranu a rozdzielczością wyświetlacza windowsa
Dla mnie nie do końca wyśrodkowany na lewym ekranie i na prawym ekranie całkowicie poza środkiem. Dodając nieco przesunięty nawias na 2 ekranach (ten sam rozmiar), zbliżam się do prawdy, ale nadal jest trochę dziwne zachowanie i różni się od rozwiązania w Excelu.
Nie ma czasu na kopanie przez następne 2-3 dni, praca mnie dogania. Skontaktuję się z Tobą tak szybko, jak to możliwe. W każdym razie, @Lynkoa15 , Twoje rozwiązanie jest najbliższe i najbardziej funkcjonalne do tej pory!
Rzeczywiście, system Windows zarządza dwoma ekranami jako jednym, gromadząc piksele na szerokość. Potwierdza to dołączone makro, pobrane w kawałkach z sieci i przystosowane do zwracania wymiarów dwóch ekranów oraz położenia okna SolidWorks.
Rozbieżność zaobserwowana przy użyciu @Lynkoa15 propozycji wydaje mi się być związana z pomyleniem jednostek dla współrzędnych ekranu:
Wymiary i położenie formularza UserForm (. Lewy. Do góry. Widt i . Wysokość) są definiowane przez VBA w punktach ekranu.
Wymiary i położenie okna SolidWorks zwrócone przez . Ramka w lewo, . Szerokość ramki, . FrameTop i . FrameHeights są definiowane przez okna w pikselach. Stosunek między tymi dwiema jednostkami zależy od samego wyświetlacza, ale zwykle wynosi 4/3.
Mam poprawną pozycję formularza w środku okna SolidWorks z następującymi wyrażeniami, niezależnie od używanego ekranu:
@m_blt testowałem szybko, wyśrodkowany na lewym ekranie, jeśli przełączę oprogramowanie na prawy ekran, jest on poza środkiem. Jutro zrobię kolejny test, jeśli będę miał czas.
To samo co @Cyril_f , nie @m_blt tak naprawdę wyśrodkowane i przesuwa się na wysokości, przełożenie nie koryguje błędu, a na ponad 20 postach informacyjnych obawiam się, że będzie to niestety bardzo przypadkowe.
Myślę, że będziemy musieli zmierzyć odpowiedni stosunek 3/4 nie działa na moim podstawowym ekranie (brak drugiego ekranu) Próbowałem zobaczyć kartę techniczną
Myślę, że będziemy musieli to obliczyć (145/25,4/(1920/210,24))=0,62 (odpowiedni stosunek dla mnie) Myślę, że to samo dotyczy drugiego ekranu tylko wtedy, gdy mają takie same ppi Z tego punktu widzenia proponuję pracować z dwoma proporcjami, na przykład, jeśli liczba pikseli przekracza 1920 (na przykład) oblicz pierwszy (lub drugi) piksel według pierwszego stosunku i dodaj resztę z obliczeniem drugiego stosunku
Prawdą jest, że używanie " punktów ekranowych " przez VBA jest często problematyczne, sądząc po dyskusjach na różnych forach (często poświęconych Excelowi lub Accessowi). Rozwiązaniem jest pozbycie się go za pomocą funkcji Windows API, które używają tylko pikseli. Załączone makro jest adaptacją poprzedniego, które spełnia swoje zadanie na moim komputerze z dwoma ekranami. Formularz UserForm1 jest wyśrodkowany w oknie SolidWorks. Szybki test: Jeśli okno SolidWorks zostanie przeniesione, kliknięcie przycisku " Środek " resetuje formularz użytkownika.
Witam @tous @m_blt twoje makro mnie przewyższa . Starałem się więc rozwinąć funkcję, o której wspomniałem wcześniej, biorąc pod uwagę Twoją uwagę na temat jednostek.
Oddaję do Waszej dyspozycji małe proste narzędzie, które pozwala na obliczenie wskaźników (mam nadzieję, że zadziała ) Makro1.swp (76 KB) Makro2.swp (56 KB) Doc1.pdf (237.9 KB)
Przede wszystkim bardzo dziękuję za poświęcony czas, nie wyobrażałem sobie, że wyśrodkowanie formularza użytkownika w oknie SW może być tak skomplikowane! @Lynkoa15 rozwiązanie jest proste, ale ponieważ to makro będzie używane na ponad 20 stacjach roboczych z liczbą ekranów od 1 do 2, najczęściej 2, oraz o zupełnie różnych rozmiarach i proporcjach. Ponadto problem z racjami istnieje również na wysokości. Dlatego zastanawiam się nad zwróceniem się do @m_blt rozwiązania, które działa idealnie. @m_blt drugiej strony mam trochę problemów ze zrozumieniem twojego makra, ponieważ jest tak kompletne. Przyznam, że jako programista samouk dochodzimy do granic swoich możliwości. Wziąłem twój kod w uproszczonym makrze z formularzem użytkownika bez niczego edt, nie mogę go dostosować. Czy w wywołaniu konieczne jest posiadanie 2 argumentów (Textbox1 i 2): CoincidentsCtresWindows UserForm1.TextBox1, UserForm1.TextBox2, True i nie tylko CoincidentsCtresWindows UserForm1 , Prawda Próbowałem zmodyfikować Twój kod, ale nie osiągnąłem tego, czego chciałem (wyśrodkowałem okno tylko z nazwą formularza użytkownika)
Przepraszam, jestem fanem powiedzenia " Po co to upraszczać, skoro można to skomplikować? ".
W załączeniu znajduje się makro centrujące okno VBA w oknie SolidWorks, pozbawione wszystkich przycisków TextBox, ListBox i innych. Jego jedyną funkcją jest umieszczenie pliku VBA UserForm w środku okna SolidWorks, gdy jest on wyświetlany po raz pierwszy. Działa na moim komputerze, z jednym lub dwoma ekranami. Nie próbowałem z trzema...
Warunki są następujące:
SolidWorks jest włączony (co w zasadzie ma miejsce od momentu uruchomienia makra);
główny moduł nazywa się CentrageUsrFrm i zawiera tylko główną procedurę;
W procedurze głównej pierwszym parametrem przekazywanym do funkcji CoincidentsCtresWindows jest podpis okna SolidWorks, zakodowany na stałe: " SOLIDWORKS ". Drugi parametr to parametr UserForm, pobierany za pośrednictwem jego właściwości caption;
Moduł IdentFenetres zawiera dwie funkcje, które wykorzystują interfejsy API systemu Windows do pobierania wymiarów okien i obliczania pozycji formularza UserForm. W zasadzie moduł ten nie wymaga żadnych zmian.
Działa idealnie, jak w przypadku poprzedniego, ale teraz jest o wiele łatwiejszy do zrozumienia! Dzięki za wyjaśnienia i uproszczone makro! Nawet jeśli przechodzenie przez interfejsy API systemu Windows pozostaje skomplikowane, aby wyśrodkować proste okno, w każdym przypadku pozostaje jedynym realnym rozwiązaniem (wiele stacji roboczych i różne ekrany)
Jeśli chodzi o korzystanie z interfejsów API systemu Windows, nie ma innych rozwiązań, ponieważ system Windows zarządza oknami różnych aplikacji. Sam SolidWorks, gdy zwraca pozycje i wymiary własnego okna (FrameLeft, FrameWidth, itp.), prawdopodobnie korzysta z interfejsów API systemu Windows.
Prawdopodobnie moglibyśmy " ukryć " dwie funkcje modułu IdentFenetres w bibliotece dll, co pozwoliłoby na usunięcie modułu i pozostawienie tylko dwóch linii w makrze do wyśrodkowania UserForm. Ale to instalacja na różnych stacjach roboczych stałaby się trudna: lokalizacja biblioteki dll, rejestracja w rejestrze systemu Windows). Zaletą makra jest to, że jest całkowicie autonomiczne z punktu widzenia instalacji.
Tak, rzeczywiście jest to całkiem możliwe, to po prostu dziwne, że solidworks nie zaimplementował czegoś, aby uprościć tę funkcję, na przykład za pomocą biblioteki DLL! A to po prostu sprawi, że będę miał jeszcze jeden moduł w moim makrze, który jest już dobrze dostarczony, nie ma się czym martwić. I jeszcze raz dziękuję.