Tengo un programa de Windows que tiene dos 2 ventanas:

hwnd (main interface)

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

Cuando me haga doble clic en hwnd, necesito hwnd2 a aparecer y mostrar algunos datos, por lo que utilizar esta función para traer hwnd2 arriba:

BringWindowToTop(hwnd2);

hwnd2 es llevado a la parte superior, pero hay una cosa extraña. Cuando hago clic en hwnd2 de nuevo, hwnd (interfaz principal) cop a sí mismo de nuevo automáticamente.
He intentado utilizar la siguiente función para solucionar este problema, pero no de ellos funciona.

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);

¿Cómo podría resolver este problema?
Gracias de antemano.

(para responder a aJ, hwnd2 no tiene padre porque debe ser una ventana principal por lo que puede ser en la parte frontal/posterior de otras ventanas)

(hwnd2 es un reproductor multimedia que se compone de varias ventanas, una de las ventanas de vídeo de la exhibición, otros dos trackbar los controles de la barra de progreso y la barra de volumen, un control de Barra de herramientas de panel de control).

(Hay uno que esta puede ser de ayuda, no importa que la ventana me clic en hwnd2, hwnd aparece automáticamente como loong como «el ratón en la parte superior de hwnd en el orden-Z», incluyendo la barra de menú y no-área de cliente, etc.)

(Este reproductor está reflejada en Directo el Espectáculo. Yo uso IVideoWindow::put_Owner para poner la ventana de vídeo como el vídeo propietario, Directa Mostrar crea internamente una sub-ventana de vídeo como un niño de la ventana de vídeo. A excepción de esta sub-ventana de vídeo que no puedo ver el código fuente, no veo cualquier cosa sospechosa en hwnd2.)

He encontrado la razón, que es la causa Directa del Show. Yo uso multithread para su ejecución, y entonces el problema resuelto. Pero…por qué??

Este problema puede ser resuelto mediante el uso de PostMessage (en lugar de SendMessage).

  • Cualquier específicos rreason por qué hwnd2 no tiene padre? hwnd se puede establecer como primario, mientras que la creación.
  • ¿Qué hacer en hwnd2 el botón del ratón código de control? Nada sospechoso, no?
  • Entonces, ¿cómo resolverlo utilizando PostMessage?

7 Comentarios

  1. 19

    probar este,se dice que viene de 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);
    • He estado buscando esta magia de canto y baile que hace ya bastante tiempo. Funciona a la perfección para mí.
    • Todavía no puedo entender lo que hace,pero sólo funciona
    • Por eso me he referido a ella como «magia» 🙂
    • Ojalá pudiera decir lo mismo. No funciona para mí. Cuadro de diálogo se presenta el enfoque, pero otro cuadro de diálogo permanece en frente de ella.
    • No trabajo para mí, cuando quiero poner una minimizar ventanas a la parte superior en win7. Simplemente no traer el minimizar ventanas en la parte superior. Se puede traer a las ventanas de la parte superior si el windows no es minimizar. El SetFocus api de devolver el código de error 0x57 «El parámetro es incorrecto.» en mi caso en win7. No sé por qué este código ignorar todas las api de windows de error.
    • sin el código fuente de la api de windows, es difícil decir

  2. 13

    Tanto un gran trabajo:

    ::SetForegroundWindow(wnd)

    o

    ::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
                );

    Pero recuerda que la última de uno de los conjuntos de la ventana de siempre en la parte superior.

    • Ambos no trabajan en win10
    • Yo podría ser un poco tarde, pero usted tiene que llamar a ::SetForegroundWindow antes de mostrar la ventana (asegúrese de actualizar la ventana aswell).
  3. 8

    SwitchToThisWindow que funciona mejor para mí.

    • MSDN: esta función es obsoleto y no para el uso general. Se recomienda que no se utilice en los nuevos programas de porque puede ser alterado o no disponible en las versiones posteriores de Windows.
  4. 5

    SwitchToThisWindow() no está en desuso en todo.

    Yo lo uso desde hace 14 años en el entorno de producción.

    Ver código fuente de Windows y verás que se llama en todas partes…

    • No hay necesidad de llamar a que aquí, es sólo para «hacer trampa». Pero en este caso, ya tenemos un primer plano de la ventana de modo que tenemos el derecho a cambiar la ventana activa
  5. 4

    Después de muchos intentos y errores.Encontré la siguiente solución a este problema:

    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);
    //redraw to prevent the window blank.
    RedrawWindow(hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN );

    El hwnd es el windows HWND . Por favor no copiar y pegar. Usted también necesita utilizar GetLastError a la api de comprobación de error después de cada llamada a la api.

    Me tienen que confirmar el siguiente resultado en mi win7:

    • Puede restaurar minimizar la ventana y no hay error de retorno.
    • Si la ventana ya parte superior, el título de la ventana parpadeará y el error de no retorno.
    • Si la ventana se ha cerrado, se mostrará el error «0x578 no Válido identificador de ventana.»
    • Que puede traer la ventana a la parte superior de todos no de ventana de nivel superior y el error de no retorno.(Por ejemplo va detrás de la parte superior-la mayoría de los taskmanager)
    • No hacer la ventana más alta. El usuario puede hacer otra ventana en la parte superior de la misma.
  6. -4

    //un gran trabajo!

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

Dejar respuesta

Please enter your comment!
Please enter your name here