Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Kleine Helferlein

Eigene Größe für neue Fenster

Lizenz:Erster Autor:Letzte Bearbeitung:
WTFPLMitgliedgrindstone 04.11.2014

WindowDefault - automatische Größenanpassung für neue Fenster

Eine angenehme Eigenschaft von Windows XP ist es, daß es sich (entsprechende Ordnereinstellungen vorausgesetzt) Position und Größe einmal geöffneter Fenster merkt und sie beim nächsten Öffnen wieder genau so anzeigt wie sie zuletzt geschlossen wurden. Neue Fenster oder auch Fenster von einem USB-Stick erscheinen jedoch immer in einer Größe von 800 x 600 Pixeln, auch wenn sie nur einen einzigen Eintrag enthalten, sind also meistens viel zu groß. Diese Startgröße lässt sich meines Wissens auch nirgendwo einstellen, die Windows-Entwickler sind offenbar der Meinung, daß alle User riesige Monitore haben und mit ihrer Vorgabe glücklich sind.

Hier greift nun dieses kleine Kommandozeilentool ein. Die Vorgehensweise ist simpel: einmal gestartet wartet es im Hintergrund auf sichtbare Fenster mit einer Größe von 800 x 600 Pixeln, die es dann automatisch auf die neue Größe setzt. Dabei wird die Größe innerhalb der vorgegebenen Grenzen an die Anzahl der Dateien angepasst, so daß das Fenster immer die richtige Größe hat, was besonders bei USB-Sticks sehr angenehm ist. Wahlweise kann auch eine fixe Größe vorgegeben werden. Eine Besonderheit dieses Programms ist es, daß die neuen Vorgabewerte nirgendwo gespeichert werden, es ändert also weder irgendetwas in der Registry, noch braucht es eine ini-Datei. Um die vorgegebenen Werte zu ändern, wird das Programm einfach noch einmal -mit den neuen Werten- auf der Kommandozeile aufgerufen. Es beendet dann von sich aus alle eventuell vorhandenen Vorgänger und übernimmt die Aufgabe.

Obwohl es sich um ein Kommandozeilentool handelt, muß es mit dem Parameter gui kompiliert werden, weil es sonst nur mit einem offenen Konsolenfenster läuft und beim Schließen dieses Fensters beendet wird.

Zur Benutzung des Tools empfehle ich folgende Vorgehensweise: Die kompilierte .exe - Datei wird in das Verzeichnis C:\Windows\System32 (oder einen anderen Ordner, der im Suchpfad liegt) kopiert und dann eine Verknüpfung zu dieser Datei in den Autostart - Ordner gelegt. Bei den Eigenschaften dieser Verknüpfung werden dann im Feld "Ziel" die neuen Parameter an die Zeile angehängt, also beispielsweise C:\WINDOWS\system32\WindowDefault.exe w400 h300 hmax800 hmin200.

Beenden läßt sich das Tool, indem als Parameter "quit" eingegeben wird.

#Include "DIR.BI"
#Include "windows.bi"
#Include "win/tlhelp32.bi"

Dim As HWND fensterHandle
Dim As WINDOWPLACEMENT koordinaten
Dim As Integer breite, hoehe, gueltig, windefaultx = 800, windefaulty = 600, x, y, eintraege, _
               maxhoehe, fensterhoehe, fensterbreite, beenden, minhoehe, maxbreite, minbreite, _
               fixhoehe, fixbreite
Dim As String filename, g, praefix
Dim As zString * 300 programmname, fenstertext
Dim As HANDLE snapshotHandle 'Handle für Systemschnappschuß
Dim As PROCESSENTRY32 prozessantwort 'Variable für Systemschnappschuß
ReDim As Integer pid(0)

GetModuleFileName(0,@programmname,300) 'eigenen Programmnamen (mit Pfad) ermitteln

'Defaultwerte
breite = 300
hoehe = 250
maxhoehe = GetSystemMetrics(SM_CYSCREEN) 'Bildschirmhöhe
minhoehe = 100
maxbreite = GetSystemMetrics(SM_CXSCREEN) 'Bildschirmbreite
minbreite = 100
beenden = 0
fixhoehe = 0
fixbreite = 0
gueltig = 1

'Kommandozeilenparameter auswerten
x = 1
Do While Len(Command(x))
    g = Trim(Command(x),Any "\/-")
    y = InStr(g,Any "0123456789")
    If y Then
        praefix = LCase(Left(g, y - 1))
    Else
        praefix = g
    EndIf

    Select Case praefix
        Case "w", "x" 'Nreite
            breite = Val(Mid(g,y))
        Case "h", "y" 'Höhe
            hoehe = Val(Mid(g,y))
        Case "hmax", "ymax" 'maximale Höhe
            maxhoehe = Val(Mid(g,y))
        Case "hmin", "ymin" 'minimale Höhe
            minhoehe = Val(Mid(g,y))
        Case "wmax", "xmax" 'maximale Breite
            maxbreite = Val(Mid(g,y))
        Case "wmin", "xmin" 'minimale Breite
            minbreite = Val(Mid(g,y))
        Case "quit" 'beenden
            beenden = 1
        Case "hfix", "yfix" 'feste Höhe
            fixhoehe = 1
        Case "wfix", "xfix" 'feste Breite
            fixbreite = 1
    End Select
    x += 1
Loop

'Werte auf Gültigkeit prüfen / korrigieren
If maxhoehe > GetSystemMetrics(SM_CYSCREEN) Then 'größer als Bildschirmhöhe
    maxhoehe = GetSystemMetrics(SM_CYSCREEN)
EndIf
If minhoehe > maxhoehe Then
    minhoehe = maxhoehe
EndIf
If hoehe > maxhoehe Then
    hoehe = maxhoehe
ElseIf hoehe < minhoehe Then
    hoehe = minhoehe
EndIf

If maxbreite > GetSystemMetrics(SM_CXSCREEN) Then 'größer als Bildschirmbreite
    maxbreite = GetSystemMetrics(SM_CXSCREEN)
EndIf
If minbreite > maxbreite Then
    minbreite = maxbreite
EndIf
If breite > maxbreite Then
    breite = maxbreite
ElseIf breite < minbreite Then
    breite = minbreite
EndIf

'Anzahl der gestarteten Instanzen dieses Programms ermitteln und PIDs in Array schreiben
ReDim pid(0) 'Array zurücksetzen
pid(0) = GetCurrentProcessID() 'eigene PID ermitteln
'Systemschnappschuß erstellen
snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0) 'Handle für Systemschnappschuß erstellen
prozessantwort.dwSize = SizeOf(prozessantwort) 'Größe der Datenstruktur
Process32First(snapshotHandle,@prozessantwort) 'ersten Prozesshandle suchen (ist SYSTEM IDLE PROCESS)

'alle Prozesse durchsuchen
Do While Process32Next(snapshotHandle, @prozessantwort)
    'gestartete Instanzen in Array eintragen
    If prozessantwort.szExeFile = Mid(programmname,InStrRev(programmname,"\") + 1) Then
        ReDim Preserve pid(UBound(pid) + 1) 'Array erweitern
        pid(UBound(pid)) = prozessantwort.th32ProcessID 'PID der gefundenen Instanz
    EndIf
Loop

CloseHandle(snapshotHandle) 'Systemschnappschuß benndet --> Ressourcen freigeben

If UBound(pid) > 1 Then 'es laufen mehrere (normalerweise 2) Instanzen dieses Programms
    For x = 1 To UBound(pid) 'alle Instanzen außer der eigenen beenden
        If pid(x) <> GetCurrentProcessID() Then
            TerminateProcess(OpenProcess(PROCESS_TERMINATE,1,pid(x)),0)
        EndIf
    Next
EndIf

If beenden Then 'Programm beenden
    End
EndIf

Do 'Endlosschleife zum prüfen und ggf. ändern der Größe aller sichtbaren Fenster
    If fensterHandle Then
        fensterHandle = GetWindow(fensterHandle, GW_HWNDNEXT) 'Handle des nächsten Fensters ermitteln
        If IsWindowVisible(fensterHandle) Then 'nur sichtbare Fenster prüfen
            GetWindowPlacement(fensterHandle, @koordinaten) 'Fensterkoordinaten ermitteln
            If ((koordinaten.rcNormalPosition.right - koordinaten.rcNormalPosition.left) = windefaultx) And _
                 ((koordinaten.rcNormalPosition.bottom - koordinaten.rcNormalPosition.top) = windefaulty) Then
                'wenn die Größe des Fensters den Vorgabewerten von Windows entspricht, wird es auf die
                ' gewünschte Größe gesetzt

                If fixhoehe Then 'feste Fensterhöhe
                    fensterhoehe = hoehe
                Else 'Fensterhöhe wird an Anzahl der Einträge angepasst
                    GetWindowText(fensterHandle,fenstertext,300)
                    If Mid(fenstertext,2,1) = ":" Then 'Verzeichnis
                        filename = DIR(fenstertext + "\*", -1)
                        eintraege = 0
                      Do 'Anzahl der Dateien/Verzeichnisse ermitteln
                        If (filename <> ".") And (filename <> "..") Then
                            eintraege += 1
                        EndIf
                        filename = Dir("",fbDirectory)
                      Loop While Len(filename)
                        fensterhoehe = 17 * (eintraege + 1) + 135
                        If fensterhoehe > maxhoehe Then
                            fensterhoehe = maxhoehe
                        ElseIf fensterhoehe < minhoehe Then
                            fensterhoehe = minhoehe
                        EndIf
                    EndIf
                EndIf

                If fixbreite Then
                    fensterbreite = breite
                Else
                    fensterbreite = breite
                EndIf

                koordinaten.rcNormalPosition.right = koordinaten.rcNormalPosition.left + fensterbreite
                koordinaten.rcNormalPosition.bottom = koordinaten.rcNormalPosition.top + fensterhoehe
                SetWindowPlacement(fensterHandle, @koordinaten) 'Fenster auf neue Größe setzen
            EndIf
        EndIf
    Else 'fensterHandle' auf Handle des ersten Fensters setzen
        fensterHandle = GetForegroundWindow()
        fensterHandle = GetWindow(fensterHandle, GW_HWNDFIRST)
        Sleep 100,1 '100ms Pause zur Ressourcenschonung
    EndIf
Loop

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 23.03.2013 von Mitgliedgrindstone angelegt.
  • Die aktuellste Version wurde am 04.11.2014 von Mitgliedgrindstone gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen