Strona: [  << <   1   > >>  ]  z  1     
Autor Temat: Rozdzielczość ekranu i częstotliwość odświeżania monitora
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002
Rozdzielczość ekranu i częstotliwość odświeżania monitora

Mam problem-gdy zmienię rozdzielczość ekranu za pomocą poniższego kodu, częstotliwość odświeżania ekranu spada mi na najniższą możliwą - 60 Hz. Czy ktoś wie jak zrobić, żeby VB dał sobie spokój z nią i zmienił tylko rozdzielczość?

Option Explicit
Const WM_DISPLAYCHANGE = &H7E
Const HWND_BROADCAST = &HFFFF&
Const EWX_LOGOFF = 0
Const EWX_SHUTDOWN = 1
Const EWX_REBOOT = 2
Const EWX_FORCE = 4
Const CCDEVICENAME = 32
Const CCFORMNAME = 32
Const DM_BITSPERPEL = &H40000
Const DM_PELSWIDTH = &H80000
Const DM_PELSHEIGHT = &H100000
Const CDS_UPDATEREGISTRY = &H1
Const CDS_TEST = &H4
Const DISP_CHANGE_SUCCESSFUL = 0
Const DISP_CHANGE_RESTART = 1
Const BITSPIXEL = 12
Private Type DEVMODE
    dmDeviceName As String * CCDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Integer
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type
Private Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As Long, ByVal iModeNum As Long, lpDevMode As Any) As Boolean
Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (lpDevMode As Any, ByVal dwFlags As Long) As Long
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As Any) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim OldX As Long, OldY As Long, nDC As Long
Sub ChangeRes(X As Long, Y As Long, Bits As Long)
    Dim DevM As DEVMODE, ScInfo As Long, erg As Long, an As VbMsgBoxResult
    'Get the info into DevM
    erg = EnumDisplaySettings(0&, 0&, DevM)
    'This is what we're going to change
    DevM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
    DevM.dmPelsWidth = X 'ScreenWidth
    DevM.dmPelsHeight = Y 'ScreenHeight
    DevM.dmBitsPerPel = Bits '(can be 8, 16, 24, 32 or even 4)
    'Now change the display and check if possible
    erg = ChangeDisplaySettings(DevM, CDS_TEST)
    'Check if succesfull
    Select Case erg&
        Case DISP_CHANGE_RESTART
            an = MsgBox("You've to reboot", vbYesNo + vbSystemModal, "Info"
            If an = vbYes Then
                erg& = ExitWindowsEx(EWX_REBOOT, 0&
            End If
        Case DISP_CHANGE_SUCCESSFUL
            erg = ChangeDisplaySettings(DevM, CDS_UPDATEREGISTRY)
            ScInfo = Y * 2 ^ 16 + X
            'Notify all the windows of the screen resolution change
            SendMessage HWND_BROADCAST, WM_DISPLAYCHANGE, ByVal Bits, ByVal ScInfo
            MsgBox "Everything's ok", vbOKOnly + vbSystemModal, "It worked!"
        Case Else
            MsgBox "Mode not supported", vbOKOnly + vbSystemModal, "Error"
    End Select
End Sub
Private Sub Form_Load()
    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail:
    Dim nDC As Long
    'retrieve the screen's resolution
    OldX = Screen.Width / Screen.TwipsPerPixelX
    OldY = Screen.Height / Screen.TwipsPerPixelY
    'Create a device context, compatible with the screen
    nDC = CreateDC("DISPLAY", vbNullString, vbNullString, ByVal 0&
    'Change the screen's resolution
    ChangeRes 640, 480, GetDeviceCaps(nDC, BITSPIXEL)
End Sub
Private Sub Form_Unload(Cancel As Integer)
    'restore the screen resolution
    ChangeRes OldX, OldY, GetDeviceCaps(nDC, BITSPIXEL)
    'delete our device context
    DeleteDC nDC
End Sub



_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


10-04-2005 18:03
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Przejrzałem funkcję i nie widzę, by zmieniała ona częstotliwość - ale może coś przeoczyłem. Sądzę jednak, że problem leży własnie w tym, że jej nie zmienia. Z założenia nie można zachować częstotliwości odświerzania z poprzedniej rozdzielczości, więc jeśli zmieniasz rozdzielczość, to sterowniki/karta graficzna automatycznie ustawiają domyślną częstotliwośc, optymalną, 60Hz (działa zawsze) lub przypisaną do rozdzielczości (zależy od możliwości sterowników).


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

10-04-2005 22:01
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Cześć! Dziękuję za odpowiedź, jednak gdy zmieniam sobie rozdzielczość za pomocą właściwości ekranu, to częstotliwość odświeżania monitora zostaje ta sama! Jak więc z poziomu VB pobrać aktualną częstotliwość odświeżania i po zmianie rozdzielczości przywrócić tę poprzednią?

Całość rozbija się o to, że w Win98 można sobie było wrzucić do traya ikonkę właściwości ekranu, co pozwalazło na szybką zmianę rozdzielczości, a w XP tej funkcji nie ma. Mnie to nie przeszkadza, ale mojemu znajomemu owszem. Poszukałem więc dla niego programiku do tego celu: http://www.southbaypc.com/FastRes/ . Okazało się jednak, że przy każdej zmianie rozdzielczości podbija on częstotliwość odświeżania do 120 Hz, czego jego monitor nie wytrzymuje (dużo monitorów nie wytrzymuje-mój akurat tak) i powoduje pojawienie się zamazanego obrazu, uniemożliwiając korzystanie z komputera - dopiero reinstalacja sterowników grafiki z trybu awaryjnego pomaga.

Chcę więc napisać od nowa podobny program, pozbawiony opisanych błędów.


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


10-04-2005 22:21
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Dzieje się tak dlatego, że Windowsowy program do zmiany ustawień ekranu (lub same sterowniki) po zmianie rozdzielczości własnoręcznie ustawiają także częstotliwość. U mnie akurat tego nie robią (mam przypisane ustawienia częstotliwosci niezależnie dla każdego mozliwego trybu wyświtlania), ale podejrzewam, że na takiej zasadzie działa to u ciebie. Tzn. jest możliwe, że akurat te, konkretne sterowniki zostawiają rozdzielczość, ale to raczej tylko źle świadczy o osobach je tworzących.
Natomiast niestety nie wiem jak pobrać/ustawić częstotliwośc odświerzania ekranu pod Windowsem i to pozostawiam narazie do dyskusji - może ktoś inny będzie wiedział. Mnie tez to interesuje, bo może w ten sposób uda mi się wymusić wyższą częstotliwość niż mam teraz (mam tylko 100Hz, w poprzednim monitorze miałem wymuszaną 160).


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

10-04-2005 23:24
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Czyli u Ciebie każda rozdzielczość ma przypisaną inną częstotliwość odświeżania? Jaki masz system operacyjny? Co do wymuszenia częstotliwości odświeżania to w XP wystarczy odhaczyć pozycję "Ukryj tryby, których monitor nie może wyświetlić".

A co do zmiany częstotliwości pod VB,to zauważyłem jedynie, że obiekt DevM w mojej funkcji posiada m. in właściwość DisplayFrequency - nie wiem tylko jak jej użyć. Może Tobie się uda?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


11-04-2005 09:25
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Tak, każda rozdzielczość i tryb kolorów ma niezależne ustawienia częstotliwości odświerzania monitora, które są przechowywane dla każdego z nich. Przykładowo: pracuję na 1024x768x32 i 100Hz. Przełączam się na 800x600x32 i zmieniam częśtotliwość na 120Hz, po czym wracam do normalnej. Potem odpalam grę pracującą w 800x600x32 i ta gra będzie już korzystała z wcześniej ustawionej częstotliwości (120Hz).

Mój system to Win98SE i niestety nie mam takiej możliwości. Kiedyś, gdy miałem jeszcze karte opartą na Savage4 miałem steorniki od innej karty i dzięki tam udało mi się wymusić 160Hz. Teraz w teorii powinienem być w stanie dochodzić do 140Hz przy 1024x768x32, ale z niewiadomych przyczyn - nie mogę.

Co do tego kodu: jest tam taka linijka:
DevM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
Pole dmFields określa, które z pozostałych pól będą brane pod uwagę przy zmianie parametrów urządzenia. W tym rpzypadku są to DM_PELSWIDTH (szerokość w px), DM_PELSHEIGHT (wysokość w px) i DM_BITSPERPEL (bpp). Nie pamiętam w tej chwili, która stała odpowiada za częstotliwość (nie jestem u siebie), ale po powrocie spróbuję coś wykombinować.


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

11-04-2005 12:09
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
hicks
raptor user



Typ: moderator
Postów: 279
Zarejestrowany: Apr 2003

Private Const DM_BITSPERPEL As Long = &H40000&
Private Const DM_COLLATE As Long = &H8000
Private Const DM_COLOR As Long = &H800&
Private Const DM_COPIES As Long = &H100&
Private Const DM_COPY As Long = 2
Private Const DM_DEFAULTSOURCE As Long = &H200&
Private Const DM_DISPLAYFLAGS As Long = &H200000&
Private Const DM_DISPLAYFREQUENCY As Long = &H400000&
Private Const DM_DITHERTYPE As Long = &H10000000
Private Const DM_DUPLEX As Long = &H1000&
Private Const DM_FORMNAME As Long = &H10000
Private Const DM_GETDEFID As Long = WM_USER + 0
Private Const DM_GRAYSCALE As Long = &H1
Private Const DM_ICMINTENT As Long = &H4000000
Private Const DM_ICMMETHOD As Long = &H2000000
Private Const DM_IN_BUFFER As Long = DM_MODIFY
Private Const DM_IN_PROMPT As Long = DM_PROMPT
Private Const DM_INTERLACED As Long = &H2
Private Const DM_LOGPIXELS As Long = &H20000&
Private Const DM_MEDIATYPE As Long = &H8000000
Private Const DM_MODIFY As Long = 8
Private Const DM_NUP As Long = &H40&
Private Const DM_ORIENTATION As Long = &H1&
Private Const DM_OUT_BUFFER As Long = DM_COPY
Private Const DM_OUT_DEFAULT As Long = DM_UPDATE
Private Const DM_PANNINGHEIGHT As Long = &H10000000&
Private Const DM_PANNINGWIDTH As Long = &H8000000&
Private Const DM_PAPERLENGTH As Long = &H4&
Private Const DM_PAPERSIZE As Long = &H2&
Private Const DM_PAPERWIDTH As Long = &H8&
Private Const DM_PELSHEIGHT As Long = &H100000&
Private Const DM_PELSWIDTH As Long = &H80000&
Private Const DM_POSITION As Long = &H20&
Private Const DM_PRINTQUALITY As Long = &H400&
Private Const DM_PROMPT As Long = 4
Private Const DM_REPOSITION As Long = (WM_USER+2)
Private Const DM_RESERVED1 As Long = &H800000
Private Const DM_RESERVED2 As Long = &H1000000
Private Const DM_SCALE As Long = &H10&
Private Const DM_SETDEFID As Long = WM_USER + 1
Private Const DM_SPECVERSION As Long = &H320
Private Const DM_TTOPTION As Long = &H4000&
Private Const DM_UPDATE As Long = 1
Private Const DM_YRESOLUTION As Long = &H2000&
Private Const WM_USER As Long = &H400

Sądzę iż w projekcie mogą się przydać:

Private Const DM_DISPLAYFREQUENCY As Long = &H400000&
i
własność dmDisplayFrequency typu DEVMODE...

do uzyskania informacji o roździałce, itd. może się przydać funkcja:
Private Declare Function EnumDisplaySettings Lib "user32.dll" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As String, ByVal iModeNum As Long, ByRef lpDevMode As DEVMODE) As Long

[Post edytowany dnia 11-04-2005 16:34 przez hicks]


_____________________________________________
TLHW Clan member

11-04-2005 16:29
Pokaż profil hicks  Wyślij email do hicks   Odwiedź stronę hicks       2511367
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002


Tak, każda rozdzielczość i tryb kolorów ma niezależne ustawienia częstotliwości odświerzania monitora, które są przechowywane dla każdego z nich. Przykładowo: pracuję na 1024x768x32 i 100Hz. Przełączam się na 800x600x32 i zmieniam częśtotliwość na 120Hz, po czym wracam do normalnej. Potem odpalam grę pracującą w 800x600x32 i ta gra będzie już korzystała z wcześniej ustawionej częstotliwości (120Hz).



Nie rozumiem... U mnie jest tak, że komputer pamięta częstotliwość odświeżania, którą ja ręcznie ustawiłem i zmiany rozdzielczości za pomocą właściwości ekranu nie wpływają na zmianę częstotliwości odświeżania monitora w żaden sposób!

Z Twojej wypowiedzi nie rozumiem natomiast, kiedy częstotliwość odświeżania zmieniasz Ty, a kiedy Windows! Kolejne dwa pytania są takie:

1.) Jak ew. przypisujesz częstotliwość odświeżania do rozdzielczości?
2.) Gdzie w Win98SE zmienia się częstotliwość odświeżania-mam te Winy na drugim komputerze i nie mogę się doszukać.

Hicks-dzięki, tyle co napisałeś wiem, nie wiem tylko jak to ugryźć :-). Inna sprawa, że nie mam też za bardzo czasu.

[Post edytowany dnia 11-04-2005 20:06 przez Viper87]


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


11-04-2005 20:00
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004


Nie rozumiem... U mnie jest tak, że...
To jest wszystko uzależnione od sterowników, najwyraźniej u ciebie działa inaczej, u mnie inaczej.


... kiedy częstotliwość odświeżania zmieniasz Ty, a kiedy Windows ...

Ja zmieniam rozdzielczość w momencie, gdy ją ustalam w ustawieniach wyświetlania. Natomiast Windows (a raczej sterowniki) ustwaiają ją podczas zmian trybu wyświetlania.

Dwa pytania
1) Nie ja to robię, tylko sterowniki.
2) Właściwosci ekranu, zakładka Ustawienia, przycisk Zaawansowane, zakładka Karta, na dole jest pole do zmiany częstotliwości odświerzania. Ewentualnie taką funkcje mogą posiadać programy dostarczone razem ze sterownikami.


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

11-04-2005 22:19
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Wszystkich odpowiedzi: 8 :: Maxymalnie na stronę: 20
Strona: [  << <   1   > >>  ]  z  1