我自己编了个计算器控件,用了WM_CHAR消息响应但还不能响应键盘输入,请问如何解决?(付源代码)(100分)

  • 主题发起人 主题发起人 Hailer
  • 开始时间 开始时间
H

Hailer

Unregistered / Unconfirmed
GUEST, unregistred user!
程序代码如下,请指教~~ 另:我是初学者,程序有什么不好的地方都请各位大虾指出来,让小弟改正,谢谢~~
现在的主要问题是,这个构件用了WM_CHAR消息,构件并不能响应

unit Cal;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Buttons, ExtCtrls;

type
TCal = class(Tpanel)
private
{ Private declarations }
Entry: TEdit;
B1: TSpeedButton;
B2: TSpeedButton;
B3: TSpeedButton;
BJia: TSpeedButton;
B4: TSpeedButton;
B5: TSpeedButton;
B6: TSpeedButton;
BJian2: TSpeedButton;
B7: TSpeedButton;
B9: TSpeedButton;
B8: TSpeedButton;
B0: TSpeedButton;
BCheng: TSpeedButton;
BChu: TSpeedButton;
BDengHao: TSpeedButton;
BDian: TSpeedButton;
BClean: TSpeedButton;
BtBack: TSpeedButton;
procedure NumberClick(Sender: TObject);
procedure OperClick(Sender: TObject);
procedure BCleanClick(Sender: TObject);
procedure BDengHaoClick(Sender: TObject);
procedure BdianClick(Sender: TObject);
procedure BtBackClick(Sender: TObject);
protected
{ Protected declarations }
procedure MyKeyPress(var message: Tmessage); message WM_CHAR;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
function Calculate(Oper: Char): string;
published
{ Published declarations }
property OnKeyPress;
end;

procedure Register;


implementation

var
LastOperator: char;
NowEntry, LastEntry: extended;
EntryChongZhi: Boolean;
OperOK: Boolean;
Total: string;

constructor TCal.Create(AOwner: TComponent);
begin
inherited create(AOwner);
Width := 153;
Height := 219;
caption := ' ';
BevelOuter := bvLowered;
BevelInner := bvRaised;
color := clTeal;

Entry := TEdit.create(self);
Entry.parent := self;
Entry.Name := 'Entry';
Entry.Left := 16;
Entry.Top := 16;
Entry.Width := 121;
Entry.Height := 21;
Entry.BiDiMode := bdLeftToRight;
Entry.Enabled := False;
Entry.MaxLength := 15;
Entry.ParentBiDiMode := False;
Entry.Text := '0';
Entry.show;

B1 := TSpeedButton.create(self);
B1.parent := self;
B1.Name := 'B1';
B1.Left := 16;
B1.Top := 80;
B1.Width := 25;
B1.Height := 25;
B1.Caption := '1';
B1.OnClick := NumberClick;
B1.show;

B2 := TSpeedButton.create(self);
B2.parent := self;
B2.Name := 'B2';
B2.Left := 48;
B2.Top := 80;
B2.Width := 25;
B2.Height := 25;
B2.Caption := '2';
B2.OnClick := NumberClick;
B2.show;

B3 := TSpeedButton.create(self);
B3.parent := self;
B3.Name := 'B3';
B3.Left := 80;
B3.Top := 80;
B3.Width := 25;
B3.Height := 25;
B3.Caption := '3';
B3.OnClick := NumberClick;
B3.show;

B4 := TSpeedButton.create(self);
B4.parent := self;
B4.Name := 'B4';
B4.Left := 16;
B4.Top := 112;
B4.Width := 25;
B4.Height := 25;
B4.Caption := '4';
B4.OnClick := NumberClick;
B4.show;

B5 := TSpeedButton.create(self);
B5.parent := self;
B5.Name := 'B5';
B5.Left := 48;
B5.Top := 112;
B5.Width := 25;
B5.Height := 25;
B5.Caption := '5';
B5.OnClick := NumberClick;
B5.show;

B6 := TSpeedButton.create(self);
B6.parent := self;
B6.Name := 'B6';
B6.Left := 80;
B6.Top := 112;
B6.Width := 25;
B6.Height := 25;
B6.Caption := '6';
B6.OnClick := NumberClick;
B6.show;

B7 := TSpeedButton.create(self);
B7.parent := self;
B7.Name := 'B7';
B7.Left := 16;
B7.Top := 144;
B7.Width := 25;
B7.Height := 25;
B7.Caption := '7';
B7.OnClick := NumberClick;
B7.show;

B8 := TSpeedButton.create(self);
B8.parent := self;
B8.Name := 'B8';
B8.Left := 48;
B8.Top := 144;
B8.Width := 25;
B8.Height := 25;
B8.Caption := '8';
B8.OnClick := NumberClick;
B8.show;

B9 := TSpeedButton.create(self);
B9.parent := self;
B9.Name := 'B9';
B9.Left := 80;
B9.Top := 144;
B9.Width := 25;
B9.Height := 25;
B9.Caption := '9';
B9.OnClick := NumberClick;
B9.show;

B0 := TSpeedButton.create(self);
B0.parent := self;
B0.Name := 'B0';
B0.Left := 16;
B0.Top := 176;
B0.Width := 25;
B0.Height := 25;
B0.Caption := '0';
B0.OnClick := NumberClick;
B0.show;

BDian := TSpeedButton.create(self);
BDian.parent := self;
BDian.Name := 'BJian';
BDian.Left := 48;
BDian.Top := 176;
BDian.Width := 25;
BDian.Height := 25;
BDian.Caption := '.';
BDian.OnClick := BdianClick;
BDian.show;

BJia := TSpeedButton.create(self);
BJia.parent := self;
BJia.Name := 'BJia';
BJia.Left := 112;
BJia.Top := 80;
BJia.Width := 25;
BJia.Height := 25;
BJia.Caption := '+';
BJia.OnClick := OperClick;
BJia.show;

BJian2 := TSpeedButton.create(self);
BJian2.parent := self;
BJian2.Name := 'BJian2';
BJian2.Left := 112;
BJian2.Top := 112;
BJian2.Width := 25;
BJian2.Height := 25;
BJian2.Caption := '--';
BJian2.OnClick := OperClick;
BJian2.show;

BCheng := TSpeedButton.create(self);
BCheng.parent := self;
BCheng.Name := 'BCheng';
BCheng.Left := 112;
BCheng.Top := 144;
BCheng.Width := 25;
BCheng.Height := 25;
BCheng.Caption := 'x';
BCheng.OnClick := OperClick;
BCheng.show;

BChu := TSpeedButton.create(self);
BChu.parent := self;
BChu.Name := 'BChu';
BChu.Left := 112;
BChu.Top := 176;
BChu.Width := 25;
BChu.Height := 25;
BChu.Caption := '/';
BChu.OnClick := OperClick;
BChu.show;

BDengHao := TSpeedButton.create(self);
BDengHao.parent := self;
BDengHao.Name := 'BDengHao';
BDengHao.Left := 80;
BDengHao.Top := 176;
BDengHao.Width := 25;
BDengHao.Height := 25;
BDengHao.Caption := '=';
BDengHao.OnClick := BDengHaoClick;
BDengHao.show;

BClean := TSpeedButton.create(self);
BClean.parent := self;
BClean.Name := 'BClean';
BClean.Left := 112;
BClean.Top := 48;
BClean.Width := 25;
BClean.Height := 25;
BClean.Caption := 'AC';
BClean.OnClick := BCleanClick;
BClean.show;

BtBack := TSpeedButton.create(self);
BtBack.parent := self;
BtBack.Name := 'BtBack';
BtBack.Left := 80;
BtBack.Top := 48;
BtBack.Width := 25;
BtBack.Height := 25;
BtBack.Caption := '<--';
BtBack.OnClick := BtBackClick;
BtBack.show;
//初始化各参数
EntryChongZhi:= true;
OperOK := true;
LastEntry := 0;
LastOperator := '+';
end;

procedure TCal.NumberClick(Sender: TObject);
begin
with Sender as TSpeedButton do
begin
if EntryChongZhi = true then
begin
Entry.text := '0';
EntryChongZhi := false;
OperOK := true;
Entry.text := Caption;
end
else
begin
OperOK := true;
Entry.text := Entry.text + Caption;
end;
end;
end;

procedure TCal.OperClick(Sender: TObject);
begin
NowEntry := StrToFloat(Entry.text);
with Sender as TSpeedButton do
begin
if OperOK = true then
begin
EntryChongZhi := true;
OperOK := false;
Entry.text := Calculate(LastOperator);
end;
LastOperator := caption[1];
end;
end;

procedure TCal.BCleanClick(Sender: TObject);
begin
EntryChongZhi := true;
OperOK := true;
Entry.text := '0';
LastEntry := 0;
LastOperator := '+';
end;

procedure TCal.BDengHaoClick(Sender: TObject);
begin
NowEntry := StrToFloat(Entry.text);
Entry.text := Calculate(LastOperator);
OperOK := true;
EntryChongZhi:= true;
LastEntry := 0;
LastOperator := '+';
end;

function TCal.Calculate(Oper: Char): string;
begin
case oper of
'+': Total := FloatToStr(LastEntry + NowEntry);
'-': Total := FloatToStr(LastEntry - NowEntry);
'x': Total := FloatToStr(LastEntry * NowEntry);
'/': try Total := FloatToStr(LastEntry / NowEntry)
except Application.Messagebox('除数不能为0', '错误', MB_OK);
end;
end;
LastEntry := StrToFloat(Total);
result := Total;
end;

procedure TCal.BdianClick(Sender: TObject);
var
i: integer;
PointOK: boolean;
begin
PointOK := true;
for i := 1 to length(Entry.text) do
if '.' = Entry.text then PointOK := false;
if PointOK = true then
begin
Entry.text := Entry.text + Bdian.Caption;
EntryChongZhi:= false;
end;
end;

procedure TCal.BtBackClick(Sender: TObject);
var
i: integer;
j: integer;
str: string;
StrResult: string;
begin
StrResult := '';
str := Entry.text;
j := length(Entry.text);
if Entry.text <> '0' then
begin
if j <> 1 then
begin
for i := 1 to (j - 1) do StrResult := StrResult + str;
Entry.text := StrResult;
end
else
begin
Entry.text := '0';
EntryChongZhi:= true;
end;
end;
end;

procedure TCal.MyKeyPress(var message: Tmessage);
begin
case message.WParam of
49: B1.OnClick(B1);
50: B2.OnClick(B2);
51: B3.OnClick(B3);
52: B4.OnClick(B4);
53: B5.OnClick(B5);
54: B6.OnClick(B6);
55: B7.OnClick(B7);
56: B8.OnClick(B8);
57: B9.OnClick(B9);
48: B0.OnClick(B0);
43: BJia.OnClick(BJia);
45: BJian2.OnClick(BJian2);
42: BCheng.OnClick(BCheng);
47: BChu.OnClick(BChu);
46: BDian.OnClick(BDian);
13: BDengHao.OnClick(BDengHao);
8 : BtBack.OnClick(BtBack);
end;
end;

procedure Register;
begin
RegisterComponents('dcyh', [TCal]);
end;

end.
 
1、最好响应消息WM_KEYDOWN,WM_KEYUP(重载函数DoKeyDown,DoKeyUP),而不是响应详细WM_CHAR,
因为WM_CHAR只对一部分字符有效。

2、就算你响应WM_KEYDOWN,WM_KEYUP消息,你也未必能收得到消息,具体原因请看下面的帖子:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1249868
 
接受答案了.
 
后退
顶部