2009-02-09 8 views
5

¿Alguien sabe cómo hacer una ventana 'siempre en la base' o una ventana fijada al escritorio? Debería recibir el foco y los clics del mouse, pero debería permanecer al final del orden Z. También sería genial si pudiera permanecer en el escritorio incluso cuando el usuario minimiza todo o muestra la operación del escritorio.Cómo hacer 'ventana siempre en la base'

Las soluciones de Delphi y C# (o soluciones/sugerencias parciales) serían geniales.

+0

Si es posible, debería usar algo más, pero Delphi, ya que la interacción entre la ventana de la aplicación oculta y la ventana principal hará que las cosas aún más complicadas. La mayor parte de esto es material privado en forms.pas, difícil de cambiar. – mghie

+0

No puede ser posible cuando se usa Show Desktop. Sin embargo, puede ser cuando se usa Minimizar todo: estableciendo la propiedad MinimizeBox en falso, se inhabilitaría la minimización del formulario. – configurator

+0

Duplicado: http://stackoverflow.com/questions/365094/window-on-desktop –

Respuesta

12

Advertencia Se sugirió que puede lograr esto llamando a SetParent y configurando la ventana para que sea un elemento secundario del escritorio. Si se hace esto, que el gestor de Win32 ventana de combinar la cola de entrada del escritorio a la ventana de su hijo, esto es una cosa mala -Raymond Chen explains why.

Además, tenga en cuenta que llamar SetWindowPos con HWND_BOTTOM es incompleta. Debe hacer esto siempre que su ventana esté cambiando zorder. Maneje el evento WM_WINDOWPOSCHANGING, mire SWP_NOZORDER para obtener más información.

7

SetWindowPos puede hacer Windows AlwaysOnTop. Lo más probable es que pueda dar el resultado opuesto. Pruebe algo como lo siguiente:

[DllImport("user32.dll")] 
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, 
    int Y, int cx, int cy, uint uFlags); 


public const uint SWP_NOSIZE   = 0x0001; 
public const uint SWP_NOMOVE   = 0x0002; 
public const uint SWP_NOACTIVATE  = 0x0010; 
public const int HWND_BOTTOM = 1; 


SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 

Nota:

  • no hemos probado este enfoque (para la fabricación de ventanas siempre en la parte inferior)
  • Si pasa a trabajar, entonces lo más probable es que el programa de escritorio la operación ocultará la ventana. Así que tal vez deberías profundizar aún más en esta 'buena' API.

EDITAR: He hecho algunas búsquedas a lo largo de estas líneas para confirmar si hace el truco y encontré algo interesante - a duplicate.

+1

+1 para el enlace a la otra pregunta de SO, debe contener todo para iniciar el OP. – mghie

1

Aquí hay una solución para la ventana ATL. Si puede aplicar a C#, lo ayudará.


BEGIN_MSG_MAP(...) 
    ... 
    MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging) 
    ... 
END_MSG_MAP() 

LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 

{ 

    if (_bStayOnBottom) 
    { 
     auto pwpos = (WINDOWPOS*)lParam; 

     pwpos->hwndInsertAfter = HWND_BOTTOM; 

     pwpos->flags &= (~SWP_NOZORDER); 

    } 
    return 0; 
} 
+0

¡Esto funciona genial! ¡Gracias! – Andy

Cuestiones relacionadas