임프랍니다..
오늘은.. 좀 늦잠을 자서 팁이 늦었네요~ 하지만.. 늦어도 꼭 나가는... 오늘의~~~
팁! (되게 폼재지요? --;;;)
오늘의 팁은, 스테이터스바에 프로그레스바 만들기입니다..
보통은 프로그레스바를 별도의 폼에 만드는게 일반적이지만, 일부 프로그램에서
프로그레스바를 스테이터스바에 만드는 걸 볼 수 있습니다.
그리고 어떤 경우에 이러한 인터페이스가 무척 유용할 때도 있죠.
근데.. 막상 디자인을 하려고 스테이터스바에 프로그레스바를 올려보려면~?
안됩니다! 원래 win32 컨트롤인 status bar는 다른 컨트롤을 가질수 있는 컨테이너
컨트롤인데, vcl에서 구현을 덜(?) 해놓은 탓에 다른 컨트롤을 올려놓을 수가
없답니다.. 그럼 어케해요??
어카긴 어카나.. 쩝.. 디자인타임에 안되면 런타임에 올려버리면 되죠~
자... 다음 코드를 봅시다.
C++ 코드
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ProgressBar = new TProgressBar(StatusBar1);
ProgressBar->Parent = StatusBar1;
ProgressBar->Position = 0;
ProgressBar->Visible = false;
}
델파이 코드
procedure TForm1.FormCreate(Sender: TObject);
begin
ProgressBar := TProgressBar.Create(StatusBar1);
ProgressBar.Parent := StatusBar1;
ProgressBar.Position := 0;
ProgressBar.Visible := false;
end;
물론 여기 ProgressBar는 이 폼의 헤더에서 TProgressBar *ProgressBar; 라고
포인터만 선언해줬죠. (잘 모르시는 분들은 컨트롤의 동적 생성에 대해 다시
공부할 필요가 있겠네요~)
자아.. 이렇게 하면 상태바위에 프로그레스바가 나오긴 합니다. (물론 필요할때만
보이려고 숨겼죠.)
그런데.. 보통 스테이터스바를 패널들로 나누면, 마지막 패널에 아무리 공간이 많아
도 첫번째 패널은 항상 고정된 크기로 나오지요? 보통 프로그레스바는 첫번째 패널에
나와야 폼이나는데, 첫번째 패널은 일정크기로 하자니 쬐그맣게 나올수 밖에 없고..
그래서 다음 핸들러를 하나 더 작성합시다.
스테이터스바를 클릭해서 인스펙터에서 OnResize 이벤트를 더블클릭, 다음 핸들러를
작성해봅시다.
C++ 코드
void __fastcall TForm1::StatusBar1Resize(TObject *Sender)
{
int Size = StatusBar1->Width;
for (int i=1; iPanels->Count; i++)
Size -= StatusBar1->Panels->Items[i]->Width;
//resize the first panel based on the form width
StatusBar1->Panels->Items[0]->Width = Size;
RECT Rect;
StatusBar1->Perform(SB_GETRECT, 0, (LPARAM)&Rect);
ProgressBar->Top = Rect.top;
ProgressBar->Left = Rect.left;
ProgressBar->Width = StatusBar1->Panels->Items[0]->Width;
ProgressBar->Height = Rect.bottom - Rect.top;
}
델파이 코드
procedure TForm1.StatusBar1Resize(Sender: TObject);
var
Size, i: integer;
Rect: TRect;
begin
Size := StatusBar1.Width;
for i:=1 to StatusBar1.Panels.Count -1 do
Dec(Size, StatusBar1.Panels[i].Width);
//resize the first panel based on the form width
StatusBar1.Panels[0].Width := Size;
StatusBar1.Perform(SB_GETRECT, 0, dword(@Rect));
ProgressBar.Top := Rect.top;
ProgressBar.Left := Rect.left;
ProgressBar.Width := StatusBar1.Panels[0].Width;
ProgressBar.Height := Rect.bottom - Rect.top;
end;
왓! 이렇게 하면, 폼을 리사이즈해도 스테이터스바에서 크기가 변하는 패널은
마지막 게 아니라 첫번째 것이 리사이즈 된답니다. 물론 프로그레스바도 같이 크기가
변하구요. 보이진 않죠? 프로그레스바는 필요할 때 외엔 보이면 안되니까..
그럼 이제 실제 프로그레스바를 움직여봅시다.
폼에 타이머를 하나 놓고, 그 OnTimer 이벤트의 핸들러를 다음과 같이 작성합니다.
C++ 코드
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if(ProgressBar->Position >= ProgressBar->Max)
{
Timer1->Enabled = false;
ProgressBar->Position = 0;
return;
}
ProgressBar->StepIt();
}
델파이 코드
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ProgressBar.Position >= ProgressBar.Max then
begin
Timer1.Enabled := false;
ProgressBar.Position := 0;
exit;
end;
ProgressBar.StepIt;
end;
그리고 폼에 버튼을 하나 놓고, 또 OnClick 이벤트 핸들러를 작성합시다.
C++ 코드
void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
ProgressBar->Visible = true;
Timer1->Enabled = true;
}
델파이 코드
procedure TForm1.Button1Click(Sender: TObject);
begin
ProgressBar.Visible := true;
Timer1.Enabled := true;
end;
이렇게만 해주면 완성~!
버튼을 눌러주면 스테이터스바의 첫번째 패널에서 프로그레스바가 진행한답니다.
아~주 멋지게 구현이 되었죠?
참고로... 이 멋진 팁은 제가 알아낸거이 아니고.. 헤헤~ 컨닝을 했는데,
Mitov's C++Builder Page에서 나온 팁을 참고한겁니다.
주소는...
http://members.xoom.com/mitov 입니다.
아주 멋진 팁들이 많은, 개인홈페이지 치고는 괜찮은 곳이죠.
그럼, 도움되시길 바라면서, 이만...
독립문에서 임펠리테리였습니다.