none
wpf窗口在win10的开始菜单上不能置顶 RRS feed

  • 问题

  • 请教各位大神:

    在win10操作系统中,我的软件置顶功能在开始菜单上不行,在其他软件上是可以置顶的,请问这个是什么问题?

    2017年11月9日 3:34

答案

  • Hi,

    上图应该是您想要的效果。

    首先,在WPF程序中添加manifest文件(app.manifest),并且修改requestedExecutionLevel属性如下:

    <requestedExecutionLevel level="highestAvailable" uiAccess="true" />

    其次,在MainWindow.xaml中的Window标签下增加属性如下:

    Topmost="True" ShowInTaskbar="True"

    然后,编译程序。编译好的程序不可以直接在编译环境下运行。将程序拷贝到可信任路径下:C:\Program Files、C:\Program Files(x86)、C:\Windows\system32之一,我是将编译好的Debug文件夹拷贝到C:\Program Files中的。

    接着,对程序进行证书签名操作:

    1.创建可信任根证书:以管理员模式运行cmd命令窗口,cd到想存储证书拷贝的目录,依次运行下面的命令:

    makecert -r -pe -n "CN=Test Certificate - For Internal Use Only" -ss PrivateCertStore testcert.cer
    certmgr.exe -add testcert.cer -s -r localMachine root

    注意,证书名自定义(我用的testcert.cer),如果certmgr.exe找不到,则需要在环境变量的path中添加certmgr.exe的路径。

    2.对文件进行签名:cmd cd到exe(你的程序)的路径下,运行下面的命令:

    SignTool sign /v /s PrivateCertStore /n "Test Certificate - For Internal Use Only" /t http://timestamp.verisign.com/scripts/timestamp.dll 程序名.exe

    同样,程序名需要替换。

    参考链接:https://stackoverflow.com/questions/12873323/how-to-make-windows-8-desktop-apps-shown-in-metro-ui-like-task-manager/15025426#15025426

    此外,我注意到您还创建了相似的问题,如果您的问题在这个帖子中得到解决,我们将会将两个帖子合并,感谢您的理解和配合!

    Best Regards,

    Charle He



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.





    2017年11月20日 6:21

全部回复

  • Hi,

    你所说的在开始菜单上的置顶功能是指什么?

    建议你附上相关的图片和代码来更清楚的描述你的问题。

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月9日 4:03
    版主
  • 您好,我加了图片如下:

    可以看到我的窗体被win10的开始菜单遮挡了,我要置顶在开始菜单之上,就是要在系统的最顶层。

    2017年11月9日 5:38
  • 在其他的软件上可以实现置顶功能:

    我的置顶的代码如下:

    while (true)
                    {

                                        

     this.Dispatcher.Invoke(new Action(() =>
                                    {

                                        this.Topmost = false;
                                        //Thread.Sleep(2);
                                        this.Topmost = true;

                                         //下面这三行代码加上和不加没有区别

                                       // HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
                                      //  IntPtr handle = source.Handle;
                                       // bool b1 = BringWindowToTop(handle);
                                    }), null);

    }

    另外用的win32API,如下:

         IntPtr CustomBar = FindWindow(null, "aaWindow");    //程序中需要置顶的窗体的名字
                if (CustomBar != null)
                {
                    SetWindowPos(CustomBar, TopMostTool.HWND_TOPMOST, 0, 0, 0, 0, TopMostTool.SWP_NOMOVE | TopMostTool.SWP_NOSIZE);

                    // SetParent(null, CustomBar);
                }

    用以上API函数和设置 this.Topmost = true;功能类似,也没有什么区别。

    2017年11月9日 5:47
  • Hi,

    初步看来,你的代码应该没有问题, 由于你的问题需要在技术上进一步深入调查,我建议您通过OneDrive上传一个可以复现你的问题的示例,包括详细的代码说明以及关于结果的详细说明,我们可以下载并进行调试。 这将帮助我们快速分析您的问题。

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月9日 6:18
    版主
  • 您好:由于公司网速限制,打不开OneDrive。

    我将前端和后端代码都贴出来了,您复制就可以用了。麻烦您了,谢谢!

    后台代码:

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfTopmost { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private Object _thisLock = new Object(); public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { Thread globalThread = new Thread((ThreadStart)delegate { MouseStopTimeSpan(); }); globalThread.IsBackground = true; globalThread.Start(); } private void MouseStopTimeSpan() { try { while (true) { try { Thread.Sleep(200); lock (_thisLock) { this.Dispatcher.Invoke(new Action(() => { // SetWindowPos(, -1, 0, 0, 0, 0, 0x4000 | 0x0001 | 0x0002); 我以前试过这个效果不太好,所以注掉了 //HwndSource source = (HwndSource)PresentationSource.FromVisual(this); //IntPtr handle = source.Handle; //bool b1 = BringWindowToTop(handle); this.Topmost = false; //Thread.Sleep(2); this.Topmost = true; //HwndSource source = (HwndSource)PresentationSource.FromVisual(this); //IntPtr handle = source.Handle; //bool b1 = BringWindowToTop(handle); //系统所在鼠标位置 MousePosTool.POINT p = new MousePosTool.POINT(); if (MousePosTool.GetCursorPos(out p))//API方法 { this.Top = p.Y - 65; this.Left = p.X - 65; } }), null); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } public static class MousePosTool { /// <summary> /// 设置鼠标的坐标 /// </summary> /// <param name="x">横坐标</param> /// <param name="y">纵坐标</param> [DllImport("User32")] public extern static void SetCursorPos(int x, int y); public struct POINT { public int X; public int Y; public POINT(int x, int y) { this.X = x; this.Y = y; } } /// <summary> /// 获取鼠标的坐标 /// </summary> /// <param name="lpPoint">传址参数,坐标point类型</param> /// <returns>获取成功返回真</returns> [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool GetCursorPos(out POINT pt); } }

    前端:

    <Window x:Class="WpfTopmost.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" WindowStyle="None" AllowsTransparency="True" Loaded="Window_Loaded" Background="Transparent" Title="MainWindow" Height="130" Width="130"> <Grid Background="Transparent"> <Ellipse Fill="Transparent" Stroke="Green" StrokeThickness="3"></Ellipse> </Grid> </Window>


    2017年11月9日 6:59
  • 由于onedrive网址打不开,只能把前后台的代码都完整的贴出来了。请大神再帮忙看看。谢谢!我用的IDE是vs2013
    2017年11月10日 1:10
  • 大神们,麻烦帮忙看看!自己顶下
    2017年11月10日 9:35
  • 每天自己顶一下,自己查资料

    https://onedrive.live.com/这个网址是真打不开,不管在公司还是在家里都打不开这个网址,在hosts里面也加了IP地址还是打不开。无奈啊!

    还是希望大神能帮我看看这个问题。

    2017年11月11日 9:18
  • 我需要实现一个软件置顶的功能(即显示在系统最上层),在win7、win8操作系统上都实现了,但是在win10操作系统上测试的时候,不能再win10的开始菜单上置顶,不能虚拟键盘上置顶。


    • 已合并 Hart Wang 2017年11月14日 7:08 相同问题
    2017年11月13日 1:34
  • 拿搜狗输入法测试了一下,搜狗输入法可以在win10的开始菜单上置顶,而我的软件不行(绿色的圈)

    我目前置顶的功能用以下方法实现的:

    第一步:循环设置topmost = true

    第二步:修改app.manifest特权

    第三步:C:\Windows目录下运行程序

    2017年11月13日 1:41
  • 拿搜狗输入法测试了一下,搜狗可以显示在开始菜单之上,不知道这个是如何实现的。

    2017年11月13日 3:31
  • Hi,

    感谢在MSDN论坛发帖。

    据我所知把软件置顶,一般就是topmost 设置成 ture 。 然后软件就可以置顶了。 下面是winform 中把置顶的方式,你可以参考一下。

    How to: Keep a Windows Form on Top

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月13日 9:33
  • 非常感谢您的回答,winform置顶的方式都试过了;

    在win7和win8操作系统上是可以的,win7,win8操作系统上都可以置顶;但是到win10系统上测试就不行了,出现了我上面截图那种情况,不能置顶。

    2017年11月14日 0:36
  • Hi,

    感谢你的回复。

    我不知道这个是不是windows 10上面的bug,你可以把这个问题提到 connect上面,那儿是专门解决bug的地方。

    你能告诉你使用的工程是windows form的程序,还是WPF?  有没有遇到什么错误信息和异常信息。

    据我所知有款免费的库,专门是软件置顶的,你可以参考一下。

    Dexpot 

    Best Regards,

    Hart

    注意:此回复包含对第三方万维网站点的引用。 Microsoft提供此信息为您提供方便。 Microsoft不控制这些网站,并且没有测试在这些网站上发现的任何软件或信息; 因此,Microsoft不能对任何软件或信息的质量,安全性或适用性做任何声明。 使用互联网上发现的任何软件都存在固有的危险,Microsoft警告您,在从互联网检索任何软件之前,请确保您完全理解风险。


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月14日 5:54
  • @Hart Cheng

    非常感谢您的回复,我的程序是wpf开发的。没有错误信息和异常信息,在win10操作系统上就像上面截图那样的效果,没有实现置顶而已。我是想要截图中的绿圈显示在开始菜单之上。但是没有实现。

    我的前台代码是:

    <Window x:Class="WpfTopmost.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            WindowStyle="None"
            AllowsTransparency="True"
            Loaded="Window_Loaded"
            Background="Transparent"
            Title="MainWindow" Height="130" Width="130">
        <Grid  Background="Transparent">
            <Ellipse Fill="Transparent" Stroke="Green" StrokeThickness="3"></Ellipse>
        </Grid>
    </Window>

    后代代码也很简单,如下:

    private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                try
                {
    
                    IntPtr desktop = GetDesktopWindow();
                    var parentHwnd = new IntPtr(0x01DE0DFC); // Running Notepad
                    var guestHandle = new WindowInteropHelper(this).Handle;
    
                    var style = MyWindowStyles.WS_VISIBLE | MyWindowStyles.WS_CLIPSIBLINGS | MyWindowStyles.WS_CHILD | MyWindowStyles.WS_POPUP;
                    SetWindowLong(guestHandle, GWL_EXSTYLE, (uint)(style));
                    SetParent(guestHandle, desktop);
    
    
    
                    Thread globalThread = new Thread((ThreadStart)delegate
                    {
                        MouseStopTimeSpan();
                    });
                    globalThread.IsBackground = true;
                    globalThread.Start();
    
                   // uint intExTemp = GetWindowLong(new WindowInteropHelper(this).Handle, GWL_EXSTYLE);
                    // uint oldGWLEx = SetWindowLong(new WindowInteropHelper(this).Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
                  //  uint oldGWLEx1 = SetWindowLong(new WindowInteropHelper(this).Handle, GWL_EXSTYLE, (uint)MyWindowStyles.WS_POPUPWINDOW);
    
                    //IntPtr myPtr = GetForegroundWindow();
    
                    //CALLBACK myCallBack = new CALLBACK(Report);
                    //EnumWindows(myCallBack, 0);
                    // IntPtr hwnd = new WindowInteropHelper(this).Handle;
                    // IntPtr hDeskTop = FindWindow("Progman", null);
                    // SetParent(hwnd, hDeskTop);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
    
    
            }
    private void MouseStopTimeSpan()
            {
                try
                {
    
                    while (true)
                    {
                        try
                        {
                            Thread.Sleep(2);
                            lock (_thisLock)
                            {
                                this.Dispatcher.Invoke(new Action(() =>
                                {
                                    //  SetWindowPos(, -1, 0, 0, 0, 0, 0x4000 | 0x0001 | 0x0002); 我以前试过这个效果不太好,所以注掉了
                                    //HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
                                    //IntPtr handle = source.Handle;
                                    //bool b1 = BringWindowToTop(handle);
                                    // this.Topmost = false;
                                    //Thread.Sleep(2);
                                    //this.Topmost = true;
                                    //HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
                                    //IntPtr handle = source.Handle;
                                    //bool b1 = BringWindowToTop(handle);
    
    
                                    IntPtr CustomBar = FindWindow(null, "MainWindow");    //程序中需要置顶的窗体的名字
                                    IntPtr desktop = GetDesktopWindow();
                                    if (CustomBar != null)
                                    {
                                        SetWindowPos(CustomBar, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    
                                        SetParent(desktop, CustomBar);
    
                                        var style = MyWindowStyles.WS_VISIBLE | MyWindowStyles.WS_CLIPSIBLINGS | MyWindowStyles.WS_CHILD | MyWindowStyles.WS_POPUP;
    
                                        uint oldGWLEx1 = SetWindowLong(new WindowInteropHelper(this).Handle, GWL_EXSTYLE, (uint)style);
    
                                      
                                    }
    
                                    try
                                    {
                                        //IntPtr hwnd = new WindowInteropHelper(this).Handle;
    
                                        //this.hDesktop = GetDesktopHandle(DesktopLayer.Progman);
                                        //EmbedDesktop(this, hwnd, this.hDesktop);
                                        //isMouseDown = false;
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.ToString());
                                    }
    
    
                                    //系统所在鼠标位置
                                    MousePosTool.POINT p = new MousePosTool.POINT();
                                    if (MousePosTool.GetCursorPos(out p))//API方法
                                    {
                                        this.Top = p.Y - 65;
                                        this.Left = p.X - 65;
                                    }
                                }), null);
                            }
                        }
                        catch (Exception ex)
                        {
    
                            MessageBox.Show(ex.Message);
                        }
    
                    }
                }
                catch (Exception ex)
                {
    
                    MessageBox.Show(ex.Message);
                }
            }
        }

    注释掉的代码也是查的各种方法经过测试还是不行。

    2017年11月14日 6:50
  • Hi,

    感谢你在 MSDN 论坛发帖。 

    根据MSDN的规则,请不要重复发相同的帖子。 我将合并这两个帖子。

    https://social.msdn.microsoft.com/Forums/zh-CN/a9f52755-42c1-46e4-b35d-2cd90d163e17/wpfwin10?forum=wpfzhchs

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月14日 7:05
  • @Hart Cheng :

    好的,非常感谢

    根据上面您提供的信息,我下载了Dexpot这个软件,在windows10系统上运行,如下

    

    开始菜单还是能在这个Dexpot软件之上。


    2017年11月14日 7:10
  • 各位大神,可以帮我看看这个问题吗?查了很多资料,试了很多方法,还是没有结果。

    楼上图的搜狗。这张图的软键盘都可以在开始菜单显示,我想我的绿圈窗口显示在虚拟键盘之上。

    2017年11月16日 7:46
  • Hi,

    上图应该是您想要的效果。

    首先,在WPF程序中添加manifest文件(app.manifest),并且修改requestedExecutionLevel属性如下:

    <requestedExecutionLevel level="highestAvailable" uiAccess="true" />

    其次,在MainWindow.xaml中的Window标签下增加属性如下:

    Topmost="True" ShowInTaskbar="True"

    然后,编译程序。编译好的程序不可以直接在编译环境下运行。将程序拷贝到可信任路径下:C:\Program Files、C:\Program Files(x86)、C:\Windows\system32之一,我是将编译好的Debug文件夹拷贝到C:\Program Files中的。

    接着,对程序进行证书签名操作:

    1.创建可信任根证书:以管理员模式运行cmd命令窗口,cd到想存储证书拷贝的目录,依次运行下面的命令:

    makecert -r -pe -n "CN=Test Certificate - For Internal Use Only" -ss PrivateCertStore testcert.cer
    certmgr.exe -add testcert.cer -s -r localMachine root

    注意,证书名自定义(我用的testcert.cer),如果certmgr.exe找不到,则需要在环境变量的path中添加certmgr.exe的路径。

    2.对文件进行签名:cmd cd到exe(你的程序)的路径下,运行下面的命令:

    SignTool sign /v /s PrivateCertStore /n "Test Certificate - For Internal Use Only" /t http://timestamp.verisign.com/scripts/timestamp.dll 程序名.exe

    同样,程序名需要替换。

    参考链接:https://stackoverflow.com/questions/12873323/how-to-make-windows-8-desktop-apps-shown-in-metro-ui-like-task-manager/15025426#15025426

    此外,我注意到您还创建了相似的问题,如果您的问题在这个帖子中得到解决,我们将会将两个帖子合并,感谢您的理解和配合!

    Best Regards,

    Charle He



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.





    2017年11月20日 6:21
  • 非常感谢您的回答,我按照您的思路再改一下。
    2017年11月20日 6:27
  • @Charles He21

    非常感谢您的回答,困扰了很久的问题终于解决了。问题不在代码上,而是在数字签名上。根据您回答的对程序进行证书签名操作的步骤,成功了。

    至于在win7,win8上为什么都可以。win10不行,只能说win10对于程序的所需权限,以及是否是正式信任的软件更规范。


    2017年11月20日 7:04