【问题标题】:How to flash/blink taskbar icon in vb.net?如何在 vb.net 中闪烁/闪烁任务栏图标?
【发布时间】:2014-05-09 12:49:02
【问题描述】:

我需要让我的 vb.net 应用程序能够在应用程序内收到通知时闪烁/闪烁以吸引用户的注意力。

就像这张图片中的 DW 图标一样:

我已经在谷歌上搜索了一段时间,并尝试了各种代码示例,但都没有成功。

这是我目前所得到的:

    Public Class FlashWindow
        Private Declare Function FlashWindow Lib "user32" (ByVal hwnd As Long, ByVal bInvert As Long) As Long
        Shared Sub main()
        FlashWindow(Me.Handle, 1)
        End Sub
    End Class

此代码立即引发以下错误:

“我”只在实例方法中有效

谁能告诉我哪里出了问题或如何实现?

【问题讨论】:

  • 您需要获取与任务栏上的按钮相关联的顶级窗口的窗口句柄。你打算怎么做?

标签: .net vb.net winapi notifications taskbar


【解决方案1】:

首先Me 用于引用当前类。当该代码在 Form 类中时,它有一个属性 Handle。在您的示例中, FlashWindow 类没有属性 Handle,因此无法编译。

其次我觉得你对API函数的定义有点偏。

将此类添加到您的项目中:

Public Class WindowsApi
    Private Declare Function FlashWindowEx Lib "User32" (ByRef fwInfo As FLASHWINFO) As Boolean

    ' As defined by: http://msdn.microsoft.com/en-us/library/ms679347(v=vs.85).aspx
    Public Enum FlashWindowFlags As UInt32
        ' Stop flashing. The system restores the window to its original state.
        FLASHW_STOP = 0
        ' Flash the window caption.
        FLASHW_CAPTION = 1
        ' Flash the taskbar button.
        FLASHW_TRAY = 2
        ' Flash both the window caption and taskbar button.
        ' This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
        FLASHW_ALL = 3
        ' Flash continuously, until the FLASHW_STOP flag is set.
        FLASHW_TIMER = 4
        ' Flash continuously until the window comes to the foreground.
        FLASHW_TIMERNOFG = 12
    End Enum

    Public Structure FLASHWINFO
        Public cbSize As UInt32
        Public hwnd As IntPtr
        Public dwFlags As FlashWindowFlags
        Public uCount As UInt32
        Public dwTimeout As UInt32
    End Structure

   Public Shared Function FlashWindow(ByRef handle As IntPtr, ByVal FlashTitleBar As Boolean, ByVal FlashTray As Boolean, ByVal FlashCount As Integer) As Boolean
    If handle = Nothing Then Return False

    Try
        Dim fwi As New FLASHWINFO
        With fwi
            .hwnd = handle
            If FlashTitleBar Then .dwFlags = .dwFlags Or FlashWindowFlags.FLASHW_CAPTION
            If FlashTray Then .dwFlags = .dwFlags Or FlashWindowFlags.FLASHW_TRAY
            .uCount = CUInt(FlashCount)
            If FlashCount = 0 Then .dwFlags = .dwFlags Or FlashWindowFlags.FLASHW_TIMERNOFG
            .dwTimeout = 0 ' Use the default cursor blink rate.
            .cbSize = CUInt(System.Runtime.InteropServices.Marshal.SizeOf(fwi))
        End With

        Return FlashWindowEx(fwi)
    Catch
        Return False
    End Try
End Function
End Class

然后可以像这样闪烁窗口 - 传递对主应用程序表单的引用:

Dim res = WindowsApi.FlashWindow(Process.GetCurrentProcess().MainWindowHandle, True, True, 5)

注意:

我编辑了这里找到的代码:http://pinvoke.net/default.aspx/user32.FlashWindowEx

并使用此处定义的定义:Get user attention without stealing focus

这两点都可能对你有用

【讨论】:

  • 这段代码全部被接受,没有错误,但是当我调用 flashwindow 函数时,没有任何反应。我确保窗口在被调用时也没有焦点,但没有任何反应。 :( 感谢您提供如此详细的回复 - 我们必须接近!
  • 如果你从 sub Main 开始,那么可能还没有创建任何窗口句柄。您只能在创建第一个窗口后调用它。函数返回什么?
  • 我没有看到任何返回 - 控制台中没有任何内容,没有错误或任何内容。我的应用程序每 60 秒检查一次数据库,以查看是否需要显示任何警报。如果它发现一个警报,它会显示一个通知栏,更新通知文本并播放声音。它是在它播放声音之后直接调用flash函数的。
  • FlashWindow 返回一个布尔值 - 如果成功则返回 True,如果失败则返回 False。
  • 啊确实-我添加了 console.writeline(res) 并返回 False :(
【解决方案2】:

如果您正在构建 Windows 窗体应用程序,Me.Handle 将是可行的方法,但这看起来像一个控制台应用程序,在这种情况下,请尝试使用 Process.GetCurrentProcess().MainWindowHandle 而不是 Me.Handle。详情请见this question。

【讨论】:

  • 它不是控制台应用程序 - 它确实是一个 Windows 窗体应用程序。
  • 如果是 Windows 窗体,请尝试将代码移动到主窗体的 Load 事件处理程序中,看看是否有效(您可能需要更新您的问题和/或标签以澄清 :-) .
猜你喜欢
  • 2010-09-06
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
相关资源
最近更新 更多