버튼을 클릭하면 어떤 작업이 끝날때까지 다시 그 버튼을 클릭 못하게 하고 싶은데..
아래처럼 버튼 클릭과 동이세 버튼을 Disable시켜도 안되네요..
왜그러죠? 델파이는 원래 그런가요? VB는 안그런거 같은데..
예를 들어 SomeDo라는 함수가 DB에 연결하는 함수라면..
버튼위에서 마우스를 다다다다~ 눌러버리면..
버튼 이벤트가 계속 먹어서 계속 DB에 연결을 시도합니다.
도와주세요~~ㅋㅋ
procedure TForm1.Button1Click(Sender: TObject);
begin
screen.Cursor := crHourGlass;
Button1.Enabled := false;
sleep(3000); ->요건 테스트를 위해서 집어넣은겁니다.
//SomeDo()...........
Button1.Enabled := true;
screen.Cursor := crdefault;
end;
가령, 아래 코드에서 SomeDo() 라는 procedure/function이 동기성을 가지지 못하는 경우, 즉 TForm1.Button1Click 이라는 procedure 안에서 호출하는 것으로 끝나는 것이 아니라 추가적인 작업을 하여서 나중에야 결과가 나타나는 경우-보통 Asyncronous call이라고들 합니다. 말씀하신 DB 연결 등도 마찬가지겠지요...- 해당 작업이 언제 끝나는 지, 지금 진행하고 있는 지 등의 정보가 필요하겠지요...
제가 생각하기에 가장 간단하고 델파이적인 방식은 TActionManager (Delphi 6), TActionList (Delphi 5)인 듯합니다.
TActionManager/TActionList에 TAction을 추가시키시고요... Object Inspector를 보시면 OnExecute, OnHint, OnUpdate 라는 Event-handler가 보입니다. 각각은,
OnExecute : Action 실행 코드
OnHint : Hint를 보일때 Hint 내용(string), 보일지 여부 결정.
OnUpdate : 해당 Action의 UI, 혹은 동작여부 결정.
등의 일을 합니다.
가령 DB 연결하기 같은 경우는 DB가 연결되어 있는 경우에는 Disabled 되면 되겠지요. 따라서 DB 연결되었음을 나타내는 변수가 있다면, 아래와 같이...
TForm1 = class(TForm)
Database1: TDatabase;
Button1: TButton;
ActionManager1: TActionManager;
acDBConnect: TAction; // Button1.Action := acDBConnect로 설정
private
FDBConnected :Boolean;
protected
procedure Invoke_DBConnection_Thread();
......
end;
TDBConThread = class(TThead)
protected
procedure Execute;override;
end;
procedure TDBConThread.Execeute;
begin
try
try
Form1.DataBase1.Connected := TRUE;
except
Form1.DataBase1.Connected := FALSE;
end;
finally
Form1.FDBConnected := Form1.DataBase1.Connected ;
end;
end;
procedure TForm1.acDBConnectExecute(Sender: TObject);
begin
if FDBConnected then exit; // 혹시라도 모르니깐...
Invoke_DBConnection_Thread();
end;
procedure TForm1.Invoke_DBConnection_Thread();
begin
// thread reference는 저장할 필요 없고 해제도 thread 자신이 함.
with TDBConThread.Create(TRUE) do begin
// 다른 설정들...
FreeOnTerminate := TRUE;
Resume();
end;
end;
procedure TForm1.acDBConnectHint(var HintStr: String;
var CanShow: Boolean);
begin
// 힌트관련...
end;
procedure TForm1.acDBConnectUpdate(Sender: TObject);
begin
acDBConnect.Enabled := not FDBConnected;
end;
음.. 역시 이런건 간단히 설명이 안되는 군요..
암튼 오늘도 즐입다...