이전에는 안그랬는데 윈도우11부터...
폼이 떠있고 다른 폼 뒤에 있는 경우 트레이아이콘의 아이콘을 더블클릭 하면
화면 전면, 즉 최상위에 프로그램이 표시되지 않고 다음과 같이 작업표시줄 아이콘만 붉은색으로 깜빡거릴 뿐 표시되지 않는 문제가 있다.
이미 트레이아이콘으로 숨겨진 경우엔 작업표시줄에 아이콘이 없기때문에 껌뻑임 없이 바로 전면에 표시되지만,
다른 폼의 뒤에 있는 경우엔 작업표시줄 아이콘이나 트레이아이콘을 한번 더 클릭해야만 전면에 나타나서 여간 성가신게 아니다.
작업표시줄에서 깜빡거리는 것은 '윈도우 설정 > 개인설정 > 작업표시줄 > 작업표시줄 동작'에서 '작업 표시줄 앱에서 깜빡임 표시'가 활성화 되어있기 때문인데, 이걸 끄면 또 아예 깜빡이지도 않고 아무런 반응이 없다.
통상 실행중인 프로그램이 최소화 또는 다른 창의 후면에 있는 경우 최상위로 폼을 표시하려면 다음을 코드를 사용했다.
(바로가기 아이콘 실행 시 중복실행을 막고 이미 실행중인 프로그램을 최상위에 표시하는 것은 마지막에 기술한다)
procedure ShowForeground;
begin
//폼이 숨김(Hide, Visible = False) 상태라면 표시한다(트레이아이콘인 경우다)
if not Visible then
begin
WindowState := wsNormal;
Visible := True;
end;
SetForegroundWindow(Self.Handle); //BringToFront가 잘 먹지않으므로
end;
//위 코드를 간단히 하면 다음과 동일하다
procedure ShowForeground;
begin
//폼이 숨김상태인 경우 처리
WindowState := wsNormal;
Show; //Show내부는 Visible := True; BringToFront; 두줄이다.
SetForegroundWindow(Self.Handle);
end;
헌데 위의 SetForegroundWindow함수가 다른 프로세스에는 잘 동작하지만, 자기 자신인 경우 동작하지 않도록(껌뻑이도록) 윈11부터 막혀벼렸다.
다음과 같이 수정한다.
procedure ShowForegroud;
begin
WindowState := wsNormal;
Show;
//강제로 최상위폼으로 만든 뒤 해제한다
FormStyle := fsStayOnTop;
FormStyle := fsNormal;
end;
위와 같이 하면 최상위에 정상적으로 폼이 표시된다.
하지만 역시나 작업표시줄 아이콘이 뻘겋게 껌뻑여서 여전히 성가신데 다음과 같이 처리한다.
이렇게 하면 작업표시줄의 내 프로그램 아이콘이 다른 아이콘들의 중간에 있더라도 작업표시줄 가장 우측으로 보내는 효과도 있다.
procedure ShowForegroud;
begin
//폼이 보이는 상태면(최상위던 뒤던) 최소화 시킨 뒤 숨긴다.
if Visible then
begin
WindowState := wsMinimized;
Hide;
end;
//위와 같이 하면 작업표시줄에서 아이콘이 없어지고...
//다음과 같이 다시 표시하면 작업표시줄 맨 마지막(우측)에 표시된다.
//폼은 최상위로 가고 작업표시줄 깜빡임도 사라짐
WindowState := wsNormal;
Show;
//강제로 최상위폼으로 만든 뒤 해제한다
FormStyle := fsStayOnTop;
FormStyle := fsNormal;
end;
이미 트레이아이콘으로 숨겨진 경우엔 작업표시줄에 아이콘이 없기 때문에 껌뻑임이 없이 바로 전면에 표시되지만,
이미 폼이 표시되어 다른 폼의 뒤에 있는 경우엔 트레이아이콘을 더블클릭해도 껌뻑이기만 하고 최상위에 나타나지 않던 문제는 완전히 해결된다.
이미 실행중인 프로그램이 다른 화면 뒤에 있거나 작업표시줄에 최소화되어 있거나 트레이아이콘으로 숨은 경우
바탕화면 등 바로가기아이콘을 클릭했을 때 중복실행을 피하고 이미 실행중인 프로그램을 최상위에 표시하려면 다음과 같이 처리한다(중복실행 방지 관련해서는 여기에서는 생략한다)
use Winapi.Windows;
procedure ProcessForegroud(Handle: THandle);
begin
//Handle: 전면에 표시할 실행중인 프로세스의 핸들
if IsIconic(Handle) then
begin
//작업표시줄에(Taskbar) 최소화된 상태면 폼 복원
ShowWindow(Handle, SW_RESTORE)
end
else if not IsWindowVisible(Handle) then
begin
//폼이 안보이면(작업표시줄에 없고 트레이아이콘에 숨긴경우) 표시하고
ShowWindow(Handle, SW_SHOWNORMAL);
end
else
begin
//그냥 다른폼 뒤에 있으면 앞으로
SetForegroundWindow(Handle);
end;
end;
IsWindowVisible은 폼이 최소화(Minimize) 또는 Hide되어 화면에 없는지를 체크한다(다른 폼 뒤에 있는 것은 보이는 폼임).
최소화는 IsIconic에서 체크하지만 ShowWindow 방식이 달라 구분한다.
최근 프로그램들은 실행파일 자체만 실행시키기 보다 서비스에서 프로세스를 구동시키거나 별도 프로세스를 생성하여 구동 되는 경우들이 많아 위와 같이 해도 잘 작동되지 않는 것들이 많다.
단순히 자신히 만든 프로그램이고 앞서 말한 것처럼 복잡하게 동작하지 않으면 잘 구동된다.
'DogFoot > Delphi' 카테고리의 다른 글
[Delphi] Zip파일 압축/해제(ft. TZipFile) (0) | 2024.10.29 |
---|---|
[Delphi] 다중 예외 처리: 다중 Exception 객체 처리 (0) | 2022.12.22 |
[IdFTP] Indy FTP, Connection reset by peer: 10054 (0) | 2022.01.20 |
[Delphi] 중첩 예외처리(try...except) (0) | 2021.04.23 |
[FireDAC] MySQL/mariaDB 서버 오류 메시지 한글 깨짐 (0) | 2021.04.16 |
댓글