장성호님 감사요... ^^
그냥 TButton을 쓰는 경우는 까끔 있습니다. 다른 놈으로 사용하지요...
안될 경우가 상당히 있군요... 프로그램 하면서... ->Click 하는 경우는 늘 몇개씩 있지만 그렇게
많지 않습니다. 그래서 요즘은 Click 에서 사용되는 놈을 함수 하나 만들어 그냥 사용하고 있습니다.
읽어보니.... 이렇게 계속 하는 것이 좋을 것 같다는 생각도 들군요.... 5까지 이상, 여러가지 원인이 있을 수 있으니...
여하튼 프로그램 바쁘면 그런 현상이 있는 것을 요근래 발견했다는 것....
빌더를 7년 사용했을 것인데... 몰랐다는 것.... 그리고 한번씩 일어나니... 개발시 발견이 잘 안된다는 것
그러므로 좀 복잡하고 Thread 많이 들고... 약간 이상한 것 보이면... 무조건 이렇게 할 생각입니다.
다시 한번 답변 감사드립니다.
장성호 님이 쓰신 글 :
: Button1->Click();
: 은 마우스로 누르는것과 같지 않습니다.
:
: 그냥 TControl클래스에 있는 Click이라는 함수 호출입니다.
: Click함수안에서 TNotifyEvent 변수인 FOnClick에 메소드가 할당되어있으면 호출해주죠
:
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
: ShowMessage("Button1Click");
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::Button2Click(TObject *Sender)
: {
: Button1->Click();
: }
: //---------------------------------------------------------------------------
:
:
: 위 코드에서 Button2Click이 호출되면
: 어떤과정을 통해 Button1Click이 호출되는지 확인해 봤습니다.
:
: 먼저 Click이라는 함수는 TControl에 dynamic으로 선언된 함수입니다.
: dynamic이란 virtual이란 비슷한놈이로 child-class에서 override해서 쓸수 있는 함수입니다.
:
: 1) 먼저 다음과 같이 Button1->Click(); 함수가 호출되면
: VMT(Virtual-Method-Table)에서 상속받은 하위 클래스에서 Click함수를 override한놈이 있는지 찾아서
: 호출해줍니다.
:
: TButton의 경우 Click을 override해서 사용합니다.
: // procedure TControl.Click; dynamic;
:
: 2) 그래서 TButton의 Click함수가 호출됩니다.
:
: procedure TButton.Click;
: var
: Form: TCustomForm;
: begin
: Form := GetParentForm(Self);
: if Form <> nil then Form.ModalResult := ModalResult;
: inherited Click; //여기서 TControl의 Click함수가 호출되구요
: end;
:
:
: 3) 세번째로 TControl.Click에서 실제 연결된 이벤트가 호출됩니다.
:
: procedure TControl.Click;
: begin
: { Call OnClick if assigned and not equal to associated action's OnExecute.
: If associated action's OnExecute assigned then call it, otherwise, call
: OnClick. }
: if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
: FOnClick(Self)
: else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
: ActionLink.Execute(Self)
: else if Assigned(FOnClick) then
: FOnClick(Self); //대부분 이경우에서 호출되죠
: end;
:
:
: 위코드에서 보는 바와같이 메세지로 동작되는 부분이 전혀 없습니다.
: 모두 그냥 함수 호출이죠
: 그래서 개인적으로 박영목님께서 격으신 그런 경우는 없다고 봅니다.
:
: -----------------------------------------------------------------------------------------
:
: 그럼에도 불구하고 Button1->Click() 호출했을때
: Button1의 OnClick이벤트 핸들러에 연결된 이벤트함수가 호출이 되지 않는경우가 있다면...?
:
: 1. Design-time에 OnClick이벤트에 연결된 이벤트 핸들러가 잘못연결된 경우가 있지 않나 하는 생각이 듭니다.
: 코딩은 100%문제가 없지만
: design-time에 Button의 property설정한것이 개발자도 모르게 실수로 바꾸러 버려니는 경우가 왕왕있거둔요
:
: 아울러 design-time에 설정한것은 xxx.dfm 파일에 모두 기록되고
: 이 dfm파일을 컴파일하면 exe또는 dll에 리소스로 모두 포함됩니다.
:
: 만약 이 리소스에 문제가 있으면 OnClick이벤트 프로퍼티가 run-time에 제대로 연결이 되지 않을수도 있습니다.
: (언어팩을 쓴다던가...)
:
: 2. 음.. 또 사용하신 컴포넌트가 기본 Button의 OnClick이벤트가 아닌 경우가에 그럴 가능성이 있지 않을까 하는
: 생각이 듭니다.
: TControl의 멤버에 TNotifyEvent 형 FOnClick이라는 변수가 있는데..
: 서드파트 컴포넌트의 Click이벤트에서는 저 변수를 이용하지 안는다면.. 그런 문제가 발생할수도 있을거 같습니다.
:
: 3. 세번째로 Click메소드를 override한 Child-class에서 TControl의 Click을 다시 호출해주지 않는다면..
: 그런 문제가 발생할수도 있을것 같습니다.
:
:
: 4. 이건 거의 일어나 가능성이 희박하지만..
: 다른곳에서 AccessViolation이 발생했는데..
: 그것이 하필이면 Button의 Virtual-Method-Table을 건드려서.. VMT의 내용을 이상하게 바꿔버렸다면..
: 그럴 경우가 발생할수도 있을것 같습니다.
:
:
: 5. 기타 제가 잘 모르는 다른 경우가 분명히 더 있을것입니다..
:
:
: 개인적으로 1번이 가장 유력하지 않나 하는 생각이 듭니다만..
: Button-Click의 경우 말고도 ..
: 프로퍼티가 자신도 모르게 바뀌어 문제의 원인을 찾는데.. 시간을 소비하는 경우가
: 저도 많이 격었구.. 또 많은 개발자들이 그러더군요...
:
: 그런 문제를 피하기 위해서는
: 중요한 프로퍼티인 경우에 반드시 코딩으로 프러퍼티를 설정해서 확인사살 해주곤 합니다.
: 다음과 같이 폼의 생성자나 OnCreate이벤트 등에서..
:
: void __fastcall TForm1::FormCreate(TObject *Sender)
: {
: Button1->OnClick = Button1Click
: }
:
:
: 위와같이 하면 실수로 프로퍼티 변경되서 발생하는 문제도 필할수 있고..
: 또한 코딩만 읽어도 동작을 알수가 있죠..
:
: 프로퍼티에만 설정해두면.. 나중에 시간이 지나서 코드를 읽을때 .. 어떻게 동작되는지 이해가 안가는 경우가
: 왕왕있더군요...
:
: 지금시간 새벽3시반
: 정신이 맑지가 않네요.. 헹설수설했더라도 용서해 주세요
:
: 그럼...
:
:
: 박영목.월천 님이 쓰신 글 :
: : Button1->Click(); 이런 형태... 요 근래... 제 프로그램에서 혹 어떤 경우에 누르지 못하는 경우를 발견했습니다.
: :
: : 저도 몇년을 사용했는 데... 요 근래 알았다는 것... 프로그램이 부하가 좀 되는 넘이라 그런 지... 이것을 뛰어 넘더군요... 그래서 생각했 보았습니다. 저것도 사람이 마우스로 누르는 것과 같으니... 바쁘면 윈도우가 띄어 넘을 수 있지 않을까? 인터페이스 쪽이라 그런가?
: :
: : 그래서... Click(); 안에 있는 놈을 그냥 함수로 하나 만들고... 이것을 Click과 다른 곳에서 호출할 때 사용하도록 바꾸었습니다.... ^^ 혹 나만 그런가? 혹 경험하신 분들 답변 부탁드립니다 ^^
: :
: :
: : 그대의의미 님이 쓰신 글 :
: : : 나그네 님이 쓰신 글 :
: : : : 한 화면에 여러개의 컴포넌트가 배치 되어 있습니다.
: : : : 버튼도 여러개 있고요...
: : : :
: : : : 그런데 Enter 키를 누르면 포커스가 어디에 있던지 무조건 한개의 버튼의 클릭이벤트를 실행하고 싶습니다.
: : : :
: : : : 한개의 화면상에서 Enter 는 무조건 한개의 버튼 클릭이벤트를 연결시키는 방법을 알고 싶습니다.
: : :
: : : void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
: : : TShiftState Shift)
: : : {
: : : if(Shift.Empty() == true && Key == VK_RETURN)
: : : Button1->Click();
: : : }
: : :
: : : 이렇게하고 프로퍼티에 KwyPreview = true
: : : 로 만들어주면 해당버튼만 눌러지는것과같습니다