폼이 죽는다는 것은 쓰레드나 타이머가 폼이 갱신되는 속도보다 더 빠르게 동작되서 그럴껍니다.
보통, 그럴경우 이벤트 부분에 처리량을 줄이거나, Interval을 늘립니다.
아래 소스를 약간 변경하여 타이머를 10ms로 해서 테스트해보십시요.
화면이 죽는 현상은 발생되지 않을껍니다.
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
/*
외부에서 FRowIndex를 0으로 하면 다시 갱신하는 구조입니다. ^^;;
전체를 다 갱신하면 FRowIndex가 RowCount보다 많기 때문에 갱신작업을 하지 않을껍니다.
*/
if(FRowIndex > StringGrid1->RowCount)
{
Caption = "갱신 완료!";
return;
}
int r;
for(r = 0; r < 100; r++)
{
for(int c = 0; c < StringGrid1->ColCount; c++)
{
StringGrid1->Cells[c][FRowIndex + r] = IntToStr(c);
}
}
Caption = "갱신 중!";
FRowIndex += r;
}
//---------------------------------------------------------------------------
김태우 님이 쓰신 글 :
: 언제나 친절하게 답변해 주셔서 감사합니다.
: 마지막으로 한가지 더 여쭙겠습니다..
: 타이머나 쓰레드로 할때는 그럼 폼이 죽는 현상을 어떻게 해결 해야되는건가요..?
:
: 이길남.HoPe 님이 쓰신 글 :
: : 머 프로그램마다 차이가 있죠. ^^;;
: :
: : 전 Application->ProcessMessages()를 잘 사용안해서요.
: :
: : Application->ProcessMessages()를 델파이 소스로 보면 아래와 같이 메세지 큐에 있는것을 처리하므로,
: :
: : 동일 시간을 보장받지 못해서 걍, 타이머나 쓰레드로 합니다. ^^;
: :
: :
: : function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
: : var
: : Handled: Boolean;
: : begin
: : Result := False;
: : if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
: : begin
: : Result := True;
: : if Msg.Message <> WM_QUIT then
: : begin
: : Handled := False;
: : if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
: : if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
: : not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
: : begin
: : TranslateMessage(Msg);
: : DispatchMessage(Msg);
: : end;
: : end
: : else
: : FTerminate := True;
: : end;
: : end;
: :
: : procedure TApplication.ProcessMessages;
: : var
: : Msg: TMsg;
: : begin
: : while ProcessMessage(Msg) do {loop};
: : end;
: :
: :
: : 김태우 님이 쓰신 글 :
: : : 타이머 방식이나..
: : : 루프문 안에 코드상으로는 아닐지 몰라도..
: : : Application->ProcessMessages();
: : : 를 넣는게 폼도 안멈추고. 괜찮은듯한데요...ㅜㅜ
: : : 아닌가욤..그냥 보여지는게..
: : : 값이 채워지는게 늦긴해도.. 폼이 죽지않고 계속 순차적으로 값이 들어가는게 보이거든요..
: : :
: : :
: : : 이길남.HoPe 님이 쓰신 글 :
: : : : 맨아래 타이머를 이용한 방법은 어떠신지요?
: : : :
: : : : 물론 다른 방법보다는 속도가 느립니다.
: : : :
: : : : 하지만, 먹통되는 현상은 일어나지 않겠지요.
: : : :
: : : : 또한, 보통 4000줄을 한 화면에 보이지 않을겁니다.
: : : :
: : : : 타이머로 한 화면에 보이는 양만큼만 조금씩 표시를 해주고,
: : : :
: : : : 메세지나 라벨로 "데이터 갱신중입니다..."라고 표시해줘도 충분히 고객분은 이해 하실듯 한데요...
: : : :
: : : : 참고로 저는 보통 우선 화면에 보이는 영역만 빠르게 갱신해주고,
: : : :
: : : : 다른 부분은 타이머로 사용해서 갱신해 줍니다.
: : : :
: : : : 사용자가 보이지 않는 영역이니깐요. ^^;;
: : : :
: : : : 물론 갱신중에 스크롤을 돌리면......... ㅠㅠ
: : : :
: : : : 말빨로.....돌리시면 안대지 말입니다.....ㅋㅋㅋ
: : : :
: : : : 김태우 님이 쓰신 글 :
: : : : : 답변 감사합니다..
: : : : : 하지만.. 지금 님같은 경우는 숫자로만 하셨지만...
: : : : : 제가 읽어 들일 파일들은 문자도 있고 숫자도 있고 빈칸도 있는 경우 입니다..
: : : : : 마찬가지로..말씀해주신결로 적용을 해보았으나..
: : : : : 마찬가지로 시간이 오래 걸리네요..30초 이상으로요..ㅜㅜ
: : : : :
: : : : :
: : : : :
: : : : :
: : : : : 이길남.HoPe 님이 쓰신 글 :
: : : : : : 제가 아래와 같이 테스트 해봤습니다.
: : : : : : 참조 하세요.
: : : : : :
: : : : : : Row, Col 수량을 4000씩 잡았습니다.
: : : : : : 하기와 같이 하면 약 6~7초 정도 걸렸습니다.
: : : : : :
: : : : : : int row = StringGrid1->RowCount - 1;
: : : : : : int col = StringGrid1->ColCount - 1;
: : : : : :
: : : : : : unsigned long tt = GetTickCount();
: : : : : :
: : : : : : for(int j = 1; j < row + 1; j++) StringGrid1->Rows[j]->BeginUpdate();
: : : : : : for(int i = 1; i < col + 1; i++) StringGrid1->Cols[i]->BeginUpdate();
: : : : : :
: : : : : : for(int j = 1; j < row + 1; j++)
: : : : : : {
: : : : : : for(int i = 1; i < col + 1; i++)
: : : : : : {
: : : : : : StringGrid1->Cells[i][j] = IntToStr(i);
: : : : : : }
: : : : : : }
: : : : : : for(int j = 1; j < row + 1; j++) StringGrid1->Rows[j]->EndUpdate();
: : : : : : for(int i = 1; i < col + 1; i++) StringGrid1->Cols[i]->EndUpdate();
: : : : : :
: : : : : : Caption = GetTickCount() - tt;
: : : : : :
: : : : : :
: : : : : : 하기와 같이 하면 약17초 정도 걸리거더군요.
: : : : : :
: : : : : : int row = StringGrid1->RowCount - 1;
: : : : : : int col = StringGrid1->ColCount - 1;
: : : : : :
: : : : : : unsigned long tt = GetTickCount();
: : : : : :
: : : : : : for(int j = 1; j < row + 1; j++)
: : : : : : {
: : : : : : for(int i = 1; i < col + 1; i++)
: : : : : : {
: : : : : : StringGrid1->Cells[i][j] = IntToStr(i);
: : : : : : }
: : : : : : }
: : : : : :
: : : : : : Caption = GetTickCount() - tt;
: : : : : :
: : : : : :
: : : : : : 이것도 느리면 타이머를 사용해서 조금씩 변경하는 방법이 있습니다.
: : : : : :
: : : : : : void __fastcall TForm1::Timer1Timer(TObject *Sender)
: : : : : : {
: : : : : : /*
: : : : : : 외부에서 FRowIndex를 0으로 하면 다시 갱신하는 구조입니다. ^^;;
: : : : : : 전체를 다 갱신하면 FRowIndex가 RowCount보다 많기 때문에 갱신작업을 하지 않을껍니다.
: : : : : : */
: : : : : : if(FRowIndex > StringGrid1->RowCount)
: : : : : : {
: : : : : : Caption = "갱신 완료!";
: : : : : : return;
: : : : : : }
: : : : : :
: : : : : : for(int c = 0; c < StringGrid1->ColCount; c++)
: : : : : : {
: : : : : : StringGrid1->Cells[c][FRowIndex] = IntToStr(c);
: : : : : : }
: : : : : :
: : : : : : Caption = "갱신 중!";
: : : : : : FRowIndex++;
: : : : : : }
: : : : : : //---------------------------------------------------------------------------
: : : : : :
: : : : : :
: : : : : : Ps. 답변이 되실련지 모르겠네요.
: : : : : :
: : : : : : 김태우 님이 쓰신 글 :
: : : : : : : for(int j = 1; j < row+1; j++)
: : : : : : : {
: : : : : : :
: : : : : : : for(int i = 1; i < col+1; i++)
: : : : : : : {
: : : : : : :
: : : : : : : StringGrid1->Cells[i][j] = XLSheet.OlePropertyGet("Cells", j , i).OlePropertyGet("Value");
: : : : : : : StringGrid1->Cells[0][j] = IntToStr(j);
: : : : : : : StringGrid1->Cells[i][0] = IntToStr(i);
: : : : : : : }
: : : : : : : }
: : : : : : :
: : : : : : : StringGrid1->Rows[0]->BeginUpdate();
: : : : : : : 이렇게 밖에 사용을 못하나요??
: : : : : : :
: : : : : : : 그러면 이렇게 엑셀에서 읽어온값을 그리드에 넣어줄때..
: : : : : : : 어떻게 사용해야되는건지...
: : : : : : : 초보입니다.. 부탁드리겠습니다.
: : : : : : : 검색을 해봐도.. 제가 적용하면 마찬가지로 프로그램이 용량이큰엑셀은 30초 정도는 멈춰 있네요..