2009-05-27 4 views
26

맨 위로 창을 가져와 내가 가지고 거기에 두 개의 2 창문이있는 Windows 프로그램 : 나는 HWND을 더블 클릭하면는 Win32 :

hwnd (main interface) 

hwnd2 (toplevel window, no parent, created by hwnd) 

, 나는 hwnd2 팝업 및 일부 데이터를 표시해야합니다, 그래서를 정상에 hwnd2 가지고이 기능을 사용

BringWindowToTop(hwnd2); 

hwnd2는 맨 위로 가져하지만, 홀수 한 가지가있다. hwnd2를 다시 클릭하면 hwnd (메인 인터페이스)가 자동으로 다시 나타납니다. 이 문제를 해결하기 위해 다음 함수를 사용하려고했지만 그 중 일부는 작동하지 않습니다.

SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
                    //doesn't work 

BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top 

SetForegroundWindow(hwnd2); //doesn't work 

SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
                    //doesn't work 

SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
             // hwnd2 "always" on top, not what I want 

SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks) 

SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function 
SwitchToThisWindow(hwnd2, FALSE); 

이 문제를 어떻게 해결할 수 있습니까? 미리 감사드립니다.

이 (hwnd2가 구성되는 미디어 플레이어 (그것이 다시 다른 창/앞에 될 수 있도록 최상위 창을 할 필요가 있기 때문에 AJ 회신를 들어, hwnd2 부모가없는) 여러 윈도우, 윈도우 중 하나는 비디오 디스 플레이 용, 다른 두 개의 트랙 바 컨트롤은 진행 막대 및 볼륨 바, 하나의 툴바 컨트롤은 제어판 용).

(이 중 하나가 도움이 될 수 있습니다. hwnd2, hwnd는 "마우스가 메뉴 막대 및 비 클라이언트 영역을 포함하여 hwnd의 맨 위에 있습니다"와 같이 자동으로 팝업됩니다.

(이 미디어 플레이어는 Direct Show로 작성되었습니다. IVideoWindow :: put_Owner를 사용하여 비디오 윈도우를 비디오 소유자로 지정하고, Direct Show는 비디오 윈도우의 자식으로 서브 비디오 윈도우를 내부적으로 만듭니다. 소스 코드를 볼 수없는이 서브 비디오 창을 제외하고는 hwnd2에서 의심스러운 것을 볼 수 없습니다.)

Direct Show 때문에 이유를 찾았습니다. 멀티 스레드를 사용하여 실행 한 다음 문제가 해결되었습니다. 하지만 ... 왜?

이 문제는 SendMessage 대신 PostMessage를 사용하여 해결할 수 있습니다.

+2

hwnd2에 부모가없는 이유는 무엇입니까? hwnd는 생성하는 동안 상위로 설정할 수 있습니다. –

+0

hwnd2의 마우스 버튼 처리 코드에서 무엇을합니까? 거기 비린내가 뭐니? –

+1

그래서 PostMessage를 사용하여 어떻게 해결 했습니까? –

답변

6

SwitchToThisWindow이 가장 적합합니다.

+15

MSDN :이 함수는 더 이상 사용되지 않으며 일반적인 용도로 사용되지 않습니다. 이후 버전의 Windows에서는 변경되거나 사용할 수 없으므로 새 프로그램에서 사용하지 않는 것이 좋습니다. –

+2

Microsoft에서 뭔가 쓸모가 없다고 말한다면 그럴 필요가 없습니다. 그들이 여전히 사용하는지 여부. –

4

SwitchToThisWindow()는 더 이상 사용되지 않습니다.
프로덕션 환경에서 14 년간 사용합니다.
참조 윈도우 소스 코드와 당신은이 모든 곳이라고 볼 수 ...

+0

"치팅"에 대해서만 여기에서 호출 할 필요는 없습니다. 그러나이 경우 이미 전경 창이 있으므로 활성 창을 변경할 수 있습니다. – Anders

13

모두 잘 작동 :

::SetForegroundWindow(wnd) 

또는

::SetWindowPos(m_hWnd,  // handle to window 
      HWND_TOPMOST, // placement-order handle 
      0,  // horizontal position 
      0,  // vertical position 
      0, // width 
      0, // height 
      SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options 
      ); 

그러나이 마지막 창을 항상 설정 기억 상단.

+9

둘 다 win10에서 작동하지 않습니다. –

+0

조금 늦을 수도 있지만 창을 표시하기 전에':: SetForegroundWindow'를 호출해야합니다 (윈도우를 업데이트해야합니다). – Cedric

-4

// 훌륭한 작업!

Var 
WndHandle:HWND; 

begin 
WndHandle :=FindWindowEx(0,0,nil,'Calculator'); 
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0); 
SetForegroundWindow(WndHandle); 
end; 
15

이 시도, 그것은이 문제에 대한 해결책 다음과 같은 많은 시도와 errors.I 후 M $

HWND hCurWnd = ::GetForegroundWindow(); 
    DWORD dwMyID = ::GetCurrentThreadId(); 
    DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL); 
    ::AttachThreadInput(dwCurID, dwMyID, TRUE); 
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
    ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
    ::SetForegroundWindow(m_hWnd); 
    ::AttachThreadInput(dwCurID, dwMyID, FALSE); 
    ::SetFocus(m_hWnd); 
    ::SetActiveWindow(m_hWnd); 
+0

나는이 마법의 노래와 춤을 꽤 오랫동안 찾고 있었다. 그것은 나를 위해 완벽하게 작동합니다. – ulatekh

+0

나는 아직도 그게 무엇인지 이해할 수는 없지만 단지 작동한다. –

+0

그래서 나는 왜 그것을 "마법"이라고 불렀 는가? :-) – ulatekh

0

에서 오는 발견 말한다 :

SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window 
SetForegroundWindow(hwnd); 
SetActiveWindow(hwnd); 
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); 
RedrawWindow(hwnd,nil,0,RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); // redraw to prevent the window blank. 

HWND를 당신의 창입니다 HWND. 복사하여 붙여 넣기 만하지 마십시오. 또한 모든 API 호출 후 api 오류를 확인하려면 GetLastError을 사용해야합니다.

  • 창 및 오류 반환을 최소화 복원 할 수 있습니다

    나는 내 WIN7에서 확인 다음과 같은 결과가 있습니다.

  • 창이 맨 위에 있으면 창 제목이 깜박이고 오류가 반환되지 않습니다.
  • 창이 닫히면 "0x578 잘못된 창 핸들"오류가 반환됩니다.
  • 윈도우가 가장 위에 있지 않고 오류가 반환되지 않을 수도 있습니다 (예 : 맨 위에있는 taskmanager 뒤)
  • 윈도우를 맨 위에 두지는 않습니다. 사용자는 그 위에 다른 창을 만들 수 있습니다.