2010-01-02 4 views
0

나는 더 이상 존재하지 않는 기존의 맞춤형 ERP 애플리케이션을 사용하는 고객이 있으며 더 이상 개발되지 않은 회사가 소스 코드를 가지고 있지 않습니다. 응용 프로그램은 2000 년에 개발되었으며 Delphi로 제작되었습니다. 마지막 실행 파일은 2003 년부터 D6 또는 D7이 될 수 있습니다.실행중인 응용 프로그램에 창 첨부하기

중요한 양식 중 하나는 고객이 다른 데이터베이스의 추가 데이터를 표시하려는 필드가 있으며 기존 양식 위에 데이터를 "덕트 테이프"로 저장할 수 있는지 묻습니다. 대상 양식이 표시 될 때

  • 때 알림을받을 방법 "일부"이벤트를 첨부 양식에 컨트롤을 창 대상 응용 프로그램의

    • 찾아보기 목록을 작성하고 찾을 :

      는 내가 가진

      첫 번째 아이디어는 것입니다 응용 프로그램을 구축하는 입니다

    • 대상 양식 필드가 대상 양식을 오버레이 작은 창에
    • 표시 추가 정보가 변경 될 때 때 "일부"이벤트가 통지를 얻을 부착

    이런 식으로하는 방법에 대한 예제가 있습니까? Google은이 질문 제목의 변형을 검색했지만 성공하지는 못했습니다.

    주 - ERP 응용 프로그램 재 작성은 계획되지 않았습니다.

    언어 정보 - C# 또는 Delphi로 할 수 있습니다.

  • +0

    휴. 델파이에서 소프트웨어를 개발한지 5 년이 지났기 때문에 대답 할 수있는 자격이 충분하지 않습니다. 그러나이 경우 바이너리 만 사용할 수 있습니다. 기쁘거나 똑똑한 사람이되는 것은 아닙니다. 오픈 소스에 대한 논쟁이 대중에게 공개되지 않는다면 유료 고객에게 열려 있어야합니다. –

    +0

    어떤 언어로 개발하고 있습니까? –

    답변

    4

    필자는 CWin32의 관점에서이 문제에 대해 대답 할 것입니다. 델파이 또는 그 라이브러리에 대해 잘 모르기 때문입니다. 이것을 C#으로 변환하는 작업은 p/invoke를 통해 수행 할 수 있지만 일부 파트는 관리되지 않아야합니다.

    먼저 떨어져, 보장 없음. 대상 응용 프로그램에서 윈도우가없는 컨트롤을 수행하는 경우 (모든 온 스크린 컨트롤 아래에 HWND이없는 경우) 운이별로 없습니다.

    //dllHMod is an HMODULE that refers to the DLL containing ShellHookProc 
    HHOOK hook = SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHMod, 0); 
    // error handling, stashing hook away for unregistering later, etc... 
    
    LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        if(nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam); 
    
        if(nCode == HSHELL_WINDOWCREATED) 
        { 
        WindowCreate((HWND)wParam); 
        } 
    
        return 0; 
    } 
    

    WindowCreated(HWND)가 떨어진 경우 HWND를 숨기고한다 : 이것은 그래서 그래 ...

    1 단계, 대상 프로세스 * 만든 새 창을 대기 창 후크를 등록, 모든 것은 드문 일이 아니다 올바른 프로세스 (GetWindowThreadProcessId 통해 결정)가 소유합니다. 이 시점에서 대상 프로세스가 소유 한 모든 최상위 창을 가져올 수 있습니다. 글로벌 훅을 등록하는 것은 성능상의 불이익을 낳습니다. 실제로는 문제가되지는 않지만 예상해야합니다.

    지금 재미있는 부분입니다. 창문이 완전히 만들어 졌는지 또는 완료된 렌더링인지 알려주는 확실한 방법은 없습니다 (렌더링을 시작할 때 알 수있는 방법이 있지만 실제로 도움이되지는 않습니다). 내 충고, 이라고 추측합니다. 그냥 임의의 몇 가지 기다려 거기에 던져 다음 시도하고 모든 자식 창을 열거하십시오.

    //targetHWND is an HWND of one of the top-level windows you've found 
    EnumChildWindows(targetHWND, ChildWindowCallback, NULL); 
    //more code... 
    
    BOOL ChildWindowCallback(HWND window, LPARAM ignored) 
    { 
        if(IsTargetWindow(window)) { /* Do something */ } 
    
        return TRUE; 
    } 
    

    IsTargetWindow를 구현하는 또 다른 까다로운 부분이다;

    는 (하지만 검색을 가정하고있어 가장 쉬운 대상 창에 대해 충분히 알고있는 경우,이 작업을 수행하는 더 나은 방법이있다) 자식 창을 열거하려면 .클래스 이름, 창 이름, 스타일 등을 확인하는 것과 같이 신뢰할 수있는 테스트를 찾아 보시길 바랍니다 ( GetWindowInfo 참조).

    모니터 할 창이 있으면 수신 한 모든 메시지를 보려면 SetWindowLongPtrGWLP_WNDPROC을 사용할 수 있습니다. 이렇게하려면 코드 삽입 (따라서 관리되지 않는 코드)이 필요하며 매우 낮은 수준입니다. 만약 당신이 그것을 피할 수 있지만 소스가 부족하다면 나는 반대 할 것입니다 ...

    나는이 답변이 괜찮은 출발점이라고 생각하지만 다시 한번 이것은 매우 고통스러워 할 것입니다. 그것도 가능하다면 조금도. 행운을 빕니다.

    * 또한 대상 앱이 시작시 (또는 감지 가능/예측 가능 시점)를 제외하고 창을 만들지 않는다는 것을 알고있는 경우 EnumWindows을 사용할 수 있습니다.

    +0

    Kevin,이 매우 구체적인 답변에 대해 매우 감사드립니다. – zendar

    관련 문제