Q&A

  • onKeyPress, onKeyUp, onKeyDown 차이점이 궁금?
키와 관련된 이벤트 중에
onKeyPress, onKeyUp, onKeyDown 다음 것들의 차이점이
궁금합니다.
2  COMMENTS
  • Profile
    소울해커 2002.11.07 01:53

    저도 잘은 모르지만...
    일단 OnKeyPress 에서는 키를 눌러져있을때의 이벤트를 정의하고
    OnKeyUp 에서는 키가 눌러졌다가 떨어졌을 때의 이벤트를 정의하고
    OnKeyDown  에서는 키가 눌러졌을 때의 이벤트를 정의합니다.
    모든 이벤트를 다 줄 경우 키를 눌렀을때의 이벤트 발생 순서는

    1. OnKeyPress
    2. OnKeyDown
    3. OnKeyUp

    의 순서로 발생합니다.

    OnKeyPress 이벤트가 먼저 발생하고 OnKeyDown 이벤트가 발생합니다.
    그리고 마지막으로 OnKeyUp 이벤트가 발생됩니다.
    이게 일반적으로 생각되는 발생 순서입니다.

    차이점은 에디트박스의 OnKeyPress 에서

    Key := #32;

    로 코드를 작성 하고 나서
    A키를 눌러보면 공백이 한칸 추가된것을 보실 수 있습니다.
    키가 눌러지자 마자 키값을 스페이스바의 키값으로 바꿔버렸기 때문입니다.
    OnKeyPress 이벤트에선 입력된 키값을 삭제하고 다른 값으로 대체시켜버립니다.
    따라서 OnKeyDown 이벤트는 무시되어버립니다.
    그러나 OnKeyDown 이벤트의 결과가 키값과 관련이 없다면 무시되지 않습니다.

    에디트 박스에서 OnKeyDown 에서

    Key := VK_LEFT;

    로 코드를 작성 하고 나서
    A키를 눌러보면 먼저 왼쪽으로 한칸 이동후 A가 입력됩니다.
    키가 눌러지면 OnKeyDown 이벤트가 발생하고
    해당 키가 입력이됩니다.
    입력되는 키에 딜레이를 준다고 할까요...

    여기까지 보자면 키보드에서 어떤 값을 입력받으면 OnKeyPress 이벤트를 지나
    OnKeyDown이 일어난 직후 해당 값이 들어가는 걸 알 수 있습니다.

    OnKeyUp의 경우는 까다롭군요.
    뭐랄까...
    일단은 키보드를 눌렀다가 떼었을때 해당 키 코드를 받아서
    그에 따른 행동을 정의한다고 생각됩니다만...
    어떻게 설명하기가 난해하군요.
    거의 KeyUp을 쓰질 않으니...

    대충 생각해보면 이벤트의 결과가 키값과 관련이 있다면
    KeyPress가 최우선이고 나머지 이벤트는 무시.
    그외에 이벤트의 결과값이 키값과의 연관이 없으면
    위의 순서 및 결과가 조금 달라지는 듯합니다.
    아래 코드를 보면 조금 감이 올지도...;;

    procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
    Edit1.Text := Edit1.Text + 'D';
    end;

    procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
    begin
    Key := #0;
    end;

    procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
    Edit1.Text := Edit1.Text + 'U';
    end;

    이와 같은 경우 먼저 KeyPress에 의해 입력된 키값은 사라집니다.
    그 다음 KeyDown에 의해 텍스트에 'D'가 추가되고
    마지막으로 KeyUp에 의해 텍스트에 'U'가 추가됩니다.

    눈여겨 볼만한건 이 상태에서 마우스로 그냥 눌러도 'U'가 추가된다는 점입니다.
    단순하게 생각하자니 MouseDown 이벤트와 KeyUp 이벤트는
    두사부일체라는 결론에 도달합니다.
    그러나 그건 헛소리인것 같고...
    얼핏보자면 현재 텍스트에 깜빡이는 커서의 이동과 연관이 있으리라 생각되고...
    음... 써놓고보니 역시나 모르겠군요.
    그냥 KeyUp은 않 쓰시면 않 되실런지요?


    OnKeyPress 이벤트에서는 키보드의 키를 읽어들일때
    ASCII값을 읽어 들입니다.
    따라서 키의 값을 줄때도 ASCII값으로 줘야 합니다.
    다만 ASCII값을 지원하지 않는 키(화살표키와 같은...)는
    이 이벤트에 해당 사항이 없습니다.

    OnKeyDown와 OnKeyUp에서는 키의 값을 윈도우 API 가상 KeyCode로 읽어들입니다.
    따라서 키의 값을 줄때도 윈도우 API 가상 KeyCode로 줘야 합니다.
    그렇기에 키보드에 있는 ASCII 값이 적용되지 않는 키도 이 이벤트의 사정거리 안에 있습니다.


    이게 맞는 건지는 저도 확실히 모르겠습니다.
    그냥 지금까지 쓰면서 몸으로 느낀(?)겁니다.
    더 잘 아시는 분이라면 좀더 알기 쉽게 상세한 예를 들어서 설명해 주시겠지만
    저로선 이 정도가 한계군요.
    쓰다보니 장황하면서 난잡하면서도 뭘 말하려는지 의도조차 보이지 않는 글이 되버렸군요.
    결국 헛소리만 늘어놓은 결과가...
  • Profile
    물고기나라 2002.11.07 00:01

    예전에 이것들의 발생순서가 궁금해서 해보긴 했는데 잊어버렸네요

    하지만 간단하게 에디트 컴포넌트를 폼에 갖다놓고 각각에 다음처럼 코딩하고
    showmessage('onKeyPress')
    showmessage('onKeyUp')
    showmessage('onKeyDown')
    실행해 보았습니다.

    KeyPress는 키를 누르면 발생하고
    눌러졌으면 KeyDown이더군요.

    키에서 손을 뗐을때 KeyUp이라고 생각했지만 이게 문제더군요 ^^;;
    발생이 좀 애매해요.
    포커스가 있는경우라도 위 두 이벤트와 같이 코딩한경우는 발생이 안되는건 아닌데 앞 두이벤트 때문인지 대개가 묻혀버리더군요.
    KeyUp만 해놓은 경우는 확실히 키에서 뗏을때 발생하고요.
    그리고 포커스가 있을땐 마우스 버튼 어느거라도 누를때마다 발생하더군요
    또 한가지는 Tab으로 그곳으로 이동해도 발생하더군요

    실제 프로그램개발하면서 KeyUp에 코딩하는 건 거의 못본거 같네요.
    더 자세히 아시분계시면 주저마시고 리플 달아주세요. 저도 궁금 ^^;;
    여튼 도움이 됐음 좋겠네요