请教:如何让窗体 始终显示在桌面
我是新手,最近尝试编写一个日历
但是,不知道如何让日历始终显示在桌面上。
系统:win7 64位
版本:visual studio 2012
要求:
1.日历不要求:始终在最前端。因为这个功能很容易实现,窗体选项中有这个。
2.按“显示桌面”的时候,日历不被隐藏。
备注:网上找了好几种方法,都不好使,比如:
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
IntPtr hWndNewParent = FindWindow("Progman", "Program Manager");
SetParent(this.Handle, hWndNewParent);
这种方法,在win7系统不好用,日历窗体变成透明的了。看不见。
非常感谢各位大大。帮帮小弟。
--------------------编程问答-------------------- Program Manger ? 是个啥?
我记得桌面是 "SysListView32"
我也是win7系统 以前做实验的时候想桌面 嵌入过 也没有啥问题 --------------------编程问答-------------------- 用spy++找桌面,然后set parent 到桌面,xp,win7,win8都做过
--------------------编程问答-------------------- http://topic.csdn.net/t/20020525/15/751915.html --------------------编程问答-------------------- 关注中, 系统 API 设置层的操作。 --------------------编程问答--------------------
private void Window_Loaded(object sender, RoutedEventArgs e) {
IntPtr desktopHwnd = GetDesktopPtr();
IntPtr ownHwnd = new WindowInteropHelper(this).Handle;
IntPtr result = Win32.SetParent(ownHwnd, desktopHwnd);
}
private IntPtr GetDesktopPtr() {
// http://blog.csdn.net/mkdym/article/details/7018318
// 情况一
IntPtr hwndWorkerW = IntPtr.Zero;
IntPtr hShellDefView = IntPtr.Zero;
IntPtr hwndDesktop = IntPtr.Zero;
IntPtr hProgMan = Win32.FindWindow("ProgMan", null);
if (hProgMan != IntPtr.Zero) {
hShellDefView = Win32.FindWindowEx(hProgMan, IntPtr.Zero, "SHELLDLL_DefView", null);
if (hShellDefView != IntPtr.Zero) {
hwndDesktop = Win32.FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null);
}
}
if (hwndDesktop != IntPtr.Zero) return hwndDesktop;
// 情况二
//必须存在桌面窗口层次
while (hwndDesktop == IntPtr.Zero) {
//获得WorkerW类的窗口
hwndWorkerW = Win32.FindWindowEx(IntPtr.Zero, hwndWorkerW, "WorkerW", null);
if (hwndWorkerW == IntPtr.Zero) break;
hShellDefView = Win32.FindWindowEx(hwndWorkerW, IntPtr.Zero, "“SHELLDLL_DefView", null);
if (hShellDefView == IntPtr.Zero) continue;
hwndDesktop = Win32.FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null);
}
return hwndDesktop;
}
——————————————————————————————————————————————————————————————————
2# 非常感谢你的回复。
但是,按照这个方法,也不能解决问题。
窗体确实是显示在桌面上的,可是,窗体是透明的。
你这边方便的话,可以试试。
按照这个方法,用spy++,查询,窗体可以插入到Progman->SHELLDLL_DefView->SysListView32下,但是,窗体是透明的,虽然在桌面上,却什么都看不到。右键点击窗体,设置的右键菜单能正常显示,可是,却看不到窗体上的东西。 --------------------编程问答-------------------- 你简单贴一下你MainWindow的代码 --------------------编程问答-------------------- --------------------编程问答-------------------- 用SetParent设置SysListView32是很危险的
这样试试,用SetWindowPos把窗体设置在最顶层,然后屏蔽最小化
--------------------编程问答-------------------- --------------------编程问答--------------------
这样不行,其他窗口不能盖住它了 --------------------编程问答-------------------- 很奇怪啊
楼主的要求是:始终在最前端。因为这个功能很容易实现,窗体选项中有这个。
明显是设置了TopMost属性,楼主几位反而用SetParent设置SysListView32,那不变成最低层了?
和楼主的要求相反了吧
--------------------编程问答-------------------- 明白了,原来是屏蔽"显示桌面"有难度,曲线救国
--------------------编程问答--------------------
topmost属性,是把窗体放在最顶端。但是,我不希望把窗体放在最顶端,只是希望不被“显示桌面”隐藏。
因为,如果把窗体放在最顶端,太碍事了。
我编写的是一个日历,没人把日历放在最顶端的。碍事。 --------------------编程问答--------------------
using System;--------------------编程问答--------------------
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows;
namespace test
{
public partial class Form1 : Form
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetParent(IntPtr hChild, IntPtr hParent);
[DllImport("User32.dll ", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childe, string strclass, string strname);
private IntPtr GetDesktopPtr()//寻找桌面的句柄
{
// http://blog.csdn.net/mkdym/article/details/7018318
// 情况一
IntPtr hwndWorkerW = IntPtr.Zero;
IntPtr hShellDefView = IntPtr.Zero;
IntPtr hwndDesktop = IntPtr.Zero;
IntPtr hProgMan = FindWindow("Progman", "Program Manager");
IntPtr aa;
if (hProgMan != IntPtr.Zero)
{
hShellDefView = FindWindowEx(hProgMan, IntPtr.Zero, "SHELLDLL_DefView", null);
if (hShellDefView != IntPtr.Zero)
{
hwndDesktop = FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null);
}
}
if (hwndDesktop != IntPtr.Zero) return hwndDesktop;
// 情况二
//必须存在桌面窗口层次
while (hwndDesktop == IntPtr.Zero)
{
//获得WorkerW类的窗口
hwndWorkerW = FindWindowEx(IntPtr.Zero, hwndWorkerW, "WorkerW", null);
if (hwndWorkerW == IntPtr.Zero) break;
hShellDefView = FindWindowEx(hwndWorkerW, IntPtr.Zero, "“SHELLDLL_DefView", null);
if (hShellDefView == IntPtr.Zero) continue;
hwndDesktop = FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null);
}
return hwndDesktop;
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
IntPtr desktopHwnd = GetDesktopPtr();
//IntPtr ownHwnd = new (this).Handle;
IntPtr result = SetParent(this.Handle, desktopHwnd);
//this.Opacity=1;
//MessageBox.Show(this.Handle.ToString()+"a"+desktopHwnd.ToString());
}
我是新手,您贴的代码中的,Win32.FindWindow ,我不知道用什么命名空间,不能用,显示无法识别Win32
所以,我修改了一下。
非常感谢,我寻找这个方法,半个月了,始终找不到一个可行的方法。
谢谢你,帮帮忙,非常感谢 --------------------编程问答-------------------- [DllImport("User32.dll", EntryPoint = "SetWindowPos", SetLastError = true)]
public static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndWinInsertAfter, int x, int y, int cx, int cy, int nFlags);
//窗口置顶,win+D失效
const int HWND_TOPMOST = -1;
const int SWP_NOSIZE = 0x0001;
const int SWP_NOMOVE = 0x0002;
SetWindowPos(Handle, (IntPtr)HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
--------------------编程问答--------------------
非常感谢,,你的方法可以是窗体置顶。
非常感谢。
请问可不可以只屏蔽win+D,而不让窗体置顶。
因为我编写的是一个日历,日历置顶的话,会影响电脑的正常使用, --------------------编程问答--------------------
或者,让窗体在最底层也可以,关键是屏蔽win+D。 --------------------编程问答-------------------- 把窗体的TopMost属性,改为true --------------------编程问答-------------------- [DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName);
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
/// <summary>
/// 钉入桌面
/// </summary>
public void SetParent()
{
IntPtr pWnd = FindWindow("Progman", null);
pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SHELLDLL_DefVIew", null);
pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SysListView32", null);
SetParent(this.Handle, pWnd);
} --------------------编程问答-------------------- !!!
各位大大,我刚刚发现的。。。。。
在win7 系统里面,假如把win7系统的窗体视觉效果关闭,
以上你们提到的方法都好用。2楼,20楼的方法,还有我在网上找到的方法,
都可以实现显示在桌面,并且屏蔽“显示桌面”功能。
但是,如果开启Win7的显示特效。窗体会变成透明的 --------------------编程问答-------------------- 现在还是存在问题:
开启Win7的窗体视觉效果,
以上方法都不好使,窗体会变成透明的。
小弟,拜托各位大大,想想办法。非常感谢。 --------------------编程问答--------------------
非常感谢,这个方法是可以让窗体始终在最顶层,这不是我想要的效果。
你想呀,我是编写一个日历,没人会让日历始终在最顶层的,这影响电脑的正常使用的。 --------------------编程问答-------------------- 楼主,请在你贴的代码中搜索 “ 字符,删除掉再运行! --------------------编程问答-------------------- 除
补充:.NET技术 , C#