[210524] Sender

Donghee Lee·2021년 5월 24일
0

Delphi

목록 보기
12/13

장비제어 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라는 매개변수를 넘겨주는 것일까?

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

profile
Better than Yesterday

0개의 댓글