es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error de rango al establecer el estilo de fuente del encabezado de TListView

En una aplicación VCL de 32 bits en Windows 10 en Delphi 11 Alexandria, tengo un TListView, donde configuro el estilo de fuente negrita para el encabezado del ListView en el controlador FormCreate:

private
  FhHeaderFont: THandle;

procedure TformMain.FormCreate(Sender: TObject);
begin  
  ...
  SetColumnHeaderFontBold;
end;

procedure TformMain.SetColumnHeaderFontBold;
const
  LVM_GETHEADER = Winapi.CommCtrl.LVM_FIRST + 31;
var
  LF: Winapi.Windows.TLogFont;
  hHeader, hCurrFont, hOldFont: THandle;
begin
  hHeader := Winapi.Windows.SendMessage(lvMRUProjects.Handle, LVM_GETHEADER, 0, 0);
  hCurrFont := Winapi.Windows.SendMessage(hHeader, WM_GETFONT, 0, 0); // ERangeError

  if GetObject(hCurrFont, SizeOf(LF), Addr(LF)) > 0 then
  begin
    LF.lfWeight := Winapi.Windows.FW_BOLD;
    FhHeaderFont := Winapi.Windows.CreateFontIndirect(LF);
    hOldFont := Winapi.Windows.SelectObject(hHeader, FhHeaderFont);
    Winapi.Windows.SendMessage(hHeader, winapi.Messages.WM_SETFONT, FhHeaderFont, 1);
  end;
end;

Ahora, ALEATORIAMENTE obtengo un ERangeError en esta línea al iniciar el programa:

hCurrFont := Winapi.Windows.SendMessage(hHeader, WM_GETFONT, 0, 0); // ERangeError

Esta es la pila de llamadas de Eurekalog:

enter image description here

Este es el mensaje de error:

Range check error at (004EDAED){MyApp.exe} [008EDAED] MainForm.TformMain.SetColumnHeaderFontBold (Line 616, "MainForm.pas") + $13.

¿Qué está causando este error y cómo puedo evitarlo?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El error es causado por el hecho de que SendMessage está devolviendo un identificador no válido para la variable hHeader, lo que resulta en un parámetro no válido que se pasa a SendMessage en la siguiente línea. Esto podría ser debido a varias razones, como que el ListView no tenga un control de cabecera, o que el identificador se haya destruido antes de enviar el mensaje.

    Para evitar este error, puedes agregar código de manejo de errores para verificar si el identificador es válido antes de continuar con la manipulación de la fuente. Una forma de hacer esto es usar la función IsWindow para verificar si el identificador es un identificador de ventana válido:

    procedure TformMain.SetColumnHeaderFontBold;
    const
      LVM_GETHEADER = Winapi.CommCtrl.LVM_FIRST + 31;
    var
      LF: Winapi.Windows.TLogFont;
      hHeader, hCurrFont, hOldFont: THandle;
    begin
      hHeader := Winapi.Windows.SendMessage(lvMRUProjects.Handle, LVM_GETHEADER, 0, 0);
    
      if IsWindow(hHeader) then // agregar manejo de errores aquí
      begin
        hCurrFont := Winapi.Windows.SendMessage(hHeader, WM_GETFONT, 0, 0);
    
        if GetObject(hCurrFont, SizeOf(LF), Addr(LF)) > 0 then
        begin
          LF.lfWeight := Winapi.Windows.FW_BOLD;
          FhHeaderFont := Winapi.Windows.CreateFontIndirect(LF);
          hOldFont := Winapi.Windows.SelectObject(hHeader, FhHeaderFont);
          Winapi.Windows.SendMessage(hHeader, winapi.Messages.WM_SETFONT, FhHeaderFont, 1);
        end;
      end;
    end
    

    Esto evitará que se ejecute el código de manipulación de la fuente si el identificador hHeader no es válido, y debería evitar el ERangeError.

Comments are closed.