如果说通过一个窗口类创建多个窗口,那么GWL_USERDATA又是什么呢?好像又重叠了。没人回,因为分少?

解决方案 »

  1.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义
      

  2.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? 
      

  3.   

    windows API函数没有采用OOP机制
    此类为窗口类,不是OOP中的类,不能继承,不要搞混了,虽然名字都是叫CLASS
    留下这两个字段的空间,是为了扩展性或者程序员自已定义使用。
      

  4.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? windows是 面向对象?听谁说的
      

  5.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? 
     你如果初步了解mfc中的CWnd这个类,就知道,什么时候该用继承,什么不该用了。说白了,那就是一个数据结构,不能够继承的,就这么简单。
      

  6.   


    getwindowlong是可以通过gwl_userdata获取user data。 这个数据即使你创建窗口的是用没有关联上,也会有数据,至于数据如何来的,不知道。参考:http://bbs.chinaunix.net/thread-2308241-1-1.html第4楼楼主,对这些问题别过于深究,深究意义不大,比如: registerclass后,那么windows如何维护 那些数据结构,你搞得清吗?
      

  7.   


    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? windows是 面向对象?听谁说的
    首先我说的不是API,我说的windows的设计思想,面向对象是一种思想,而不是形式,你可以拿windows内核源码看一下,这么庞大的操作系统,你们认为他没有一套设计思想?没有一套结构? 内核那么多种对象, 难道是想到哪,写到哪,想到什么,写什么?难道一定要语言支持的样式,才叫面向对象? 不能透过表象看实质嘛?
      

  8.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? 
     你如果初步了解mfc中的CWnd这个类,就知道,什么时候该用继承,什么不该用了。说白了,那就是一个数据结构,不能够继承的,就这么简单。你这种心态就不太对,难道什么都得过且过,不求甚解,对进步有帮助?
    你对这个问题根本就不了解,所以给出的答案也让人哭笑不得,C++的类,难道不是数据结构? 他本质上就是,只是隐藏了第一成员,一个函数指针表而已。编译器为他传this指针。C语言模仿C++实现面向对象的所有特质,网上一搜一大把,麻烦你先去看一看。这已经不是天方夜谭了。
    只要你想知道内核是怎么维护的,可以去逆向win32k呀,我之所以没去,是想来碰碰运气,看看有没有前辈做过同样的事情,愿意分析成果的。 因为我不想造轮子。
    你说到MFC就更有意思了,它只是在win32上层稍作封装,并没有啥改动,只是用windows hook把窗口回调函数,指向自己而已,  而它的后辈WTL同样,只是用thunk改进了一下window hook消耗过大的问题,
    这说明什么? 这说明windows这窗口, 本身就有面向对象的精神,骨子里就是,所以根本不需要改,
    只是用C++这种语言上支持面向对象特性,给它再封装一下,使它变的更清晰一下。
      

  9.   

    看到楼主的想法,我尿了,楼主啥叫面向对象知道不?
    wndclass 只是一个名字而已,不是类。概念混淆
      

  10.   

    代码没仔细看, 首先这个“类名”的历史,估计是 c++还没在windows上大行其道的时候,就引入了,所以别和面向对象中的类混在一块。第二:这个“类名”是不能够继承的, 可以说,我不明白继承这东西有什么意义第一,代码没仔细看,就发表评论,会不会有些不负责任?第二,面向对象是编程思想,和C++有什么关系? 他俩是用等号联系吗?很多论文和书籍,都曾经提到,windows是按面向对象的思想设计的。第三,怎么就不能继承呢?难道必须语言内部支持,才可以实现面向对象的特性吗?lua那种用C实现的小巧脚本语言,同样可以把面向对象表现的淋漓尽致。至于有什么意义? 你可以不去做,但是必须要懂,刨根究底,是搞技术的好品质,只有懂的越多,遇到问题,才能想出更多的解决方案。 同样是程序员,高手和菜鸟用什么来区分? 
     你如果初步了解mfc中的CWnd这个类,就知道,什么时候该用继承,什么不该用了。说白了,那就是一个数据结构,不能够继承的,就这么简单。你这种心态就不太对,难道什么都得过且过,不求甚解,对进步有帮助?
    你对这个问题根本就不了解,所以给出的答案也让人哭笑不得,C++的类,难道不是数据结构? 他本质上就是,只是隐藏了第一成员,一个函数指针表而已。编译器为他传this指针。C语言模仿C++实现面向对象的所有特质,网上一搜一大把,麻烦你先去看一看。这已经不是天方夜谭了。
    只要你想知道内核是怎么维护的,可以去逆向win32k呀,我之所以没去,是想来碰碰运气,看看有没有前辈做过同样的事情,愿意分析成果的。 因为我不想造轮子。
    你说到MFC就更有意思了,它只是在win32上层稍作封装,并没有啥改动,只是用windows hook把窗口回调函数,指向自己而已,  而它的后辈WTL同样,只是用thunk改进了一下window hook消耗过大的问题,
    这说明什么? 这说明windows这窗口, 本身就有面向对象的精神,骨子里就是,所以根本不需要改,
    只是用C++这种语言上支持面向对象特性,给它再封装一下,使它变的更清晰一下。这个封装与windows与面向对象根本无关,它只是一些api和数据结构,只不过用 c++ 封装出来
      

  11.   


    getwindowlong是可以通过gwl_userdata获取user data。 这个数据即使你创建窗口的是用没有关联上,也会有数据,至于数据如何来的,不知道。参考:http://bbs.chinaunix.net/thread-2308241-1-1.html第4楼楼主,对这些问题别过于深究,深究意义不大,比如: registerclass后,那么windows如何维护 那些数据结构,你搞得清吗?
    还是我先给你启蒙一下吧,
    第一,WNDCLASS和C++那些类都是普通的数据结构,在内存中的布局是完全相同的。第二,WNDCLASS也和C++类的思想一样,有属性,什么style,光标,背景颜色等等。也有一系列方法,什么GetClassLong和SetClassLong之类,这种获取和设置属性的。当然还有CreateWindow这些, 那么Register和UnRegister就是它的new和delete只是它在系统内核里来分配内存。 为什么这些方法第一个参数,不是它的this,而是HWND呢? 这就是内核在维护,通过HWND作为索引来找到内核为他开辟的那片内存空间,这难道不是封装???你告诉我这和你那C++面向对象有什么分别?只能说你对面向对象理解的不够深刻,稍微一变化,你就看不到本质了
      

  12.   

    MFC你肯定用过吧?  CRect 和CPoint 类肯定见过吧? 你告诉我 RECT和POINT是不是你所谓简单的数据结构?你再看看MFC为他们做了什么深奥的封装? 完全没有,换个外壳而已。在MFC里,你就认为那是对象? 那是类?在win32里你就体会不到?朋友你毕业了吗?  毕业后再来讨论吧
      

  13.   

    楼主这帖有意思cbClsExtra和cbWndExtra的价值绝对没有重叠,楼主也在#1提到了通过一个窗口类创建多个窗口
    其实就是共性与个性的问题,为窗口类分配的cbClsExtra大小的数据就好比C++类中的静态变量,在内存中只有一份,
    而为窗口分配的cbWndExtra大小的数据就相当于C++类中的一般的成员变量了,只有实例化后才分配内存,并且每个对象都分配了cbWndExtra大小的空间。至于GWL_USERDATA,它是不够用的,写界面库子类化窗口时使用GWL_USERDATA来储存数据时是否要考虑这个问题:如果这个界面库的dll要给其他人用,而人家的项目之前已经使用GWL_USERDATA储存了其它数据怎么办?
      

  14.   

    我还是不拿windows系统来说事吧,这对你们2位有些太神秘了。我举个简单的例子,我用C++按照面向对象的思想写一个动态链接库给你们2位来用,而我不喜欢导出一个类给你们,而是导出一些全局函数,比如Register(), 而我在Register内部调用new。 难道你们就不理解了?再举个例子吧,COM编程,你说它是不是面向对象? 你调用一个COM用new吗?只是需要给你们一个声明,你们才可以使用  Ixx -> xxx.你才知道有this指针可以用吗?那么我不声明,而且导出全局函数,通过HWND作为索引,才查找对象指针就不行?
    这就不是面向对象了?换个马甲就都不认识了?那就说明了解的还不够
      

  15.   


    啥都不说典型乱套按照说法, 面向对象不是所有都需要继承do you konw?举个极端例子:C#的main函数的那个类, 继承有什么意义?纯而继承而继承, 你就是这样理解面向对象的。还好意思
      

  16.   


    啥都不说典型乱套按照说法, 面向对象不是所有都需要继承do you konw?举个极端例子:C#的main函数的那个类, 继承有什么意义?纯而继承而继承, 你就是这样理解面向对象的。还好意思只是凭借语法技巧强行封装,强行继承,破坏事务的原理这样的面向对象不要也罢。面向对象只是解决问题的, 有的问题本神就不需要。
    你自己强奸windows,还
      

  17.   


    很高兴终于有一位就问题本质给出答案,昨晚看见,我好好琢磨了一下,现在才回复。首先,我没有win32k的源码,也不认识主创人员,所以无真相,只能大胆假设,小心求证。我假设它本身就是按照面向对象的思想设计的。(你认同这个假设吗?)struct CWindow
    {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc; //这个函数指针可以看成是纯虚函数,可由使用者实现。
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
    //子类成员
    SOCKET uPeople;
    HANDLE hEvent;
    };根据msdn给出的信息,系统会在Local Heap上根据cbClsExtra的值,并在CWindow的尾部,追加内存空间,这和类继承的特性是一样的,我们都知道class,struct和数组,在内存都是一样的线性排列,而子类在内存中,就是在父类尾部的。
    所以我认为RegisterClass就等于new CWindow,只是它不返回系统分配的内存指针,而是返回一个原子。CreateWindow第一个参数class name等于这个原子,传入字符串name正确,传入返回的ATOM也正确。就是PE结构里的导入表和导出表,可以通过字符串索引,也可以通过"编号"索引一样。
    如果说CreateWIndow是CWindow的成员方法,cbClsExtra也是为子类化而设计的话,那问题就来了。
    msdn说cbWndExtraThe number of extra bytes to allocate following the window instance.这句好像就颠覆了上面的架设。
    那么能不能麻烦你给出点伪代码,使我能更清晰一些,谢谢
      

  18.   


    啥都不说典型乱套按照说法, 面向对象不是所有都需要继承do you konw?举个极端例子:C#的main函数的那个类, 继承有什么意义?纯而继承而继承, 你就是这样理解面向对象的。还好意思只是凭借语法技巧强行封装,强行继承,破坏事务的原理这样的面向对象不要也罢。面向对象只是解决问题的, 有的问题本神就不需要。
    你自己强奸windows,还
    唉,秀才遇到兵,我也不想和你多说什么了,你也不用再回了,都是些小儿之见,我无视了。
    只是最后奉劝一句,谦虚点,就算你掌握的是真理。 何况还不是?动不动就一口咬定别人是错误的,可是又说不出个所以然,一句让人信服的论据都有,只能让人觉得你在胡说八道。要想来装,也要花点本钱,再多买几本书看看吧,增加点斗嘴的资本。你说的那些都太苍白,太无力了。还有别那么粗俗,好歹你也是受过高等教育的,一会尿了,一会又强奸, 你这样很难让人把你和有学问联系在一起。
      

  19.   


    啥都不说典型乱套按照说法, 面向对象不是所有都需要继承do you konw?举个极端例子:C#的main函数的那个类, 继承有什么意义?纯而继承而继承, 你就是这样理解面向对象的。还好意思只是凭借语法技巧强行封装,强行继承,破坏事务的原理这样的面向对象不要也罢。面向对象只是解决问题的, 有的问题本神就不需要。
    你自己强奸windows,还
    唉,秀才遇到兵,我也不想和你多说什么了,你也不用再回了,都是些小儿之见,我无视了。
    只是最后奉劝一句,谦虚点,就算你掌握的是真理。 何况还不是?动不动就一口咬定别人是错误的,可是又说不出个所以然,一句让人信服的论据都有,只能让人觉得你在胡说八道。要想来装,也要花点本钱,再多买几本书看看吧,增加点斗嘴的资本。你说的那些都太苍白,太无力了。还有别那么粗俗,好歹你也是受过高等教育的,一会尿了,一会又强奸, 你这样很难让人把你和有学问联系在一起。
    哈哈哈哈
      

  20.   


    我不认为RegisterClass等于new CWindow,虽然都有面向对象的思想,但它们面向的对象不同,一个是面向Class,一个是面向Window,据此,我认为CreateWindow类似于new,DestroyWindow类似于delete ,当然,只是思想上相同,都要为Window对象分配内存
      

  21.   

    struct CWindow
    {
        UINT cbSize;
        UINT style;
        WNDPROC lpfnWndProc; //这个函数指针可以看成是纯虚函数,可由使用者实现。
        int cbClsExtra;
        int cbWndExtra;
        HINSTANCE hInstance;
        HICON hIcon;
        HCURSOR hCursor;
        HBRUSH hbrBackground;
        LPCTSTR lpszMenuName;
        LPCTSTR lpszClassName;
        HICON hIconSm;
     
         
        //子类成员
        SOCKET uPeople;
        HANDLE hEvent;
    };
    不好意思,我没注意你说的CWindow是指这个结构
    但WNDCLASSEX这个结构是为创造类而设计的,所以这个结构你命名为CWindow,感觉有点不妥,应该命名为CClass
      

  22.   


    我不认为RegisterClass等于new CWindow,虽然都有面向对象的思想,但它们面向的对象不同,一个是面向Class,一个是面向Window,据此,我认为CreateWindow类似于new,DestroyWindow类似于delete ,当然,只是思想上相同,都要为Window对象分配内存
    一个面向window,一个面向class,这说法,好像可以解释为什么有一个cbClsExtra又有一个cbWndExtra。可以面向class?这个命名会不会有些太过抽象哇,再者DestroyWindow好像是发WM_DESTROY消息给回调函数,而回调函数是WNDCLASS的成员,如果说WNDCLASS是一个对象,而WINDOW又是一个对象。他们之间是怎么样的关系呢? 父子? 模板? 在看雪有位前辈给出我这样的答案,你帮分析一下:class Class : public WNDCLASSEX
    {
            public:
            ClsExtra = some_defined_data
            WndExtra = new byte [cbWndExtra]
    }hwnd = new Class 
    这代码给我的感觉是,cbWndExtra只是WNDCLASS里一个很普通的成员,它的目的是为了,某一天,某人通过这个类创建窗口,需要开辟一个buffer,来存放一些个性化的东西。struct CWindow
    {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc;        //这个函数指针可以看成是纯虚函数,可由使用者实现。
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
    //子类成员
    SOCKET uPeople;
    HANDLE hEvent;
    };CWindow::CWindow()
    {
    cbClsExtra = 8;
    cbWndExtra = 4;
    }ATOM CWindow::RegisterClass()
    {
    return new CWindow()
    }HWND CWindow::CreateWindow()
    {
    buffer = new BYTE[cbWndExtra];
    }
      

  23.   

    又或者说,下面这种代码,和上面那种代码,那一个更贴边,那一个更靠谱,那一个更接近真相?
    struct CWindow
    {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc;        //这个函数指针可以看成是纯虚函数,可由使用者实现。
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
    //子类成员
    SOCKET uPeople;
    HANDLE hEvent;
    };CWindow::CWindow()
    {
    cbClsExtra = 8;
    cbWndExtra = 4;
    }ATOM RegisterClass()
    {
    CWindow * pThis = new CWindow(); return Insert(pThis);   //通过内核某种存储表,插入数据,返回对应索引;
    }
    struct CWnd  //另外一个面向窗口的对象
    {
    CWindow * pcw;
    };
    HWND CreateWindow(ATOM atom)
    { CWindow * pcw = GetClassInfo(hInstance,atom);  //atom = lpszClassName;
    CWnd * pwnd = new CWnd(); 


    pwnd->pcw = pcw;  //CWnd类保存CWindow指针;
    PVOID pChild = realloc(pwnd,pcw ->cbWndExtra);    //cbWndExtra负责子类化CWnd 
    return Insert(pChild); //通过内核某种存储表,插入数据,返回对应索引; 
    }
    //那么接下来一切以HWND为第一参数的成员函数,都可以索引到CWnd和CWindow的所有内容如果说第一种靠谱,对于窗口,只有一个CWIndow类,那说它本身就是按面向对象设计的,就很契合了。如果说第二种靠谱,对于窗口,有2个结构CWindow和CWnd,那说它是面向对象就有点牵强了,
    窗口是一个对象,为什么要有2个结构来描述呢?
      

  24.   

    面向class,意思是说将窗口类作为一个对象来看,可能有点抽象,但它确实有自己的数据结构,而它的数据结构也不可能和窗口的数据结构相同,微软并没公开窗口的数据结构,只告诉你一个句柄和提供一系列的API,事实上,不只窗口,系统中很多东西都是用一个句柄来标识一个对象,只不过窗口类不是用句柄而是用ATOM
    WNDCLASS的lpfnWndProc成员只是默认使用,每个窗口都可以有自己的WindowProc
    如果要我用C++描述,就这样吧:
    class CWndClass : public WNDCLASSEX
    {
      ATOM m_atom;  CWndClass()
      {
        cbSize = sizeof(WNDCLASSEX);
        style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
        lpfnWndProc = DefWindowProc;
        cbClsExtra = sizeof(CWndClass) - cbSize;
        cbWndExtra = 4;   // 
        hInstance = GetModuleHandle(NULL);
        hIcon = LoadIcon(NULL,IDI_APPLICATION);
        hCursor = LoadCursor(NULL,IDC_ARROW);
        hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        lpszMenuName = NULL;
        lpszClassName = TEXT("WHAT");
        hIconSm = LoadIcon(NULL,IDI_EXCLAMATION);
        m_atom = RegisterClassEx(this);
      }
    };class CWindow
    {
      HWND m_hWnd;
      static CWndClass s_WndClass;
      static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
      {
        switch (uMsg)
        {
          // 自己处理了
          // case ...    }
        return CallWindowProc(s_WndClass.lpfnWndProc, hwnd, uMsg, wParam, lParam);
      }  CWindow()
      {
        m_hWnd = CreateWindow(s_WndClass.m_atom, ...);    // 每个窗口都可以有自己的WindowProc
        // 但我们不知道窗口内部的数据结构,所以只能微软提供的API函数SetWindowLong来修改
        // 如果不修改,默认就是使用它所属窗口类的lpfnWndProc了
        SetWindowLong(m_hWnd, GWL_WNDPROC, WindowProc); 
      }
    };CWndClass CWindow::s_WndClass;
      

  25.   

    或者说WNDCLASS是一个基类,cbClsExtra这个成员为其预留扩展功能。CWND是其子类,cbWndExtra这个成员才是为了用户子类化CWnd用的。
    像MFC那样 CWnd是个相对基类,继承它有CFrame,CDialog,CView,CControl等等。
    而我最初的想象创建自己的窗口,应该继承WNDCLASS,其实不对,应该用cbWndExtra继承,就是继承CFrame;