Wie suche ich den Desktop für ein neues Fenster aus?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
langinagel
Beiträge: 30
Registriert: 03.08.2005 21:06
Computerausstattung: AMD-Krücke 8GB / Lubuntu 18.04
core i3 / 4GB / 1TB / Ubuntu 16.04
und noch paar alte Schinken
Wohnort: Germ-any
Kontaktdaten:

Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von langinagel »

Servus,

die Desktopfunktionen sind zahlreich, aber nur abfragend.
die Windows-Funktionen beziehen sich hauptsächlich auf das, was im Window abgeht.

Frage wie oben:
Wie kann ich selbst bestimmen (bzw. überprüfen), dass ein Fenster im gewünschten Desktop öffnet?

Hintergrund: ich will verhindern, dass z.B. beim Laptop mit üblichen mehreren Desktops im reinen Laptop-Betrieb (ohne weitere Bildschirme) mein Hauptfenster im Nirwana geöffnet wird.

Vielen Dank, viele Grüße, bleibt zuhause und programmiert gesund.
LN
https://www.doerpsoft.org

Boost. Work. Efficiency.

AMD-Krücke mit Lubuntu-18.04 / iCore7 mit Win10-64
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von STARGÅTE »

> "Wie kann ich selbst bestimmen (bzw. überprüfen), dass ein Fenster im gewünschten Desktop öffnet?"
Einen direkten Weg (beim Aufruf von OpenWindow) sehe ich nicht, dort den Desktop anzugeben.
Allerdings kannst du mit ExamineDesktops() alle Desktops in ihrer Position und Größe abfragen.
So kannst du (bevor du dein Fenster öffnen willst) zumindest sicherstellen, dass die Koordinaten/Größe innerhalb des Desktop-Bereichs ist und entsprechend deine X,Y Werte anpassen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von mk-soft »

Das kenne ich ... :mrgreen:

Selbst Programme von großen Herstellern haben diese blöde mache.

Programm öffnen und im WQHD Monitor ganz rechts schieben und schliessen.
WQHD Monitor abklemmen und Programm neu starten. Ergebnis Fenster Weg :mrgreen:

Hier mal ein Beispiel für Programm Daten sichern und Fenster Position, Größe sichern.

Code: Alles auswählen

;-TOP ProgramData and CheckWindowPosition, by mk-soft, v0.6

EnableExplicit

; Change names
#CompanyName = "mk-soft"
#ApplicationName = "MyApp"

Structure udtWindowPosition
  x.i
  y.i
  Width.i
  Height.i
  State.i
EndStructure

Structure udtProgramData
  Window.udtWindowPosition
  DataPath.s
  LastPath.s
  List LastFiles.s()
EndStructure

Structure udtProjectData
  Version.i
  Date.s
  ; Data
  ;TODO
EndStructure

Global ProgramData.udtProgramData
Global ProjectData.udtProjectData

; ----

Enumeration
  #MainWindow
EndEnumeration

Enumeration
  #MainMenu
EndEnumeration

Enumeration
  #MainMenuItem_Exit
  #MainMenuItem_LoadProject
  #MainMenuItem_SaveProject
EndEnumeration

Enumeration
  #MainStatusBar
EndEnumeration

; ----

Procedure GetWindowPosition(Window)
  With ProgramData\Window
    ; Get window state mode 
    \State = GetWindowState(Window)
    ; Set window state to normal
    SetWindowState(Window, #PB_Window_Normal)
    ; Get window postion and size
    \x = WindowX(Window)
    \y = WindowY(Window)
    \Width = WindowWidth(Window)
    \Height = WindowHeight(Window)
  EndWith
EndProcedure

Procedure SetWindowPosition(Window)
  Protected cnt, i
  
  With ProgramData\Window
    ; Check the position and size of the program is aviable
    If \Width <= 0 Or \Height <= 0
      ProcedureReturn #False
    EndIf
    ; Checks that the position and size of the program fits on the available desktop.
    cnt = ExamineDesktops()
    For i = 0 To cnt - 1
      If \x >= DesktopX(i) And \x < DesktopX(i) + DesktopWidth(i)
        If \y >= DesktopY(i) And \y < DesktopY(i) + DesktopHeight(i)
          If \x - DesktopX(i) + \Width <= DesktopWidth(i) And \y - DesktopY(i) + \Height <= DesktopHeight(i)
            ResizeWindow(Window, \x, \y, \Width, \Height)
            SetWindowState(Window, \State)
            ProcedureReturn #True
          EndIf
        EndIf
      EndIf
    Next
    ProcedureReturn #False
  EndWith
EndProcedure

; ----

Procedure LoadProgramData(FileName.s = "ProgramData.xml")
  Protected basepath.s, subpath.s, datapath.s, filepath.s, xml
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    basepath = GetHomeDirectory()
    subpath = basepath + "." + #CompanyName + #PS$
  CompilerElse
    basepath = GetUserDirectory(#PB_Directory_ProgramData)
    subpath = basepath + #CompanyName + #PS$
  CompilerEndIf
  datapath = subpath  + #ApplicationName + #PS$
  filepath = datapath + FileName
  If FileSize(filepath) > 0 Or 1
    xml = LoadXML(#PB_Any, filepath)
    If xml And XMLStatus(xml) = #PB_XML_Success
      ExtractXMLStructure(MainXMLNode(xml), @ProgramData, udtProgramData, #PB_XML_NoCase)
      FreeXML(xml)
      ProgramData\DataPath = datapath
      ProcedureReturn #True
    EndIf
  EndIf
  ProgramData\DataPath = ""
  ProcedureReturn #False
EndProcedure

; ----

Procedure SaveProgramData(FileName.s = "ProgramData.xml")
  Protected basepath.s, subpath.s, datapath.s, filepath.s, xml
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    basepath = GetHomeDirectory()
    subpath = basepath + "." + #CompanyName + #PS$
  CompilerElse
    basepath = GetUserDirectory(#PB_Directory_ProgramData)
    subpath = basepath + #CompanyName + #PS$
  CompilerEndIf
  datapath = subpath  + #ApplicationName + #PS$
  If FileSize(datapath) <> -2
    If FileSize(subpath) <> -2
      CreateDirectory(subpath)
    EndIf
    If FileSize(datapath) <> -2
      CreateDirectory(datapath)
    EndIf
  EndIf
  filepath = datapath + FileName
  xml = CreateXML(#PB_Any)
  If xml
    If InsertXMLStructure(RootXMLNode(xml), @ProgramData, udtProgramData)
      FormatXML(xml, #PB_XML_ReFormat)
      SaveXML(xml, filepath)
    EndIf
    FreeXML(xml)
  EndIf
EndProcedure

; ----

Procedure LoadProjectData(FileName.s, *ProjectData.udtProjectData)
  Protected xml
  
  If FileSize(FileName) > 0
    xml = LoadXML(#PB_Any, FileName)
    If xml And XMLStatus(xml) = #PB_XML_Success
      ExtractXMLStructure(MainXMLNode(xml), *ProjectData, udtProjectData, #PB_XML_NoCase)
      FreeXML(xml)
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; ----

Procedure SaveProjectData(FileName.s, *ProjectData.udtProjectData)
  Protected r1, xml
  
  xml = CreateXML(#PB_Any)
  If xml
    *ProjectData\Version = 101
    *ProjectData\Date = FormatDate("%YYYY-%MM-%DD %HH.%II.%SS", Date())
    If InsertXMLStructure(RootXMLNode(xml), *ProjectData, udtProjectData)
      FormatXML(xml, #PB_XML_ReFormat)
      If SaveXML(xml, FileName)
        r1 = #True
      Else
        r1 = #False
      EndIf
    EndIf
    FreeXML(xml)
  EndIf
  ProcedureReturn r1
EndProcedure

; ----

Procedure Main()
  Protected state, file.s
  
  LoadProgramData()
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_Invisible
  
  OpenWindow(#MainWindow, #PB_Ignore, #PB_Ignore, 800, 600, "Program-Data", #MainStyle)
    
  SetWindowPosition(#MainWindow)
  
  CreateMenu(#MainMenu, WindowID(#MainWindow))
  MenuTitle("&File")
  MenuItem(#MainMenuItem_LoadProject, "&Load Project")
  MenuItem(#MainMenuItem_SaveProject, "&Save Project")
  MenuBar()
  MenuItem(#MainMenuItem_Exit, "E&xit")
  
  CreateStatusBar(#MainStatusBar, WindowID(#MainWindow))
  AddStatusBarField(#PB_Ignore)
  StatusBarText(#MainStatusBar, 0, "ProgramDataPath: " + ProgramData\DataPath)
  
  HideWindow(#MainWindow, #False)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Menu
        Select EventMenu()
          CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
          Case #PB_Menu_Quit
            Break
          CompilerEndIf
          
        Case #MainMenuItem_LoadProject
          file = OpenFileRequester("Load Project", ProgramData\LastPath, "", 0)
          If file
            If Not LoadProjectData(file, @ProjectData)
              MessageRequester("Error", "Load Projekt" + #LF$ + file)
            Else
              ProgramData\LastPath = GetFilePart(file)
            EndIf
          EndIf
          
        Case #MainMenuItem_SaveProject
          file = SaveFileRequester("Save Project", ProgramData\LastPath + "project.xml", "", 0)
          If file
            If Not SaveProjectData(file, @ProjectData)
              MessageRequester("Error", "Save Projekt" + #LF$ + file)
            Else
              ProgramData\LastPath = GetFilePart(file)
            EndIf
          EndIf
          
        Case #MainMenuItem_Exit
          Break
          
      EndSelect
      
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
  
  GetWindowPosition(#MainWindow)
  
  SaveProgramData()
  
EndProcedure : Main()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von tft »

mmmmm.

ich habe mich auch sehr fiel mit dem Thema befast. Und konnte keine geniale Lösung finden. Daher checke ich mit ExamineDesktop
ob es mehere Bildschirme gibt. Und im Laptop betrieb gibt es nur einen. Daher weis ich .... 0,0 oder Center.
es gibt ein Positions Layout für einen oder mehrere Monitore, wobei ich noch nicht die Lösung für die Falsche Position eines Desktop
finden konnte. So gibt es bei mir die Taste F12, um das Haupt Fenster im Main Desktop zu zentrieren. Und die Taste F11 um alle
Fenster dorthin zu bewegen. Die Positionen werden natürlich gespeichert. Leider bietet PB für die Desktops nur die Auflösung und nicht die
Position der Desktop. Das einzige was noch geht ist ein Max Size Window zu erzeugen. Sind die Positions Werte Negativ. Ist das Fenster auf dem Linke
Monitor. folglich ist der andere rechts. Aber das ist nicht sehr Professionell.

Also wer sich hier gefordert fühlt. Ne PBI könnte helfen

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
helpy
Beiträge: 635
Registriert: 29.08.2004 13:29

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von helpy »

tft hat geschrieben:Leider bietet PB für die Desktops nur die Auflösung und nicht die Position der Desktop.
Bei DesktopX() und DexktopY() steht in der Beschreibung folgendes:
PureBasic Help hat geschrieben:DesktopX(#Desktop): Gibt die x-Koordinate (in Pixel) der linken oberen Ecke des angegebenen Desktops zurück. Die Koordinate ist relativ zur linken oberen Ecke des Hauptmonitors. Sie ist negativ, wenn sich der angebenene Monitor links vom Hauptmonitor befindet.

DesktopY(#Desktop): Gibt die y-Koordinate (in Pixel) der linken oberen Ecke des angegebenen Desktops zurück. Die Koordinate ist relativ zur linken oberen Ecke des Hauptmonitors. Sie ist negativ, wenn sich der angebenene Monitor oberholb vom Hauptmonitor befindet.
Damit sollte die Position der Desktops relativ zum primären Monitor (Index = 0) doch bekannt sein.
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von Nino »

STARGÅTE hat geschrieben:Allerdings kannst du mit ExamineDesktops() alle Desktops in ihrer Position und Größe abfragen.
So kannst du (bevor du dein Fenster öffnen willst) zumindest sicherstellen, dass die Koordinaten/Größe innerhalb des Desktop-Bereichs ist und entsprechend deine X,Y Werte anpassen.
So würde ich es auch machen.
Benutzeravatar
langinagel
Beiträge: 30
Registriert: 03.08.2005 21:06
Computerausstattung: AMD-Krücke 8GB / Lubuntu 18.04
core i3 / 4GB / 1TB / Ubuntu 16.04
und noch paar alte Schinken
Wohnort: Germ-any
Kontaktdaten:

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von langinagel »

Dankeschön allerseits,
http://forums.purebasic.com/german/post ... 20b441b248#
damit scheint diese Frage hinreichend geklärt.

Bisher klappte es bei mir immer, dass MessageRequester auf dem vorherigen Desktop landeten, jedenfalls bei mir unter Windows und Linux. Gab es dort schon andere Ergebnisse?

Viele Grüße, bleibt gesund und programmiert zuhause.
LN
https://www.doerpsoft.org

Boost. Work. Efficiency.

AMD-Krücke mit Lubuntu-18.04 / iCore7 mit Win10-64
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von tft »

Halo @helpy

das dachste ich auch . Aber bei mir gaben diese nie die richtigen Werde zurück. Ich habe lange PB 5.61 LTE benutzt. Ob das gefixt wurde weis ich jetzt nicht.
Aber sobald ich wider an meiner 3 Monitor System sitze teste ich das mal.

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
HeX0R
Beiträge: 2959
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von HeX0R »

Ich habe mir mal das hier gebastelt, das rufe ich vor dem Öffnen eines Fensters einfach mit den gewünschten x/y/w/h Koordinaten auf, und die Prozedur verändert sie, wenn nötig.
minWidth/minHeight sind nötig, damit die Prozedur weiss, wie klein das Fenster minimal werden darf (falls es auch die Größe verändern muss).

Code: Alles auswählen

Procedure CheckWindowXY(*x.INTEGER, *y.INTEGER, *w.INTEGER, *h.INTEGER, minWidth, minHeight)
	Protected i, j, maxX, maxY, minX, minY
	
	;first find the min/max dimensions of all enabled desktops 
	j = ExamineDesktops()
	For i = 0 To j - 1
		If DesktopX(i) < minX
			minX = DesktopX(i)
		EndIf
		If DesktopX(i) + DesktopWidth(i) > maxX
			maxX = DesktopX(i) + DesktopWidth(i)
		EndIf
		If DesktopY(i) < minY
			minY = DesktopY(i)
		EndIf
		If DesktopY(i) + DesktopHeight(i) > maxY
			maxY = DesktopY(i) + DesktopHeight(i)
		EndIf
	Next i
	
	;next, check if this window will fit inside the desktop(s), if not change the coordinates
	;first on the x axis
	If *w\i < minWidth
		;this window is smaller than allowed, we set w to the minimum width
		*w\i = minWidth
	EndIf
	If *x\i < minX
		;the left edge is outside of our desktop(s), we use the very left point as new x value.
		*x\i = minX
	EndIf
	If *w\i > maxX - minX
		;the width is bigger then the whole desktop environment, we set it to minWidth and the x position to the left edge of the desktop
		*w\i = minWidth
		*x\i = minX
	ElseIf *x\i + *w\i > maxX
		;the right edge of the window is outside the desktop(s), we move the window completely to the right
		*x\i = maxX - *w\i
	EndIf
	
	;next on the y axis
	If *h\i < minHeight
		;this window is not high enough, we use minHeight instead as h
		*h\i = minHeight
	EndIf
	If *y\i < minY
		;the top of the window is above our desktop(s), we use the top edge of our desktop(s) instead
		*y\i = minY
	EndIf
	If *h\i > maxY - minY
		;the height is bigger then the overall height of the desktop(s), we set it to minHeight and the y position to the top edge of the desktop
		*h\i = minHeight
		*y\i = minY
	ElseIf *y\i + *h\i > maxY
		;the bottom of the window will be below the bottom of our desktop(s), we move it higher (not taking taskbar size into account!)
		*y\i = maxY - *h\i
	EndIf
	
EndProcedure
Derren
Beiträge: 557
Registriert: 23.07.2011 02:08

Re: Wie suche ich den Desktop für ein neues Fenster aus?

Beitrag von Derren »

Ich denke, wenn man gar nicht weiß, wohin mit dem Fenster, ist es eine gute Idee das Fenster dort zu öffnen, wo der Cursor ist - mittels dem angesprochenen ExamineDesktops() und DesktopMouseX() bzw ..Y()

Es gibt sicher auch eine API um den "Haupt-Desktop" zu ermitteln. Somit kann das Fenster gar nicht im Nirvana auftauchen
Signatur und so
Antworten