Bildschirm drehen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Then
Beiträge: 281
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Bildschirm drehen

Beitrag von Then »

Ich habe gerade das Forum durchsucht und bin auf einen API Befehl gestoßen :

Code: Alles auswählen

SetDisplayAutoRotationPreferences(
Dieser macht jedoch bei mir nöscht. :( Ich habe ein Notebook und daran per Dockingstation einen 2. Monitor dran, welcher bei zugeklappten Notebook als Anzeigegerät fungiert. Muss ich da vorher noch die Displaynummer festlegen ? Wenn ja, wie ??
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Axolotl
Beiträge: 274
Registriert: 31.12.2008 16:34

Re: Bildschirm drehen

Beitrag von Axolotl »

Moin,
ich habe mal nach DISPLAY_DEVICE gesucht und das hier gefunden....
Re: Erweiterte Anzeigen/ Monitore in Standby bringen?
Im englischen Forum wird es da sicherlich mehr dazu geben....
Hinweis: Ich habe es nicht selbst ausprobiert, da ich nur einen Monitor habe und der gerade richtig herum steht.

Detailbeschreibung zum Thema findet man hier:
Microsoft

Weitere interessante Links (zum Thema) und alles ohne Gewähr:
ClickMonitorDDC7.2
rotate-screen
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
Then
Beiträge: 281
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Re: Bildschirm drehen

Beitrag von Then »

Ich habe nun folgenden Code bekommen und bekomme den nicht zum Laufen.

Code: Alles auswählen

; PureBasic Code zum Drehen des Monitors in den Portrait-Modus

; Importiere die benötigten Windows-API-Funktionen
Import "user32.lib"
ChangeDisplaySettingsEx(*lpszDeviceName, *lpDevMode, hWnd, dwFlags)
EnumDisplaySettings(*lpszDeviceName, iModeNum, *lpDevMode)
ChangeDisplaySettings(*lpDevMode, dwFlags)
EndImport

; Struktur für die DEVMODE
Structure DEVMODE
dmPelsWidth.l
dmPelsHeight.l
dmDisplayFlags.l
dmDisplayFrequency.l
dmFields.l
; Weitere Felder können hier hinzugefügt werden
EndStructure

; Hauptprogramm
Procedure RotateToPortrait()
Define.devmode.DEVMODE
Define result.l

; Hole die aktuellen Einstellungen
If EnumDisplaySettings(0, 0, @devmode)
; Setze die neuen Werte für Portrait-Modus
devmode\dmPelsWidth = devmode\dmPelsHeight
devmode\dmPelsHeight = devmode\dmPelsWidth
devmode\dmFields = 1 ; DM_PELSWIDTH und DM_PELSHEIGHT

; Wende die neuen Einstellungen an
result = ChangeDisplaySettings(@devmode, 0)
If result = 0
MessageRequester("Erfolg", "Der Monitor wurde in den Portrait-Modus gedreht.", 0)
Else
MessageRequester("Fehler", "Konnte den Monitor nicht drehen. Fehlercode: " + Str(result), 0)
EndIf
Else
MessageRequester("Fehler", "Konnte die aktuellen Anzeigeeinstellungen nicht abrufen.", 0)
EndIf
EndProcedure

; Rufe die Funktion auf
RotateToPortrait()
:cry:
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Axolotl
Beiträge: 274
Registriert: 31.12.2008 16:34

Re: Bildschirm drehen

Beitrag von Axolotl »

Vielleicht ist das hier ein (besserer) start.
Hinweis: Ich habe solche Änderungen noch nie gemacht, und habe das auch nicht vor. (Deshalb kein Code dazu)
Ein guter Start ist immer mit dem GET anzufangen und den Ist-Zustand abzufragen.
Und dann unbedingt die Hilfeseiten von Ms beachten...
https://learn.microsoft.com/en-us/windo ... ettingsexw

Code: Alles auswählen

; DEVMODE is still included
; 

Enumeration 
  #DMDO_DEFAULT   ; The display orientation is the natural orientation of the display device; it should be used as the default. 
  #DMDO_90        ; The display orientation is rotated 90 degrees (measured clockwise) from DMDO_DEFAULT. 
  #DMDO_180       ; The display orientation is rotated 180 degrees (measured clockwise) from DMDO_DEFAULT. 
  #DMDO_270       ; The display orientation is rotated 270 degrees (measured clockwise) from DMDO_DEFAULT. 
EndEnumeration 

; helper 

Procedure.s GetDisplayDeviceStateFlags(Flags) 
  Protected result$ 

  If Flags & #DISPLAY_DEVICE_ACTIVE : result$ + "ACTIVE + " : EndIf 
  If Flags & #DISPLAY_DEVICE_ATTACHED_TO_DESKTOP : result$ + "ATTACHED_TO_DESKTOP + " : EndIf 
  If Flags & #DISPLAY_DEVICE_PRIMARY_DEVICE : result$ + "PRIMARY_DEVICE + " : EndIf 
  ProcedureReturn RTrim(RTrim(result$), "+")  
EndProcedure 


Procedure main()
  Protected devmode.DEVMODE
  Protected device.DISPLAY_DEVICE                                         ; to store results from EnumDisplayDevices_()
  Protected result, n 

  If OpenWindow(1,0,0,400,400, "INFO", #PB_Window_WindowCentered|#PB_Window_SystemMenu)
    ListViewGadget(1,10,10,380,380)

    device\cb = SizeOf(DISPLAY_DEVICE)  ; <--- very important !!! 
    devmode\dmSize = SizeOf(DEVMODE)    ; <-- not a bad idea anyway 

    While EnumDisplayDevices_(0, n, @device, 0) > 0      ; check all devices 
      n + 1 ; increment 
      If device\StateFlags & #DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      ; check if it's part of the desktop
        If EnumDisplaySettings_(@device\DeviceName, #ENUM_CURRENT_SETTINGS, @devmode) > 0
          AddGadgetItem(1, -1, "Display = " + #DQUOTE$ + PeekS(@device\DeviceName, 32) + #DQUOTE$) 

          AddGadgetItem(1, -1, "  Flags = " + GetDisplayDeviceStateFlags(device\StateFlags)) 

          AddGadgetItem(1, -1, "  Frequency = " + Str(devmode\dmDisplayFrequency))  
          AddGadgetItem(1, -1, "  BitsPerPel = " + Str(devmode\dmBitsPerPel)) 
          AddGadgetItem(1, -1, "  PelsWidth = " + Str(devmode\dmPelsWidth))
          AddGadgetItem(1, -1, "  PelsHeight = " + Str(devmode\dmPelsHeight))  

          AddGadgetItem(1, -1, "  DO = " + StringField("DEFAULT 90 180 270", 1+devmode\Display\dmDisplayOrientation, " ") + "  (" + Str(devmode\Display\dmDisplayOrientation)+")") 
          AddGadgetItem(1, -1, "") 
        EndIf
      EndIf
    Wend


    While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend 
  EndIf 

  ProcedureReturn 0 
EndProcedure

main()
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Bildschirm drehen

Beitrag von HeX0R »

Ein bisschen verfeinert.
Nicht erschrecken, wenn man den X-Button wegen leichter Verwirrung nicht mehr erreichen kann, einfach ALT+F4 drücken :mrgreen:

Code: Alles auswählen

; DEVMODE is still included
;

Enumeration
	#DMDO_DEFAULT   ; The display orientation is the natural orientation of the display device; it should be used as the default.
	#DMDO_90        ; The display orientation is rotated 90 degrees (measured clockwise) from DMDO_DEFAULT.
	#DMDO_180       ; The display orientation is rotated 180 degrees (measured clockwise) from DMDO_DEFAULT.
	#DMDO_270       ; The display orientation is rotated 270 degrees (measured clockwise) from DMDO_DEFAULT.
EndEnumeration

#DISP_CHANGE_SUCCESSFUL  = 0
#DISP_CHANGE_RESTART     = 1
#DISP_CHANGE_FAILED      = -1
#DISP_CHANGE_BADMODE     = -2
#DISP_CHANGE_NOTUPDATED  = -3
#DISP_CHANGE_BADFLAGS    = -4
#DISP_CHANGE_BADPARAM    = -5
#DISP_CHANGE_BADDUALVIEW = -6


Procedure main()
	Protected devmode.DEVMODE, devmodeC.DEVMODE
	Protected result.l, n, Dev$, Orig_Orientation, DesktopName$
	
	If OpenWindow(1, 0, 0, 400, 400, "INFO", #PB_Window_WindowCentered | #PB_Window_SystemMenu)
		ListViewGadget(1, 10, 10, 380, 380)
		
		Count = ExamineDesktops()
		For n = 0 To Count - 1
			Dev$ = DesktopName(n)
			If EnumDisplaySettings_(@Dev$, #ENUM_CURRENT_SETTINGS, @devmode) > 0
				AddGadgetItem(1, - 1, "Display = " + #DQUOTE$ + Dev$ + #DQUOTE$)
				If n = 0
					;copy main desktop settings for some fun
					CopyStructure(@devmode, @devmodeC, DEVMODE)
					AddGadgetItem(1, - 1, "  Primary Monitor")
					Orig_Orientation = devmode\Display\dmDisplayOrientation
					DesktopName$ = Dev$
				EndIf
				AddGadgetItem(1, - 1, "  Frequency = " + Str(devmode\dmDisplayFrequency))
				AddGadgetItem(1, - 1, "  BitsPerPel = " + Str(devmode\dmBitsPerPel))
				AddGadgetItem(1, - 1, "  PelsWidth = " + Str(devmode\dmPelsWidth))
				AddGadgetItem(1, - 1, "  PelsHeight = " + Str(devmode\dmPelsHeight))
				
				AddGadgetItem(1, - 1, "  DO = " + StringField("DEFAULT 90 180 270", 1 + devmode\Display\dmDisplayOrientation, " ") + "  (" + Str(devmode\Display\dmDisplayOrientation) + ")")
				AddGadgetItem(1, - 1, "")
			EndIf
		Next n
		
		;just for fun, swap main monitor 90°
		devmodeC\Display\dmDisplayOrientation = #DMDO_90
		Swap devmodeC\dmPelsHeight, devmodeC\dmPelsWidth

		result = ChangeDisplaySettingsEx_(@DesktopName$, @devmodeC, 0, 0, 0)
		Select result
			Case #DISP_CHANGE_SUCCESSFUL
				Debug "The settings change was successful."
			Case #DISP_CHANGE_BADDUALVIEW
				Debug "The settings change was unsuccessful because the system is DualView capable."
			Case #DISP_CHANGE_BADFLAGS
				Debug "An invalid set of flags was passed in."
			Case #DISP_CHANGE_BADMODE
				Debug "The graphics mode is Not supported."
			Case #DISP_CHANGE_BADPARAM
				Debug "An invalid parameter was passed in. This can include an invalid flag Or combination of flags."
			Case #DISP_CHANGE_FAILED
				Debug "The display driver failed the specified graphics mode."
			Case #DISP_CHANGE_NOTUPDATED
				Debug "Unable To write settings To the registry."
			Case #DISP_CHANGE_RESTART
				Debug "The computer must be restarted For the graphics mode To work."
		EndSelect
		
		
		While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
		devmodeC\Display\dmDisplayOrientation = Orig_Orientation
		Swap devmodeC\dmPelsHeight, devmodeC\dmPelsWidth
		ChangeDisplaySettingsEx_(@DesktopName$, @devmodeC, 0, 0, 0)
	EndIf
	
	ProcedureReturn 0
EndProcedure

main()
Irgendwie fallen mir da lustige Sachen ein, um Kollegen zu ärgern...

Wobei ich das Problem nicht wirklich vestanden habe.
Ich habe hier einen Laptop mit drei Monitoren.
Würde ich einen hochkant nutzen, würde ich das Windows einmalig sagen und es merkt sich das.
Ich kann den Laptop auch aufklappen, dann habe ich 4 Monitore und wieder zu, dann wieder drei und die Orientierungen stimmen trotzdem?
Benutzeravatar
darius676
Beiträge: 512
Registriert: 08.03.2010 22:12
Computerausstattung: Intel i5 16GB RAM nVidia 1050, Win11
Atari Jaguar, Surface Pro 5,Surface Laptop i5 7200, XBOX ONE X, XBOX Series X
Wohnort: AT
Kontaktdaten:

Re: Bildschirm drehen

Beitrag von darius676 »

Wenn dies temporär benötigt wird, bzw. nicht aus dem Programm heraus, angesteuert werden soll:

Wenn Sie zum Beispiel Windows 10 verwenden, können Sie die STRG-Taste plus die ALT-Taste plus eine der Pfeiltasten gedrückt halten, um die Ausrichtung zu ändern.
Antworten