2021年1月31日日曜日

実りある一日か?

 今日は、DOSコマンドを調べていました。


動画の作成の為ですけど、途中で…

以前からの課題、ウインドウの巻き上げを調べて羽目になってしまった!


成果

本体を作る

 大体できた(makiage.py)

方針!

方法1 グローバルフック タイトルバーのシステムメニューにハックして追加する

方法2 グローバルフック 

https://www.google.com/search?q=python+dwmapi.h&sxsrf=ALeKk01azuNBKkDk_XuWNuQyS1SnEM3BZA:1612088907747&ei=S4YWYP2GLZr6-QbJhb2QBQ&start=10&sa=N&ved=2ahUKEwi92MSV-8XuAhUafd4KHclCD1IQ8NMDegQICBBI&biw=1005&bih=589


How can I paint an image in the caption bar?

http://answers.flyppdevportal.com/MVC/Post/Thread/0b4ce5c1-bb71-4641-bbef-c54d32e630c8?category=vcgeneral


※問題点

WPFでは、大丈夫なのか


そんなこんなもあり(時間もあり)

タイトルバーには、自前でアイコンを表示する事にした

(これが安全で簡単)その検証が、(mainPin.py)

である。

マウスを動かすと小さなウインドウが追従する

これを利用して、以下を実現!


全てのウインドウにこの小さなウインドウ(アイコンを)付ける

(最小化アイコンの左側)


これをクリックすると巻き上げするというやり方だ!

どうかな~な!

でも、これが一番だと思ってやりますね




(mainPin.py)

# -*- coding: utf-8 -*-


# http://algomarket.wikidot.com/win32-api-in-python

# `Hello world in python using win32py'

# 手持ちのPython 3環境で動かしたらちょっと手直しが必要だったので、まずフォーク。

import mouse

import win32gui

import win32con



def mouseCallback( event ):



    print('mouseCallback-Event:', event, type(event))


    xx = event.x

    yy = event.y

    # //MoveWindow(hwnd, xx+10, yy, 20, 20, True)

    win32gui.SetWindowPos(hwnd,win32con.HWND_TOPMOST,xx+10,yy, 20, 20,win32con.SWP_SHOWWINDOW)


    

# //mouse.on_click(mouse_callback)

mouse.hook( mouseCallback )



from win32api import (GetModuleHandle,)

from win32gui import (WNDCLASS,

                      GetStockObject,

                      RegisterClass,

                      CreateWindow,

                      ShowWindow,

                      MoveWindow,

                      UpdateWindow,

                      GetMessage,

                      TranslateMessage,

                      DispatchMessage,

                      PostQuitMessage,

                      BeginPaint,

                      GetClientRect,

                      DrawText,

                      EndPaint,

                      )

from win32con import (WHITE_BRUSH,

                      WS_OVERLAPPEDWINDOW,

                      WS_CAPTION,

                      WS_POPUP,

                      WS_VISIBLE,

                      CW_USEDEFAULT,

                      SW_SHOW,

                      WM_PAINT,

                      WM_DESTROY,

                      CS_VREDRAW,

                      CS_HREDRAW,

                      DT_SINGLELINE,

                      DT_CENTER,

                      DT_VCENTER,

                      )


def OnPaint(hwnd, message, wParam, lParam):

  hdc, ps = BeginPaint(hwnd)

  rect = GetClientRect(hwnd)

  int, rect = DrawText(hdc, u"Hello, Windows 98!" , -1 , rect,

                       DT_SINGLELINE | DT_CENTER | DT_VCENTER)

  EndPaint(hwnd, ps)

  return 0


def OnDestroy(hwnd, message, wParam, lParam):

  PostQuitMessage(0)


message_map = {

                 WM_PAINT: OnPaint,

               WM_DESTROY: OnDestroy,

              }


# have to create hInstance explicitly

hInst = GetModuleHandle()


# create window class structure

szAppName = u"HelloWin"

wndclass = WNDCLASS()

wndclass.style = CS_HREDRAW | CS_VREDRAW

wndclass.lpfnWndProc = message_map

wndclass.cbWndExtra = 0

wndclass.hInstance = hInst

wndclass.hIcon = 0

wndclass.hCursor = 0

wndclass.hbrBackground = GetStockObject(WHITE_BRUSH)

wndclass.lpszMenuName = ''

wndclass.lpszClassName = szAppName

# need encode!


# register window class

hr_registerclass = RegisterClass(wndclass)


# create window

# //hwnd = CreateWindow(szAppName,

                    # //u"The Hello Program",

                    # //WS_OVERLAPPEDWINDOW | WS_CAPTION,

                    # //CW_USEDEFAULT,

                    # //CW_USEDEFAULT,

                    # //CW_USEDEFAULT,

                    # //CW_USEDEFAULT,

                    # //0,

                    # //0,

                    # //hInst,

                    # //None) # must be None!

                    

                    

hwnd = CreateWindow(szAppName,

                    u"The Hello Program",

                    WS_POPUP | WS_VISIBLE,

                    # //WS_POPUP,

                    # //WS_OVERLAPPEDWINDOW | WS_CAPTION,


                    0,   0,

                    0,   0,

                    0,   0,

                    hInst,

                    None) # must be None!

                    

MoveWindow(hwnd, 100, 100, 120, 120, True)

ShowWindow(hwnd, SW_SHOW)

UpdateWindow(hwnd)


# message loop

while True:

  b, msg = GetMessage(hwnd, 0, 0)

  if msg == 0:

    break

  TranslateMessage(msg)

  DispatchMessage(msg)










(makiage.py)

import win32gui

import win32con

from pynput import mouse


hndTbl ={}

heightSV =0


def onlyTtl( X_Point,Y_Point ):


    global heightSV


    Handle = win32gui.WindowFromPoint((X_Point,Y_Point))


    print(Handle)

    (x01, y01, x02, y02) = win32gui.GetWindowRect(Handle)

    width0 = x02 - x01


    height0 = y02 - y01


    (x1, y1, x2, y2) = win32gui.GetClientRect(Handle)

    width = x2 - x1

    height = height0 -y2

    print( "height", height,y2)

    

    if Handle in hndTbl:

        print( "hndTbl 1=", hndTbl)

        heightSV = hndTbl[Handle]

        hndTbl.pop( Handle )

        # //if y2 < heightSV:

        print("dbg=",Handle, hndTbl)

        win32gui.SetWindowPos(Handle,win32con.HWND_NOTOPMOST,x01,y01, width0, heightSV,win32con.SWP_SHOWWINDOW)

    else:

        win32gui.SetWindowPos(Handle,win32con.HWND_TOPMOST,x01,y01, width0, 25,win32con.SWP_SHOWWINDOW)

        heightSV= y02 - y01

        print("dbg=",Handle, hndTbl)

        if not Handle in hndTbl:

            hndTbl[ Handle ] = heightSV

            print( "hndTbl 2=", hndTbl)



# //def Ttl( X_Point,Y_Point ):


    # //global height0


    # //Handle = win32gui.WindowFromPoint((X_Point,Y_Point))


    # //print(Handle)

    # //(x01, y01, x02, y02) = win32gui.GetWindowRect(Handle)

    # //width0 = x02 - x01

    # //height0 = y02 - y01


    # //(x1, y1, x2, y2) = win32gui.GetClientRect(Handle)

    # //width = x2 - x1

    # //height = height0 -y2

    # //print( "height", height,y2)

    # //win32gui.SetWindowPos(Handle,win32con.HWND_TOPMOST,x01,y01, width0, height,win32con.SWP_SHOWWINDOW)



def on_move(x, y):

    print('Pointer moved to {0}'.format(

        (x, y)))


def on_click(x, y, button, pressed):

    print('{0} at {1}'.format(

        'Pressed' if pressed else 'Released',

        (x, y)))


    if not pressed:

        Handle = win32gui.WindowFromPoint((x,y))

        Handle2= win32gui.ChildWindowFromPoint( Handle, (x, y) )

        print(Handle, Handle2)

        deltaX = -200

        deltaY = 30

        (x01, y01, x02, y02) = win32gui.GetWindowRect(Handle)


        print(x,x02,(x02 + deltaX) )

        print(y,y01,(y01 + deltaY) )


        if x02-90 >x and (x02 + deltaX) <x:

            print("X OK")

            if y01 <y and (y01 + deltaY) >y:

                print("YY OK")

                onlyTtl( x,y )


    # //if not pressed:

        # Stop listener

        # //return False


def on_scroll(x, y, dx, dy):

    print('Scrolled {0} at {1}'.format(

        'down' if dy < 0 else 'up',

        (x, y)))


# Collect events until released

with mouse.Listener(

        on_move=on_move,

        on_click=on_click,

        on_scroll=on_scroll) as listener:

    listener.join()

    

    


print("--------------------------------------------")


# //トップ画面のハンドル

Top_Handle = win32gui.FindWindow("hogegoge",None)


# //特定ハンドルの座標

X_Point = 50

Y_Point = 50


Handle = win32gui.WindowFromPoint((X_Point,Y_Point))


print(Handle)

(x01, y01, x02, y02) = win32gui.GetWindowRect(Handle)

width0 = x02 - x01

height0 = y02 - y01


(x1, y1, x2, y2) = win32gui.GetClientRect(Handle)

width = x2 - x1

height = height0 -y2

print( "height", height,y2)

win32gui.SetWindowPos(Handle,win32con.HWND_TOPMOST,x01,y01, width0, height,win32con.SWP_SHOWWINDOW)




2021年1月30日土曜日

Pythonで グローバル フック(システムフック)

 https://stackoverflow.com/questions/31379169/setting-up-a-windowshook-in-python-ctypes-windows-api


from ctypes import *
from ctypes.wintypes import *

user32 = WinDLL('user32', use_last_error=True)

HC_ACTION = 0
WH_MOUSE_LL = 14

WM_QUIT        = 0x0012
WM_MOUSEMOVE   = 0x0200
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP   = 0x0202
WM_RBUTTONDOWN = 0x0204
WM_RBUTTONUP   = 0x0205
WM_MBUTTONDOWN = 0x0207
WM_MBUTTONUP   = 0x0208
WM_MOUSEWHEEL  = 0x020A
WM_MOUSEHWHEEL = 0x020E

MSG_TEXT = {WM_MOUSEMOVE:   'WM_MOUSEMOVE',
            WM_LBUTTONDOWN: 'WM_LBUTTONDOWN',
            WM_LBUTTONUP:   'WM_LBUTTONUP',
            WM_RBUTTONDOWN: 'WM_RBUTTONDOWN',
            WM_RBUTTONUP:   'WM_RBUTTONUP',
            WM_MBUTTONDOWN: 'WM_MBUTTONDOWN',
            WM_MBUTTONUP:   'WM_MBUTTONUP',
            WM_MOUSEWHEEL:  'WM_MOUSEWHEEL',
            WM_MOUSEHWHEEL: 'WM_MOUSEHWHEEL'}

ULONG_PTR = WPARAM
LRESULT = LPARAM
LPMSG = POINTER(MSG)

HOOKPROC = WINFUNCTYPE(LRESULT, c_int, WPARAM, LPARAM)
LowLevelMouseProc = HOOKPROC

class MSLLHOOKSTRUCT(Structure):
    _fields_ = (('pt',          POINT),
                ('mouseData',   DWORD),
                ('flags',       DWORD),
                ('time',        DWORD),
                ('dwExtraInfo', ULONG_PTR))

LPMSLLHOOKSTRUCT = POINTER(MSLLHOOKSTRUCT)

def errcheck_bool(result, func, args):
    if not result:
        raise WinError(get_last_error())
    return args

user32.SetWindowsHookExW.errcheck = errcheck_bool
user32.SetWindowsHookExW.restype = HHOOK
user32.SetWindowsHookExW.argtypes = (c_int,     # _In_ idHook
                                     HOOKPROC,  # _In_ lpfn
                                     HINSTANCE, # _In_ hMod
                                     DWORD)     # _In_ dwThreadId

user32.CallNextHookEx.restype = LRESULT
user32.CallNextHookEx.argtypes = (HHOOK,  # _In_opt_ hhk
                                  c_int,  # _In_     nCode
                                  WPARAM, # _In_     wParam
                                  LPARAM) # _In_     lParam

user32.GetMessageW.argtypes = (LPMSG, # _Out_    lpMsg
                               HWND,  # _In_opt_ hWnd
                               UINT,  # _In_     wMsgFilterMin
                               UINT)  # _In_     wMsgFilterMax

user32.TranslateMessage.argtypes = (LPMSG,)
user32.DispatchMessageW.argtypes = (LPMSG,)

@LowLevelMouseProc
def LLMouseProc(nCode, wParam, lParam):
    msg = cast(lParam, LPMSLLHOOKSTRUCT)[0]
    if nCode == HC_ACTION:
        msgid = MSG_TEXT.get(wParam, str(wParam))
        msg = ((msg.pt.x, msg.pt.y),
                msg.mouseData, msg.flags,
                msg.time, msg.dwExtraInfo)
        print('{:15s}: {}'.format(msgid, msg))
    return user32.CallNextHookEx(None, nCode, wParam, lParam)

def mouse_msg_loop():
    hHook = user32.SetWindowsHookExW(WH_MOUSE_LL, LLMouseProc, None, 0)
    msg = MSG()
    while True:
        bRet = user32.GetMessageW(byref(msg), None, 0, 0)
        if not bRet:
            break
        if bRet == -1:
            raise WinError(get_last_error())
        user32.TranslateMessage(byref(msg))
        user32.DispatchMessageW(byref(msg))

if __name__ == '__main__':
    import time
    import threading
    t = threading.Thread(target=mouse_msg_loop)
    t.start()
    while True:
        try:
            time.sleep(1)
        except KeyboardInterrupt:
            user32.PostThreadMessageW(t.ident, WM_QUIT, 0, 0)
            break