「デスクトップの表示」でも消えないウィンドウを作るには?

解決


K  2006-04-16 02:40:07  No: 21035

常に最背面でデスクトップの表示を押されても消えないウィンドウを作成しようとしています。
常に最背面で表示するほうは出来たんですけど、
デスクトップの表示のほうはさっぱり判りません。

何かよい方法はものでしょうか?
よろしくお願いします。


forever  2006-04-16 14:22:06  No: 21036

実験してみたけど、
メインフォームに WM_SHOWWINDOW がきた時、かつ
Message.lParamがSW_PARENTCLOSINGの時に
何かすれば、なんとかなるかもしれない。
PostMessageで表示できるかと思ったけど
うまくいきませんでした。

別に適当でいいなら Timerかなにかで
後で Showさせるとかいう方法も・・・。
privates
    FAppWndProc:pointer;
    FOriginalProc:pointer;

implements

procedure TForm1.AppWndProc(var Message: TMessage);
begin
{
Application
WM_WINDOWPOSCHANGING
WM_NCCALCSIZE
WM_WINDOWPOSCHANGED
WM_MOVE
WM_SIZE

MainForm
Unknown($88)
WM_NCPAINT
WM_GETTEXT
WM_ERASEBKGND
WM_NOTIFY
WM_NOTIFY
WM_NOTIFY
WM_NOTIFY
WM_SHOWWINDOW
WM_SHOWWINDOW
}
//        DebugLog(Self,IntToStr(Message.Msg));
    if Message.Msg = WM_SHOWWINDOW then
    begin
        DebugLog(Self,'WM_SHOWWINDOW');

            DebugLog(Self,'Closing');
            if Message.lParam=SW_PARENTCLOSING then
            begin
                DebugLog(Self,'Parent Closing');
            end;
            Message.Result:=1;
            Exit;
    end;

    with Message do
    Result := CallWindowProc(
        FOriginalProc, Handle, Msg, WParam, LParam);

end;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FAppWndProc:=MakeObjectInstance(AppWndProc);
  if FAppWndPRoc<>nil then
  begin
    FOriginalProc:=
        pointer(SetWindowLong(
            Handle,GWL_WNDPROC,longint(FAppWndProc)));
  end;
end;

destructor TForm1.Destroy;
begin
  if  (FOriginalProc<>nil) then
  begin
        SetWindowLong(
            Handle, GWL_WNDPROC, LongInt(FOriginalProc));
        FreeObjectInstance(FAppWndProc);
  end;
  inherited;

end;

最初は TApplicationのメッセージを調べたんだけど、
もしかしたら、Applicationの
WM_WINDOWPOSCHANGEDのほうが、よかったかもしれない。

とりあえず、ここまで分かればあとは時間をかければ
何とかなると思います。
以上。


ママん  2006-04-16 18:53:00  No: 21037

ウィンドウスタイルにWS_EX_TOOLWINDOWを追加してあげればよかとです。

program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  SetWindowLong(Application.Handle,
                GWL_EXSTYLE,
                WS_EX_TOOLWINDOW);
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.


K  2006-04-17 07:41:25  No: 21038

foreverさん、ママんさん、ご返事ありがとうございます。

foreverさん
Timerを使って、Showで表示させようとしましたが無理でした。
変わりにApplication.Restoreで表示させてみましたら、表示することが出来たのですが、
ShowWindow(Application.Handle, SW_HIDE)でタスクバーに表示してない状態だと表示されません。
タスクバーに表示してない状態では、Application.Restoreの効き目は無くなってしまうものなのでしょうか?

ママんさん
ウィンドウスタイルにWS_EX_TOOLWINDOWを追加してみても、
「デスクトップの表示」を使用するとウィンドウが非表示になってしまいます。
何か他に設定等が必要なのでしょうか?


ママん  2006-04-17 08:26:36  No: 21039

すみません、駄目ですね…
私は「ミ田+M」を良く使うのですが、こっちはOKです。
動いてるプログラムが違うんですね…

「デスクトップの表示」ボタンを押しても屈強に隠れないアプリは私は見つけることができませんでした。
こうなると消されて飛び出るしかないかもしれませんね。
しかしWS_EX_TOOLWINDOWは他の一個目のウィンドウ出現と同時に出てきます。ちょっと不振な挙動ですね。


forever  2006-04-17 14:51:52  No: 21040

ママんさんの方法で
できたっぽいけど。( D5 win2000)
"prevent show desktop" でググるといろいろと情報があります。
んで、

オブジェクトインスペクタで
 BorderIcons の
   biMinimize を False
 FormStyle
   を StayOnTop

TFormのOnShowで、
begin
  SetWindowLong(getwindow(Handle,GW_OWNER),GWL_STYLE,0);
  SetWindowLong(getwindow(Handle,GW_OWNER),GWL_EXSTYLE,0);
  OnShow:=nil;
end;


追伸  2006-04-17 14:53:15  No: 21041

ShowWindow(Application.Handle, SW_HIDE);
の状態でも OK だった。
以上。


J  2006-04-17 16:49:20  No: 21042

StayOnTopが必要ですか・・・
質問者は
>常に最背面で・・・
とのことのようですが。
ちなみに「デスクトップの表示」はキーでは「ミ田+D」です(トグルします)


K  2006-04-18 07:06:31  No: 21043

ママんさん、foreverさん、Jさん、ご返事有難うございます。

ママん
自分の知る限りで「デスクトップの表示」ボタンを押しても屈強に隠れないアプリは
「Samurize」です。

foreverさん
Jさんの仰られているとおり、最前面だと上手くいくのですが、
それ以外だとやはり駄目なようです。

「デスクトップの表示」は「ToggleDesktop」という命令で動作しているらしいのですが、
この「ToggleDesktop」が何をしているのかが良くわかりません。

他にもアドバイス等がありましたら、よろしくお願いします。


うーむ  2006-04-18 22:14:27  No: 21044

SSみました。
DeskTopDCに Bitblt してるとかじゃないんですよね・・・


えーと  2006-04-19 07:47:44  No: 21045

ランチャとか、タスクバー自身も最小化しないですよね。AppBar アプリなら大丈夫なのでは?


deldel  2006-04-19 20:25:55  No: 21046

AppBarなら大丈夫ですね。
でも、きっとこれじゃないですよね・・・


ええーと  2006-04-20 04:40:52  No: 21047

AppBar アプリでも最背面にできるし、必ずしも周囲にドックしなくてもいいので
大丈夫なのでは?


K  2006-04-22 06:52:46  No: 21048

うーむさん、えーとさん、deldelさん、ええーとさん
ご返事ありがとうございます。

http://www.asahi-net.or.jp/~GV4J-SGUR/narik/stp001.htm#SHAppBarMessage
このページを参考にAppBarを試してみたんですが、
今までと同じくStayOnTop状態でないと隠れてしまいます。
何か設定が必要なのでしょうか?
教示よろしくお願いします。


forever  2006-04-25 01:17:02  No: 21049

Parentを Program Managerにすればいいようです。
なんか定番の方法らしい(汗)
ただ、実験したところ、起動時にProgmanの下にいるらしく
表示されないので SetZOrderでTopMostにしてやる必要があります。

FProgmanHwnd: THandle;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FProgmanHwnd:=FindWindow('Progman','Program Manager');
  if FProgmanHwnd<>0 then
  begin
    ParentWindow:= FProgmanHwnd;
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
    //上に持ってきて表示する
    SetZOrder( True);
    //タスクバーに表示しないって事だったと思うんで。
    ShowWindow(Application.Handle, SW_HIDE);
end;

こんな感じで。
実験用のコードです。
実装は、ご自分で最適化してください。

(SpyするとProgmanはExplorer.EXEの子にいます。)
D5 + W2KとXPで確認。
以上。


forever  2006-04-25 01:20:14  No: 21050

ちなみに
FormStyle=fsNormal
でOK。
BorderIconsもいじらなくていいようです。


ママん  2006-04-25 04:34:35  No: 21051

おおーっ!すばらしい!
私も結構な時間を費やして調べたのですが、結局分からず終いでした。
喉のつかえが取れた感じです。
ありがとうございます。


K  2006-04-25 06:58:37  No: 21052

皆様今までありがとうございます。
foreverさんのお陰で解決することが出来ました。

自分もママんさんと同じく、喉のつかえが取れた感じです。
本当にありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加