抄的(下载自<a href="http://www.torry.ru/vcl/lbcb/fucombo97.zip">这里</a>
unit ComboBox97;
interface
uses Windows, Messages, Classes, Forms, Controls, Graphics, StdCtrls;
type
TComboState97 = set of (csButtonPressed, csMouseCaptured);
TCustomComboBox97 = class(TCustomComboBox)
private
FFlat: Boolean;
FOldColor: TColor;
FOldParentColor: Boolean;
FButtonWidth: Integer;
FEditState: TComboState97;
FMouseInControl: Boolean;
procedure SetFlat(const Value: Boolean);
procedure DrawButtonBorder(DC: HDC);
procedure DrawControlBorder(DC: HDC);
procedure DrawBorders;
function NeedDraw3DBorder: Boolean;
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure CMEnabledChanged(var Msg: TMessage); message CM_ENABLEDCHANGED;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
protected
procedure TrackButtonPressed(X, Y: Integer);
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
property Flat: Boolean read FFlat write SetFlat default False;
public
constructor Create(AOwner: TComponent); override;
end;
TComboBox97 = class(TCustomComboBox97)
published
property Style;
property Flat;
{$IFDEF VER120}
property Anchors;
property BiDiMode;
property Constraints;
{$ENDIF}
property Color;
property Ctl3D;
property DragCursor;
{$IFDEF VER120}
property DragKind;
{$ENDIF}
property DragMode;
property DropDownCount;
property Enabled;
property Font;
{$IFNDEF VER90}
property ImeMode;
property ImeName;
{$ENDIF}
property ItemHeight;
property Items;
property MaxLength;
{$IFDEF VER120}
property ParentBiDiMode;
{$ENDIF}
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Sorted;
property TabOrder;
property TabStop;
property Text;
property Visible;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnDropDown;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
property OnStartDrag;
{$IFDEF VER120}
property OnEndDock;
property OnStartDock;
{$ENDIF}
end;
procedure Register;
implementation
{ TCustomComboBox97 }
constructor TCustomComboBox97.Create(AOwner: TComponent);
begin
inherited;
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL) + 2;
FOldColor := inherited Color;
FOldParentColor := inherited ParentColor;
end;
procedure TCustomComboBox97.SetFlat(const Value: Boolean);
begin
if Value <> FFlat then
begin
FFlat := Value;
Ctl3D := not Value;
Invalidate;
end;
end;
procedure TCustomComboBox97.CMEnter(var Message: TCMEnter);
begin
inherited;
if not (csDesigning in ComponentState) then
DrawBorders;
end;
procedure TCustomComboBox97.CMExit(var Message: TCMExit);
begin
inherited;
if not (csDesigning in ComponentState) then
DrawBorders;
end;
procedure TCustomComboBox97.CMMouseEnter(var Message: TMessage);
begin
inherited;
if not FMouseInControl and Enabled then
begin
FMouseInControl := True;
DrawBorders;
end;
end;
procedure TCustomComboBox97.CMMouseLeave(var Message: TMessage);
begin
inherited;
if FMouseInControl and Enabled then
begin
FMouseInControl := False;
DrawBorders
end;
end;
procedure TCustomComboBox97.CMEnabledChanged(var Msg: TMessage);
begin
inherited;
if FFlat then
if Enabled then
begin
inherited Color := FOldColor;
inherited ParentColor := FOldParentColor;
end
else
begin
FOldParentColor := inherited Parentcolor;
FOldColor := inherited Color;
inherited ParentColor := True;
end;
end;
procedure TCustomComboBox97.WMPaint(var Message: TWMPaint);
var
DC: HDC;
PS: TPaintStruct;
procedure DrawButton;
var
ARect: TRect;
begin
GetWindowRect(Handle, ARect);
OffsetRect(ARect, -ARect.Left, -ARect.Top);
Inc(ARect.Left, ClientWidth - FButtonWidth);
InflateRect(ARect, -1, -1);
DrawFrameControl(DC, ARect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX or DFCS_FLAT);
ExcludeClipRect(DC, ClientWidth - FButtonWidth - 4, 0, ClientWidth, ClientHeight);
end;
begin
if not FFlat then
begin
inherited;
Exit;
end;
if Message.DC = 0 then
DC := BeginPaint(Handle, PS)
else
DC := Message.DC;
try
if Style <> csSimple then
begin
FillRect(DC, ClientRect, Brush.Handle);
DrawButton;//(DC);
end;
PaintWindow(DC);
finally
if Message.DC = 0 then
EndPaint(Handle, PS);
end;
DrawBorders;
end;
function TCustomComboBox97.NeedDraw3DBorder: Boolean;
begin
if csDesigning in ComponentState then
Result := Enabled
else
Result := FMouseInControl or (Screen.ActiveControl = Self);
end;
procedure TCustomComboBox97.DrawButtonBorder(DC: HDC);
const
Flags: array[Boolean] of Integer = (0, BF_FLAT);
var
ARect: TRect;
BtnFaceBrush: HBRUSH;
begin
ExcludeClipRect(DC, ClientWidth - FButtonWidth + 4, 4,
ClientWidth - 4, ClientHeight - 4);
GetWindowRect(Handle, ARect);
OffsetRect(ARect, -ARect.Left, -ARect.Top);
Inc(ARect.Left, ClientWidth - FButtonWidth - 2);
InflateRect(ARect, -2, -2);
if NeedDraw3DBorder then
DrawEdge(DC, ARect, EDGE_RAISED, BF_RECT or Flags[csButtonPressed in FEditState])
else
begin
BtnFaceBrush := CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
try
InflateRect(ARect, -1, -1);
FillRect(DC, ARect, BtnFaceBrush);
finally
DeleteObject(BtnFaceBrush);
end;
end;
ExcludeClipRect(DC, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
end;
procedure TCustomComboBox97.DrawControlBorder(DC: HDC);
var
ARect: TRect;
BtnFaceBrush, WindowBrush: HBRUSH;
begin
BtnFaceBrush := CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
WindowBrush := CreateSolidBrush(GetSysColor(COLOR_WINDOW));
try
GetWindowRect(Handle, ARect);
OffsetRect(ARect, -ARect.Left, -ARect.Top);
if NeedDraw3DBorder then
begin
DrawEdge(DC, ARect, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
FrameRect(DC, ARect, BtnFaceBrush);
InflateRect(ARect, -1, -1);
FrameRect(DC, ARect, WindowBrush);
end
else
begin
FrameRect(DC, ARect, BtnFaceBrush);
InflateRect(ARect, -1, -1);
FrameRect(DC, ARect, BtnFaceBrush);
InflateRect(ARect, -1, -1);
FrameRect(DC, ARect, WindowBrush);
end;
finally
DeleteObject(WindowBrush);
DeleteObject(BtnFaceBrush);
end;
end;
procedure TCustomComboBox97.DrawBorders;
var
DC: HDC;
begin
if not FFlat then
Exit;
DC := GetWindowDC(Handle);
try
DrawControlBorder(DC);
if Style <> csSimple then
DrawButtonBorder(DC);
finally
ReleaseDC(DC, Handle);
end;
end;
procedure TCustomComboBox97.TrackButtonPressed(X, Y: Integer);
var
ARect: TRect;
begin
SetRect(ARect, ClientWidth - FButtonWidth, 0, ClientWidth, ClientHeight);
if (csButtonPressed in FEditState) and not PtInRect(ARect, Point(X, Y)) then
begin
Exclude(FEditState, csButtonPressed);
DrawBorders;
end;
end;
procedure TCustomComboBox97.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if DroppedDown then
begin
Include(FEditState, csButtonPressed);
Include(FEditState, csMouseCaptured);
Invalidate;
end;
inherited;
end;
procedure TCustomComboBox97.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if csMouseCaptured in FEditState then
TrackButtonPressed(X, Y);
inherited;
end;
procedure TCustomComboBox97.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
TrackButtonPressed(-1, -1);
inherited;
end;
procedure Register;
begin
RegisterComponents('Additional', [TComboBox97]);
end;
end.