문제

몇 가지 예비 테스트를 통해 다음과 같은 것 같습니다. EnumWindows 항상 역 인스턴스화 순서로 창을 반환합니다. 즉,가장 최근에 인스턴스화된 창이 먼저 표시됩니다.그것은 유효한 관찰인가?그렇다면 모든 Windows 버전에서 해당됩니까?그리고 이것은 믿을만한 가정입니까?그 행동이 어딘가에 문서화되어 있습니까?


문맥: 여러 개의 비모달 창을 열기 위해 타사 응용 프로그램을 트리거하고 해당 창이 열리면 해당 창에 일부 창 메시지를 보내야 하지만 식별할 수 있는 확실한 방법이 없는 상황을 다루고 있습니다. 창 클래스나 캡션이 다르지 않고 예상되는 좌표도 알 수 없기 때문입니다.그러나 위의 동작에 의존할 수 있다면 EnumWindows 나는 단순히 반환된 첫 번째 핸들을 사용할 수 있습니다. EnumWindows 그 클래스와 캡션이 내 기대와 일치합니다.여전히 가설적인 루프 구멍이 남아 있지만 충분히 좋을 것이라고 생각합니다.그럼에도 불구하고 대체 제안을 환영합니다.

도움이 되었습니까?

해결책

Z 순서로 반환합니다.먼저 최상위 창 WS_EX_TOPMOST 가장 아래쪽 창까지 설정합니다. WS_EX_TOPMOST set, 그런 다음 없는 맨 위 창 WS_EX_TOPMOST, 하지만 가장 아래쪽 창에는 WS_EX_TOPMOST.가시성은 결정 요인이 아니므로 보이는 창보다 Z 순서가 더 높은 보이지 않는 창은 여전히 ​​그 앞에 나타납니다.

편집하다:

당신이 원하는대로 이것을 사용할 가능성은 거의 없습니다. EnumWindows.새 창이 처음으로 반환될 가능성이 없을 뿐만 아니라 그 동안 다른 창이 열릴 수 있는 경쟁 조건이 발생할 수 있습니다.그러나 응용 프로그램에 대해 알려진 모든 창 목록을 유지하고 새로 열린 창을 찾아야 하는 경우 다음을 호출할 수 있습니다. EnumWindows 창 핸들을 목록의 핸들과 비교하십시오.올바른 클래스와 캡션이 있는 항목을 찾으면(다음을 사용하여 올바른 프로세스에 속해 있는지 확인할 수도 있습니다) GetWindowThreadProcessID) 그건 ~ 아니다 목록에서 새 창을 찾았습니다.

그러나 귀하의 목적에 따라 CBT 후크를 설치하고 HCBT_CREATEWND 알림을 관찰하면 더 나은 서비스를 받을 수 있습니다.MSDN 도움말을 참조하세요. SetWindowsHookEx() 그리고 그만큼 CBTProc 콜백 자세한 내용은.

열거 순서에 대한 확실성 수준:

이 질문에 대한 많은 의견과 기타 답변에서는 MSDN의 순서에 대한 정확한 문서가 부족하다고 언급했습니다. EnumWindows 창 핸들을 반환합니다.그리고 실제로 다음 페이지에는 EnumWindows 그리고 그만큼 EnumWindowsProc 콜백 둘 다 이 문제에 대해 매우 침묵하고 있습니다.나는 다음과 같은 증거를 제시합니다.

  1. MSDN 매거진의 C++ Q&A 기사 구체적으로 다음과 같이 말합니다.

    EnumWindows는 하향식 Z 순서로 창을 열거합니다.

  2. 페이지 EnumChildWindows 비고 섹션의 주문을 암시합니다.

    열거 프로세스 중에 Z 순서로 이동되거나 위치가 변경된 하위 창은 올바르게 열거됩니다.

    이는 순서가 Z 순서에 종속됨을 의미합니다.그리고 이후 설명에는 hWndParent 매개변수에는 다음과 같이 표시됩니다.

    이 매개변수가 NULL인 경우 이 함수는 EnumWindows와 동일합니다.

    동일한 논리와 순서가 적용된다고 가정할 수 있습니다. EnumWindows.

  3. 이는 이 함수의 관찰 가능한 동작이므로 이를 변경하는 것은 획기적인 변경입니다.일반적으로 Microsoft는 관찰 가능한 동작을 크게 변경하지 않는 데 매우 능숙했습니다.보장되는 것은 아니지만 꽤 안전한 내기입니다.다음 버전에서는 사용 중인 함수가 더 이상 사용되지 않고 다른 "Ex" 버전으로 대체되었다는 사실을 발견할 가능성이 관찰 가능한 동작이 변경되었다는 사실을 발견할 가능성이 더 높습니다.

물론 현시점에서는 이 모든 것이 매우 학문적입니다. EnumWindows 아마도 OP 문제에 대한 최선의 해결책은 아닐 것입니다. 적어도 EnumThreadWindows 아마도 더 적합할 것입니다. 하지만 이 게시물을 접하게 될 다른 사람들을 위해 언급할 가치가 있다고 생각했습니다.

다른 팁

이전 답변에는 상당한 개선이 필요합니다.Enum-order = GetSystemMetrics(SM_IMMENABLED)=0인 경우에만 Z 순서, 즉입력 방법 관리자/입력 방법 편집기 기능이 비활성화됩니다.모든 Windows 클래스 "IME"(제목 "기본 IME") 및 "MSCTFIME UI"는 "Progman"("프로그램 관리자") 창 다음에 열거되기 때문에 - 즉,Z 순서가 아닙니다.

API에는 순서가 지정되지 않았습니다(MSDN 링크) 따라서 특별히 보장되는 것은 없습니다. 보장이 있는 경우 API에 명시적으로 지정됩니다.예를 들어, 열거형 중간에 창이 생성되면 어떻게 됩니까? 열거형에 포함됩니까?이를 통해 창 관리자는 구현을 보다 효율적으로 변경할 수 있는 자유를 얻게 됩니다.

그러나 창을 구별하는 데 사용할 수 있는 고유한 값, 즉 창 핸들 자체가 있습니다.당신의 EnumWindowProc 방법을 사용하려면 일치하는 각 창에 대한 창 핸들을 저장하세요. 어쨌든 창에 메시지를 보내려면 이 핸들이 필요합니다.

두 프로세스를 모두 제어하는 ​​경우 첫 번째 매개변수로 "HWND_BROADCAST"를 사용하여 첫 번째 프로세스에서 SendMessage를 보낼 수 있습니다.

그러면 다른 프로그램은 메시지를 받을 때 자신의 자식 창에 SendMessage를 보낼 수 있습니다.

문서에 열거 순서에 대한 내용이 나와 있지 않으면 어떤 가정도 하지 말 것을 적극 권장합니다.Raymond Chen의 블로그(blogs.msdn.com/oldnewthing)에 있는 몇 가지 게시물을 보면 문서화되지 않은 모든 내용/관찰에 의존하는 앱이 얼마나 많은지 알 수 있으며, 새 버전의 Windows가 출시되면 문제가 심각하게 발생합니다(단, 제외). MS 개발자는 잘못 작동하는 또 다른 앱에 대해 또 다른 심을 도입했습니다.

귀하의 목적에 따라 작업을 달성하는 데 도움이 될 수 있는 GetWindowThreadProcessID, GetParent, EnumThreadWindows 및 EnumWindows와 같은 여러 함수가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top