2017-07-02 7 views
0

Goで画面上の複数のウィンドウのサイズを変更できるツールを作成したいとします。例として、自分のFirefoxウィンドウとAtom(テキストエディタ)ウィンドウを見つけて配置して、画面の半分(FF左、Atomの右)を使用すると仮定します。Go for Windowsでウィンドウジオメトリを取得する

これまでのところ、Windows APIを使用する必要があることに気付きました。私はすべてのハンドルとすべてのウィンドウのタイトルを私に与えるメソッドを作成しましたが、私はジオメトリ情報に苦しんでいます。私はAPI呼び出しGetWindowRectが助けになることを理解していますが、どのようにしてrectへのポインタから情報を得ることができますか?

質問1:私は窓について他にどんな情報を得ることができますか? 質問2:画面サイズのちょうど半分になるようにウィンドウのサイズを変更するにはどうすればよいですか?私は、モニターの寸法を得るために別の呼び出しが必要だと思います。

これまでのコードは以下のとおりです。メインプログラムはすべてのハンドルを見つけ、タイトルに「Atom」を含むものを表示します。 Windowsパッケージには、Windows APIにアクセスするコードが含まれています。

私の現在の結果は、原子のハンドルが2つあることです。私は、Windows APIについてもっと知る必要があると思います。基本を理解するための良い要約はありますか?

main.go:

package main 

import (
    "resizer/windows" 
    "fmt" 
    "log" 
    "strings" 
) 

func main() { 
    const title = "Atom"  
    m := windows.GetAllWindows() 
    fmt.Printf("Map of windows: \n") 
    for handle := range m { 
     if strings.Contains(m[handle].Title(), title) { 
      fmt.Printf("'%v'\n", m[handle]) 
     } 
    } 
} 

windows.go:

package windows 

import (
    "fmt" 
    "log" 
    "syscall" 
    "unsafe" 
) 

var (
    user32    = syscall.MustLoadDLL("user32.dll") 
    procEnumWindows = user32.MustFindProc("EnumWindows") 
    procGetWindowTextW = user32.MustFindProc("GetWindowTextW") 
) 

// Window represents any Window that is opened in the Windows OS 
type Window struct { 
    handle syscall.Handle 
    title string 
} 

// Title returns the title of the window 
func (w Window) Title() string { 
    return w.title 
} 

// GetAllWindows finds all currently opened windows 
func GetAllWindows() map[syscall.Handle]Window { 
    m := make(map[syscall.Handle]Window) 
    cb := syscall.NewCallback(func(h syscall.Handle, p uintptr) uintptr { 
     bytes := make([]uint16, 200) 
     _, err := GetWindowText(h, &bytes[0], int32(len(bytes))) 
     title := "||| no title found |||" 
     if err == nil { 
      title = syscall.UTF16ToString(bytes) 
     } 
     m[h] = Window{h, title} 
     return 1 // continue enumeration 
    }) 
    EnumWindows(cb, 0) 
    return m 
} 

// EnumWindows loops through all windows and calls a callback function on each 
func EnumWindows(enumFunc uintptr, lparam uintptr) (err error) { 
    r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(lparam), 0) 
    if r1 == 0 { 
     if e1 != 0 { 
      err = error(e1) 
     } else { 
      err = syscall.EINVAL 
     } 
    } 
    return 
} 

// GetWindowText gets the title of a Window given by a certain handle 
func GetWindowText(hwnd syscall.Handle, str *uint16, maxCount int32) (len int32, err error) { 
    r0, _, e1 := syscall.Syscall(procGetWindowTextW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(str)), uintptr(maxCount)) 
    len = int32(r0) 
    if len == 0 { 
     if e1 != 0 { 
      err = error(e1) 
     } else { 
      err = syscall.EINVAL 
     } 
    } 
    return 
} 
+0

キャプションの代わりにウィンドウクラス名を使用する方が良いです。ファイル名が 'Firefox.txt'のオープンテキストエディタです。また、ウィンドウを移動するには、MoveWindowのAPIラッパーを実装する必要があります。また、GetSystemMetricsを使用して画面サイズを取得します。 – mattn

+0

クラス名は間違いなく役に立ちます。しかし、私はまだ2つのAtomハンドル(そして1つのウィンドウ)しか持っていません。どのように2つの画面のサイズを取得する任意のアイデア? –

+0

フォローアップの質問は非常に曖昧です。あなたは窓でできることがたくさんあり、そこから出ることができるものはたくさんあります。あなたはあなたが知りたいことに固執しているほうが良いです。また、 'GetWindowTextW()'のような関数を呼び出すときには、渡す長さがC文字列の最後に来る終了NUL文字(整数値0)を正しく考慮していることを確認するためにMSDNをチェックする必要があります。 'syscall.UTF16ToString()'は取り除きます。必要な正確な長さを得る方法もあります。 – andlabs

答えて

1

GetWindowRect()は、あなたがへのポインタを渡すRECT構造にジオメトリを書き込みそれはまったく同じ動作します。 GetWindowText()あなたには既に電話があります。違いはRECT構造体をあなた自身で提供しなければならないことです。

あなたはになります。そのまま構造体をそのままコピーすることができます。データ型を置換するには、this pageを使用します。 RECTの定義では、すべてのフィールドがLONGであり、そのページには「[a] 32ビット符号付き整数」と記載されています。したがって、このべきで十分:

type RECT struct { 
    left int32 // or Left, Top, etc. if this type is to be exported 
    top int32 
    right int32 
    bottom int32 
} 

(ほとんどの場合、無関係が、それはRECTlefttopMaxMinrightbottomことで、image.Rectangleと同一に動作することを指摘する価値があるimage.Rectangleので、彼らは同じではありません。 intを使用するので、imageのジオメトリ関数を使用してGDIの代わりに矩形を操作する場合は、変換関数を提供することを検討することをお勧めします)

+0

良い解決策https:// github .com/AllenDang/w32は私の人生を楽にします –

関連する問題