你能帮忙把这个非常小的 C++ 组件翻译成 Delphi 吗? [英] Can you help translating this very small C++ component to Delphi?
本文介绍了你能帮忙把这个非常小的 C++ 组件翻译成 Delphi 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在将以下 C++ 组件翻译成 Delphi:
I'm translating the following C++ component to Delphi:
但它不起作用...我正在附上翻译后的代码,可以请一位专业人士看一下吗?
But it's not working... I'm attaching the translated code, could one of the pros take a look?
谢谢!
代码如下:
unit ComboBoxPlus;
interface
uses
SysUtils, Classes, Controls, StdCtrls, Messages, Types, Windows, Graphics;
type
TComboBoxPlus = class(TComboBox)
private
FClickedItem: Integer;
FListHandle: HWND;
ListWndProcPtr: Longint;
OldListWndProc: Pointer;
function GetIsEnabled(Index: Integer): Boolean;
procedure SetIsEnabled(Index: Integer; Value: Boolean);
protected
procedure WndProc(var Message: TMessage);
procedure ListWndProc(var Message: TMessage); virtual;
procedure DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Enabled[Index: Integer]: Boolean read GetIsEnabled write SetIsEnabled;
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Win32', [TComboBoxPlus]);
end;
constructor TComboBoxPlus.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Style := csOwnerDrawFixed;
Height := 21;
ItemHeight := 17;
ListWndProcPtr := Longint(Classes.MakeObjectInstance(ListWndProc));
end;
destructor TComboBoxPlus.Destroy;
begin
if FListHandle <> 0 then
SetWindowLong(FListHandle, GWL_WNDPROC, Longint(OldListWndProc));
FreeObjectInstance(Pointer(ListWndProcPtr));
inherited Destroy;
end;
function TComboBoxPlus.GetIsEnabled(Index: Integer): Boolean;
begin
if Boolean(Items.Objects[Index]) then Result := false
else Result := true;
end;
procedure TComboBoxPlus.SetIsEnabled(Index: Integer; Value: Boolean);
begin
if Value then
Items.Objects[Index] := TObject(false)
else
Items.Objects[Index] := TObject(true);
end;
procedure TComboBoxPlus.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
begin
if odSelected in State then
begin
if not Boolean(Items.Objects[Index]) then
begin
Canvas.Brush.Color := clHighlight;
Canvas.Font.Color := clHighlightText;
Canvas.FillRect(Rect);
end else
begin
Canvas.Brush.Color := Color;
Canvas.Font.Color := clGrayText;
Canvas.FillRect(Rect);
Canvas.DrawFocusRect(Rect);
end;
end else
begin
if not Boolean(Items.Objects[Index]) then
begin
Canvas.Brush.Color := Color;
Canvas.Font.Color := Font.Color;
end else
begin
Canvas.Brush.Color := Color;
Canvas.Font.Color := clGrayText;
end;
Canvas.FillRect(Rect);
end;
Canvas.TextOut(Rect.Left + 3, Rect.Top + (((Rect.Bottom - Rect.Top) div 2) -
(Canvas.TextHeight('Wg') div 2)), Items.Strings[Index]);
end;
procedure TComboBoxPlus.WndProc(var Message: TMessage);
begin
if (Message.Msg = WM_CTLCOLORLISTBOX) then
begin
if FListHandle = 0 then
begin
FListHandle := HWnd(Message.LParam);
inherited WndProc(Message);
OldListWndProc := Pointer(SetWindowLong(FListHandle, GWL_WNDPROC, ListWndProcPtr));
exit;
end;
end;
inherited WndProc(Message);
end;
procedure TComboBoxPlus.ListWndProc(var Message: TMessage);
var
R: TRect;
X, Y: Integer;
begin
if (Message.Msg = WM_LBUTTONDOWN) or (Message.Msg = WM_LBUTTONUP) then
begin
X := Message.LParamLo;
Y := Message.LParamHi;
Windows.GetClientRect(FListHandle, R);
if PtInRect(R, Point(X, Y)) then
begin
FClickedItem := SendMessage(FListHandle, LB_GETTOPINDEX, 0, 0) + (Y div ItemHeight);
if (not Enabled[FClickedItem]) then
begin
Message.Result := 0;
exit;
end;
end;
end else if (Message.Msg = WM_LBUTTONDBLCLK) then
begin
Message.Result := 0;
exit;
end;
Message.Result := CallWindowProc(OldListWndProc, FListHandle, Message.Msg,
Message.WParam, Message.LParam);
end;
end.
推荐答案
午夜过后我累了 - 对不起我的愚蠢.它正在进行以下修改:
It's after midnight I'm tired - sorry about my stupidity. It's working with the following modifications:
procedure WndProc(var Message: TMessage); override;
procedure ListWndProc(var Message: TMessage);
procedure DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState); override;
(添加两个覆盖并取出虚拟)
(add two overrides and take out the virtual)
最后要整理的是,如果在没有键盘键的情况下选择了禁用的项目,不要让组合框关闭!
The last thing to sort out is not to let the combobox close up if the disabled item is selected without keyboard keys!
这篇关于你能帮忙把这个非常小的 C++ 组件翻译成 Delphi 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文