Пример #1
0
 def enum_windows_cb(hwnd, lparam):
     if not IsWindowVisible(hwnd):
         log("window %#x is not visible", hwnd)
         return True
     pid = c_ulong()
     thread_id = GetWindowThreadProcessId(hwnd, byref(pid))
     if pid==ourpid:
         log("skipped our own window %#x, thread id=%#x", hwnd, thread_id)
         return True
     rect = RECT()
     if GetWindowRect(hwnd, byref(rect))==0:
         log("GetWindowRect failure")
         return True
     if hwnd==taskbar:
         log("skipped taskbar")
         return True
     #skipping IsWindowEnabled check
     length = GetWindowTextLengthW(hwnd)
     buf = create_unicode_buffer(length+1)
     if GetWindowTextW(hwnd, buf, length+1)>0:
         window_title = buf.value
     else:
         window_title = ''
     left, top, right, bottom = rect.left, rect.top, rect.right, rect.bottom
     w = right-left
     h = bottom-top
     if left<=-32000 or top<=-32000:
         log("%r is not visible: %s", window_title, (left, top, w, h))
     if w<=0 and h<=0:
         log("skipped invalid window size: %ix%i", w, h)
         return True
     windows[hwnd] = (window_title, (left, top, w, h))
     return True
Пример #2
0
def get_owner_info(owner, our_window):
    if not owner:
        return "unknown"
    if owner==our_window:
        return "our window (hwnd=%#x)" % our_window
    pid = DWORD(0)
    GetWindowThreadProcessId(owner, byref(pid))
    if not pid:
        return "unknown (hwnd=%#x)" % owner
    #log("get_owner_info(%#x) pid=%s", owner, pid.value)
    proc_handle = OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
    if not proc_handle:
        return "pid %i (hwnd=%#x)" % (pid.value, owner)
    try:
        size = DWORD(256)
        process_name = create_string_buffer(size.value+1)
        if not QueryFullProcessImageNameA(proc_handle, 0, process_name, byref(size)):
            return "pid %i" % pid.value
        return "'%s' with pid %s (hwnd=%#x)" % (bytestostr(process_name.value), pid.value, owner)
    finally:
        CloseHandle(proc_handle)
Пример #3
0
 def enum_windows_cb(hwnd, lparam):
     if not IsWindowVisible(hwnd):
         l("skipped invisible window %#x", hwnd)
         return True
     pid = c_int()
     thread_id = GetWindowThreadProcessId(hwnd, byref(pid))
     if pid == ourpid:
         l("skipped our own window %#x", hwnd)
         return True
     #skipping IsWindowEnabled check
     length = GetWindowTextLengthW(hwnd)
     buf = create_unicode_buffer(length + 1)
     if GetWindowTextW(hwnd, buf, length + 1) > 0:
         window_title = buf.value
     else:
         window_title = ''
     l(
         "get_shape_rectangles() found window '%s' with pid=%i and thread id=%i",
         window_title, pid, thread_id)
     rect = RECT()
     if GetWindowRect(hwnd, byref(rect)) == 0:
         l("GetWindowRect failure")
         return True
     left, top, right, bottom = rect.left, rect.top, rect.right, rect.bottom
     if right < 0 or bottom < 0:
         l("skipped offscreen window at %ix%i", right, bottom)
         return True
     if hwnd == taskbar:
         l("skipped taskbar")
         return True
     #dirty way:
     if window_title == 'Program Manager':
         return True
     #this should be the proper way using GetTitleBarInfo (but does not seem to work)
     #import ctypes
     #from ctypes.windll.user32 import GetTitleBarInfo        #@UnresolvedImport
     #from ctypes.wintypes import (DWORD, RECT)
     #class TITLEBARINFO(ctypes.Structure):
     #    pass
     #TITLEBARINFO._fields_ = [
     #    ('cbSize', DWORD),
     #    ('rcTitleBar', RECT),
     #    ('rgstate', DWORD * 6),
     #]
     #ti = TITLEBARINFO()
     #ti.cbSize = sizeof(ti)
     #GetTitleBarInfo(hwnd, byref(ti))
     #if ti.rgstate[0] & win32con.STATE_SYSTEM_INVISIBLE:
     #    log("skipped system invisible window")
     #    return True
     w = right - left
     h = bottom - top
     l("shape(%s - %#x)=%s", window_title, hwnd, (left, top, w, h))
     if w <= 0 and h <= 0:
         l("skipped invalid window size: %ix%i", w, h)
         return True
     if left == -32000 and top == -32000:
         #there must be a better way of skipping those - I haven't found it
         l("skipped special window")
         return True
     #now clip rectangle:
     if left < 0:
         left = 0
         w = right
     if top < 0:
         top = 0
         h = bottom
     rectangles.append((left, top, w, h))
     return True
Пример #4
0
    def get_layout_spec(self):
        KMASKS = (0xffffffff, 0xffff, 0x3ff)
        layout = None
        layouts = []
        variant = None
        variants = None
        options = ""
        layout_code = 0
        try:
            l = _GetKeyboardLayoutList()
            log("GetKeyboardLayoutList()=%s", csv(hex(v) for v in l))
            for hkl in l:
                for mask in KMASKS:
                    kbid = hkl & mask
                    if kbid in WIN32_LAYOUTS:
                        code, _, _, _, _layout, _variants = WIN32_LAYOUTS.get(
                            kbid)
                        log(
                            "found keyboard layout '%s' / %#x with variants=%s, code '%s' for kbid=%i (%#x)",
                            _layout, kbid, _variants, code, kbid, hkl)
                        if _layout not in layouts:
                            layouts.append(_layout)
                            if not layout_code:
                                layout_code = kbid
                            break
        except Exception as e:
            log.error("Error: failed to detect keyboard layouts:")
            log.error(" %s", e)

        try:
            pid = DWORD(0)
            GetWindowThreadProcessId(0, byref(pid))
            tid = GetWindowThreadProcessId(0, pid)
            hkl = GetKeyboardLayout(tid)
            log("GetKeyboardLayout(%i)=%#x", tid, hkl)
            for mask in KMASKS:
                kbid = hkl & mask
                if kbid not in WIN32_LAYOUTS:
                    continue
                code, _, _, _, layout0, variants = WIN32_LAYOUTS.get(kbid)
                log(
                    "found keyboard layout '%s' / %#x with variants=%s, code '%s' for kbid=%i (%#x)",
                    layout0, kbid, variants, code, kbid, hkl)
                if layout0 not in layouts:
                    layouts.append(layout0)
                #only override "layout" if unset:
                if not layout and layout0:
                    layout = layout0
                    layout_code = kbid
        except Exception:
            log.error("Error: failed to detect keyboard layout", exc_info=True)

        KL_NAMELENGTH = 9
        name_buf = create_string_buffer(KL_NAMELENGTH)
        if GetKeyboardLayoutName(name_buf):
            log("get_layout_spec() GetKeyboardLayoutName()=%s",
                bytestostr(name_buf.value))
            try:
                #win32 API returns a hex string
                ival = int(name_buf.value, 16)
            except ValueError:
                log.warn("Warning: failed to parse keyboard layout code '%s'",
                         bytestostr(name_buf.value))
            else:
                sublang = (ival & 0xfc00) >> 10
                log("sublang(%#x)=%#x", ival, sublang)
                for mask in KMASKS:
                    val = ival & mask
                    kbdef = WIN32_KEYBOARDS.get(val)
                    log("get_layout_spec() WIN32_KEYBOARDS[%#x]=%s", val,
                        kbdef)
                    if kbdef:
                        _layout, descr = kbdef
                        if _layout == "??":
                            log.warn(
                                "Warning: the X11 codename for %#x is not known",
                                val)
                            log.warn(" only identified as '%s'", descr)
                            log.warn(" please file a bug report")
                            continue
                        elif not layout:
                            layout = _layout
                            layout_code = val
                            break
                if not layout:
                    log.warn("Warning: unknown keyboard layout %#x", ival)
                    log.warn(" please file a bug report")
                    self.last_layout_message = layout

        if layouts and not layout:
            layout = layouts[0]

        if layout and self.last_layout_message != layout:
            log.info("keyboard layout code %#x", layout_code)
            log.info("identified as '%s' : %s", descr, layout)
            self.last_layout_message = layout
        return layout, layouts, variant, variants, options