사용자 도구

사이트 도구


project:peekwindow

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
project:peekwindow [2015/08/08 19:15] – [설명] changwooproject:peekwindow [2015/08/08 20:22] (현재) – [설명] changwoo
줄 491: 줄 491:
  
 우선 제대로 이벤트를 던지면 p_buf에는 각 항목의 텍스트가 복사됩니다. WinAPI가 여기까지는 해 줍니다. 그 다음 우선 제대로 이벤트를 던지면 p_buf에는 각 항목의 텍스트가 복사됩니다. WinAPI가 여기까지는 해 줍니다. 그 다음
-''__read_from_buffer()'' 메소드가 호출됩니다. 여기서 [[https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms680553%28v=vs.85%29.aspx|ReadProcessMemory()]] 함수를 이용해 p_buf의 메모리를 다시 파이썬 스크립트 프로세스 쪽의 메모리 공간, extraction_buffer로 재차 복사합니다. 다른 프로세스에서 데이터를 끌어 오는 거라 좀 번거롭죠. extraction_buffer의 값을 드디어 파이썬 리스트가 받아 저장합니다.+''<nowiki>__read_from_buffer()</nowiki>'' 메소드가 호출됩니다. 여기서 [[https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms680553%28v=vs.85%29.aspx|ReadProcessMemory()]] 함수를 이용해 p_buf의 메모리를 다시 파이썬 스크립트 프로세스 쪽의 메모리 공간, extraction_buffer로 재차 복사합니다. 다른 프로세스에서 데이터를 끌어 오는 거라 좀 번거롭죠. extraction_buffer의 값을 드디어 파이썬 리스트가 받아 저장합니다.
  
 리스트의 각 항목을 선택하려면 [[https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb761196%28v=vs.85%29.aspx|LVM_SETITEMSTATE]] 이벤트를 던져 주어야 합니다. 이 때 LVITEM 구조체는 이렇게 되어 있어야 합니다. 리스트의 각 항목을 선택하려면 [[https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb761196%28v=vs.85%29.aspx|LVM_SETITEMSTATE]] 이벤트를 던져 주어야 합니다. 이 때 LVITEM 구조체는 이렇게 되어 있어야 합니다.
줄 500: 줄 500:
   * 이외: 이외의 필드는 0으로 해도 무방합니다.   * 이외: 이외의 필드는 0으로 해도 무방합니다.
  
-그런데 TeraCopy는 ListView Control에서 LVM_SETITEMSTATE 이벤트를 제대로 수신하지 않습니다. ListView Control을 이용한 다른 앱을 이용해서 확인하기 바랍니다.+그런데 TeraCopy는 ListView Control에서 LVM_SETITEMSTATE 이벤트를 제대로 수신하지 않습니다. ListView Control을 이용한 다른 앱을 이용해서 확인하기 바랍니다. 추정컨데 TeraCopy는 [[https://msdn.microsoft.com/en-us/library/windows/desktop/bb761849%28v=vs.85%29.aspx|WM_CTL_COLORBTN]] 이벤트로 항목을 하이라이트하는 것 같습니다. 그래서 저는 예전에 제가 만들어 둔 [[https://www.dropbox.com/s/4ff6q0yx5zdciyn/SubRenamer.exe?dl=0|SubRenamer]]를 이용하였습니다. 
 + 
 +==== Control Picker ==== 
 +ListView Control를 찾아내고 조정하는 역할을 합니다. 
 + 
 +<code python control_picker.py> 
 +# -*- coding: utf-8 
 +import win32gui 
 +import pywintypes 
 +from listview_peek import ListViewPeek 
 + 
 + 
 +class ControlPicker: 
 +    def __init__(self, parent_window_name): 
 +        self.parent_window_handle = 0 
 +        self.child_windows = [] 
 + 
 +        try: 
 +            win32gui.EnumWindows(self.__enum_window_handler, parent_window_name) 
 +        except pywintypes.error as e: 
 +            if e[0] == 0: 
 +                pass 
 + 
 +        win32gui.EnumChildWindows(self.parent_window_handle, self.__enum_child_window_handler, None) 
 + 
 +    def __enum_window_handler(self, window_handle, extra): 
 +        window_text = win32gui.GetWindowText(window_handle) 
 +        if window_text.find(extra) != -1: 
 +            self.parent_window_handle = window_handle 
 +            return pywintypes.FALSE  # stop enumerating 
 + 
 +    def __enum_child_window_handler(self, window_handle, extra): 
 +        self.child_windows.append(window_handle) 
 + 
 +    def pick_control(self, target_class_name, target_control_id = None): 
 +        for child_window in self.child_windows: 
 +            window_class = win32gui.GetClassName(child_window) 
 +            control_id = win32gui.GetDlgCtrlID(child_window) 
 + 
 +            if window_class != target_class_name: 
 +                continue 
 + 
 +            if target_control_id: 
 +                if target_control_id == control_id: 
 +                    return child_window 
 +            else: 
 +                return child_window 
 + 
 + 
 +if __name__ == '__main__': 
 +    import sys 
 +    import time 
 + 
 +    picker = ControlPicker('SubRenamer'
 +    list_view_control = picker.pick_control('SysListView32', 0x3EC) 
 +    if not list_view_control: 
 +        print "SysListView32 not found!" 
 +        sys.exit(1) 
 + 
 +    peek = ListViewPeek(list_view_control) 
 + 
 +    print "There are %d items in the ListView control!" % (peek.get_item_count(),
 +    for x in peek.get_list_items(): 
 +        print x 
 +    print 
 + 
 +    if peek.get_item_count() < 2: 
 +        print "Make sure Subrenamer has enough unmatched video lists!" 
 +        sys.exit(1) 
 + 
 +    pause = 5 
 +    win32gui.SetActiveWindow(picker.parent_window_handle) 
 +    win32gui.SetForegroundWindow(list_view_control) 
 +    print "Target window is selected. %d seconds sleep..." % (pause, ) 
 +    time.sleep(pause) 
 + 
 +    peek.select_item(-1, False) 
 +    print "No item selected. %d seconds sleep..." % (pause, ) 
 +    time.sleep(pause) 
 + 
 +    peek.select_item(0, True) 
 +    print "The first item selected. %d seconds sleep..." % (pause, ) 
 +    time.sleep(pause) 
 + 
 +    peek.select_item(-1, False) 
 +    peek.select_item(1, True) 
 +    print "The second item selected. %d seconds sleep..." % (pause, ) 
 +    time.sleep(pause) 
 + 
 +    peek.select_item(-1, True) 
 +    print "All selected. %d seconds sleep..." % (pause, ) 
 +    time.sleep(pause) 
 + 
 +    peek.select_item(-1, False) 
 +    print "None selected again." 
 +    print "Done!" 
 + 
 +</code> 
 + 
 +=== 설명 === 
 + 
 +{{:project:subrenamer.png?nolink&600|}} 
 + 
 +위 그림이 SubRenamer입니다. [[https://www.wxwidgets.org/|wxWidget]]을 이용하 C++ 버전으로 제작한 것인데 바이너리만 남고 소스가 어딨는지... 알 수 없네요. m( 보다시피 두 개의 ListView 컨트롤이 있습니다. 위쪽의 ID는 0x3EC, 아래쪽이 0x3ED입니다. Spy++로 확인 가능합니다. 
 + 
 +이 프로그램은 동영상과 자막을 맞춰주는 프로그램입니다. [[.:pysubrenamer|파이썬 버전으로도 문서를 만들었으니]] 참고하기 바랍니다. 이 프로그램은 간단하게 폴더 안에 같은 이름으로 mp4, avi, mkv 같은 동영상 확장자와 smi 확장자 한 쌍이 맞춰져 있는지를 확인합니다. 짝이 맞지 않으면 동영상은 위쪽 리스트에, 자막은 아래쪽 리스트에 표시됩니다. 실제 동영상이 아니어도 괜찮습니다. 0바이트짜리 파일을 만들어 적당히 video_001.mp4, video_002.mp4 이런 식으로 가짜 동영상 파일만 서너개 만든 후, 아래쪽의 'scan' 버튼만 눌러 보면 바로 결과를 확인할 수 있습니다. 
 + 
 +{{:project:subrenamer_capture_01.png?nolink|}} 
 + 
 +control picker 스크립트도 subrenamer 프로그램을 상대로 제작했습니다. 스크립트를 실행하면 subrenamer 창을 찾고, 창을 가장 위로 올린 다음, 리스트 컨트롤의 항목을 선택하는 데모를 보여 줍니다.
  
project/peekwindow.1439061310.txt.gz · 마지막으로 수정됨: 2015/08/08 19:15 저자 changwoo

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki