Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 41. - Úprava knihovny Comctrls pro použití ve Windows XP; Úprava fontu bublinkové nápovědy

Jan Šindelář - 22.5.2002

Úprava knihovny Comctrls pro použití ve Windows XP

Před časem (konkrétně ve 28. dílu našeho seriálu) jsme se zabývali použitím vizuálních stylů ve Windows XP. Jistě si vzpomenete na jednoduchý postup, kterým jsme použití stylů do aplikace zakomponovali prostřednictvím souboru manifestu. Možná si také vzpomenete, že tato poměrně jednoduchá akce ale nebyla nakonec úplně bez komplikací, protože VCL knihovna Delphi obsahuje několik chyb, které se za určitých okolností projeví pádem aplikace pod Windows XP.

Za jednu z nejvážnějších jsem tehdy označil chybu v komponentě ListView, kdy při použití stylu vsReport a nedefinování hlavičky jednotlivých sloupců (nebo i jednoho sloupce) se při spuštění aplikace pod Windows XP okamžitě zhroutí. Jak z toho tedy ven? Aktualizace vydané Borlandem bohužel věc neřeší, takže si v tomto konkrétním případě pomůžeme sami úpravou knihovny Comctrls, jejíž zdrojový kód (tedy soubor comctrls.pas) byste měli najít ve složce {Delphi}\Source\Vcl.

Soubor si nakopírujte do složky s vaší aplikací, otevřete jej a najděte si proceduru TCustomListView.UpdateColumn, kterou upravte podle tohoto vzoru (stačí, když celou původní proceduru přepíšete tou, která je uvedena níže, neboť je kompletní):

procedure TCustomListView.UpdateColumn(AnIndex: Integer);
const IAlignment: array[Boolean, TAlignment] of LongInt =
  ((LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_CENTER),
  (LVCFMT_RIGHT, LVCFMT_LEFT, LVCFMT_CENTER));
var
  Column: TLVColumn;
  AAlignment: TAlignment;
begin
  if HandleAllocated then
    with Column, Columns.Items[AnIndex] do
    begin
mask := LVCF_TEXT or LVCF_FMT;
if FImageIndex >= 0 then mask := mask or LVCF_IMAGE;
      iImage := FImageIndex;
      pszText := PChar(Caption);
      AAlignment := Alignment;
      if Index <> 0 then
        fmt := IAlignment[UseRightToLeftAlignment, AAlignment]
      else fmt := LVCFMT_LEFT;
      if FImageIndex <> -1 then
        fmt := fmt or LVCFMT_IMAGE or LVCFMT_COL_HAS_IMAGES;
      if WidthType > ColumnTextWidth then
      begin
        mask := mask or LVCF_WIDTH;
        cx := FWidth;
        ListView_SetColumn(Handle, Columns[AnIndex].FOrderTag, Column);
      end
      else begin
        ListView_SetColumn(Handle, Columns[AnIndex].FOrderTag, Column);
      if ViewStyle = vsList then
          ListView_SetColumnWidth(Handle, -1, WidthType)
      else if (ViewStyle = vsReport) and not OwnerData then
          ListView_SetColumnWidth(Handle, Columns[AnIndex].FOrderTag, WidthType);
      end;
    end;
end;

Když nyní projekt znovu zkompilujete, komponenta ListView už bude fungovat pod Windows XP bez problémů a většina potenciálních problémů je tak vyřešena. Zkompilovanou knihovnu (soubor comctrls.dcu) můžete poté zkopírovat do složky Lib a přepsat tak originální knihovnu, aby tato upravená verze byla použita i ve všech dalších projektech.

Úprava fontu bublinkové nápovědy

Bublinkovou nápovědou (Hint) jsme se již zabývali mnohokrát. Ukázali jsme si, jak se dá nastavit doba, po jaké se má objevit, barva a další parametry. Nyní si ukážeme vlastně poslední z chybějících nastavení a to je druh písma nápovědy.

.
.
.
implementation

{$R *.DFM}

Type
  TMyHintWindow = Class (THintWindow)
  Constructor Create (AOwner: TComponent); override;
  end;

Constructor TMyHintWindow.Create (AOwner: TComponent);
Begin
  Inherited Create (Aowner);
  Canvas.Font.Name := `Verdana`;
  Canvas.Font.Style:= [fsBold];
  Canvas.Font.Size := 18;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.ShowHint := False;
  HintWindowClass := TMyHintWindow;
  Application.ShowHint := True;
end;
.
.
.

Takto dosáhneme velkého a tučného fontu. Pravda, pro použití v reálu je poněkud nevhodný, ale jako ukázka ideální a vy si již určitě najdete vhodnou kombinaci. Někteří uživatelé jistě ocení, pokud jim nabídnete možnost zvolit si i takovýto drobný detail v nastavení aplikace.