コンテンツを画面に表示する場合は、常にそのコンテンツを保持するウィンドウを作成する必要があります。デスクトップ(自分が所有していないウィンドウ)でペイントするのは悪い考えです。
解決策は、拡張スタイルWS_EX_NOACTIVATE
を使用してウィンドウを作成し、WM_PAINT
メッセージに対する応答として描画することです。 WinFormsアプリケーションの場合、ランタイムはWM_PAINT
を取得したときにForm.OnPaint
を呼び出して、そのイベントを処理してそこでペイントすることができます。証明するために:
[DllImport("User32.dll")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int index);
[DllImport("User32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int index, IntPtr value);
[DllImport("User32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int GWL_EXSTYLE = -20;
private const uint SWP_NOMOVE = 0x0002;
private const uint SWP_NOSIZE = 0x0001;
private const uint SWP_NOZORDER = 0x0004;
private const uint SWP_FRAMECHANGED = 0x0020;
private const uint StyleUpdateFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED;
public Form1()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.Paint += Form1_Paint;
this.Shown += Form1_Shown;
}
private void Form1_Shown(object sender, EventArgs e)
{
IntPtr currentStyle = GetWindowLong(this.Handle, GWL_EXSTYLE);
int current = currentStyle.ToInt32();
current |= WS_EX_NOACTIVATE;
SetWindowLong(this.Handle, GWL_EXSTYLE, new IntPtr(current));
SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, StyleUpdateFlags);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.Black);
}
を、あなたのウィンドウがトップにフロートしたい場合はtrueにフォームのTopMost
プロパティを設定します。あなたはあなたの窓はZ-注文(TopMost
の正反対)の底に固執したい場合は、フォームに次のロジックを追加します。
private struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
private const int WM_WINDOWPOSCHANGING = 0x0046;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_WINDOWPOSCHANGING)
{
if (m.LParam != IntPtr.Zero)
{
WINDOWPOS posInfo = Marshal.PtrToStructure<WINDOWPOS>(m.LParam);
posInfo.hwndInsertAfter = HWND_BOTTOM;
Marshal.StructureToPtr(posInfo, m.LParam, true);
m.Result = IntPtr.Zero;
return;
}
}
base.WndProc(ref m);
}
これはWM_WINDOWPOSCHANGING
ウィンドウメッセージを処理し、そしてから窓を防止ウィンドウマネージャーにZ軸を下に置くように指示することでZオーダーで上に移動します。
自分が所有していないため、実際にデスクトップウィンドウに直接ペイントしないでください。それをしたい場合は、 'WS_EX_NOACTIVATE'でウィンドウを作成し、そのウィンドウに描画する必要があります。 (あなたは 'SetWindowLongPtr'と' SetWindowPos'を呼び出して、winformsフォームのウィンドウスタイルを変更することができます) – theB
このような意味になります:http://stackoverflow.com/a/6823357/3016335 – carefulnow1
はい、それはチケットです。そうすることで、デスクトップが何をしているのか気にする必要はなく、無効化された四角形があなたの希望する領域であるかどうかを調べる必要はありません。私はこれが何らかのデスクトップウィジェットのためのものだと思いますか? – theB