Wie mit "ma"-Einheiten umgehen?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Wie mit "ma"-Einheiten umgehen?

Beitrag von Stephan »

Die Größe von Basic-Dialogen und darauf enthaltenen Steuerelementen sowie die Koordinaten selbiger werden in "ma"-Einheiten angegeben. Im SO 7 Programmierhandbuch heißt es dazu (Kapitel 11 „Dialoge“ ; Seite 187):

„...Um eine möglichst hohe Plattformunabhängigkeit zu gewährleisten verwendet StarOffice zur Angabe von Positionen und Größen innerhalb von Dialogen die interne Einheit Namens Map AppFont (ma). Ein ma entspricht einem Achtel der durchschnittlichen Höhe eines Zeichens aus dem im Betriebssystem definierten Systemfonts sowie einem Viertel der Breite eines entsprechenden Zeichens. Durch die Verwendung von ma-Einheiten stellt StarOffice sicher, dass ein Dialog trotz unterschiedlichen Systemen und bei verschiedenen Systemeinstellungen stets gleich erscheint....“

Da ich bisher nur auf Windows-Computern (deren Desktopeinstellungen alle nach meinen Vorlieben angepaßt waren und gleich) Basic-Dialoge erstellt hatte war mir die Verwendung dieser "ma"-Einheiten nie richtig bewußt. Ich stelle jetzt fest das von mir sorgfältig erstellte Dialoge auf anderen Systemen völlig verändert aussehen. Problematisch ist das:

(a)diese Größenskallierung nicht proportional erfolgt
Beispiel:
Ein StarBasic-Dialog ist 278x242 ma-Einheiten groß, für folgende Windows-Desktopeinstellungen ergibt sich hieraus (Breite in Pixel/Höhe in Pixel/Verhältnis Höhe-Breite)
'Windows klassisch' -->(499/418/1,194)
'Flieder' -->(499/422/1,182)
"meine" Einstellungen -->(597/451/1,324)

(b)die Umrechnung von "ma" in Pixel nicht ganzzahlig erfolgen kann
Beispiel:
auf meinem Windowssystem ergibt ein Steuerelement folgende Größen:
100x100 [ma] = 212x174 [Pixel]
101x101 [ma] = 214x176 [Pixel]
jedoch
110x110 [ma] = 233x192 [Pixel]

Da die Aussage des Programmierhandbuches suggeriert das es sich bei den "ma"-Einheiten um ein Feature handelt:
Kann mir jemand sagen worin dieses (praktischerseits) besteht?
Wie kann ich das Ganze handhabbar machen?

(Ich will 4 Bilder auf einem Basic-Dialog anordnen das sie genau aneinander grenzen und nicht skalliert sind, wie realisiere ich das für verschiedene vorher unbekannte Einstellungen des Zielsystems?)

Gruß
Stephan
Speedy
***
Beiträge: 95
Registriert: Di, 23.03.2004 12:53
Wohnort: Heddesheim

Beitrag von Speedy »

Hallo Stephan

Bin zwar im OOo SO7 programmieren nicht ganz so bewandert, aber aus meinen erfahrungen in JAVA weiss ich, dass wir in der Firma uns zur Possitioniereung und Skalierung von Dialogen Metholden geschrieben haben, die die Anordnung erledigen. In deinem Falle würde ich eine Methoden schreiben, die die ma in pixel umwandeln. Dazu ist es notwendig, dass du die Bildschirmwerte abfragst und daraus deine ma errechnest. Des Weiteren wäre es (so denke ich) auch möglich, dass das Bild als Rückgabewert seine Position und seine genaue Größe hat (in Java möglich da das Bild ein Objekt ist), um diese abfragen zu können. Dann sollte es gehen, dass du die Bilder wie Gewünscht anordnest.

Hoffe mein Ansatz bringt die etwas oder auch einfach nur eine Idee.

Grüße

Speedy
IBM Thinkpad R40 - Cetrino (Pentium-M 1400) / 512 MB / 80GB HDD / Windows XP Pro & Suse 10.2
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Beitrag von Stephan »

In deinem Falle würde ich eine Methoden schreiben, die die ma in pixel umwandeln. Dazu ist es notwendig, dass du die Bildschirmwerte abfragst und daraus deine ma errechnest.
Das war auch mein Gedanke, nur gibt es ebend keine feste Umrechnung zwischen "ma" und Pixel. Genau das ist ja das Problem. Die Größe eines "ma" ist abhängig von der Systemschriftart, die Definition ist wie schon oben genannt:
"...Ein ma entspricht einem Achtel der durchschnittlichen Höhe eines Zeichens aus dem im Betriebssystem definierten Systemfonts sowie einem Viertel der Breite eines entsprechenden Zeichens..."

Um die Größe eines "ma" zu ermitteln muß ich also:
1. den Systemfond ermitteln
2. die durchschnittliche Höhe und Breite eines Zeichens

Bloß wie mache ich das? Ich kann möglicherweise den Namen des Fonts ermitteln, aber wie ist die durchschnittliche Höhe eines Zeichen dieses Fonts?
Auf meinem System kenne ich den Font, aber nicht mal dann weiß ich wie ich "ma" rechnerisch ermitteln soll, da mir ebend unklar ist was die durchschnittliche Höhe aller Zeichen eines Fonts ist.
(Für die angegebenen Werte in meinem ersten post habe ich jeweils einen Screenshot gemacht und dann die Pixel bei 800facher Vergrößerung gezählt.)
Es geht auch nicht um Abweichungen von 1 oder 2 Pixeln, sondern (im Grundsatz) darum das die Skallierung nicht proportional ist, Beispiel:
Auf einem System ist ein BasicDialog 300 Pixel breit und 200 Pixel hoch, ich könnte es rechnerisch beherrschen, wenn auf einem anderen System der selbe Dialog 330 x 220 Pixel groß wäre, das wären dann ebend 10% mehr. Nur ist es so das auf einem anderen System der Dialog z.B. 340 x 210 Pixel groß ist (13,4% breiter aber nur 5% höher), weil auf unterschiedlichen Systemen (mit unterschiedlichen Systemfonds) das Verhältnis von durchschnittlicher Höhe und Breite eines Zeichens des jeweiligen Fonts unterschiedlich ist.

Gruß
Stephan
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Beitrag von Stephan »

Ich konnte eine prinzipielle Lösung zur Umrechnung von "ma" in Pixel finden:

In der Mailingliste (dev@gsl.openoffice.org) erhielt ich von Thomas Benisch folgenden Code:

Code: Alles auswählen

REM  *****  BASIC  *****

Dim oDialog As Object

Sub Main

     Dim oLibContainer As Object, oLib As Object
     Dim oInputStreamProvider As Object
     Dim oButton As Object
     Dim oButtonModel As Object
     Dim aRectangle As new com.sun.star.awt.Rectangle
     Dim nWidthAppFont As Integer
     Dim nWidthPixel As Integer

     Const sLibName = "Standard"
     Const sDialogName = "Dialog1"

     REM library container
     oLibContainer = DialogLibraries

     REM load the library
     oLibContainer.loadLibrary( sLibName )

     REM get library
     oLib = oLibContainer.getByName( sLibName )

     REM get input stream provider
     oInputStreamProvider = oLib.getByName( sDialogName )

     REM create dialog control
     oDialog = CreateUnoDialog( oInputStreamProvider )

     REM get the button control
     oButton = oDialog.getControl("CommandButton1")
	
     REM get the button model
     oButtonModel = oButton.Model
	
     REM get the width of the button in units of MAP_APPFONT
     nWidthAppFont = oButtonModel.Width
	
     REM get the position and size of the button in pixel
     REM by using the getPosSize() method of the
     REM com.sun.star.awt.XWindow interface
     aRectangle = oButton.getPosSize()
	
     REM get the width of the button in pixel
     nWidthPixel = aRectangle.Width

     MsgBox "width in units of MAP_APPFONT: " & nWidthAppFont
     Msgbox "width in pixel: " & nWidthPixel

     REM show the dialog
     oDialog.execute()

End Sub
Gruß
Stephan
Antworten