MFC子窗体向父窗体传递参数的几种方法
- 格式:docx
- 大小:15.49 KB
- 文档页数:3
1.WS_EX_ACCEPTFILES = 0x00000010指明了一个已创建视窗具有拖拽文件功能(指定以该风格创建的窗口接受一个拖拽文件)2.WS_EX_APPWINDOW = 0x00040000强制一个可见的顶级视窗到工具栏上(当窗口可见时,将一个顶层窗口放置到任务条上)3.WS_EX_CLIENTEDGE = 0x00000200使一个视窗具有凹陷边框(指定窗口有一个带阴影的边界)4.WS_EX_COMPOSITED = 0x02000000Windows XP:将一个窗体的所有子窗口使用双缓冲按照从低到高方式绘制出来,参阅remark项.如果这个视窗已经使用经典样式中的下列值CS_OWNDC , CS_CLASSDC,WS_EX_CONTEXTHELP.此参数将不能使用.这个样式的视窗在标题栏上有一个问号,当拥护点击着个问号,鼠标变成一个问号,如果用户然后点击一个子窗口,子窗就会收到一条WM_HELP消息.子窗口将把这个消息传递给他的父进程,这个父进程将用HELP_WM_HELP命令调用WinHelp函数.这个帮助程序常常弹出一个典型的包含其子窗口的帮助的窗口本参数不能和WS_MAXIMIZEBOX ,WS_MINIMIZEBOX一起使用.5.WS_EX_CONTEXTHELP = 0x00000400在窗口的标题条包含一个问号标志。
当用户点击了问号时,鼠标光标变为一个问号的指针、如果点击了一个子窗口,则子窗口接收到WM_HELP消息。
子窗口应该将这个消息传递给父窗口过程,父窗口再通过HELP_WM_HELP命令调用WinHelp函数。
这个Help应用程序显示一个包含子窗口帮助信息的弹出式窗口。
WS_EX_CONTEXTHELP不能与WS_MAXIMIZEBOX和WS_MINIMIZEBOX 同时使用。
6.WS_EX_CONTROLPARENT = 0x00010000这个窗体本身包含了参与对话框导航的子窗口.如果使用了这个参数,对话框管理器进入这个窗体的子窗口,当执行导航操作时,比如按住TAB键,方向键.(允许用户使用Tab键在窗口的子窗口间搜索)7.WS_EX_DLGMODALFRAME = 0x00000001创建一个具有双边框的窗口,这个窗口可以通过使用WS_CAPTION样式被创建成具有一个标题栏的窗口.(创建一个带双边的窗口;该窗口可以在dwStyle 中指定WS_CAPTION风格来创建一个标题栏。
移动标准窗口是通过用鼠标单击窗口标题条来实现的,但对于没有标题条的窗口,就需要用鼠标单击窗口标题条以外区域来移动窗口。
有两种方法可以达到这一目标。
方法一:当窗口确定鼠标位置时,Windows向窗口发送WM_NCHITTEST消息,可以处理该消息,使得只要鼠标在窗口内,Windows便认为鼠标在标题条上。
这需要重载CWnd类处理WM_NCHITTEST消息的OnNcHitTest函数,在函数中调用父类的该函数,如果返回HTCLIENT,说明鼠标在窗口客户区内,使重载函数返回HTCAPTION,使Windows误认为鼠标处于标题条上。
下例是使用该方法的实际代码:UINT CEllipseWndDlg::OnNcHitTest(CPoint point){// 取得鼠标所在的窗口区域UINT nHitTest = CDialog::OnNcHitTest(point);// 如果鼠标在窗口客户区,则返回标题条代号给Windows// 使Windows按鼠标在标题条上类进行处理,即可单击移动窗口return (nHitTest==HTCLIENT) ? HTCAPTION : nHitTest;}方法二:当用户在窗口客户区按下鼠标左键时,使Windows认为鼠标是在标题条上,即在处理WM_LBUTTONDOWN消息的处理函数OnLButtonDown中发送一个wParam参数为HTCAPTION,lParam为当前坐标的WM_NCLBUTTONDOWN消息。
下面是使用该方法的实际代码:void CEllipseWndDlg::OnLButtonDown(UINT nFlags, CPoint point){// 调用父类处理函数完成基本操作CDialog::OnLButtonDown(nFlags, point);// 发送WM_NCLBUTTONDOWN消息// 使Windows认为鼠标在标题条上PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x, point.y)); //或SendMessage(WM_SYSCOMMAND,0xF012,0); //0xF012 = SC_MOVE | HTCAPTION}首先,看看在正常情况下系统是怎样来移动程序窗口的。
mfc 中nm_rclick的用法在MFC中,nm_rclick是指当用户右键点击某个控件时触发的消息。
nm_rclick 是通过向父窗口发送NM_RCLICK消息来实现的。
下面将详细介绍nm_rclick 的用法。
首先,需要了解一些基本概念。
在MFC中,控件是通过CWnd类的派生类来表示的,处理控件的消息一般是在父窗口中进行的。
通过向父窗口发送消息的方式来实现对控件的操作。
当用户在控件上右键点击时,控件会发送一条NM_RCLICK消息给父窗口。
父窗口可以通过处理该消息来执行相应的操作。
nm_rclick消息的处理方式有两种:消息映射和自定义处理。
一、消息映射的方式:在父窗口的消息映射表中添加对NM_RCLICK消息的映射。
示例如下:ON_NOTIFY(NM_RCLICK, IDC_LIST, OnRclickList)上述代码表示当ID为IDC_LIST的列表控件接收到NM_RCLICK消息时,调用OnRclickList函数进行处理。
在OnRclickList函数中可以对右击事件进行相应的处理,例如显示一个右键菜单或执行其他操作。
void CMyDialog::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult) {处理右键点击事件TODO: 添加代码*pResult = 0;}二、自定义消息处理的方式:在父窗口中重载PreTranslateMessage函数,在该函数中判断是否接收到了NM_RCLICK消息,并进行相应的处理。
示例如下:BOOL CMyDialog::PreTranslateMessage(MSG* pMsg){if (pMsg->message == WM_RBUTTONDOWN){HWND hWnd = ::GetForegroundWindow();CWnd* pWnd = CWnd::FromHandle(hWnd);if (pWnd != NULL && pWnd->GetDlgCtrlID() == IDC_LIST){处理右键点击事件TODO: 添加代码return TRUE; 拦截消息}}return CDialog::PreTranslateMessage(pMsg);}上述代码中,首先判断当前接收消息的窗口是否为打开的对话框,并且判断窗口ID是否为IDC_LIST,表示列表控件。
c语言函数调用时参数传递方式的有哪几种,分别简述他们的传
递方式
C语言函数调用时参数的传递方式主要有以下几种:
1. 值传递:函数调用时,将实际参数的值复制给形式参数,函数内部对形式参数进行修改不会影响实际参数的值。
这是最常见的参数传递方式。
2. 引用传递:通过传递变量的指针作为参数,函数内部可以直接通过指针访问和修改实际参数的值。
这种方式可以实现在函数内部改变实参的值。
3. 地址传递:传递变量的地址作为参数,在函数内部通过指针来访问和修改实际参数的值。
和引用传递类似,通过地址传递也可以改变实参的值。
4. 数组传递:将数组的首地址作为参数传递给函数,函数内部可以通过指针来访问和修改数组的元素。
5. 结构体传递:将整个结构体作为参数传递给函数,在函数内部可以直接访问和修改结构体中的成员。
需要注意的是,C语言中的参数传递都是按值传递的,包括引
用传递和地址传递。
所谓按值传递,是指在函数调用时将实参的值复制给形参,函数内部对形参的操作不会影响到实参的值。
但是通过引用传递和地址传递,可以通过指针来访问和修改实参的值,使得函数可以改变实参的值。
MFC 消息类型(详解)1、命令消息(WM_COMMAND)所有派生自 CCmdTarget 的类都有资格接受WM_COMMAND。
2、Window消息(WM_xxx)所有派生自 CWnd 的类都有资格接受 WM_xxx。
3、控件消息(WM_NOTIFY)控件向其父窗口通知消息。
三、消息处理1、WM_xxx 消息处理窗口类(自身)处理→基类处理→CWnd∷DefWindowProc()处理;其所对应的宏一般为在消息 WM_ 前面加上 ON_。
2、命令消息处理命令消息来自命令用户接口对象(菜单、加速键或工具栏按钮)发出的WM_COMMAND消息;㈠、WM_COMMAND消息其所包含的类型和对应的宏如下:①、ON_COMMAND(ID,pfn)标准的命令消息;②、ON_COMMAND_EX(ID,pfn)多个对象对同一个命令 ID 的处理;其函数的原型如下:afx_msg BOOL pfn(UINT nID)说明:当返回 TRUE 时表示已经处理,不用在消息处理链中继续处理该命令;为 FALSE 时表示继续在消息处理链中处理该命令。
注意:其一:在多对象处理中一定要使用该宏;其二:pfn(UINT nID)(消息处理函数)返回值将其类型void改成BOOL,而且必须为FALSE;其三:多个对象的处理是由高层向低层的过程:即视图类→主框架窗口类→应用程序类;③、ON_COMMAND_RANGE(nID,nLastID,pfn)多个命令 ID 提供相同的处理;注意:其一:确保nID、nLastID的值在 Resource.h 中是连续的。
其二:一般在函数 pfn(UINT nID) 中加入参数,用来确定那一个按钮点击。
㈡、CN_UPDATE_COMMAND_UI消息当菜单项、工具栏按钮等[命令用户接口对象]要更新其状态时所对应的消息,它所包含的类型和对应的宏如下:①、ON_UPDATE_COMMAND_UI(ID,pfn)其中函数的原型如下:afx_msg void pfn(CCmdUI* pCmdUI)②、ON_UPDATE_COMMAND_UI_RANGE(nID,nLastID,pfn)该函数可以处理一组[命令用户接口对象]的外观;其中函数的原型如下:afx_msg void pfn(CCmdUI* pCmdUI)重要:CCmdUI 中的 m_nID 成员表示不同的 ID,因此可以利用它来进行区别处理。
mfc 线程afxbeginthread基本用法,传多个参数===========MFC(Microsoft Foundation Classes)是微软提供的一个用于开发Windows应用程序的类库,它提供了许多方便的类和函数,用于简化Windows应用程序的开发。
在MFC中,线程是常用的概念之一,用于在程序中实现多任务处理。
`AfxBeginThread`函数是MFC中用于创建新线程的函数,它可以接受多个参数,用于指定线程的参数和回调函数。
一、基本用法------`AfxBeginThread`函数的原型如下:```cppvoid AFXAPI AfxBeginThread(DWORD (CALLBACK* lpfn)(void*),void* lpParam);```其中,`lpfn`是一个指向线程函数的指针,它接受一个`void*`类型的参数,并返回一个`DWORD`类型的结果。
`lpParam`是一个指向线程函数的参数的指针。
下面是一个简单的示例,演示了如何使用`AfxBeginThread`函数创建新线程,并传递多个参数:```cppvoid MyThreadFunction(void* param){// 在这里实现线程函数逻辑// 可以通过传递的参数进行相应的处理// ...}int main(){// 创建新线程,并传递多个参数DWORD threadId;CWinThread* pThread = AfxBeginThread(MyThreadFunction, NULL, 1, "MyThread", &threadId);if (pThread){// 线程创建成功,可以进行相应的操作...}else{// 线程创建失败,可以处理错误情况...}return 0;}```在上面的示例中,我们创建了一个新线程,并传递了四个参数:`MyThreadFunction`是线程函数的指针,`NULL`是线程函数的参数(因为这里没有需要传递的参数),`1`是线程ID,最后一个参数是线程的名称(可选)。
MFC控件使用说明书未央1117 2018-04-19 10:10:18VC++控件工具箱:2 按钮(Button):用来接收用户的命令,应用程序在接收到用户命令后,通常需要进行一些后台工作。
按钮可以响应单击或双击动作,在按钮接收到鼠标动作后,向其父窗口发送相应的控件通知,用户可以对这些控件通知进行消息映射,从而进行相应的处理。
在一个对话框中,可以定义一个默认按钮,这只要选中按钮属性中的“Default”选项。
如果在对话框活动的时候按下了Enter键,则等同于单击了默认按钮。
MFC提供了CButton类支持按钮控件。
3 复选框(Check Box):用来显示某种可能的选择,该项选择是独立的,用户可以选中或取消该选项。
在选项被选中的时候核选标记出现,选项被取消时核选标记消失。
MFC中由CButton类对核选框进行支持,用户可以通过SetCheck()函数和GetCheck()函数设置或获取核选框当前的状态。
[cpp]1.BST_UNCHECKED==((CButton*)GetDlgItem(IDC_CHECK_ RES1))->GetCheck()[cpp]1.((CButton*)GetDlgItem(IDC_CHECK_RES1))->SetCheck(true);4 编辑框(Edit Control):用来接收用户输入的字符串。
通过选择编辑框的选项,编辑框可以接收字符串、数字、密码等;编辑框还可以设置成接收多行字符串的模式;可以自动进行大小写转换。
编辑框可能向其父窗口发送多种控件通知,如果用户需要,可以对这些控件通知进行处理。
MFC提供了CEdit类支持编辑框控件。
[cpp]1.GetDlgItem(IDC_***)->SetWindowT ext(Cstring);2.GetDlgItem(IDC_***)->GetWindowText(Cstring);5 组合框(Combo Box):列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。
用户自定义消息SendMessage的使用这里主要讲一下mfc中SendMessage的使用方法。
传递消息主要分4步:1.在类的定义中声明消息函数:afx_msg void AAA();2.在相应的cpp文件中的MESSAGE_MAP区域内添加ON_MESSAGE(MESSAGE_ID,AAA),其中参数1为要传递消息的ID,参数2为刚刚声明的函数名称,不用带括号。
3.实现消息函数:在cpp文件中添加LRESULT 类名::AAA(WPARAM wparam,LPARAM lparam){执行内容……return 0;}4.发送消息:在需要发送消息的地方添加下列语句:HWND hWnd = ::FindWindowEx( m_hWnd, NULL, NULL, WINDOW_TEXT ) ;FromHandle(hWnd)->SendMessage(MESSAGE_ID,a,b);其中,m_hWnd为接收消息的父窗口的句柄,WINDOW_TEXT为接收消息窗口的标题,得到的hWnd为接收消息窗口的句柄。
调用该窗口的SendMessage 函数,MESSAGE_ID为刚刚设定的消息ID,a和b是要传递的参数。
注:在这4个步骤中,前三个我在做的时候基本没什么障碍。
问题主要出现在第4步。
开始找到网上的例子给的都是FindWindow函数,怎么用都不好使。
后来看到有人说FindWindow是找操作系统下打开的窗口的句柄,找窗口中子窗口要用FindWindowEx函数。
我也尝试过用对话框的ID找到相应的句柄,像GetDlgItem(ID)函数一样,未果。
我使用的对话框都是没有标题栏的,所以也就没有窗口的标题,当然这并不会影响我设置标题。
只要在生成该窗口的区域内添加SetWindowText(“窗口标题”)就可以了。
也就是说窗口标题可以设置,但是不会显示。
最后一点在SendMessage()函数中,MFC默认传递的参数是WPARAM和LPARAM型(一个是UINT型,一个LONG型),如果要传递浮点类型,或者其它不是整数的类型,就可以用指针的形式传递(如果发送方只是申请一个变量并以地址的形式传递,然后接收方以指针的形式接收,如果在执行完SendMessage 之后原函数体立即结束了,我不知道在接收函数体接收和使用该变量的之间的一瞬间,该内存区域会不会被占用,我觉得还是有这种可能的。
使用Windows标准控件我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对话框或其它窗口中充当与用户交互的元素。
在Visual C++中,可以使用的控件分成三类:(1) Windows标准控件Windows标准控件由Windows操作系统提供,在Windows 95中还提供了一些新增的控件。
所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。
Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。
表6.1 Windows标准控件续表6.1前面提到过,在MFC中,类CWnd是所有窗口类的基类,很自然的,它也是所有控件类的基类。
Windows标准控件在以下环境下提供:•Windows 95•Windows NT 3.51及以后版本•Win32s 1.3•注意:•Visual C++ 4.2及以后版本不再支持Win32s。
(2) ActiveX控件ActiveX控件可用于对话框中,也可用于HTML文档中。
这种控件过去被称为OLE 控件。
本书将在专门的章节中来讲述关于ActiveX控件的知识。
这里仅指出ActiveX控件使用了与标准控件完全不同的接口和实现方法。
(3) 其它MFC控件类除了Windows标准控件和自己编写的或者来自于第三方软件开发商的ActiveX 控件以外,MFC还提供了另外三种控件,它们由下面的三个类进行封装:•类CBitmapButton用于创建以位图作为标签的按钮,位图按钮最多可以包括四个位图图片,分别代表按钮的四种不同状态。
•类CCheckListBox用于创建选择列表框,这种列表框中的每一项前面有一个复选框,以决定该项是否被选中。
•类CDragListBox用于创建一种特殊的列表框,这种列表框允许用户移动列表项。
在本章我们仅讲述第一类控件,即Windows标准控件。
所涉及的内容包括各个控件的使用及相应的技巧。
MFC隐藏和显示一个控件的方法在MFC中,可以通过以下几种方法隐藏和显示一个控件。
1. 使用SetWindowPos函数可以使用CWnd::SetWindowPos函数来隐藏和显示一个控件。
此函数用于移动和调整窗口或控件的大小。
要隐藏一个控件,可以将SWP_HIDEWINDOW标志传递给该函数的nFlags参数。
要显示一个控件,可以将SWP_SHOWWINDOW标志传递给nFlags参数,如下所示:```//隐藏一个控件GetDlgItem(IDC_CONTROL_ID)->ShowWindow(SW_HIDE);//显示一个控件GetDlgItem(IDC_CONTROL_ID)->ShowWindow(SW_SHOW);```2. 使用ShowWindow函数使用CWnd::ShowWindow函数也可以隐藏和显示一个控件。
该函数接受一个参数nCmdShow,指定要采取的操作,可以使用SW_HIDE常量隐藏一个控件,使用SW_SHOW常量显示一个控件,如下所示:```//隐藏一个控件GetDlgItem(IDC_CONTROL_ID)->ShowWindow(SW_HIDE);//显示一个控件GetDlgItem(IDC_CONTROL_ID)->ShowWindow(SW_SHOW);```3. 使用ModifyStyle函数可以使用CWnd::ModifyStyle函数来修改控件的样式。
通过修改控件的样式,可以隐藏或显示控件。
要隐藏一个控件,可以从控件样式中移除WS_VISIBLE样式;要显示一个控件,可以将该样式添加回控件中,如下所示:```//隐藏一个控件GetDlgItem(IDC_CONTROL_ID)->ModifyStyle(WS_VISIBLE, 0);//显示一个控件GetDlgItem(IDC_CONTROL_ID)->ModifyStyle(0, WS_VISIBLE);```注意:上述示例代码中的IDC_CONTROL_ID应替换为要隐藏或显示的控件的ID。
在MFC中实现子窗体向父窗体传递参数的几种方法
简述
典型问题举例
窗体和子窗体均有一个Edit控件和一个按钮,点击父窗体按钮显示子窗体;
点击子窗体按钮后,子窗体中Edit控件的值显示在在父窗体中的Edit控件中。
在MFC中实现子窗体向父窗体传递参数的几种方法
简述
1、在父窗体定义静态变量
2、传窗体的指针给子窗体
3、子窗体调用GetParent
4、向父窗体sendMessage
方法1,使用静态变量,如果有多个子对象和父对象存在时,处理比较麻
烦。
方法2, 传指针给子窗体,子窗体需要另外保存这个指针,此方法可由方
法3替代。
方法3, 比方法2优,但与方法2都与父窗体耦合较深。
方法4,推荐采用方法;采用这种方法,子窗体可以放到任何父窗体上,
只要父窗体响应此消息即可。
示例源码
通过子窗体调用GetParent向父窗体传递参数的示例
GetParent()->SetDlgItemText(IDC_EDIT1,TCHAR *)
通过向父窗体发送消息(sendMessage)来传递参数示例
SendMessage的基本结构如下
SendMessage(
HWND hWnd, //消息传递的目标窗口或线程的句柄。
UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定义,下文具体介绍,)
WPARAM wParam, //参数1 (WPARAM 其实是与UINT是同种类型的,
//在vc编译器中右键有个“转到WPARAM的定义”的选项可以查看。
LPARAM lParam); //参数2
其中一些参数的说明如下:
//typedef unsigned int UINT;
//typedef UINT WPARAM;
//typedef LONG LPARAM;
//typedef LONG LRESULT;
可以用以下语句发送消息:
::SendMessage(this->m_hWnd, WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0);
这里我发送的消息是本窗体接收的,所以句柄用:this->m_hWnd。
这里的消息类别WM_MY_DOSOME是用户自定义的,在接收消息的窗体或线程
所在的头文件里:
#define WM_MY_DOSOME WM_USER+1 // do something
当然你还可以定义更多如:
#define WM_DOOTHER WM_USER+2 // do other表示要做一些事情。
我们发了一个消息出去,那么接收方要能识别这个消息是干什么,就是通过
消息类别来区分,并且根据消息类别去调用消息处理函数。接收方需要做以下
几步:
1、在接收方编写一个消息处理函数
我们在接收窗体里定义一个消息处理函数,以处理接收到该消息后应该做
什么事情。
afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2)
{
MessageBox("收到消息了,我要开始做一些事情了。","收到",MB_OK);
//可以运用iParam1,iParam2 来做一些事情。
return 0;
}
编写消息处理函数有3点需要格外注意:
1)使用了afx_msg,并且要将afx_msg LRESULT DoSomeThing(WPARAM
iParam1,LPARAM iParam2) 改写到头文件的 {{AFX_MSG ... AFX_MSG}}包含的
灰色部分,如下:
//{{AFX_MSG
//。。。改写到这里,颜色会变成灰的。这一点非常重要。
//}}AFX_MSG
2)参数有2个,WPARAM iParam1,LPARAM iParam2,哪怕没有东西传进来
也要写,不然会吃苦头的,vc里不会提醒你少写了一个,但如果不写可能会产
生莫名奇妙的错误。
3)类型用 LRESULT,完了要return 0;
2、在接收方定义各种消息类型与消息处理函数的映射关系,即让接收方知道每
个消息要调用哪个处理函数
映射关系书写示例如下
//{{AFX_MSG_MAP
//。。。这里写上
ON_MESSAGE(WM_MY_DOSOME,DoSomeThing)
//如果还有其他消息就再写一个
ON_MESSAGE(WM_DOOTHER,DoOther)
//}}AFX_MSG_MAP
到这里,当发送方用SendMessage,发出一个WM_MY_DOSOME类型的消息过
来的时候,接收方就会去做DoSomeThing(WPARAM iParam1,LPARAM iParam2);
发送方发出一个WM_DOOTHER类型的消息过来的时候,接收方就会去做
DoOther(WPARAM iParam1,LPARAM iParam2)。
.h头文件中要定义的内容
#define WM_MYMSG WM_USER+5 //自定义一个消息
afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam); //自定义消息的处理函数声明
.cpp文件要实现的内容
ON_MESSAGE(WM_MYMSG, OnMyMessage)
//利用ON_MESSAGE()宏在自定义消息与其处理函数间建立映射关系
void CModelessDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
//从lParam中取出CString对象的指针,并将字符串内容在IDC_MSGEDIT中显示出来
{
CString *str;
str=(CString *)lParam;
SetDlgItemText(IDC_EDIT,*str);
}
按下按钮发送消息
void CModelessDlg::OnMsgBTN()
{
CString str= "自定义消息被触发了!";
SendMessage(WM_MYMSG, 0, (LPARAM) &str); //给ModelessDlg自己发一个自定义的消息
}