ガジェット サイドバーのように、フォームをデスクトップに固定しようとしています。
Win+D および [デスクトップの表示] ボタンの影響を受けません。
これに最適な方法はどれですか?
Progman を見つけてフォームの親をこれに設定することはできますが、これは最善の方法ではないと読みました。
免責事項:API呼び出しや「フック」なしでWinFormsで特定の方法で何かを実行できるからといって、その手法を使用する必要があるという意味ではありません。フォーム/ウィンドウを動かせない、一番上などにするためのAPI呼び出しは非常に簡単です。通常のAPIの「単純な手法」には、デスクトップ上のファイルアイコンとフォルダアイコンの上に表示される以下に示す手法と同じ問題があることに注意してください。
Windows-Dキーの組み合わせとタスクバーの「デスクトップの表示」アイコン-ヒッキーの設計された動作を「妨害」することにより、ユーザーのマシンの非標準構成に従事していることに注意してください。一般的な「知恵」はそうではないことを示しますこれを行うのは良い考えです!
「疑似サイドバー」は、C#WinFormsのVistaでエミュレートできます...Windows-Dまたは「デスクトップの表示」アイコンの使用に影響されません-システムトレイのヒッキー...API呼び出しまたは「フック」なし:しかし、落とし穴があります:フォーム/ウィンドウはデスクトップ上のアイテム(フォルダー、ファイル)の上に表示され、移動できないため、その下のアイテムにアクセスできなくなります。 「」あなたがその制限に「我慢する」ことをいとわないなら:読んでください:)これの終わりに記されたもう一つの「より小さな奇妙さ」。
例 :
Visual Studioで新しいフォームソリューションを作成します:
a。フォームのサイズ、背景色などを好みに合わせて設定します
b。コントロールまたはユーザーコントロールを追加します。
c。フォームの「TopMost」プロパティを「他のアプリケーションのウィンドウの前に常に表示する場合はtrue」に設定し、他のアプリケーションのウィンドウをその前に表示できるようにする場合は「false」に設定します。
フォームの「ControlBox」、「MinimizeBox」、および「MaximizeBox」プロパティを「false」に設定します。
'FormBorderStyleを'プロパティエクスプローラードロップダウンに表示される'固定スタイルの1つに設定します。FormBorderStyle = FixedToolWindowをFormのTextプロパティで「空の文字列」として使用することをご存知かもしれませんが、TitleBarとCaptionのないウィンドウが作成されます。ディスカッション:はい、必要に応じてサイズ変更を許可できます:SizeChangedハンドラーにコードを記述し、フォームのロックを解除したままにします。
これらのイベントハンドラーは、フォームを閉じられない、移動できない、最小化できないなどにするために何が必要かについてのアイデアを提供する必要があります。
.........ラフスケッチコードpocは次のとおりです:明らかにリファクタリング、改善できます...
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
// set your Form's 'Top here ...
private void Form1_LocationChanged(object sender, EventArgs e)
{
this.Top = 100;
this.Left = Screen.PrimaryScreen.Bounds.Width - this.Width;
}
private void Form1_VisibleChanged(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
}
private void Form1_Deactivate(object sender, EventArgs e)
{
this.Activate();
}
private void Form1_SizeChanged(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("button1 is alive");
}
'button1のクリックイベントハンドラーはそこで何をしていますか?私のテストでフォームが使用可能であることを確認するためだけに。
上記の「イベントの非アクティブ化」ハンドラーでフォームを再アクティブ化すると、フォームはWindows-Dおよび「デスクトップの表示」の影響を受けなくなりますが、Vistaでは奇妙な副作用もあります。フォームからフォーカスを切り替えるとウィンドウ(たとえば、デスクトップ上のフォルダをクリックすることにより):タスクバーが跳ね返り、立ち上がったままになり(非表示の場合)、しばらく点滅します:アクティブになりたいと思っていることを示していると思います。
開いたままのタスクバーに我慢することは、APIを使用せずに、この「代用品サイドバー」を使用することのさらに別の代償かもしれません。
注:忘れないでください:必要な'不透明度:取得した'不透明度:)
[1]注:フォームを非表示にしたり閉じたりする方法をユーザーに提供することを検討したいですか?[/ 1]
あなたが求めているのはApplication Desktop Toolbarのようです。
私は間違っている可能性がありますが、Win + D はおそらく開いているすべてのウィンドウにグローバル最小化メッセージを送信する可能性があります
したがって、フォームをウィンドウ最小化メッセージの影響を受けないようにしてください。フックの使用
関連記事はこちら。
回答ありがとうございます。
私は最初にこの方法を持っていました:
[DllImport("User32.dll")]
static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
IntPtr pWnd = FindWindow("Progman", null);
pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SHELLDLL_DefVIew", null);
pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SysListView32", null);
IntPtr tWnd = this.Handle;
SetParent(tWnd, pWnd);
しかし、主な問題は、子ウィンドウもデスクトップの親であり、不透明度や透明度を使用できないことです。
次のコードを使用してウィンドウハンドルを関数に渡しますが、フォームの読み込みはこれで問題が完全に解決されることを願っています
public void SetFormOnDesktop(IntPtr hwnd) {
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}