Flash ShowMessage(Pos) o cualquier otra ventana predefinida en la unidad de diálogos en Delphi para SO posterior a WInXP

StackOverflow https://stackoverflow.com/questions/1974143

Pregunta

Este es el enfoque que encontré para Tray...:

http://www.programmersheaven.com/mb/delphikylix/257563/257563/how-can-i-make-a-system-tray-flash/

¿Funciona la misma técnica para los diálogos (ya que, de hecho, son formularios con parámetros de suma)?¿O puedo hacerlo con métodos mucho más rápidos como obtener identificador/dirección/interfaz y sobrecargar o sobrecargar la función con el método FlashWindow(Ex)?

Quiero decir, ¿puedo hacer, por ejemplo ShowMessage(), una ventana/diálogo flash usando el método FlashWindowEx() y, si puedo, puedo hacerlo usando el ejemplo en el enlace que figura arriba?

Por favor, señale la mejor dirección o aclare mis dudas.

Gracias.

Perdón por la mala formulación de la pregunta.

¿Fue útil?

Solución

Hay muchas formas en que se puede mostrar un formulario o diálogo modal (tanto VCL como nativo del sistema) desde un programa Delphi, por lo que necesita conectarse de alguna manera al procesamiento de mensajes y capturar los mensajes que se envían cuando se muestra un formulario o diálogo modal.

Para eso un mensaje gancho se puede configurar usando el SetWindowsHookEx() Función API.Dado que solo necesita esto mientras la aplicación está inactiva, puede configurarlo en el controlador del OnDeactivate evento de aplicación y restablecerlo en el controlador para el OnActivate evento de aplicación:

var
  gNextHook: HHOOK;

procedure TForm1.AppActivate(Sender: TObject);
begin
  if gNextHook <> 0 then
    UnhookWindowsHookEx(gNextHook);
  gNextHook := 0;
end;

procedure TForm1.AppDeactivate(Sender: TObject);
begin
  gNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @WndProcHook, 0,
    GetCurrentThreadId);
end;

La función de enlace vigilaría los mensajes que se envían cuando se muestra un cuadro de diálogo o formulario modal y llamaría FlashWindowEx() con los parámetros correctos:

function WndProcHook(nCode: integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT; stdcall;
var
  DataPtr: PCWPStruct;
  Fwi: TFlashWInfo;
begin
  DataPtr := PCWPStruct(ALParam);
  if (DataPtr^.message = WM_INITDIALOG)
    or ((DataPtr^.message = CM_ACTIVATE) and (DataPtr^.lParam = 0) and (DataPtr^.wParam = 0))
  then begin
    Fwi.cbSize := SizeOf(TFlashWInfo);
    // flash caption of new modal window
    Fwi.hwnd := DataPtr^.hwnd;
    Fwi.dwFlags := FLASHW_ALL or FLASHW_TIMERNOFG;
    Fwi.uCount := 0;
    Fwi.dwTimeout := 0;
    FlashWindowEx(Fwi);
    // uncomment this to flash task bar button as well
(*
    Fwi.hwnd := Application.MainForm.Handle;
    Fwi.dwFlags := FLASHW_TRAY or FLASHW_TIMERNOFG;
    FlashWindowEx(Fwi);
*)
  end;
  Result := CallNextHookEx(gNextHook, nCode, AWParam, ALParam);
end;

Elegí WM_INITDIALOG que se envía para cuadros de diálogo nativos como los cuadros de diálogo abrir o guardar, y CM_ACTIVATE que se envía cuando un formulario VCL se muestra modalmente.Es posible que haya más mensajes de este tipo que deban detectarse.El código anterior funciona para el MessageDlg() función, la Application.MessageBox() función y TOpenDialog al menos.

Dado que estos cuadros de diálogo no tienen su propio botón en la barra de tareas, también agregué (comenté) código para mostrar el botón de la barra de tareas del formulario principal.Esto no es óptimo, ya que no están sincronizados.

Probado con Delphi 2009 en Windows XP, se omitió todo el manejo de errores, utilícelo solo como punto de partida.

Otros consejos

La misma técnica se aplica a cualquier ventana de nivel superior, que incluye cuadros de diálogo. Si usted puede conseguir la manija de la ventana, puede pasarlo a FlashWindowEx .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top