一个运用程序窗口常日包含标题栏、菜单栏、系统菜单、最小化框、最大化框、可调边框、滚动条等
窗口可以分为客户区和非客户区,客户区是窗口的一部分,运用程序常日在客户区中显示笔墨或绘制图形。而标题栏、菜单栏、系统菜单、最小化和最大化,可调系统边框为窗口的非客户区,他们由windows来管理,而运用程序则紧张管理客户区的外不雅观及操作。
窗口可以有一个父窗口,有父窗口的窗口称为子窗口,其余,对话框和框也是一种窗口,在对话框上面还包含许多子窗口,这些子窗口的形式有按钮、单选按钮、复选框、组框、文本编辑框等。
此外,在我们启动Windows系统后,我们的桌面也是一个窗口,称为桌面窗口,是位于最上层的窗口,由Windows系统创建和管理。
2 窗口句柄当用你CreateWindow创建了一个窗口,这个窗口实在并不是你创建的,而是系统替你的创建的,系统为创建这个窗口,它必须要保留很多的和这个窗口干系的数据,这些数据并不是给你用的,而是系统用来掩护窗口用的,而句柄便是系统用来找到这个窗口干系数据的一人索引。你向一个API供应一个句柄,比如ShowWindow(HWND);要显示这个窗口,这个事情还是系统替你做的,它根据你供应的索引,也便是句柄,找到窗口,然后进行干系的处理。以是说,句柄是干系工具的唯一索引。从这一点上看,有点像指针,但是指针的内容是工具的地址,而句柄并不是地址,句柄只是一个索引,一个整数。
句柄的本色便是一个构造体的实例。
Windows系统中有许多内核对象(这里的工具不完备等价于\"大众面向工具程序设计\公众一词中的\"大众工具\"大众,虽然本色上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些主要的工具肯定不是4个字节或者8个字节足以完备描述的,他们拥有大量的属性。为了保存这样一个\公众工具\公众的状态,每每须要上百乃至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间通报这些数据呢?拖着这成百上千的字节拷贝来拷贝去吗?显然会摧残浪费蹂躏效率。那么怎么办?当然通报这些工具的首地址是一个办法,但这至少有两个缺陷:
I 暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修正工具地内部状态(首地址都知道了,还有什么不能改的?),这显然是操作系统内核所不许可的;
II 操作系统有定期整理内存的任务,如果一些内存整理过一次后,工具被搬走了怎么办?
以是,Windows操作系统就采取进一步的间接:在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的工具,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。
在Windows系统中,这个编号就叫做\公众句柄\"大众。
在Windows运用程序中,窗口是通过句柄HWND来标识的,我们要对某个窗口进行操作,首先就要获取到这个窗口的句柄。
每个窗口在被创建出来之后就会被授予一个句柄,该句柄指向一个数据构造体,构造体里明确表示着该窗口的各种信息,窗口大小,窗口名等,当我们得到这个句柄时就可以要求操作系统对它做一系列操作,列如:移动窗口,关闭窗口,最小化最大化等,这些都是通过窗口句柄来见告操作系统的,我们要对哪个窗口进行操作,而则是见告操作系统要做什么样的操作,的附加参数便是操作值,列如移动窗口,会有附加的xy坐标参数!
句柄有Windows句柄,文件句柄,分配内存句柄,图形句柄等,系统在创建这次资源的时候回为其分配内存,并返回标识这些资源的标识号,这个标识号便是句柄,实际上,我们可以将句柄看做是指针。
在利用句柄之前,必须先创建他们,当不在利用时,应该及时销毁,如果不销毁他们,终极将到时资源透露,资源透露有可能导致系统崩溃,以是,务必确保在适当的时候销毁不在利用的句柄。
其余,程序运行时也因此进程存在,进程也是用ID或句柄去标识。
进程创建时,windows系统为进程布局了一个句柄表。当该进程希望得到一个内核对象句柄或者创建一个内核对象从而得到该工具句柄时。系统会将在句柄表中增加一个表项,表项的内容中存储了指向目标内核对象的指针。同时,系统返回这个表项在句柄表中的索引作为句柄。这样,进程就通过句柄查询句柄表得到工具指针,从而可以访问该工具。同时又由于有了句柄表的保护,可以防止对内核对象的造孽操作。
3 Windows工具和MFC工具的差异windows工具并不是我们平时所说的“面向工具”程序设计中的“类的工具”,而是一种windows资源实体,如画笔、字体等。
如果想要去利用这些windows工具我们须要用句柄来标识它们。
而MFC工具则是真正的“面向工具”思想中的“类的工具”(必须用布局函数去创建)。
在windows编程中,除了普通的“类的工具”外,用得最多的“C++类的工具”该当是MFC工具了(如果你是用MFC编程的话),
MFC工具是指“封装了windows工具的C++工具”(也便是MFC工具中有一个掌握window工具的掌握器,那么掌握器想事情就得和一个window工具链接起来,这样就能掌握器就能掌握这个工具了)。
所谓Windows工具是Win32下用句柄表示的Windows操作系统工具;
所谓MFC工具便是C++工具,是一个C++类的实例.
一个MFC窗口工具是一个C++ CWnd类(或派生类)的实例,是程序直接创建的。
在程序实行中它随着窗口类布局函数的调用而天生,随着析构函数的调用而消逝。
而Windows窗口则是Windows系统的一个内部数据构造的实例,由一个“窗口句柄”标识,Windows系统创建它并给它分配系统资源。
Windows窗口在MFC窗口工具创建之后,由CWnd类的Create成员函数创建,“窗口句柄”保存在MFC窗口工具的m_hWnd成员变量中。
Windows窗口可以被一个程序销毁,也可以被用户的动作销毁。
MFC中的窗口类,便是C++类与Windows窗口的句柄的结合。在基于CWnd继续而来的所有类中,都有一个公有的成员变量m_hWnd,这个成员变量便是窗口工具关联的windows窗口句柄。我们在类中可以直策应用这个窗口句柄成员变量。这个窗口工具便是标准的C++工具。实在MFC窗口类并不神奇,便是包装了一下API而已。m_hWnd的类型便是HWND。MFC给CWnd供应了两个成员函数Attach(HWND hWndNew )和Detach()。前者传入一个窗口句柄,将该窗口关联到C++工具,后者则是将当前关联的窗口解关联。而关联便是给m_hWnd赋值,解关联便是将m_hWnd设置为NULL。解关联后,窗口工具就不关联任何窗口了,此时就不能实行窗口干系的任何操作,都会失落败。如果要关联新的窗口,只要实行Attach函数即可。
4 对话框控件相应函数中可以直接调用的函数4.1 MFC全局函数,如:
AfxMessageBox 显示一个框
AfxGetApp 返回运用程序工具CWinApp的一个指针
AfxGetAppName 返回运用程序的名称
AfxInitRichEdit 为运用程序初始化RichEdit控件
4.2 API函数,如:
SendMessage(),调用一个窗口的窗口函数,将一条发给那个窗口;
OpenFile() 这个函数能实行大量不同的文件操作;
RegCreateKey() 在指定的项下创建或打开一个项;
GetCaretPos() 判断插入符确当前位置;
ShellExecute() 用指定程序打开指定路径下的文件;
4.3 其父类定义的成员函数,如CWnd类:
PreSubclassWindow()
在调用SubclassWindow之前,许可其它必要的子类化事情
FromHandle()
当给定一个窗口的句柄时,返回CWnd工具的指针。如果没有CWnd工具与这个句柄相连接,则创建一个临时的CWnd工具并与之相连接
GetSafeHwnd
返回m_hWnd,如果该指针为NULL,则返回NULL
etFocus()
哀求输入焦点
SetWindowPos()
改变子窗口、弹出窗口和顶层窗口的大小、位置以及顺序
GetClientRect
得到CWnd客户区域的大小
GetDlgItem(),
得到指定的对话框中具有指定ID的控件
UpdateData()
初始化对话框或得到对话框中的数据
SetWindowText()
将窗口的文本或标题笔墨(如果有)设为指定的文本
SetWindowText
将窗口的文本或标题笔墨(如果有)设为指定的文本
SetTimer()
安装一个别系定时器,当它被激活时,发送一个WM_TIMER
MessageBox()
创建并显示一个窗口,个中包含了运用程序供应的和标题
SendMessage()
向CWnd工具发送一个,直到这条被处理之后才返回
OnPaint()
调用这个函数以重画窗口的一部分
OnLButtonDown()
当用户按下鼠标左键时调用这个函数
OnTimer()
当达到SetTimer指定的韶光间隔时调用这个函数
4.4 继续关系不同的GetDlgItem()
1) CWindow::GetDlgItemHWND GetDlgItem(int nID)const;2) CWnd::GetDlgItemCWnd GetDlgItem(int nID) const;void CWnd::GetDlgItem( int nID, HWND phWnd) const;3)Windows SDKHWND GetDlgItem(HWND hDlg,int nIDDlgItem);5 窗口句柄和指针利用的场合
先看下面的两行代码,大略理解一下窗口句柄和指针的一个利用场合:
5.1 API函数以句柄为参数
CString str = \"大众在编辑框上显示给定文本。\"大众;SendMessage(GetActiveWindow()->GetDlgItem(IDC_textbox)->m_hWnd, WM_SETTEXT , 0 , (LPARAM)str.GetBuffer(0));
此代码可以在当前活动窗口的IDC_textbox文本框控件中显示一个字符串str。
① API函数SendMessage()功能:将指定的发送到一个或多个窗口。
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)
hWnd:其窗口程序将吸收的窗口的句柄。如果此参数为HWND_BROADCAST,则将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但不被发送到子窗口。
Msg:指定被发送的。
wParam:指定附加的特定信息。
IParam:指定附加的特定信息。
返回值:指定处理的结果,依赖于所发送的。
② CWnd类方法GetDlgItem(IDC_textbox),能够返回一个MFC指针CWnd;
③ CWnd类方法GetActiveWindow(),可以返回当前窗口的一个HWND句柄;
④ “->m_hWnd”是将一个指针转换为句柄。一样平常窗口工具都会有一个其对应的句柄变量,以是我们可以取此工具的m_hWnd属性来得到句柄。
5.2 MFC工具指针调用成员函数
下面的的代码也是在编辑框上显示给定文件:
CString str = \"大众在编辑框上显示给定文本。\"大众;CEdit edit1=(CEdit)GetDlgItem(IDC_EDIT2);edit1->SetWindowText(str);
GetDlgItem()可以返回一个MFC指针CWnd,并用(CEdit)做了下类型转换,然后就可以利用CEdit类的成员函数,例如SetWindowText()。
5.3 API函数利用句柄作为参数
CString str = \公众F:\\help\\list.html\"大众;API函数ShellExecute(this->m_hWnd, \公众open\公众, str,\"大众\公众, NULL, SW_SHOW);
this->m_hWnd; //返回的便是窗口类自己的句柄呢,也可以用MFC全局函数:
AfxGetMainWnd()->m_hWnd;
6 窗口ID和指针对MFC编程来说,对话框和控件都可以理解为一个子窗口,都有对应的一个ID和类。可以返回对应的工具指针。
7 得到窗口句柄的方法HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)
HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)
HWND WindowFromPoint(POINT& Point)//获得当前鼠标光标位置的窗口HWND
在任何类中得到运用程序类
HWND AfxGetInstanceHandle()
获取当前活动窗口句柄
HWND GetActiveWindow(VOID)
获取前台窗口句柄
HWND GetForegroundWindow(void);
得到对话框中某控件的句柄
HWND GetDlgItem(m_hDLG,m_nID_DlgItem);
得到GDI工具的句柄
HWND m_hGDIObj = m_pGDIObj->GetSafeHanle();
8 获取窗口指针的办法① 获取当前运用进程的指针
AfxGetApp();
② 得到主框架窗口指针(任何时候都可以用,只假如MFC程序中)
CWnd pWnd = AfxGetMainWnd();
③ 得到对话框中控件指针
CWnd pWnd = GetDlgItem(IDC_xxx);
可以逼迫转换为详细类型,如CEdit edit1 = (CEdit)GetDlgItem(IDC_xxx);
④ 得到工具栏指针
CToolBar pToolBar=(CtoolBar)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
9 窗口、控件的指针和句柄的相互转化① 指针转化为句柄
在MFC运用程序中首先要得到窗口的指针,然后将其转化为句柄
CWnd pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到资源管理器HWND hwnd = pwnd->m_hwnd; //得到它的HWND
这样的代码当开始得到的pwnd为空的时候就会涌现一个“General protection error”,并关闭运用程序,由于一样平常不能对一个NULL指针访问其成员,如果用下面的代码:
CWnd pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到资源管理器HWND hwnd = pwnd->GetSafeHwnd(); //得到它的HWND
就不会涌现问题,由于只管当pwnd是NULL时,GetSafeHwnd仍旧可以用,只是返回NULL
② 句柄转化为指针
在MFC运用程序中首先用GetDlgItem()得到对话框控件的句柄,然后得到其指针:
HANDLE hWnd;GetDlgItem(IDC_xxx,&hWnd);CWnd pWnd=CWnd::FromHandle(hWnd);pWnd->Attach(hWnd); //Attaches a Windows to a CWnd object
// 用FindWindow()得到一个窗口句柄,然后转换为容器指针
HWND hWnd=::FindWindow(NULL,_T(\"大众IDD_Assistants\"大众)); //得到对话框的句柄CAssistantsDialog pWnd= (CAssistantsDialog)CAssistantsDialog::FromHandle(hWnd); //由句柄得到对话框的工具指针pWnd- >xxx( ); //调用CDialog中的函数xxx();10 窗口、控件的指针和句柄与其ID的相互转化
ID->句柄,hWnd = ::GetDlgItem(hParentWnd,id);
ID->指针,CWnd::GetDlgItem();
句柄->ID,id = GetWindowLong(hWnd,GWL_ID);
指针->ID,id = GetWindowLong(pWnd->GetSafeHwnd,GWL_ID);
HICON->ID,HICON hIcon = AfxGetApp()->LoadIcon(nIconID);
ID->HICON,HICON hIcon = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(nIconID));
-End-