안녕하세요~
저는 폼 1에서 검색어를 입력하고 버튼을 눌러 폼 2에 결과값이 dbgrid에 나오게 하고 있습니다.
그런데 이상한 점이.. 폼 2의 dbgrid에서 keypress event에서 엔터키 누르는 현상과 더블클릭 event를 같은 역할을 하게 했는데요.
유독 keypress 이벤트에서만 몇 번 검색하다보면 access violation 에러가 납니다. DblClick이벤트에서는
10번 넘게 해도 에러가 안 나구요..
밑에 소스 올릴께요.
procedure TForm1.sbt_selClick(Sender: TObject); // 폼 1의 소스
begin
try
begin
Form2 := TForm2.Create(nil);
Form2.Show;
end;
except
showmessage('폼 생성 에러입니다');
exit;
end;
end;
----------------------------------------------------------------------
<<폼 2 에서의 소스>>
procedure TForm2.DBGrid2DblClick(Sender: TObject);
begin
Form1.ed_name.Text := Query2.FieldByName('name').AsString;
Form1.ed_phone_num.Text := Query2.FieldByName('phone_num').AsString;
Form1.ed_tel.Text := Query2.FieldByName('tel').AsString;
Form1.ed_email.Text := Query2.FieldByName('email').AsString;
Form1.ed_hp.Text := Query2.FieldByName('hp').AsString;
Form1.ed_fax.Text := Query2.FieldByName('fax').AsString;
Form1.Query1.Locate('seq',Query2.FieldByName('seq').AsInteger,[loPartialKey]);
Close();
Form2.Free;
Form2 := Nil;
end;
procedure TForm2.DBGrid2KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then -> 이 부분을 제외하곤 같습니다.
begin
Form1.ed_name.Text := Query2.FieldByName('name').AsString;
Form1.ed_phone_num.Text := Query2.FieldByName('phone_num').AsString;
Form1.ed_tel.Text := Query2.FieldByName('tel').AsString;
Form1.ed_email.Text := Query2.FieldByName('email').AsString;
Form1.ed_hp.Text := Query2.FieldByName('hp').AsString;
Form1.ed_fax.Text := Query2.FieldByName('fax').AsString;
Form1.Query1.Locate('seq',Query2.FieldByName('seq').AsInteger,[loPartialKey]);
Close();
Form2.Free;
Form2 := Nil;
end;
end;
도대체 어디가 잘못된걸까요??
일단 {폼1에 넘기도 자기자신인 폼2응 닫는 부분}은 한곳에 함수로 만드시는게 좋을 거 같구요.
방법1로는 2번 이상 실행하지 않도록 전역변수를 선언해 실행중이면 안하도록 keypress에 넣는 방안
<!--CodeS-->
....
var
FirstkeypressOK : Boolean = False;
.....
procedure TForm2.DBGrid2KeyPress(Sender: TObject; var Key: Char);
begin
if (FirstkeypressOK = False) and(Key = #13) then
begin
FirstkeypressOK := True;
CallForm2;{폼1에 넘기도 자기자신인 폼2 닫는 부분}
//FirstkeypressOK := False;
end;
Key := #0; //버튼의 무용화
end;
<!--CodeE-->
아무래도 KeyPress는 좀 그렇습니다,
그래서 방법2로는 KeyUp에서 사용하는게 좋을거 같구요.
방법3은 타이머가 시간 조절에는 제일입니다, 다른 컴포나 스래드 뭐 이유없는 에러는 카이머가 알아서 해줍니다.
<!--CodeS-->
procedure TForm2.DBGrid2KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = #13) then
begin
Timer1.Enabled := False;
Timer1.Enabled := True;
end;
Key := #0; //버튼의 무용화
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
CallForm2;{폼1에 넘기도 자기자신인 폼2 닫는 부분}
end;
<!--CodeE-->
방안4는 폼 1에서 웬만하면 다하는겁니다, 폼 2는 설정 값만 던져주고 닫구요.
방안5는 DBGrid2KeyPress에서 DBGrid2.OnKeyPress := nil;로 막는 방법도...
....
더 생각해보면 더 좋은 방안도 있습니다만....