Eben
Imagination at work
posts - 3,comments - 31,trackbacks - 0

今天看到这篇文章,觉得蛮有用的,我之前也对这个不大了解,特转载此处.

转载地址:http://www.51testing.com/html/200804/n80848.html

在Window 的图形界面下,最基本显示信息的元素就是窗口,每一个Window 窗口都管理着自己和其他窗体之间的关系和自身的一些信息,如:是否可见,窗口的所有者,窗口的父/子关系等等信息,当窗口创建、销毁、显示的时候,就会用到这些信息。
  
  在每一个窗口实例中,有四个元素被窗口管理器用来建立窗口管理链表。
  
  

  q

  
   Child : 指向窗口子窗口的句柄
   Parent: 指向窗口父窗口的句柄
   Owner: 指向窗口所有者的句柄
   Next:  指向下一个同属窗口的句柄
   
        众所周知当Window 初始化的时候,它创建桌面这个窗口,桌面覆盖着整个窗口,窗口管理器用这个窗口作为窗口链表中第一个元素。因此桌面在窗口的层次关系中在最上层。
   
        在窗口层次关系中,桌面窗口下一层窗口叫做顶层窗口,顶层窗口就是那些不是子窗口的窗口,顶层窗口不能够有WS_CHILD 属性。窗口管理器是如何把桌面窗口和顶层窗口联系起来的呢?窗口管理器把顶层窗口都组织到一个链表中,而这个链表的头存储的就是桌面窗口的子窗口句柄,每一个子窗口通过Next 就可以找到链表中下一个窗口了。这个链表被称为子窗口链表,在同一个子窗口链表中的窗口是互为同属窗口,所有顶层窗口都是同属窗口。窗口在子窗口链表中的次序,也表明了窗口距离距离桌面窗口的距离。顶层窗口所形成的子窗口链表构成了一个Z 轴,窗口管理器就是根据Z 序列来觉得窗口的哪一部分是显示的,哪一部分是被遮盖的。
   
        所有顶层窗口的父窗口都是指向桌面窗口的,这样一来顶层窗口就好像是桌面窗口的子窗口,所有顶层窗口构成的链表是桌面窗口的子窗口链表。当顶层窗口创建的时候,窗口管理器把顶层窗口放在Z 轴的顶上,这样使得整个窗口可见,窗口管理器把窗口插入到桌面窗口子窗口链表的前面。WS_EX_TOPMOST 这个属性控制着窗口管理器创建顶层窗口,窗口管理器把没有WS_EX_TOPMOST 属性的窗口放在具有WS_EX_TOPMOST 属性的窗口的后面,这样就使得具有WS_EX_TOPMOST 属性的窗口一直显示在前面。
  
  
  qqqq

   
        在顶层窗口之间还有另外一直关系,拥有或者属于其他的顶层窗口,属于其他窗口的窗口叫做归属窗口,拥有其他窗口叫做宿主窗口,在Z 轴中,归属窗口一定在他的宿主窗口的前面,如果一个宿主窗口最小化,那么归属他的窗口会隐藏掉,如果宿主窗口隐藏起来,归属他的窗口不会被隐藏掉。如果有三个窗口A、B、C ,A 拥有 B,B 拥有 C ,如果A 最小化,那么B 会隐藏,但是 C 还是可见的。怎么才能够在窗口之间建立所有关系呢?方法是在调用CreateWindow或者CreateWindowEx 创建窗口的时候,指定hwndParent 参数。
  
  
  qqq
 
  桌面窗口是在窗口层次中的第一层,顶层窗口在窗口层次中的第二层,子窗口也就是那些创建的时候指定了WS_CHILD 属性的窗口占据了窗口层次的其他层。窗口和子窗口之间的联系,就像桌面窗口和顶层窗口之间的关系一样。
  
  
qq

客户区域,所有同一个窗口的子窗口同样建立一个Z 轴,这个和顶层窗口是类似的,顶层窗口也是显示在其父窗口――桌面窗口的客户区域。
  
16 位和32 位窗口系统的区别
        窗口之间的父子关系、归属所有关系、以及根据 Z 轴来显示的这些规则在16 位和32 位窗口系统中都是相同的。这样可以是在两种窗口系统中高度的兼容。两种窗口系统的区别在于安全和多线程。
        Window Nt 在原有的窗口层次关系中多增加了一层,每一个运行着Window NT 的系统中都有一个Window 工作站对象,这个对象是安全对象的第一层,是所有用户安全对象的继承之源,每一个Window 工作站对象可以拥有一些桌面对象,每一个桌面都拥有上面描述的那样的窗口关系。Window Nt 用了两个桌面窗口对象,一个是用来处理登陆界面、屏蔽、锁住工作站等,一个是我们登陆之后进来操作的窗口了。J 通常用户是不能够创建和删除桌面的,不过那是通常,实际上在Window 下面也可以实现类似 Linux 中的多个桌面的效果,每一个桌面都是一个独立的世界。
  
  两种窗口系统还有两位一个区别,在16 位窗口系统中不支持多线程,所以应用程序开发者在创建窗口的时候不必考虑线程的问题了。而在32 位窗口系统中由于又支持了窗口的父子关系,归属与拥有关系,同一个窗口下面的所有线程都拥有相同的一个输入队列,应用程序开发者应该明白输入队列是共享的,在同一个时刻只能有一个线程处理消息,其他的线程都在等待输入队列一直到GetMessage 或者PeekMessage 返回,而且必须注意的是父窗口和子窗口或者是归属与拥有窗口共用同一个线程。
  
  在32 窗口系统中定义两种新的窗口类型,前台窗口和背景窗口,这两种窗口没有列到窗口的层次关系中,前台窗口就是用户当前操作的窗口,其他的所有窗口都是背景窗口。 32 位窗口系统中支持两个函数来处理前台窗口SetForegroundWindow 和GetForegroundWindow。
posted @ 2008-10-14 14:03 Eben 阅读(630) 评论(0) 编辑

题目:

一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。
复杂度最好是O(n)

1. 初始化一个数组,长度为 N + 1; (iArray[N + 1])

2. 遍历数列,将数列中的元素依次填充到新申请的数组对应下标的位置上。(也就是说如果元素是5,那么 iArray[5] = 5)

    这样简单的实现了一种从大到小的排序(没有用那些复杂的排序算法,呵呵), 没有元素的位置上的值为0.

3. 由于和是 N + 1, 那么1 开始遍历iArray.

     如果找到一个下标为ix的元素不为0, 那么用 N + 1 - ix 得到了一个iPartner,如果iArray[iPartner] 不为0, 那么 ix 与 iPartner就是符合条件的数对.

     需要注意的是我们只需要找 N / 2次 就行了~~ 否则找出来的数对有可能会重复(如果没有次序要求的话).

4. 这个算法没有考虑整数溢出的情况~~!!(不晓的有没有空间复杂的的要求~~)

大概写了一个算法如下(C#)

 

        public void FindPartner(int N,int[] iNumSequ)
        {
            Debug.Assert(N >= 0,"N >= 0");
            Debug.Assert(N >= Int32.MaxValue, "N >= Int32.MaxValue");
            Debug.Assert(iNumSequ != null, "iNumSequ != null");
            Debug.Assert(iNumSequ.Length > N, "iNumSequ.Length >= N");

            if(null == iNumSequ)
                return;
            if(N <= 1)
                return;
            int[] iFullSequ = new int[N + 1];
            foreach(int iI in iNumSequ)
            {
                iFullSequ[iI] = iI;
            }
            if(N == 2)
            {
                if(iNumSequ.Length <= 1)
                    return;
                else
                    Debug.WriteLine(iFullSequ[0].ToString() + " + " + iFullSequ[1].ToString() + "=" + (N + 1).ToString());
            }
            int iSum = N + 1;
            int iPartner = 0;
            for (int ix = 1; ix <= N; ix++)
            {
                if (ix == N / 2)
                {
                    if(iFullSequ[ix] == 0)
                        break;
                    else
                    {
                        if (iFullSequ[ix + 1] == 0)
                            break;
                        else
                        {
                            Debug.WriteLine(iFullSequ[ix].ToString() + " + " + iFullSequ[ix + 1].ToString() + " = " + iSum.ToString());
                            break;
                        }
                    }

                }
                if (iFullSequ[ix] == 0)
                    continue;
                iPartner = iSum - ix;
                if (iFullSequ[iPartner] == 0)
                    continue;
                else
                    Debug.WriteLine(iFullSequ[ix].ToString() + " + " + iFullSequ[iPartner].ToString() + " = " + iSum.ToString());
            }
        }

posted @ 2008-10-09 14:17 Eben 阅读(2996) 评论(29) 编辑

注册申请博客园的帐号还真麻烦,不过现在终于搞好了。 已经看了很多博客园的文章,所以想在这里写一些自己的东东。把工作中遇到的东西都能尽量总结一下,好提高自己的技术水平~ 呵呵

posted @ 2008-09-30 09:14 Eben 阅读(107) 评论(2) 编辑
仅列出标题