Calc(64)コンテナウィンドウとコンポーネントウィンドウの位置の取得

2018-02-01

旧ブログ

t f B! P L
コンテナウィンドウとコンポーネントウィンドウからその位置を取得して出力するマクロを作成しました。コンポーネントウィンドウはコンテナウィンドウの中に存在するものです(LibreOffice(32)デベロッパーガイド4:コンポーネントフレームワーク参照)。

前の関連記事:Calc(63)セルの固定、ウィンドウの分割、の境界を取得する


コンテナウィンドウとコンポーネントウィンドウから位置情報を取得するマクロ

def macro(documentevent=None):  # 引数は文書のイベント駆動用。import pydevd; pydevd.settrace(stdoutToServer=True, stderrToServer=True)
 outputs = [("", "X", "Y", "X onScreen", "Y onScreen"),]  # 出力する行。列数は統一する必要あり。
 doc = XSCRIPTCONTEXT.getDocument()  # 現在開いているドキュメントを取得。
 controller = doc.getCurrentController()  # コントローラの取得。
 frame = controller.getFrame()  # フレームを取得。
 # コンテナウィンドウ
 outputs.append(("ContainerWindow",)) 
 containerwindow = frame.getContainerWindow()
 possize = containerwindow.getPosSize()
 outputs.append(("PosSize", possize.X, possize.Y))
 outputs.append(("AccessibleContext",))
 accessiblecontext = containerwindow.getAccessibleContext()
 location = accessiblecontext.getLocation()
 outputs.append(("Location", location.X, location.Y), )
 locationonscreen = accessiblecontext.getLocationOnScreen()
 outputs.append(("LocationOnScreen", "", "", locationonscreen.X, locationonscreen.Y))
 outputs.append(("",)) 
 # コンポーネントウィンドウ
 outputs.append(("ComponentWindow",)) 
 componentwindow = frame.getComponentWindow()
 possize = componentwindow.getPosSize()
 outputs.append(("PosSize", possize.X, possize.Y))
 outputs.append(("AccessibleContext",))
 accessiblecontext = componentwindow.getAccessibleContext()
 location = accessiblecontext.getLocation()
 outputs.append(("Location", location.X, location.Y))
 locationonscreen = accessiblecontext.getLocationOnScreen()
 outputs.append(("LocationOnScreen", "", "", locationonscreen.X, locationonscreen.Y)) 
 outputs.append(("",)) 
 # コントローラ
 outputs.append(("Controller", "Left", "Top"))
 border = controller.getBorder()
 outputs.append(("Border", border.Left, border.Top))
 # シートに出力。
 sheet = getNewSheet(doc, "Positions")  # 連番名の新規シートの取得。
 rowsToSheet(sheet["A1"], outputs)
 controller.setActiveSheet(sheet)  # 新規シートをアクティブにする。
関数getNewSheet()とrowsToSheet()はCalc(44)ファイルフィルターのオプションダイアログで作成したものを使っています。

ハイライトした行で取得したStructのアトリビュートの値を1行ずつPositionという名前のシートに出力します。

WindowPositions.ods

このマクロを埋め込んだCalcドキュメントです。

コンテナウィンドウとコンポーネントウィンドウの位置を取得する


マクロセレクターからドキュメント内のWindowsPositions→macroを実行すると次のような結果が出力されます。

ドキュメントウィンドウを最大化して実行しています。


これはlinuxBean14.04での実行結果です。


Windows10での実行結果です。

linuxBean14.04もWindows10いずれもドキュメントウィンドウを移動させたときに変化するのは3行目のPosSizeと6行目と12行目のLocationOnScreenだけで、他は変化しません。

これらの数字がドキュメントウィンドウのどの部分を反映したものかキャプチャーツールで実際にピクセルを測定して調べました。

以下の図はlinuxBean14.04ですが、containerwindow.getAccessibleContext().getLocation()を除いてWindows10でも同じ結果でした。

画面の左上角を原点とする座標にある点



これらの点が画面の左上角を原点とする座標にある点でした。

containerwindow.getPosSize()とcontainerwindow.getAccessibleContext().getLocationOnScreen()は同じ点を指し、メニューバーの左上角の点を指していました。

これがコンテナウィンドウの左上角に該当します。

LibreOffice(32)デベロッパーガイド4:コンポーネントフレームワークではコンテナウィンドウはウィンドウタイトルバーを含んだものにしていましたが、測定してみるとウィンドウタイトルはコンテナウィンドウバーに含まれていませんでした。

componentwindow.getAccessibleContext().getLocationOnScreen()は数式バーの左上角の点を指していました。

これはコンポーネントウィンドウの左上角に該当します。

ウィンドウの左上角を原点とする座標にある点


この点だけWindows10では何を示しているのかわかりませんでした(Y=31はツールバーの高さと一致していました)。

以下はlinuxBean14.04でのみ該当します。


ウィンドウ(図の薄青色の点線で囲われた部分)の左上角を原点とする座標にある点はcontainerwindow.getAccessibleContext().getLocation()でした。

ここでいう「ウィンドウ」とはLibreOfficeの用語ではなくOSでの「ウィンドウ」、つまり普通にいうウィンドウという意味で使っています。

この点はウィンドウに対するコンテナウィンドウの相対位置に該当します。

このコンテナウィンドウの親となるウィンドウの位置を取得する方法はわかりませんでした。

おそらくLibreOfficeのAPIでは取得できないように思います。

最初はこのウィンドウがフレームと思いましたが、フレームというのみは位置も大きさもないもののはずなのでフレームではないと思います。

コンテナウィンドウの左上角を原点とする座標にある点



コンテナウィンドウ(図の薄青色の点線で囲われた部分)の左上角を原点とする座標にある点はcomponentwindow.getAccessibleContext().getLocation()でした。

コンテナウィンドウに対するコンポーネントウィンドウの相対位置に該当します。

コンテナウィンドウの子AccessibleWindowの1つの左上角を原点とする座標にある点



componentwindow.getPosSize()は上図の薄青色の点線で囲まれたAccessibleWindowの左上角を原点とする座標の点に該当します。

このAccessibleWindowはコンテナウィンドウの子AccessibleWindowの一つになります。

AccessibleWindowは親AccessibleWindowはともかく、複数取得できる子AccessibleWindowの1つのを取り出すのは難しいときもあるので、子AccessibleWindowに対する相対位置は使いにくいです。

コントローラのgetBorder()メソッドで行ヘッダの幅と列ヘッダの高さが取得できる



controller.getBorder().Leftは行ヘッダの幅、controller.getBorder().Topは行ヘッダの高さに一致していました。

次の関連記事:Calc(65)フレームとコントローラの位置

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ