zoukankan      html  css  js  c++  java
  • 【转】将程序窗口嵌入到任务栏中

      今天我们来看看VB.NET怎样将程序窗口嵌入到任务栏(Taskbar)中,下图是我们实现的效果。

          开始之前,小孟先简单介绍一下任务栏的组成,在这里小孟只介绍与我们的程序有关的部分。整个任务栏是有一个大的窗口容器(该容器类名是 Shell_TrayWnd)和一些窗口共同组成的,在这个类名是Shell_TrayWnd的容器中,有一个类名是ReBarWindow32的二级容 器。这个二级容器中包含的窗口在Win7和WinXP中是不同的(小孟使用的Win7,不过在这个程序中Win7和WinXP的效果都是一样的)。在 WinXP中,包含一个类名是MSTaskSwWClass的窗口外,这个窗口就是来显示任务栏按钮的(就是显示你打开了哪些窗口的那个区域,在这里小孟 叫他最小化窗口),还包含快速启动栏(在左侧以小图标显示,单击后会启动相应程序的那个区域);在Win7中只有一个类名是MSTaskSwWClass 的窗口,因为Win7中没有快速启动栏,虽然左侧也有一个类似快速启动的区域,但那个并不是快速启动,而是属于最小化窗口的一部分。以上就是与我们程序有 关的任务栏组成了,小孟这表达能力很有限,大家可能看不懂,so 小孟在下面贴了一张图。

    =====================================================================================

    Win7:

        红色区域:类名是Shell_TrayWnd的容器                       黄色区域:类名是ReBarWindow32的二级容器

       绿色区域:类名是MSTaskSwWClass的窗口

    WinXP:

        红色区域:红色区域——类名是Shell_TrayWnd的容器          黄色区域:类名是ReBarWindow32的二级容器

        绿色区域:快速启动区域                                                 紫色窗口:类名是MSTaskSwWClass的窗口

    =====================================================================================

          任务栏组成我们介绍完了,下面我们说说大体的思路。首先,我们要最小化窗口的width缩短,来给我们的程序腾出地方;然后,将我们的程序设置成任务栏的子窗口,以便于嵌入任务栏;最后,调整程序的大小和在任务栏中的位置。

    准备工作做了这么多,下面正式开工。

    新建一个【Windows窗体应用程序】。将窗体BorderStyle属性改成None来把窗体的边框去掉。然后在窗体上添加一个文本框,如下图所示:


    下面开始写代码。

    我们先把程序需要用到的API和structure来声明一下(先在类外面加上ImportsSystem.Runtime.InteropServices):

       '寻找窗口列表中第一个符合指定条件的顶级窗口
        Private Declare Function FindWindow Lib "user32" _
                        Alias "FindWindowA" (ByVal lpClassName As String, _
                                             ByVal lpWindowName As String) As Integer
    
        '在窗口列表中寻找与指定条件相符的第一个子窗口
        Private Declare Function FindWindowEx Lib "user32" _
                        Alias "FindWindowExA" (ByVal hWnd1 As Integer, _
                                               ByVal hWnd2 As Integer, _
                                               ByVal lpsz1 As String, _
                                               ByVal lpsz2 As String) As Integer
    
        '指定一个窗口的新父
        Private Declare Function SetParent Lib "user32" _
                        Alias "SetParent" (ByVal hWndChild As Integer, _
                                           ByVal hWndNewParent As Integer) As Integer
    
        '改变指定窗口的位置和大小。顶级窗口可能受最大或最小尺寸的限制,那些尺寸优先于这里设置的参数
        Private Declare Function MoveWindow Lib "user32" _
                        Alias "MoveWindow" (ByVal hWnd As IntPtr, _
                                            ByVal x As Integer, _
                                            ByVal y As Integer, _
                                            ByVal nWidth As Integer, _
                                            ByVal nHeight As Integer, _
                                            ByVal bRepaint As Integer) As Integer
    
        '获得整个窗口的范围矩形,窗口的边框、标题栏、滚动条及菜单等都在这个矩形内
        Private Declare Function GetWindowRect Lib "user32" _
                        Alias "GetWindowRect" (ByVal hWnd As IntPtr, _
                                               ByRef lpRect As RECT) As Integer
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Private Structure RECT
            Public Left As Integer
            Public Top As Integer
            Public Right As Integer
            Public Bottom As Integer
        End Structure
    

          为了方便调试,我们先添加程序退出的代码:

        Private Sub cmdTextBox_KeyPress(ByVal sender As Object, ByVal e As _  
                                        System.Windows.Forms.KeyPressEventArgs) _  
                                        Handles cmdTextBox.KeyPress  
            If e.KeyChar = Chr(13) Then  
                If UCase(cmdTextBox.Text) = "END" Then  
                    Me.Close()  
                End If  
            End If  
        End Su  
    

          这样,我们就可以通过在文本框里输入“end”,然后按回车来退出程序了。

          既然要改变最小化窗口的width,那么我们就先来找最小化窗口的Handle,先声明一个全局变量,来储存我们找到的最小化窗口的Handle:

        Dim hMin As Long  
    

          接下来,我们查找最小化窗口的句柄(下面的代码都在窗体的Load事件里):

    Dim hTaskbar, hBar As Long  
    hTaskbar = FindWindow("Shell_TrayWnd", vbNullString)            '寻找类名是Shell_TrayWnd的窗口Handle  
    hBar = FindWindowEx(hTaskbar, 0, "ReBarWindow32", vbNullString) '寻来找二级容器的Handle  
    hMin = FindWindowEx(hBar, 0, "MSTaskSwWClass", vbNullString)    '寻找最小化窗口的Handle
    

          找到句柄后,我们来获得二级容器的坐标和最小化窗口的坐标:

        Dim rcBar As RECT  
        GetWindowRect(hMin, rcMin)  '获得最小化窗口的Handle  
        GetWindowRect(hBar, rcBar)  '获得二级容器的Handle  
    

         下面我们通过用MoveWindow函数来改变窗口的width:

        MoveWindow(hMin, 0, 0, rcMin.Right - rcMin.Left - Me.Width, _  
                   rcMin.Bottom - rcMin.Top, True)  
    

          已经为任务栏腾出地方了,是时候把程序嵌入到任务栏里了:

        SetParent(Me.Handle, hBar)  '把程序窗口设置成任务栏的子窗口  
    

          调整程序窗口的大小和位置:

        Me.Height = cmdTextBox.Height  
        Me.Width = cmdTextBox.Width  
        MoveWindow(Me.Handle, rcMin.Right - rcMin.Left - Me.Width + 2, _  
                  (rcBar.Bottom - rcBar.Top - Me.Height) / 2, _  
                   Me.Width, Me.Height, True)  
    


          把程序窗口嵌入到任务栏里的任务已经完成了,但我们还需要处理一下窗体的Closing事件,使程序关闭的时候,把最小化窗口的width恢复回去(下面这一行代码放在窗体的Closing事件里):

    MoveWindow(hMin, 0, 0, rcMin.Right - rcMin.Left, rcMin.Bottom - rcMin.Top, True) 
    

          终于完成了,现在可以运行看一下效果了,和文章一开始的效果一样吧?

  • 相关阅读:
    Score, ACM/ICPC Seoul 2005, UVa 1585
    Score, ACM/ICPC Seoul 2005, UVa 1585
    Molar Mass, ACM/ICPC Seoul 2007, UVa 1586
    Molar Mass, ACM/ICPC Seoul 2007, UVa 1586
    Digit Counting, ACM/ICPC Danang 2007, UVa 1225
    Digit Counting, ACM/ICPC Danang 2007, UVa 1225
    Periodic Strigs, UVa455
    【开发技术】java+mysql 更改表字段的步骤
    【编程技巧】JAVA读取url地址中的文本内容
    【问题解决】java中为什么不建议使用DataInputStream 的readLine()方法
  • 原文地址:https://www.cnblogs.com/luoshupeng/p/2151081.html
Copyright © 2011-2022 走看看