当前位置:编程学习 > C#/ASP.NET >>

请教:如何让窗体 始终显示在桌面

我是新手,
最近尝试编写一个日历

但是,不知道如何让日历始终显示在桌面上。
系统: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都做过


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;
}
--------------------编程问答-------------------- http://topic.csdn.net/t/20020525/15/751915.html --------------------编程问答-------------------- 关注中, 系统 API 设置层的操作。 --------------------编程问答--------------------
引用 2 楼  的回复:
用spy++找桌面,然后set parent 到桌面,xp,win7,win8都做过

C# code

private void Window_Loaded(object sender, RoutedEventArgs e) {
    IntPtr desktopHwnd = GetDesktopPtr();
    IntPtr ownHwnd = new WindowInterop……

——————————————————————————————————————————————————————————————————

2#  非常感谢你的回复。
但是,按照这个方法,也不能解决问题。
窗体确实是显示在桌面上的,可是,窗体是透明的。

你这边方便的话,可以试试。

按照这个方法,用spy++,查询,窗体可以插入到Progman->SHELLDLL_DefView->SysListView32下,但是,窗体是透明的,虽然在桌面上,却什么都看不到。右键点击窗体,设置的右键菜单能正常显示,可是,却看不到窗体上的东西。 --------------------编程问答-------------------- 你简单贴一下你MainWindow的代码 --------------------编程问答-------------------- --------------------编程问答-------------------- 用SetParent设置SysListView32是很危险的
这样试试,用SetWindowPos把窗体设置在最顶层,然后屏蔽最小化



--------------------编程问答-------------------- --------------------编程问答--------------------
引用 8 楼  的回复:
用SetParent设置SysListView32是很危险的
这样试试,用SetWindowPos把窗体设置在最顶层,然后屏蔽最小化


这样不行,其他窗口不能盖住它了 --------------------编程问答-------------------- 很奇怪啊
楼主的要求是:始终在最前端。因为这个功能很容易实现,窗体选项中有这个。
明显是设置了TopMost属性,楼主几位反而用SetParent设置SysListView32,那不变成最低层了?
和楼主的要求相反了吧

--------------------编程问答-------------------- 明白了,原来是屏蔽"显示桌面"有难度,曲线救国

--------------------编程问答--------------------
引用 11 楼  的回复:
很奇怪啊
楼主的要求是:始终在最前端。因为这个功能很容易实现,窗体选项中有这个。
明显是设置了TopMost属性,楼主几位反而用SetParent设置SysListView32,那不变成最低层了?
和楼主的要求相反了吧


topmost属性,是把窗体放在最顶端。但是,我不希望把窗体放在最顶端,只是希望不被“显示桌面”隐藏。
因为,如果把窗体放在最顶端,太碍事了。
我编写的是一个日历,没人把日历放在最顶端的。碍事。 --------------------编程问答--------------------
引用 6 楼  的回复:
你简单贴一下你MainWindow的代码

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());
        }
--------------------编程问答--------------------
引用 6 楼  的回复:
你简单贴一下你MainWindow的代码


我是新手,您贴的代码中的,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);
          --------------------编程问答--------------------
引用 16 楼  的回复:
 [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 n……


非常感谢,,你的方法可以是窗体置顶。

非常感谢。
请问可不可以只屏蔽win+D,而不让窗体置顶。
因为我编写的是一个日历,日历置顶的话,会影响电脑的正常使用, --------------------编程问答--------------------
引用 16 楼  的回复:
 [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 n……


或者,让窗体在最底层也可以,关键是屏蔽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的窗体视觉效果,

以上方法都不好使,窗体会变成透明的。

小弟,拜托各位大大,想想办法。非常感谢。 --------------------编程问答--------------------
引用 19 楼  的回复:
把窗体的TopMost属性,改为true


非常感谢,这个方法是可以让窗体始终在最顶层,这不是我想要的效果。

你想呀,我是编写一个日历,没人会让日历始终在最顶层的,这影响电脑的正常使用的。 --------------------编程问答-------------------- 楼主,请在你贴的代码中搜索 “ 字符,删除掉再运行! --------------------编程问答-------------------- 除
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,