unit TdkFontComboBox; { Unit: TdkFontcombo purpose: Improved KOL Font combobox Author: Thaddy de Koning Copyright: None Remarks: based on code by Boguslav Brandys, but almost everything has changed. Basic processing not changed except for use of NewFont, now much simpler. Turned into a real TControl; The original needed an Icon resource, this one takes icons for truetype, vector and Opentype from "fontex.dll". which should be present on all systems from win95. If XP or 2000 then OpenType fonts are supported. Thaddy Revisions: Version 1.01: Added wndprocFontCombo, so Onchange stays available Version 1.02: Cleaned up } interface uses Windows, Messages, KOL; type PFontComboData = ^TFontComboData; TFontComboData = object(Tobj) Fowner:PControl; ICOpenType, ICTrueType, ICVector, ICRaster:PIcon; destructor destroy;virtual; function DrawOneItem(Sender: PObj; DC: HDC; const Rect: TRect; ItemIdx: Integer; DrawAction: TDrawAction; ItemState: TDrawState): Boolean; end; function NewFontComboBox(AOwner: PControl): PControl; implementation uses objects; const FT_RASTER = 0; FT_VECTOR = 1; FT_TRUETYPE = 2; FT_OPENTYPE = 3; function WndprocFontCombo( Sender: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean; var struct:TDrawItemStruct; States:TDrawAction; Action:TDrawstate; DC:HDC; begin Result:=False; if (msg.message = WM_COMMAND) and (HIWORD(msg.wparam) = CBN_SELCHANGE) then sender.font.Assign(PGraphicTool(sender.Itemdata[sender.CurIndex])); end; function EnumFontsProc(var EnumLogFont: TEnumLogFont; var TextMetric: TNewTextMetric; FontType: Integer; Data: LPARAM): Integer;stdcall; var FaceName: String; control: PControl; i: Integer; Font:pGraphicTool; begin Font:=NewFont; Applet.Add2AutoFree(Font); Font.tag:=Fonttype; if Fonttype = 0 then Font.tag:=FT_VECTOR else if fonttype = RASTER_FONTTYPE then font.tag := FT_RASTER else if FontType = TRUETYPE_FONTTYPE then Font.tag := FT_TRUETYPE; If (WinVer > WvNT) and (Getbits(TextMetric.ntmFlags,17,18) > 0) then Font.tag:=FT_OPENTYPE; Control := PControl(Data); FaceName := String(EnumLogFont.elfLogFont.lfFaceName); with EnumLogFont do begin elfLogFont.lfHeight := Control.font.FontHeight; elfLogFont.lfWidth := 0; end; if (Control.count = 0) or (Control.IndexOf(FaceName) < 0) then begin if EnumLogFont.elflogfont.lfCharSet = SYMBOL_CHARSET then font.AssignHandle(0) else font.Assignhandle(CreateFontIndirect(EnumLogFont.elfLogFont)); i := Control.Add(FaceName); Control.ItemData[i] := Cardinal(Font); end; Result := 1; end; function NewFontComboBox; var h:Thandle; Data:PFontcombodata; begin New(Data,create); Result := NewComboBox(AOwner, [coReadOnly, coSort, coOwnerDrawVariable]); with Result^ do begin Color:=clWindow; Data.Fowner:=Result; CustomObj:=Data; H:=LoadLibrary('fontext.dll'); if H <> 0 then with Data^ do begin ICTruetype:= NewIcon; ICTruetype.LoadFromResourceID(H,2,16); ICRaster:= NewIcon; ICRaster.LoadFromResourceID(H,3,16); ICVector:= NewIcon; ICOpenType:= NewIcon; if WinVer > WvNT then begin ICVector.LoadFromResourceID(H,5,16); ICOpentype.LoadFromResourceID(H,6,16) end else begin ICOpentype.LoadFromResourceID(H,2,16); // prevent dll hell ICVector.LoadFromResourceID(H,3,16); end; end; FreeLibrary(H); OnDrawItem := Data.DrawOneItem; CurIndex:=IndexOf(Parent.Font.FontName); AttachProc(WndProcFontCombo); EnumFontFamilies(Result.canvas.handle, NIL, @EnumFontsProc, LongInt(Result)); end end; function TFontComboData.DrawOneItem(Sender: PObj; DC: HDC; const Rect: TRect; ItemIdx: Integer; DrawAction: TDrawAction; ItemState: TDrawState): Boolean; var xRect: TRect; xfont: HFONT; FD: pGraphictool; begin if ItemIdx > -1 then begin FD := Pointer(pControl(Sender).ItemData[ItemIdx]); xRect := Rect; InFlateRect(xRect,-1,-1); FillRect(DC, Rect, 0); if FD.Tag = FT_TRUETYPE then DrawIconEx(DC, Rect.Left + 1,Rect.Top,ICTruetype.handle,16,16,0,0,DI_NORMAL) else if FD.Tag = FT_OPENTYPE then DrawIconEx(DC, Rect.Left + 1,Rect.Top,ICOpentype.handle,16,16,0,0,DI_NORMAL) else if FD.tag = FT_RASTER then DrawIconEx(DC, Rect.Left + 1,Rect.Top,ICRaster.handle,16,16,0,0,DI_NORMAL) else if FD.tag = FT_VECTOR then DrawIconEx(DC, Rect.Left + 1,Rect.Top,ICVector.handle,16,16,0,0,DI_NORMAL); xfont := FD.Handle; xRect.Left := xRect.Left + 20; if xfont <> 0 then SelectObject(DC, xfont) else SelectObject(DC, pControl(Sender).Font.Handle); DrawText(DC, PChar(pControl(Sender).Items[ItemIdx]), Length(pControl(Sender).Items[ItemIdx]), xRect, DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX); if (odaSelect in DrawAction) then InvertRect(DC, Rect); end; Result := true; end; destructor TFontComboData.Destroy; begin IcTruetype.free; ICRaster.free; IcOpenType.free; IcVector.Free; inherited; end; end.