질문전에 관련된 사항을 최대한 찾아보고 글을 올립니다만 여러번 나온 질문이라면 죄송합니다. 읽어보시고 조그마한 정보라도 부탁드려요. :)
*** 질문의 요지는 'while true do... '에서 탈출 조건을 줬는데 그 조건을
*** 받아 들이지 못한 다는 것입니다.
먼저 간략히 설명하면 아래 프로시져는 윈도우 보조프로그램속에 있는 계산기와 비슷한 계산기를 만들면서.. 계산기 버튼들에 대한 클릭 이벤트 핸들러입니다.(모든 버튼을 하나의 핸들러로 처리하게 했습니다.)
procedure TfrmCaculator.btnClick(Sender: TObject);
if Sender btn1 then .... //숫자 1 버튼을 눌렀을 때...
else if Sender btn2 then ....
else if Sender btnReset then .... // 계산기의 CE(clear)버튼 눌렀을 때..
else if Sender btnResult then .... // 계산기의 '='버튼입니다.
begin
.... (생략)
if SecondInput = 0 then begin // 나누려는 값이 0일 때
edtWindow.text := '0으로 나눌 수 없습니다!';
while true do begin
// 계산기의 Reset버튼을 누르면 while문을 벗어납니다. exit 사용
if Sender = btnReset then begin
reset; // 변수들을 0으로 만들어 줍니다.
exit;
end
end;
end
// 나누려는 수가 0이 아니라면 나누기 작업을 수행합니다.
else
Result := FirstInput / SecondInput;
... (하략)
어떤 수를 0으로 나누었을 때 '0으로 나눌 수 없습니다!'라는 메시지를 출력시키고 reset 버튼(계산기의 CE 버튼에 해당)을 누르면 reset이라는 사용자 지정함수가 계산에 사용되는 변수들을 0으로 만들고 procedure를 탈출하게 하려고 했습니다.
그.런.데!
reset 버튼(name = btnReset)을 눌러도 while을 벗어나지 않습니다.
그리고 CPU 점유율 100%가 됩니다.
[알고자 하는 것]
1.왜 while문에서 reset버튼 누르는 이벤트를 인식하지 못하는 거지요?
Sender = btnReset에서 문제가 있다면 어떻게 바꿔야하나요?
2.이와 더불어... while true do... 를 쓰면 cpu 점유율이 100%이되는데 이와 같은 현상을 막으면서도 동일한 기능을 하는(버튼의 입력을 기다린다) 방법이 있나요?
도움 부탁드립니다. :)
코드 답변은 다른분이 하셨고, 전 질문에 답변해 드리죠.
1.왜 while문에서 reset버튼 누르는 이벤트를 인식하지 못하는 거지요?
인식합니다.
OS 관점에서 보죠. 해당 함수로 CPU사용권이 넘어갔고, while 코드로 가서 맹렬하게 while 문을 탑니다. 메모리 상에서만 작동하는 것이고 딜레이 걸릴 코드가 없으므로 CPU를 100% 쓰게 됩니다.
이때 사용자가 마우스를 클릭했습니다. 그럼 시스템은 OS에게 이벤트를 알리고, OS는 해당 어플리케이션 메세지큐에 이벤트를 넣죠. 어플리케이션은 해당 폼(윈도우) 메세지큐에 이벤트를 넣죠.
버튼 클릭 이벤트를 사용하려면 메세지 큐에서 이벤트를 꺼내야 하는데, CPU가 너무 바뻐서 못 꺼냅니다. 그래서 Application.ProcessMessages 함수를 호출해서 CPU제어권을 코드에서 잠시 뺐어서 메세지 큐를 점검하는 쪽으로 사용하죠.
Sleep(0) 도 같은 효과를 냅니다. 이 함수는 파라미터로 넣은 시간동안 CPU를 다른 프로세스로 넘겨줍니다. 0을 넣으면 CPU제어권을 다시 자신 프로세스로 넘긴겁니다. 0 대신 3 정도 값을 넘기면 프로세스가 CPU를 전부쓰지 못하게 해서 CPU 점유율이 100%가 안됩니다.
다시 처음으로, 버튼 클릭을 인식하긴 합니다. 시스템 속도에 따라 영원만큼 길어지기도 하고, 비교적 짧은 기간안에 인식하기도 합니다.
2.이와 더불어... while true do... 를 쓰면 cpu 점유율이 100%이되는데 이와 같은 현상을 막으면서도 동일한 기능을 하는(버튼의 입력을 기다린다) 방법이 있나요?
이미 위에 답변했군요. Application.ProcessMessage; 다음에 딜레이 함수를 넣거나, Sleep 함수를 쓰면서 파라미터 값에 3 에서 10 정도의 값을 넣어서 쓰면 됩니다.
제 경우에는 좋은 시스템 또는 WinNT 플랫폼 에서는 3 정도, Win95 플랫폼에선 4,5 정도 줍니다.
즐푸하세여..
타락천사..
사족: 검색해 봤는데 못 찿으셨다고요? ^^
저도 그렇지만 시스템적인 사항은 잘 안쓰게 되더군요.
팁과 질답에 관련사항이 있습니다만, 검색해도 안나오면 질문하세요..^^