この前
Kindle for PCのスクショを撮るPythonプログラムの記事を書きました。
スクショ自体はちゃんと撮れているようなのですが、本当に突貫で作ったので、幾つか気に入らない所がありました。
コミックなどの画像のみの電子書籍の左右に巨大な黒余白が出来る
一番の問題はこれなんですが、これに関しては別プログラムでそのうち対応出来ればいいと思っています。というか、一応出来てはいます。
白黒画像をカラーとして保存するのでサイズが大きくなる
これも別プログラム対応したいと思っています。
タイトル入力時にキャンセルを押すとエラー終了する
まあ、エラーチェックくらいしとけよって事ですね。
たまにフルスクリーン化に失敗する。
この原因は恐らくマウスを動かすと起こります。Kindle for PCを最前面に持ってきた後、一度タイトルバー上で左クリックをしているので、そのときにマウスが変な所に移動しているとフルスクリーン化に失敗します。
小説でたまにページ最後の行が次のページ行頭とダブる
これってKindle for PCの問題じゃないんですかね?
なんとかできるんでしょうか?
たまに別のプログラムに誤爆する。
別のって言うか、Google chromeでタイトルバーに"Kindle"が入ってると誤爆します。探すウィンドウ文字列を'Kindle for PC'にすれば少しは減りますが、それでもタイトルバーに同じ文字があると誤爆する可能性が有ります。
最後のはちょっと致命的なので、
その辺りを改良する前提で、最後の動作を改良するためのプログラムを作りました。と言うより、ただのWin32APIのラッパーです。
ソースコード
from ctypes import *
from ctypes.wintypes import *
import os.path
EnumWindows = windll.user32.EnumWindows
WNDENUMPROC = WINFUNCTYPE(c_bool, POINTER(c_int), POINTER(c_int))
ignores = ['Default IME', 'MSCTFIME UI']
ghwnd = None
wintitle = ''
pName = None
windowlist = []
def EnumWindowsProc(hwnd, lParam):
global ghwnd, wintitle, pname
length = windll.user32.GetWindowTextLengthW(hwnd)
buff = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hwnd, buff, length + 1)
if buff.value.find(wintitle) != -1:
if pname is not None:
p = os.path.basename(GetWindowThreadProcessName(hwnd))
if p.upper() != pname.upper():
return True
ghwnd = hwnd
return False
return True
def EnumWindowsListProc(hwnd, lParam):
global windowlist, ignores
length = windll.user32.GetWindowTextLengthW(hwnd)
buff = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hwnd, buff, length + 1)
if not any([buff.value.find(x) != -1 for x in ignores]) and buff.value != '':
windowlist.append({'Text': buff.value, 'HWND': hwnd,
'Pos': GetWindowRect(ghwnd),
'pid': GetWindowThreadProcessId(hwnd) ,
'Location': GetWindowThreadProcessName(hwnd)})
return True
def GetWindowThreadProcessId(hwnd):
pid = c_ulong()
windll.user32.GetWindowThreadProcessId(hwnd,pointer(pid))
return pid.value
def GetWindowThreadProcessName(hwnd):
pid = c_ulong()
windll.user32.GetWindowThreadProcessId(hwnd, pointer(pid))
handle = windll.kernel32.OpenProcess(0x0410, 0, pid)
buffer_len = c_ulong(1024)
buffer = create_unicode_buffer(buffer_len.value)
windll.kernel32.QueryFullProcessImageNameW(handle, 0,pointer(buffer),pointer(buffer_len))
buffer = buffer[:]
buffer = buffer[:buffer.index("\0")]
return str(buffer)
def GetWindowHandle(title):
global ghwnd, wintitle, pname
ghwnd = None
wintitle = title
pname = None
EnumWindows(WNDENUMPROC(EnumWindowsProc), 0)
return ghwnd
def GetWindowHandleWithName(title,name):
global ghwnd, wintitle, pname
ghwnd = None
wintitle = title
pname = name
EnumWindows(WNDENUMPROC(EnumWindowsProc), 0)
return ghwnd
def GetWindowList():
global windowlist
windowlist = []
EnumWindows(WNDENUMPROC(EnumWindowsListProc), 0)
return windowlist
def SetForeWindow(ghwnd):
windll.user32.SetForegroundWindow(ghwnd)
def SetWindowPos(ghwnd,x,y,cx,cy,uflags):
hwndinsertafter = HWND()
windll.user32.SetWindowPos(ghwnd,hwndinsertafter,x,y,cx,cy,uflags)
def GetWindowText(hwnd):
length = windll.user32.GetWindowTextLengthW(hwnd)
buff = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hwnd, buff, length + 1)
return buff.value
def GetWindowRect(ghwnd):
rect = RECT()
windll.user32.GetWindowRect(ghwnd, pointer(rect))
return rect.left,rect.top,rect.right,rect.bottom
if __name__ == '__main__':
hwnd = GetWindowHandle('メモ帳')
print('メモ帳のhwnd : ', hwnd)
print('メモ帳のプロセスID : ', GetWindowThreadProcessId(hwnd))
print('メモ帳の実行ファイル : ', GetWindowThreadProcessName(hwnd))
print('メモ帳のウィンドウタイトル : ',GetWindowText(hwnd))
print('メモ帳のウィンドウ座標 : ', GetWindowRect(hwnd))
#SetForeWindow(ghwnd) #メモ帳をアクティブ化
#SetWindowPos(hwnd,0,0,840,880,0)
hwnd = GetWindowHandleWithName('.py','code.exe')
print('".py"を含むVSCODE :',end=' ')
if hwnd == None:
print('なし')
else:
print('あり')
l = GetWindowList()
for i in l:
print(i['Text'], i['Location'])
使い方
GetWindowHandle(ウィンドウタイトルに含まれる文字)
か
GetWindowHandleWithName(ウィンドウタイトルに含まれる文字,実行ファイル名)
でウィンドウハンドル(hwnd)を取得して、
GetWindowThreadProcessId(hwnd)
プロセスID
GetWindowThreadProcessName(hwnd)
実行ファイル(フルパス)
GetWindowText(hwnd)
ウィンドウのタイトル
GetWindowRect(hwnd)
ウィンドウの座標
を取得できます
SetForeWindow(hwnd)
ウィンドウをアクティブにして前面に表示
SetWindowPos(hwnd,x,y,cx,cy,uflags)
ウィンドウのサイズ変更
もできます。
GetWindowList()
で一覧をリストで取得できます。
リスト内は辞書型で、'Text' , 'HWND' , 'Pos' , 'pid' , 'Location' が入っています。
ソースコード先頭のignores
のリストに含まれるものと空白のタイトルは無視します。