장비제어 Main 화면에서 Motor 혹은 그 밖에 PLC와 통신을 하는 Component의 Bit와 Address를 확인하려면 Device가 정리되어 있는 자료나 직접 소스코드를 열어서 확인해야 했다.
그래서 번거로움을 덜기 위해 마우스를 올리면 Hint 기능을 써서 Bit, Address가 뜨도록 구현했다. 이 때 각 Component에 맞는 정보가 뜨게하기 위해선 코드 자체에서 선택한 Component를 인식하게 해야했다. 그러던 중 Sender의 기능을 찾아보게 되었다.
procedure TForm1.Button1Click(Sender: TObject);
begin
…
end;
위의 Button1Click 메소드는 Sender라는 TObject 포인터를 매개변수로 받는다. 델파이에서 모든 이벤트핸들러는 최소한 한 개의 Sender 매개변수를 가진다. 버튼이 클릭될 때 OnClick에 대한 이벤트핸들러가 호출되는데 Sender라는 매개변수는 해당 이벤트핸들러를 호출하는데 사용된 버튼(여기서는 당연히 버튼)을 참조한다. Button1을 클릭하면 Button1Click이 호출되며 Button1이라는 객체의 포인터가 Sender라는 매개변수를 통해 전달받게 된다.
Sender 매개변수의 역할은 해당 이벤트를 실행한 주체가 어떤 컴포넌트인지 알려준다. 이를 통해 서로 다른 두 컴포넌트가 동일한 이벤트 핸들러를 사용하는 것이 가능해진다. 예를 들어 button1과 button2이 동일한 기능을 수행하도록 할 때 이벤트 핸들러를 각각 작성하지 않고 한 개만 작성하여 두 컴포넌트가 이를 공유하도록 하면 된다.
procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender = Button1 then
ShowMessage(‘Button1 clicked!’)
else if Sender = MenuItem1 then
ShowMessage(‘Button2 clicked!’)
else
ShowMessage(‘??? clicked’);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Button1Click(Button2);
end;
procedure TForm1.Button2Click(Sender: TObject);의 결과는?
결과 : ‘??? clicked’
출처 : 링크텍스트
210525 追加
실제 lib에 적용한 코드
procedure MouseMoveEvent(var Sender, OldSender: TObject);
var
ii : integer;
bitarr : array[0..7] of string;
comarr : array[0..4] of string;
lockarr : array[0..4] of string;
addarr : array[0..4] of string;
A : array[0..7] of string; // used for bit
B : array[0..7] of string; // used for command
C : array[0..7] of string; // used for Intlockbit
D : array[0..7] of string; // used for Address
bitStr, comStr, lockStr, addStr, gattaiStr : String;
begin
if OldSender <> Sender then begin
if Sender.ClassType = TDspItem then begin
bitarr[0] := TDspItem(Sender).Bit1;
//~.Bit8
comarr[0] := TDspItem(Sender).Command1;
//~.Command3
lockarr[0] := TDspItem(Sender).IntlockBit1;
//.~IntlockBit5
for ii:= 0 to 7 do begin
if bitarr[ii] <> '-1' then begin
A[ii] := bitarr[ii];
//if A[ii] = '' then exit;
bitStr := bitStr + format(' bit%d:',[ii+1]) + A[ii] + ' ';
end;
end;
for ii := 0 to 2 do begin
if comarr[ii] <> '-1' then begin
B[ii] := comarr[ii];
comStr := comStr + format(' command%d:', [ii+1]) + B[ii] + ' ';
end;
end;
for ii := 0 to 4 do begin
if lockarr[ii] <> '-1' then begin
C[ii] := lockarr[ii];
lockStr := lockStr + format(' Intlockbit%d:', [ii+1]) + C[ii] + ' ';
end;
end;
gattaiStr := bitStr + #13#10 + comStr + #13#10 + lockStr;
TDspItem(Sender).Hint := gattaiStr;
//TDspItem(Sender).Hint := format('%s %s, %s %s, %s ', [bitStr, gattaiStr, comStr, gattaiStr, lockStr]);
TDspItem(Sender).ShowHint := True;
if TDspItem(Sender).TabStop then
TDspItem(Sender).MouseON;
end
여기서 Hint 시간이 너무 짧게 떠서 모든 Form에서 적용되게끔 자체 Lib 안에 HintHidePause를 넣었다
Forms.Application.HintHidePause := 7000; //uses : Forms, Controls 추가
처음에 어떻게 해도 안되길래 모든 Form에 넣어야 되는 줄 알았지만 다행...
참고 : embarcadero/Libraries