喫茶XRAYトップページ


[12532] MainFormOnTaskbar返信 削除
2019/1/18 (金) 13:54:09 Mr.XRAY
[ GetWindowでのオーナーフォームハンドルの取得について ]
https://www.freeml.com/delphi-users/5087/latest

ということで MainFormOnTaskbar のテストです.
テストコードは以下です.

//-----------------------------------------------------------------------------
//  ウィンドウのハンドルからクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetClassNameStr(hWindow: HWND): string;
var
  LLength : Integer;
  LBuffer : array[0..MAX_PATH-1] of Char;
begin
  FillChar(LBuffer, SizeOf(LBuffer), #0);
  LLength := GetClassName(hWindow, LBuffer, Length(LBuffer));
  if LLength > 0 then begin
    SetString(Result, LBuffer, LLength);
  end else begin
    Result := '';
  end;
end;

//=============================================================================
//  指定ウィンドウのオーナーウィンドウを取得してそのクラス名を表示
//
//  MainFormOnTaskBar が True の時は TForm1 はトップレベルのウィンドウ
//  MainFormOnTaskBar が False の時は TApplication がトップレベルのウィンドウ
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LhTargetWnd : HWND;
  LhOwnerWnd  : HWND;
  LIsVisible  : Boolean;
begin
  Memo1.Lines.Clear;

  //Delphi2007以上
  {$IF CompilerVersion > 18.49}
  Memo1.Lines.Add('MainFormOnTaskbar  : ' + BoolToStr(Application.MainFormOnTaskbar, True));
  {$IFEND}
  Memo1.Lines.Add('Application.Handle : $' + IntToHex(Application.Handle, 8));


  LhTargetWnd := Handle;
  LhOwnerWnd := GetWindow(LhTargetWnd, GW_OWNER);

  Memo1.Lines.Add('');
  Memo1.Lines.Add('Target Window');
  Memo1.Lines.Add('Handle    : $' + IntToHex(LhTargetWnd, 8));
  Memo1.Lines.Add('ClassName : ' + GetClassNameStr(LhTargetWnd));

  LIsVisible := IsWindowVisible(LhTargetWnd) and (LhTargetWnd <> 0);
  Memo1.Lines.Add('Visible   : ' + BoolToStr(LIsVisible, True));


  Memo1.Lines.Add('');
  Memo1.Lines.Add('Owner Window of Target window');
  Memo1.Lines.Add('Handle    : $' + IntToHex(LhOwnerWnd, 8));
  Memo1.Lines.Add('ClassName : ' + GetClassNameStr(LhOwnerWnd));

  LIsVisible := IsWindowVisible(LhOwnerWnd) and (LhOwnerWnd <> 0);
  Memo1.Lines.Add('Visible   : ' + BoolToStr(LIsVisible, True));
end;

下図は MainFormOnTaskBar が True の時です.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.
タスクバーの表示にも注目ですね.


[12533] Re:MainFormOnTaskbar返信 削除
2019/1/18 (金) 13:55:23 Mr.XRAY
MainFormOnTaskBar が False の時です.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.
タスクバーの表示にも注目ですね.


[12534] Re:MainFormOnTaskbar返信 削除
2019/1/18 (金) 13:57:11 Mr.XRAY
Delphi 6 の場合です.
MainFormOnTaskBar が False の時と同じことになります.
動作確認は Windows 7 U64(SP1) + Delphi 6(UP2) です.
タスクバーの表示にも注目ですね.


[12539] 他のアプリのウィンドウの最小化と元に戻す返信 削除
2019/1/20 (日) 17:39:22 Mr.XRAY
[ GetWindowでのオーナーフォームハンドルの取得について ]
https://www.freeml.com/delphi-users/5087/latest

>メニュープログラムであるExeを起動させるとき、
>それが既に起動済みならそれを前面に持ってくる処理を作成しています。
>対象Exeが起動中かの判断はうまくいくのですが、
>それが最小化されている場合元に戻す処理がうまく動作せず苦慮しています。


それ (EXE) を前面に持ってくるとか,
それ (EXE) を最小化とか元に戻すというのはないですね.
そういう操作の対象はウィンドウです.
質問のタイトルにあるようにフォームですね.
対象 EXE のメインフォームのクラス名が TTargetForm とします.
こんな感じでしょうか.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.


# 前面に持ってくる処理はできているのか ?


//=============================================================================
//  対象のウィンドウを最小化
//  対象のウィンドウがメインフォームの場合は子フォームも最小化する
//
//  ShowWindow(LhWindow, SW_MINIMIZE); は対象のウィンドウだけを最小化できる
//  他のアプリの子フォームだけを最小化する必要性はまずないだろう
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LhWindow : HWND;
  LhOwner  : HWND;
begin
  // 対象のウィンドウハンドル
  LhWindow := FindWindow('TTargetForm', nil);
  LhOwner  := GetWindow(LhWindow, GW_OWNER);

  // Delphi 7 以前で作成したアプリ等
  // MainFormOnTaskbar := False; のアプリの場合
  // Delphi 7 以前で作成したアプリでもメインフォームだけなら不要
  if LhOwner <> 0 then begin
    LhWindow := LhOwner;
  end;
  if LhWindow <> 0 then begin
    PostMessage(LhWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
  end;
end;

//=============================================================================
//  最小化したウィンドウを元に戻す
//
//  MainFormOnTaskbar := True; のアプリの場合
//    元に戻してもこのアプリがアクティブのまま
//  MainFormOnTaskbar := False; のアプリの場合
//    元に戻すと対象のアプリがアクティブになる

//  対象が子フォームの場合は表示位置がシステムのデフォルトの位置になる
//  上のコードでメインフォームを最小化した場合
//  上のコードの実行前に最小化されている子フォームは元に戻らない
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LhWindow : HWND;
  LhOwner  : HWND;
begin
  LhWindow := FindWindow('TTargetForm', nil);
  LhOwner  := GetWindow(LhWindow, GW_OWNER);

  // Delphi 7 以前で作成したアプリ等
  // MainFormOnTaskbar := False; のアプリの場合
  // Delphi 7 以前で作成したアプリでもメインフォームだけなら不要
  if LhOwner <> 0 then begin
    LhWindow := LhOwner;
  end;
  if LhWindow <> 0 then begin
    PostMessage(LhWindow, WM_SYSCOMMAND, SC_RESTORE, 0);

    // 前面に表示するなら,例えば
    SetForegroundWindow(LhWindow);
  end;
end;


[12555] Re:他のアプリのウィンドウの最小化と元に戻す返信 削除
2019/1/23 (水) 12:59:39 Mr.XRAY
こちらもサンプルを作成して掲載しました.

[ 648_他のアプリのメインフォームの最小化と元に戻す ]
http://mrxray.on.coocan.jp/Delphi/plSamples/648_OtherApp_MinimizeRestore.htm


[12540] 実行時にメインフォームを非表示返信 削除
2019/1/20 (日) 17:49:06 Mr.XRAY
ググっていたらこんな質問を見かけました.
子フォーム Form2 をメインフォーム Form1 から表示するとします.
Form2 を表示してメインフォームを非表示にします.
すると,タスクバーにアプリまたはフォームのアイコンが表示されなくなってしまいます.

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Self);
  Form2.Show;

  Hide;
end;

サンプルプログラム主にアクティブなフォームのアイコンだけをタスクバーに表示する
サンプルがありますが,以下のような方法もあります.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.

procedure TForm1.Button1Click(Sender: TObject);
begin
  // まずメインフォームを非表示にする
  Hide;

  Form2 := TForm2.Create(Self);
  Form2.Left := Self.Left + 100;
  Form2.Top  := Self.Top + 100;
  Form2.Show;
end;

表示する子フォームのコードを以下のようにします.

uses Unit1;

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  //このフォームの親をDesktopとする
  //タスクバーにForm1とは別にアイコン表示される
  if not Form1.Visible then begin
    Params.WndParent := GetDesktopWindow;
  end;
end;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Form1.Show;
end;




[12541] Re:実行時にメインフォームを非表示返信 削除
2019/1/20 (日) 17:56:36 Mr.XRAY
> Form2 を表示してメインフォームを非表示にします.
> すると,タスクバーにアプリまたはフォームのアイコンが表示されなくなってしまいます.


MainFormOnTaskbar の値が False の時,つまり Delphi 7 以前であれば,
タスクバーにはアプリケーションウィンドウのアイコンが表示されます.
表示はデフォルトで Project1 です.


[12544] Re:実行時にメインフォームを非表示返信 削除
2019/1/21 (月) 17:35:34 Mr.XRAY
サンプルとして掲載しておくことにしました.

[712] [03_メインフォームを非表示にして子フォームを表示  -  ITaskbarList]
http://mrxray.on.coocan.jp/Delphi/plSamples/712_Taskbar_Progress.htm#03

[712] [04_メインフォームを非表示にして子フォームを表示 - WndParent]
http://mrxray.on.coocan.jp/Delphi/plSamples/712_Taskbar_Progress.htm#04


INCM/CMT
Cyclamen v3.82