視窗
包含某種用戶界面的可視區域 来自维基百科,自由的百科全书
包含某種用戶界面的可視區域 来自维基百科,自由的百科全书
視窗是在使用者界面上的一個可見的範圍。視窗一般都是長方形的。它包含著各種控件,是用作輸入和輸出的界面。雖然視窗一般用於圖形使用者界面,但又有時用於命令行界面的。而一個使用視窗為主要用戶界面的系統則稱為視窗系統。這個想法源於施乐帕洛阿尔托研究中心。
在視窗系統上,視窗一般被畫成一些二維的物件,被安置在桌面之上。大多數的視窗都可以隨使用者的意願而更改大小、移動、隱藏、回復和關閉。當兩個視窗重疊的時候,就如日常生活中一樣,其中一個要位於另一個之上,而下方的則會有些地方被上方個視窗所遮蓋。而視窗系統中管理這個操作的部份,則叫做視窗管理員。
視窗是數種圖形使用者界面中的一種重要的widget。當中有VMS的DEC Windows、GNU/Unix-like系統的X Window系統、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.