C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[1172] 지정 시간 후 자동으로 닫히는 Modal 폼
박지훈.임프 [cbuilder] 2662 읽음    2016-05-03 08:10
showmodaltime.zip 900.4KB ShowModalTime 데모 및 소스
잘 아시다시피 델파이/C++빌더에서 폼을 여는 방식에는 Show와 ShowModal 두 가지 방법이 있습니다. 각각 modeless, modal이라고 하는데요. modal로 폼을 연다는 것은 해당 폼을 닫기 전에는 다른 폼으로 입력 포커스를 이동할 수 없도록 강제하는 것입니다. 그런데 가끔은, modal 방식으로 폼을 열었으면서도 일정 시간 이후에는 자동으로 폼이 닫히는 동작이 필요할 수 있습니다. 예를 들어 단순 알림 정도의 메시지를 뿌릴 때가 그런데요.

자주 메시지를 내보내야 하는 프로그램의 경우에 단순한 메시지 창을 자주 modal 방식으로 열면 사용자 입장에서는 일일이 클릭해서 닫아야 하는 게 사용자에게는 꽤나 번거로울 수 있겠지요. 특히 요즘은 스마트폰 앱들에서 자동으로 사라지는 메시지 창들에 사용자들이 익숙해져서 더욱 그럴 수 있습니다.

그래서 경우에 따라 modal로 폼을 열면서도 지정한 시간 이후에 폼이 닫히도록 하는 동작이 필요할 수 있는데요. 델파이/C++빌더에서는 기본적으로 이런 방법을 제공하지 않으므로 직접 만들어봤습니다. 그리 복잡할 것도 없는 간단한 코드죠. 아래의 함수를 호출하여 폼을 열면 인자로 지정한 시간(초) 이후에 자동으로 폼이 닫힙니다. (이 ShowModalTime 함수는 기본 VCL에서 TCustomForm의 ShowModal 프로시저에서 modal 폼 동작에 관련된 코드를 발췌해서 만든 것입니다)

먼저 델파이 코드는 다음과 같습니다.

function ShowModalTime(AForm: TCustomForm; iSec: integer): integer;
var
  ActiveWindow: HWnd;
  WindowList: TTaskWindowList;
  I: Integer;
begin
  ActiveWindow := GetActiveWindow;
  WindowList := DisableTaskWindows(0);
  try
    AForm.ModalResult := 0;
    AForm.Show;
    for I := 1 to iSec * 10 do
    begin
      Sleep(100);
      if AForm.ModalResult <> 0 then break;
      Application.ProcessMessages;
    end;
    result := AForm.ModalResult;
  finally
    AForm.Close;
    EnableTaskWindows(WindowList);
    SetActiveWindow(ActiveWindow);
  end;
end;

C++빌더에서 사용 가능한 코드는 아래와 같고요.

int __fastcall ShowModalTime(TCustomForm *AForm, int iSec)
{
	HWND ActiveWindow = GetActiveWindow();
	TTaskWindowList WindowList = DisableTaskWindows(0);
	try
	{
		AForm->ModalResult = 0;
		AForm->Show();
		for (int I = 1; I <= iSec * 10; I++)
		{
			Sleep(100);
			if (AForm->ModalResult != 0) break;
			Application->ProcessMessages();
		};
		return AForm->ModalResult;
	}
	__finally
	{
		AForm->Close();
		EnableTaskWindows(WindowList);
		SetActiveWindow(ActiveWindow);
	};
}

이 함수를 호출하는 방식은 폼객체.ShowModal 을 호출하는 대신에 함수의 인자로 오픈할 폼의 객체와 시간(초 단위)을 넘겨주기만 하면 됩니다. 예를 들어 Form2.ShowModal; 대신 ShowModalTime(Form2, 5); 이렇게 호출하면 되지요.



코드를 보시면 짐작하시겠지만 여기서 지정한 초 단위의 시간은 그렇게 정확하지는 않습니다. 단지 for 문으로 루핑하며 내부의 Sleep을 호출한 시간을 합산해서 시간 지연을 시키는데, 루프 내에는 ModalResult를 체크하는 코드와 Application.ProcessMessages 호출도 있기 때문이죠. ProcessMessages는 일반적인 상황에서는 CPU 타임을 그닥 먹지 않습니다만 시스템이 극단적으로 busy해지면 상황이 다를 수 있습니다. 하지만 이 함수의 목적은 아주 정확한 시간을 체크하는 것이 아니라 단순히 사용자에게 폼을 보여준 후 닫는 것이기 때문에 그렇게 많이 정확할 이유 자체가 없지요. 이런 정도면 충분하다고 봅니다.

ShowModalTime 함수는 폼의 ShowModal의 기능을 1:1로 대체하는 목적으로 만든 것이기 때문에 폼을 생성하고(create) 파괴하는(free) 역할은 하지 않습니다. 여러분이 그런 목적의 함수가 필요하시다면 생성하고 파괴하는 코드를 넣어서 확장할 수도 있겠지요. 물론 그렇게 기능을 확장하려면 첫번째 인자는 이미 생성된 폼 객체가 아니라 폼 클래스 타입을 받도록 수정해야 되겠지요.

별거 없습니다만, 데모 실행파일과 샘플 코드도 혹시 참고하실 분이 있으실까 싶어서 올려놓습니다.

그럼...

+ -

관련 글 리스트
1172 지정 시간 후 자동으로 닫히는 Modal 폼 박지훈.임프 2662 2016-05-03
(링크)     Delphi Tip'N Tricks > 지정 시간 후 자동으로 닫히는 Modal 폼
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.