Remove ads
包含某種用戶界面的可視區域 来自维基百科,自由的百科全书
视窗是在用户界面上的一个可见的范围。视窗一般都是长方形的。它包含着各种控件,是用作输入和输出的界面。虽然视窗一般用于图形用户界面,但又有时用于命令行界面的。而一个使用视窗为主要用户界面的系统则称为视窗系统。这个想法源于施乐帕洛阿尔托研究中心。
在视窗系统上,视窗一般被画成一些二维的对象,被安置在桌面之上。大多数的视窗都可以随用户的意愿而更改大小、移动、隐藏、恢复和关闭。当两个视窗重叠的时候,就如日常生活中一样,其中一个要位于另一个之上,而下方的则会有些地方被上方个视窗所遮盖。而视窗系统中管理这个操作的部分,则叫做窗口管理器。
视窗是数种图形用户界面中的一种重要的widget。当中有VMS的DEC Windows、GNU/Unix-like系统的X窗口系统、Microsoft Windows和Open Windows。
这个概念是由斯坦福大学研究所(由 道格拉斯·恩格尔巴特 领导)开发实现的。[1] 他们最早的系统支持多窗口,但没明显的方法显示它们的分界线(比如窗口边框、标题栏等)。[2]
研究在 Xerox 公司的 Palo Alto 研究中心 / PARC (由 艾伦·凯领导)中继续。他们使用了重叠的窗口。[3]
在1980年代,PARC 提出术语"WIMP",分别代表了窗口、图标、菜单、指针。
那时Apple与PARC进行了简单的合作。Apple 根据 PARC 的界面开发了自己的新界面。它首次应用是在 Apple的 Lisa上,此后用于 Macintosh 电脑。与此同时,Microsoft在为"Mac"开发办公软件。之后他们在 Apple 系统的基础上开发了自己的窗口系统。[2]
窗口子类化是对一个窗口实例通过GetWindowLong和SetWindowLong将窗口过程地址修改为一个新函数地址,新的窗口过程函数处理那些感兴趣的消息,将其它消息传递给原窗口过程。即实例子类化。在某控件已经创建的情况下,为了获得窗口消息,必须子类化它。子类化不需要创建一个完整的新窗口类,只需要拦截单个窗口。
窗口超类化是一个已存在的窗口类(WNDCLASS或WNDCLASSEX),改变窗口类的特征。仅影响窗口类新创建的窗口实例,不会影响窗口过程地址修改前已经创建的窗口。超类化只能改变用户自创的窗口的特性,不能用于系统创建的窗口(如对话框上的标准按钮)。超类话过程示例如下:
WNDCLASSEX wc;
wc.cbsize=sizeof(wc);
GetClassInfoEx(hinst,"XXXX",&wc); //hinst---定义窗口类XXXX的模块的句柄,如为系统定义的窗口类(如: Edit,Button)则hinst=NULL
wc.lpszClassName="YYYY";//必须改变窗口类的名字
wc.hbrBackground=CreateSolidBrush(RGB(0,0,0));
wc.lpfnWndProc=NewWndProc;//改变窗口过程
RegisterClassEx(&wc);
MFC的CWindowImplBaseT::SubclassWindow用于动态地把一个窗口实例绑定到当前的CWnd对象,消息循环首先调用CWnd对象的窗口过程,传递给基类的消息将被默认的窗口过程处理。CWnd::SubclassDlgItem用于把对话框的一个控件子类化绑定到一个基于CWnd的类对象。CWindowImplBaseT::UnsubclassWindow恢复一个被子类化的窗口。
模板类CWindowImplBaseT提供一个数据成员WNDPROC m_pfnSuperWindowProc并且初始化为 ::DefWindowProc.然而在窗口超类化处理时它存储了已注册窗口类的窗口过程,在窗口子类化时它保存窗口实例句柄原有的窗口过程。
CWnd::CreateEx在创建窗口前调用SetWindowsHookEx函数安装了一个钩子函数_AfxCbtFilterHook。窗口刚创建好,钩子函数_AfxCbtFilterHook就被调用。_AfxCbtFilterHook调用SetWindowLong将窗口过程替换为AfxWndProcBase,并将SetWindowLong返回的原窗口地址保存到成员变量oldWndProc。可见,通过CWnd::CreateEx创建的所有窗口都会被子类化。在DefWindowProc函数中,消息会传给子类化时保存的原窗口地址oldWndProc。
ATL提供DECLARE_WND_SUPERCLASS来支持超类化。
使用Windows API函数CreateWindowEx,可以指定创建的窗口的类型:
GetParent函数,对于子窗口返回其父窗口句柄;对于弹出窗口,返回拥有者窗口句柄;对于层叠窗口,返回0.
GetWindow函数,指出GW_OWNER参数,则可以返回弹出窗口或层叠窗口的拥有者窗口句柄。
FindWindowEx函数,用于找到指定父窗口、指定子窗口的下一个子窗口。
WNDCLASS中cbClsExtra和cbWndExtra,分别用于指定附加于窗口类与窗口实例的额外存储空间字节大小,不能超过40字节。分别类似于C++类中的static变量与类似于C++类中的成员变量。
GetClassLong(hwnd,GCL_CBCLSEXTRA)获取的是类附加空间的大小,即cbClsExtra的值。GetClassLong(hwnd,GCL_CBWNDEXTRA)获取的是窗口附加空间的大小,即cbWndExtra的值。
使用方法:
其它相关Windows API有:GetWindowWord、GetWindowLongPtr、SetWindowWord、SetWindowLongPtr。
常见的窗口系统:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.