Winform :判断是否为顶层窗口

今天遇到一个需求,就像MSN提示信息一样,如果窗口未当前,则需闪烁提醒用户

好久没动笔了,写一写记下来吧,嘿嘿

引用:http://www.codeproject.com/KB/dialog/Is_My_Application_on_Top_.aspx

以上图是从copeproject copy下来的,从此图可以看出一个流程吧,但是作者用的是一个GetTopWindow的函数,感觉并不正确,尽管做出来的效果是跟讲的一样,但是。。。。有兴趣的朋友可以看一下,以下是他判断是否当前窗口为最顶层的函数,VB。NET代码

 

Private Function IsOnTop(ByVal hwnd As Integer) As Boolean
    Dim i As Integer = GetTopWindow(0)    'Initialize
    Dim x As Integer = 1
    Dim s As String
 
    ' Enumeration
    Do    
        i = GetNextWindow(i, 2) ' Find next window in Z-order
        If i = hwnd Then
            Exit Do
        Else
            If i = 0 Then        ' Never find any window match the input handle
                Return False
            End If
        End If
 
        If IsWindowVisible(i) = True Then
            s = Space(256)
            If GetWindowText(i, s, 255) <> 0 Then
            ' Very important to prevent confusing
            ' of BalloonTips and ContextMenuStrips
                x += 1
            End If
        End If
    Loop
 
    ' x is Z-order number
 
    If x = 1 Then
        Return True
    Else
        Return False
    End If
End Function

 

但通过console打印出自已当前处于最顶层窗口句柄时,也打印出GetTopWindow获得的句柄,再用SPY++查看,并不一致,那里出错呢,对这函数的理解出错了么?

 

幸好忽闪过一个函数:

[DllImport("user32.dll")]

  private static extern IntPtr GetForegroundWindow();

再与当前自已处于顶层的窗口句柄比较了一下,是一致的,就直接采用了

 

 

查了一下MSDN

GetForegroundWindow Function


The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working). The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.

 

GetTopWindow Function


The GetTopWindow function examines the Z order of the child windows associated with the specified parent window and retrieves a handle to the child window at the top of the Z order.

自已英语很菜,但这gettopwindow的意思是获取子窗口的顶层窗口的句柄,但网上别人说:传0进去是获得WINDOWS当前顶层窗口?

 

而闪烁则是通过flashwindow函数,这大多C++ coder都清楚的,嘿嘿,就能跟MSN一样,当用户并未操作当前消息窗口时能提示

 

顺便写写这个例中过程中曾用过的几个API

[DllImport("user32", EntryPoint = "GetTopWindow", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]

public static extern int GetTopWindow(int hwnd);

[DllImport("user32", EntryPoint = "GetWindow", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]

public static extern int GetNextWindow(int hwnd, int wFlag);

[DllImport("user32", EntryPoint = "IsWindowVisible", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]

public static extern bool IsWindowVisible(int hwnd);

[DllImport("user32", EntryPoint = "GetWindowTextA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]

public static extern int GetWindowText(int hwnd, string lpString, int cch);

[DllImport("user32.dll")]

private static extern IntPtr GetForegroundWindow();

 

 

也记一下一篇文章,很好的介结了WINDOWS窗口机制,改天好好验证一下每个函数

http://blog.csdn.net/chenshaoying/archive/2008/04/24/2324304.aspx

 

其实上面主要涉及到的,还是一个Z轴的问题,老的WIN32 coder是很熟啦,通过Z轴,能做出一些很漂亮的效果哦,最明显的就是一个OUTLOOK的控件,codeproject上有好几个介绍的,一个是作者自已写的,好长好长的代码呀,另一个,则是作者通过设置Z轴达到的效果,很好很强大

 

 

以下是其设置Z轴的一段代码

         void ButtonClick(object sender, System.EventArgs e)

         {

              // Get the clicked button...

              Button clickedButton = (Button)sender;   

              // ... and it's tabindex

              int clickedButtonTabIndex = clickedButton.TabIndex;    

             

              // Send each button to top or bottom as appropriate

              foreach (Control ctl in panel1.Controls)

              {

                   if (ctl is Button)

                   {

                       Button btn = (Button)ctl;

                       if (btn.TabIndex > clickedButtonTabIndex)

                       {

                            if (btn.Dock != DockStyle.Bottom)

                            {

                                 btn.Dock = DockStyle.Bottom;

                                 // This is vital to preserve the correct order

                                 btn.BringToFront();             

                                                   }

                       }

                       else

                       {

                            if (btn.Dock != DockStyle.Top)

                            {

                                 btn.Dock = DockStyle.Top;

                                 // This is vital to preserve the correct order

                                 btn.BringToFront();

                                                   }

                       }

                   }

              }

             

              // Determine which button was clicked.

              switch (clickedButton.Text)

              {

                   case "Cars":

                       CreateCarList();

                       break;

                      

                   case "Outlook Shortcuts":

                       CreateOutlookList();

                       break;

                      

                   case "Zip Files":

                       CreateZipList();

                       break;

              }

                     listView1.BringToFront(); // Without this, the buttons will hide the items.

             

         }

 

很简单地设置一个Z轴就达到OUTLook效果了,给自已标志一下,加油

 

别告诉我那种VS效果是怎么做出来的哦,那要说的话可以写好长好长的一篇文章了,CODEPROJECT上就有一个开源的控件做,嘿嘿,很佩服作者的精神,坚持下去。。。。。。。。。

 

posted @ 2008-09-03 15:15  yellowyu  阅读(3320)  评论(0编辑  收藏  举报