想给控件增加一个ReadOnly属性,请高手帮助!(给出正确答案者追加100分) (100分)

  • 主题发起人 主题发起人 sundart
  • 开始时间 开始时间
S

sundart

Unregistered / Unconfirmed
GUEST, unregistred user!
我继承TCombobox控件写了个控件,想增加一个ReadOnly属性,
请问如何实现?
注:
设置Style属性为csDropDownList,可以实现类似的效果,
但不接受焦点了。
 
参考一下TCustomEdit.SetReadOnly看看。
 
试过了,好像没有效果
 
呵呵,覆盖KeyPress方法
unit ComboBoxEx;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls;
type
TComboBoxEx1 = class(TComboBox)
private
{ Private declarations }
FReadOnly: boolean;
procedure SetReadOnly(Value: Boolean);
protected
{ Protected declarations }
procedure KeyPress(var Key: Char);override;
public
{ Public declarations }
published
{ Published declarations }
property ReadOnly: boolean read FReadOnly write SetReadOnly default false;
end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('dwh', [TComboBoxEx1]);
end;

procedure TComboBoxEx1.KeyPress(var Key: Char);
begin
if FReadOnly then
key := #0
else
inherited;
end;

procedure TComboBoxEx1.SetReadOnly(Value: Boolean);
begin
if FReadOnly <> Value then
begin
FReadOnly := Value;
//if HandleAllocated then
//SendMessage(Handle, EM_SETREADONLY, Ord(Value), 0);
end;
end;

end.
 
影 子:你的方法可行吗?
是试试 粘贴 功能!
它只能屏蔽键盘输入,却可以通过剪贴板粘贴数据:)
TEdit的ReadOnly属性绝对可以!
请继续建议!
谢谢!
 
无法拦截WM_CUT,WM_PASTE消息!
如果屏蔽PopupMenu的话,不知道你满不满意。
constructor TComboBoxEx1.Create(AOwner: TComponent);
begin
inherited;
FPopupMenu := TPopupMenu.Create(self);
self.PopupMenu := FPopupMenu;
end;

destructor TComboBoxEx1.Destroy;
begin
FPopupMenu.Free;
inherited;
end;
 
如果按照楼上的意思,我还得拦截Ctrl+C, Ctrl+V了。
没有更好的办法吗?
 
我没有更好的方法,Ctrl+C,Ctrl+V已经在KeyPress事件中过滤了。
 
屏蔽KeyPress事件。
key=#39 then
Exit
else
Exit;
呵呵,简单吧
 
关键是使用 FEditHandle域:

unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyComboBox = class(TComboBox)
private
FReadOnly:Boolean;
procedure SetReadOnly(Value:Boolean);
protected
procedure Createwnd;override;
published
property ReadOnly:Boolean Read FReadOnly write SetReadOnly;
end;

implementation
procedure TMyComboBox.SetReadOnly(value:Boolean);
begin
if FReadOnly <> Value then
begin
FReadOnly := Value;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
end;
procedure TMyComboBox.CreateWnd;
begin
inherited CreateWnd;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(FReadOnly), 0);
end;
end.
 
xeen:你的方法我试了,好像没用?
代码如下:
unit QMyComboBox;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls;
type
TMyComboBox = class(TCombobox)
private
FReadOnly:Boolean;
procedure SetReadOnly(Value:Boolean);
protected
procedure CreateWnd;override;
published
property ReadOnly:Boolean Read FReadOnly write SetReadOnly;
end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TMyComboBox]);
end;
procedure TMyComboBox.SetReadOnly(value:Boolean);
begin
if FReadOnly <> Value then
begin
FReadOnly := Value;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
end;
procedure TMyComboBox.CreateWnd;
begin
inherited CreateWnd;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(FReadOnly), 0);
end;
end.
 
不会吧,我试了好好的.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,unit2, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
cb:TMycombobox;
begin
cb:=tmycombobox.Create(self);
cb.ReadOnly := true;
cb.Parent := form1;
end;

end.
 
呵呵,xeen,我知道为什么试的结果不一样了
cb:=tmycombobox.Create(self);
cb.Items.Add('11');
cb.Items.Add('22');
cb.Text := '33';
cb.ReadOnly := true;
cb.Parent := form1;
你输入:'11',或按退格键试试.
谢谢!!!
 
退格键可以通过keypress......
 
hehe,是 KeyPress 过程搞得鬼.Delphi还真弄了些小暗门,下面的代码除了上下方向键都没
反应了,这没问题了吧.
unit QMyComboBox;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls;
type
TMyComboBox = class(TCombobox)
private
FReadOnly:Boolean;
procedure SetReadOnly(Value:Boolean);
protected
procedure CreateWnd;override;
procedure KeyPress(var Key: Char);
override;
published
property ReadOnly:Boolean Read FReadOnly write SetReadOnly;
end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TMyComboBox]);
end;
procedure TmyComboBox.KeyPress(var Key: Char);
begin
if FReadOnly then
key := #0
else
inherited KeyPress(Key);
end;
procedure TMyComboBox.SetReadOnly(value:Boolean);
begin
if FReadOnly <> Value then
begin
FReadOnly := Value;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
end;
procedure TMyComboBox.CreateWnd;
begin
inherited CreateWnd;
if FEditHandle > 0 then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(FReadOnly), 0);
end;
end.
 
呵呵,基本接近我的要求了.
给分了.
 
多人接受答案了。
 
后退
顶部