MFC对话框禁止移动 使标题栏不响应鼠标消息 通过客户区移动窗体 OnNcHitTest()的实现

合集下载

MFC教程 MFC工具条和状态栏

MFC教程 MFC工具条和状态栏

13. MFC工具条和状态栏1. Windows控制窗口Windows (Windows95或者以上版本) 提供了系列通用控制窗口,其中包括工具条(ToolBar)、状态栏(StatusBar)、工具条提示窗口(ToolTip)。

Windows在一个DLL加载时注册个控制窗口的“窗口类”。

例如,工具条的“窗口类”是“ToolbarWindow32”,状态栏的“窗口类”是“msctls_statusbar32”,工具条提示窗口的“窗口类”是“tooltips_class32”。

为了保证该DLL被加载,使用控制“窗口类”前,应该首先调用函数InitCommonControl。

MFC在窗口注册函数AfxDeferRegisterClass中实现了这一点。

见2.2.1节MFC下窗口的注册。

创建通用控制窗口,可以使用专门的创建函数,如创建工具条的函数::CreateToolBarEx,创建状态栏的函数::CreateStatusBarEx。

也可以调用窗口创建函数::CreateWindowEx,但是需要指定预定义的“窗口类”,必要的话还要其他步骤,如使用“ToolbarWindow32”“窗口类”创建工具栏后,还需要在工具栏中添加或者插入按钮。

一般,通用控制可以指定控制窗口风格(Style)。

例如,具备风格CCS_TOP,表示该控制窗口放到父窗口客户区的顶部,具备CCS_BOTTOM,表示该控制窗口在客户区的底部。

具体的控制窗口类可以有特别的适合于自己的风格,例如,TTS_ALWAYSTIP表示只要光标落在工具栏的按钮上,ToolTip窗口不论激活与否都会显示出来。

每一控制窗口类都有自己的窗口过程来处理自己的窗口消息,实现特定的功能。

控制窗口类的窗口过程由Windows提供。

● 工具条工具条的窗口过程处理了必要的消息,提供了标准工具条的功能,例如,工具条对客户化特征提供内在的支持,用户可以通过一个客户化对话框来添加、修改、删除或者重新安排工具条按钮。

关于OnOK()、OnCancel()、OnClose()、OnDestroy() 模式对话框

关于OnOK()、OnCancel()、OnClose()、OnDestroy() 模式对话框

关于OnOK()、OnCancel()、OnClose()、OnDestroy() 模式对话框总结OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别(转)2009年09月22日下午08:33第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数,即WM消息响应函数。

从应用程序结构的角度,拿对话框来说,红色的X对应的是CWnd,而处于对话框中的“确定”、“取消”按钮则对应了CDialog。

第二,OnClose()和OnDestroy()在单视图程序中,根据<<深入浅出MFC>>所讲,程序退出时执行的操作顺序为(从点X按钮开始)(1)用户点击X退出按钮,发送了WM_CLOSE消息----->响应OnClose()(2)在WM_CLOSE消息的处理函数中,调用DestroyWindow()----->销毁与指定CWnd窗口对象关联的窗口,但未销毁CWnd对象(3)在DestroyWindow()中发送了WM_DESTROY消息----->窗口销毁后响应OnDestroy()(4)在WM_DESTROY消息中调用PostQuitMessage(),发送WM_QUIT消息,结束消息循环可以看到,程序的退出过程,是先响应OnClose(),然后响应OnDestroy(),在响应OnDestroy()之前,窗口对象已经被销毁。

OnDestroy()到底干了什么呢?它就像一个teller,先通知CWnd 对象告诉它即将被销毁,尔后OnDestroy的真正运行是在CWnd对象已经从屏幕上清除以后被调用的。

第三,OnOK()、OnCancel()()、OnClose()、OnDestroy()CDialog::OnOK首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框;CDialog::OnCancel只调用CDialog::EndDialog关闭对话框;OnClose()是响应WM_CLOSE 的.一定程度上可以说CDialog::EndDialog()和OnClose()完成类似的工作,但处理的机制不一样,前者是CDialog的对象机制,后者是WM 的消息映射机制。

VB禁止移动窗口

VB禁止移动窗口

VB禁⽌移动窗⼝--VB禁⽌移动窗⼝--禁⽌⼀个窗⼝被移动最简单的⽅法是设置Form的Moveable属性为False,这样就⽆法拖动标题栏来改变窗⼝的位置了,同时系统菜单的“移动”命令变成了灰⾊,除此之外,还有两种⽅法也可禁⽌移动窗⼝。

1.拦截拖动标题栏的消息当⽤户在标题栏的空⽩处上按下会产⽣WM_NCLBUTTONDOWN消息和HTCAPTION附加消息,我们可以拦截这个消息来防⽌⽤户通过拖动标题栏来移动窗⼝,此外还要拦截系统菜单的“移动”命令,所以我们还要处理WM_SYSCOMMAND消息,代码如下:'Form1中'-----------------------------------------------------------Private Sub Form_Load()Me.ShowhWindow = Me.hWndOldWindowProc = SetWindowLong(hWindow, GWL_WNDPROC, AddressOf WindowProc)End SubPrivate Sub Form_Unload(Cancel As Integer)Call SetWindowLong(hWindow, GWL_WNDPROC, OldWindowProc)End Sub'Module1中'-----------------------------------------------------------Option ExplicitDeclare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As LongDeclare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongDeclare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic Const GWL_WNDPROC = (-4)Public Const WM_NCLBUTTONDOWN = &HA1Public Const WM_SYSCOMMAND = &H112Public Const HTCAPTION = 2Public Const SC_MOVE = &HF010&Public hWindow As LongPublic OldWindowProc As Long'⼦类消息Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long'拦截拖动标题栏消息If uMsg = WM_NCLBUTTONDOWN And wParam = HTCAPTION Then Exit Function'拦截系统菜单的“移动”消息If uMsg = WM_SYSCOMMAND And wParam = SC_MOVE Then Exit FunctionWindowProc = CallWindowProc(OldWindowProc, hWnd, uMsg, wParam, lParam)End Function2.修改窗⼝结构全⾯禁⽌移动窗⼝上⾯两种⽅法都可以禁⽌移动⼀个窗⼝,但是这种⽅法只能欺骗⽤户,⽽⽆法欺骗操作系统,即它不能防⽌⽤户通过其它第三⽅⼯具来改变⼀个窗⼝的位置,如调⽤MoveWindow或SetWindowPos函数来改变⼀个窗⼝的位置,然⽽下⾯这种⽅法就可以。

(MFC)无标题栏窗口移动方法

(MFC)无标题栏窗口移动方法

移动标准窗口是通过用鼠标单击窗口标题条来实现的,但对于没有标题条的窗口,就需要用鼠标单击窗口标题条以外区域来移动窗口。

有两种方法可以达到这一目标。

方法一:当窗口确定鼠标位置时,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对话框基础要点

mfc对话框基础要点

第五章对话框对话框是一种用户界面,它的主要功能是输出信息和接收用户的输入。

对话框与控件是密不可分的,在每个对话框内一般都有一些控件,对话框依靠这些控件与用户进行交互。

一个典型的对话框例子是选择了File-Open命令后弹出的文件对话框。

5.1对话框和控件的基本概念5.1.1对话框的基本概念对话框(Dialog)实际上是一个窗口。

在MFC中,对话框的功能被封装在了CDialog类中,CDialog类是CWnd类的派生类。

对话框分为模态对话框和非模态对话框两种。

大部分读者都会有这样的经历,当你通过File-Open命令打开一个文件对话框后,再用鼠标去选择菜单将只会发出嘟嘟声,这是因为文件对话框是一个模态对话框。

模态对话框垄断了用户的输入,当一个模态对话框打开时,用户只能与该对话框进行交互,而其它用户界面对象收不到输入信息。

我们平时所遇到的大部分对话框都是模态对话框。

非模态对话框的典型例子是Windows95提供的写字板程序中的搜索对话框,搜索对话框不垄断用户的输入,打开搜索对话框后,仍可与其它用户界面对象进行交互,用户可以一边搜索,一边修改文章,这样就大大方便了使用。

本节主要介绍模态对话框,在第四节将介绍非模态对话框。

从MFC编程的角度来看,一个对话框由两部分组成:1.对话框模板资源。

对话框模板用于指定对话框的控件及其分布,Windows根据对话框模板来创建并显示对话框。

2.对话框类。

对话框类用来实现对话框的功能,由于对话框行使的功能各不相同,因此一般需要从CDialog类派生一个新类,以完成特定的功能。

5.1.2控件的基本概念图5.1对话框中的控件控件(Control)是独立的小部件,在对话框与用户的交互过程中,控件担任着主要角色。

控件的种类较多,图5.1显示了对话框中的一些基本的控件。

MFC的控件类封装了控件的功能,表5.1介绍了一些常用的控件及其对应的控件类。

表5.1控件实际上都是窗口,所有的控件类都是CWnd类的派生类。

几种MFC对话框的隐藏方法

几种MFC对话框的隐藏方法

几种MFC对话框的隐藏方法有很多应用程序要求一起动就隐藏起来,这些程序多作为后台程序运行,希望不影响其他窗口,往往只在托盘区显示一个图标。

这些程序通常都是对话框程序,而对话框在初始化的过程上与SDI、MDI的初始化是不同的,对话框只需要DoModule或者是CreateDialog等等对话框函数调用一次便可,SDI、MDI则要好几步才行。

这样看来,对话框在使用方法上面是隐藏了不少细节的,其中就没有SDI、MDI所要求的ShowWindow(nCmdShow)这一步。

因此对话框要想一运行就隐藏,并不是很直接的。

有一些方法可以做到这一点,下面我们就来看看几种方案。

1.定时器最直观,又是最无奈的一个方法就是使用定时器。

既然我们在对话框开始显示之前不能用ShowWindow(SW_HIDE)将其隐藏,那就给一个时间让它显示,完了我们在隐藏它。

方法:1.在OnInitDialog()函数里设置定时器:(WINDOWS API里面响应消息WM_INITDIALOG)SetTimer(1, 1, NULL);2.添加处理WM_TIMER的消息处理函数OnTimer,添加代码:if(nIDEvent == 1){DeleteTimer(1);ShowWindow(SW_HIDE);}这种方法的缺点是显而易见的,使用定时器,使得程序的稳定性似乎打一个折扣;窗口是要先显示出来的,那么效果就是窗口闪了一下消失。

2.改变对话框显示状况在对话框初始化时改变其显示属性可以让它隐藏起来。

方法是调用SetWindowPlacement函数:BOOL CDialogExDlg::OnInitDialog(){CDialog::OnInitDialog();//DO somethingWINDOWPLACEMENT wp;wp.length=sizeof(WINDOWPLACEMENT);wp.flags=WPF_RESTORETOMAXIMIZED;wp.showCmd=SW_HIDE;SetWindowPlacement(&wp);return TRUE;}在需要显示时(通常是响应热键或者托盘图标的鼠标消息):WINDOWPLACEMENT wp;wp.length=sizeof(WINDOWPLACEMENT);wp.flags=WPF_RESTORETOMAXIMIZED;wp.showCmd=SW_SHOW;SetWindowPlacement(&wp);这样的效果很不理想:窗口显示在屏幕的左上角,并且是只有标题栏,要正常显示,还需加上如下代码:定义一个成员变量CRect rect;在OnInitDialog()里面:GetWindowRect(&rect);在需要显示的地方:SetWindowPos(&wndNoTopMost, wndRc.left, wndRc.top, w ndRc.right, wndRc.bottom,SWP_SHOWWINDOW);CenterWindow();即使这样,效果还是很差。

如何单击除了窗口标题栏以外的区域使窗口移动

如何单击除了窗口标题栏以外的区域使窗口移动

如何单击除了窗口标题栏以外的区域使窗口移动当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该信息使Windows认为鼠标在窗口标题上。

对于对话框和基于对话的应用程序,可以使用ClassWizard处理该信息并调用基类函数,如果函数返回HTCLIENT 则表明鼠标在客房区域,返回HTCAPTION表明鼠标在Windows的标题栏中。

UINT CSampleDialog : : OnNcHitTest (Cpoint point ){UINT nHitTest =Cdialog: :OnNcHitTest (point );return (nHitTest = =HTCLIENT)? HTCAPTION :nHitTest ;}上述技术有两点不利之处,其一是在窗口的客户区域双击时,窗口将极大;其二,它不适合包含几个视窗的主框窗口。

还有一种方法,当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上,使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送一个WM_NCLBUTTONDOWN信息和一个单击测试HTCAPTION。

voidCSampleView : : OnLButtonDown (UINT nFlags , Cpoint point ) {CView : : OnLButtonDow (nFlags , pont );//Fool frame window into thinking somene clicked onits caption bar .GetParentFrame ( ) —>PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARAM (poitn .x ,point .y) );}该技术也适用于对话框和基于对的应用程序,只是不必调用CWnd : : GetParentFrame 。

MFC中MessageBox使用方法

MFC中MessageBox使用方法

一函数原型及参数function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer;hWnd:对话框父窗口句柄,对话框显示在Delphi窗体内,可使用窗体的Handle属性,否则可用0,使其直接作为桌面窗口的子窗口。

Text:欲显示的信息字符串。

Caption:对话框标题字符串。

Type:对话框类型常量。

该函数的返回值为整数,用于对话框按钮的识别。

2、类型常量对话框的类型常量可由按钮组合、缺省按钮、显示图标、运行模式四种常量组合而成。

(1)按钮组合常量MB_OK = $00000000;//一个确定按钮MB_OKCANCEL =$00000001;//一个确定按钮,一个取消按钮MB_ABORTRETRYIGNORE = $00000002;//一个异常终止按钮,一个重试按钮,一个忽略按钮MB_YESNOCANCEL = $00000003;//一个是按钮,一个否按钮,一个取消按钮MB_YESNO = $00000004;//一个是按钮,一个否按钮MB_RETRYCANCEL = $00000005;//一个重试按钮,一个取消按钮(2)缺省按钮常量MB_DEFBUTTON1 = $00000000;//第一个按钮为缺省按钮MB_DEFBUTTON2 = $00000100;//第二个按钮为缺省按钮MB_DEFBUTTON3 = $00000200;//第三个按钮为缺省按钮MB_DEFBUTTON4 = $00000300;//第四个按钮为缺省按钮(3)图标常量MB_ICONHAND = $00000010;//“×”号图标MB_ICONQUESTION = $00000020;//“?”号图标MB_ICONEXCLAMATION = $00000030;//“!”号图标MB_ICONASTERISK = $00000040;//“i”图标MB_USERICON = $00000080;//用户图标MB_ICONWARNING = MB_ICONEXCLAMATION;//“!”号图标MB_ICONERROR = MB_ICONHAND;//“×”号图标MB_ICONINFORMATION = MB_ICONASTERISK;//“i”图标MB_ICONSTOP = MB_ICONHAND;//“×”号图标(4)运行模式常量MB_APPLMODAL = $00000000;//应用程序模式,在未结束对话框前也能切换到另一应用程序MB_SYSTEMMODAL = $00001000;//系统模式,必须结束对话框后,才能做其他操作MB_TASKMODAL = $00002000;//任务模式,在未结束对话框前也能切换到另一应用程序MB_HELP = $00004000;//Help Button3、函数返回值0//对话框建立失败IDOK = 1//按确定按钮IDCANCEL = 2//按取消按钮IDABOUT = 3//按异常终止按钮IDRETRY = 4//按重试按钮IDIGNORE = 5//按忽略按钮IDYES = 6//按是按钮IDNO = 7//按否按钮二用法1. MessageBox("这是一个最简单的消息框!");2. MessageBox("这是一个有标题的消息框!","标题");3. MessageBox("这是一个确定取消的消息框!","标题", MB_OKCANCEL );4. MessageBox("这是一个警告的消息框!","标题", MB_ICONEXCLAMATION );5. MessageBox("这是一个两种属性的消息框!","标题", MB_ICONEXCLAMATION|MB_OKCANCEL );6. if(MessageBox("一种常用的应用","标题" ,MB_ICONEXCLAMATION|MB_OKCANCEL)==IDCANCEL)return;注意:以上消息框的用法是在CWnd的子类中的应用,如果不是,则要MessageBox(NULL,"ddd","ddd",MB_OK); 或MessageBox(hWnd,"ddd","ddd",MB_OK);hWnd为某窗口的句柄,或者直接用AfxMessageBox。

MFC开发文档

MFC开发文档

MFC开发文档.txt7温暖是飘飘洒洒的春雨;温暖是写在脸上的笑影;温暖是义无反顾的响应;温暖是一丝不苟的配合。

8尊重是一缕春风,一泓清泉,一颗给人温暖的舒心丸,一剂催人奋进的强心剂我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对话框或其它窗口中充当与用户交互的元素。

在Visual C++中,可以使用的控件分成三类:(1) Windows标准控件Windows标准控件由Windows操作系统提供,在Windows 95中还提供了一些新增的控件。

所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。

Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。

表6.1 Windows标准控件控件MFC类描述动画CAnimateCtrl显示连续的AVI视频剪辑按钮CButton用来产生某种行为的按钮,以及复选框、单选钮和组框组合框CComboBox编辑框和列表框的组合编辑框CEdit用于键入文本标题头CHeaderCtrl位于某一行文本之上的按钮,可用来控制显示文件的宽度热键CHotKeyCtrl用于通过按下某一组合键来很快的执行某些常用的操作图象列表CImageList一系列图象(典型情况下是一系列图标或位图)的集合。

图象列表本身不是一种控件,它常常是和其它控件一起工作,为其它控件提供所用的图象列表列表CListCtrl显示文本及其图标列表的窗口列表框CListBox包括一系列字符串的列表进度CProgressCtrl用于在一较长操作中提示用户所完成的进度多格式文本编辑CRichEditCtrl提供可设置字符和段落格式的文本编辑的窗口滚动条CScrollBar为对话框提供控件形式的滚动条滑块CSliderCtrl包括一个有可选标记的滑块的窗口旋转按钮CSpinButtonCtrl提供一对可用于增减某个值的箭头静态文本CStatic常用于为其它控件提供标签状态条CStatusBarCtrl用于显示状态信息的窗口,同MFC类CStatusBar类似续表6.1控件MFC类描述选项卡CTabCtrl在选项卡对话框或属性页中提供具有类似笔记本中使用的分隔标签的外观的选项卡工具条CToolBarCtrl具有一系列命令生成按钮的窗口,同MFC类CToolBar类似工具提示CToolTipCtrl一个小的弹出式窗口,用于提供对工具条按钮或其它控件功能的简单描述树CTreeCtrl用于显示一系列的项的继承结构前面提到过,在MFC中,类CWnd是所有窗口类的基类,很自然的,它也是所有控件类的基类。

mfc,vc 禁止标题栏重绘,改变标题栏,双缓冲标题栏贴图

mfc,vc 禁止标题栏重绘,改变标题栏,双缓冲标题栏贴图

mfc,vc 禁止标题栏重绘,改变标题栏,双缓冲标题栏贴图需要在标题栏上贴图,更换标题栏背景的时候,不想要标题栏显示颜色,尤其拉动改变窗体大小的时候,所以需要禁止标题栏重绘的方法。

只需要处理WM_NCPAINT消息就好了,消息处理函数OnNcPaint中去掉CDialog::OnNcPaint(),从此世界安静了标题栏更换颜色,标题栏贴图,窗体其他位置贴图也可以用这里的贴图函数//*******************************************************************//voidCMyDlg::DrawTitleBar(CDC *pDC){CDC memDC;CBitmap bmp;CRectrect, rtTitle;CPoint point;GetClientRect(rect);//获取标题栏大小rtTitle.left = GetSystemMetrics(SM_CXFRAME);rtTitle.top = GetSystemMetrics(SM_CYFRAME);rtTitle.right = rect.right - rect.left - GetSystemMetrics(SM_CXFRAME);rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE);point.x = rect.right +GetSystemMetrics(SM_CXFRAME);point.y = 30;memDC.CreateCompatibleDC(NULL);bmp.CreateCompatibleBitmap(pDC,point.x,point.y);CBitmap *pOldBit=memDC.SelectObject(&bmp);//背景颜色memDC.FillSolidRect(0,0,point.x,point.y,RGB(125,0,125));////贴图//CBitmap pic;//pic.LoadBitmap(IDB_BITMAP1);//ShowBitmap(&memDC,0,0, rtTitle.right, 30, pic);pDC->BitBlt(0,0,point.x,point.y,&memDC,0,0,SRCCOPY);pOldBit->DeleteObject();memDC.DeleteDC();bmp.DeleteObject();}LRESULT CMyDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam){//return CDialog::DefWindowProc(message, wParam, lParam);LRESULT lrst=CDialog::DefWindowProc(message, wParam, lParam);if(message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message= =WM_NCACTIVATE ||message == WM_NOTIFY){CDC* pWinDC = GetWindowDC();if (pWinDC)DrawTitleBar(pWinDC);ReleaseDC(pWinDC);}return lrst;}voidCMyDlg::OnNcPaint(){//CDialog::OnNcPaint();}BOOL CMyDlg::OnEraseBkgnd(CDC* pDC){return TRUE;}voidCMyDlg::ShowBitmap(CDC *pDC, int x, int y, intnW, intnH, CBitmap&m_bitmap) {CDC memDc, mdc;memDc.CreateCompatibleDC(NULL);mdc.CreateCompatibleDC(NULL);CBitmapmemBitmap;memBitmap.CreateCompatibleBitmap(pDC,nW,nH);CBitmap *OldBmp = memDc.SelectObject(&m_bitmap);mdc.SelectObject(&m_bitmap);memDc.BitBlt(x,y,nW,nH,&mdc,0,0,SRCCOPY);BITMAP bm;m_bitmap.GetBitmap(&bm );//贴图//pDC->BitBlt(x, y,// x + bm.bmWidth,y + bm.bmHeight,// &MemDc,// 0, 0,// SRCCOPY);//拉伸pDC->StretchBlt(x,y, nW, nH ,&memDc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);memDc.SelectObject(OldBmp);memDc.DeleteDC();}。

MFC对话框禁止移动 使标题栏不响应鼠标消息 通过客户区移动窗体 OnNcHitTest()的实现

MFC对话框禁止移动 使标题栏不响应鼠标消息 通过客户区移动窗体 OnNcHitTest()的实现

MFC对话框禁止移动使标题栏不响应鼠标消息通过客户区移动窗体OnNcHitTest()的实现//这个函数允许我们对windows鼠标消息进行处理对于基类函数的返回值我们可以通过判断消息类型来进行不同的处理//也就是说我们可以对鼠标消息做任意处理比如是菜单栏上的消息我们可以返回标题栏的值//对应的消息类型有如下查找MSDN此函数的值有介绍UINT CMyDlg::OnNcHitTest(CPoint point){UINT nFlags= CDialog::OnNcHitTest(point); //调用基类的OnNcHitTest获得返回值if(nFlags==HTCAPTION||nFlags==HTSYSMENU) //如果鼠标消息是在标题栏上或者系统菜单栏我们就返回FALSE 不进行处理{return FALSE ;}else if(nFlags==HTCLIENT) //可以通过客户区域移动窗体但是不能通过标题栏移动return HTCAPTION ;elsereturn nFlags;}下面是一些测试枚举值::OnNcHitTestafx_msg UINT OnNcHitTest( CPoint point );返回值:下面列出的鼠标击中测试枚举值之一。

· HTBORDER 在不具有可变大小边框的窗口的边框上。

· HTBOTTOM 在窗口的水平边框的底部。

· HTBOTTOMLEFT 在窗口边框的左下角。

· HTBOTTOMRIGHT 在窗口边框的右下角。

· HTCAPTION 在标题条中。

· HTCLIENT 在客户区中。

· HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。

· HTGROWBOX 在尺寸框中。

MFC 对话框教程

MFC 对话框教程

ID 框:修改或选择对话框的标识符名称 Caption 框:输入对话框的标题名称,中英文均可。 Font 按钮:单击此按钮可选择字体的种类(如宋体)及尺寸(如 9 号) Xpos/Ypos:对话框左上角在父窗口中的 X,Y 坐标都为 0 时表示居中 Menu 框:默认值为无,当对话框需要选单时输入或选择指定的选单资源 Class name:默认值为无,它提供 C/C++语言编程时所需要的对话框类名,对 MFC 类库的资源文件来说,该项不被激活 三、控件的创建和使用方法(197 页) 控件是在系统内部定义的能够完成特定功能的控制程序单元。在应用程序中使用控件 不仅简化了编程,还能完成常用的各种功能。为了更好地发挥控件的作用,用户还必须理 解和掌握控件的属性、消息以及创建和使用方法。 注:控件工具栏及各按钮含义: 1、控件的选择 2、静态文本 3、组框 4、复选框 5、组合框 6、水平滚动条 7、旋转按钮 8、滑动条 9、列表视图 10、标签 11、复合编辑 12、月历 13、用户定制工具 14、静态图片 15、编辑框 16、按钮 17、单选框 18、列表框 19、垂直滚动条 20、进展条 21、热键 22、树形视图 23、动画 24、日期选择 25、IP 地址 26、组合框的扩展(从左边往下数,再从右边往下数)
(1)打开上个项目,在 CMyDlg 类的头文件 MyDlg.h 里添加一个按钮类 CButton 指针变量: (public:里) CButton *m_btnWnd; (2)按 Ctrl+W 或 ViewClassWizard 打开 MFClassWizard 对话框,并切换到 Message Maps 页面,在 Object IDs 列表中选定点黑 CMyDlg 项,并在 Message 列表中找到 WM_INITDIALOG 消息点黑AddFunctionEditCode (3)添加代码: BOOL CMyDlg::OnInitDialog() { ----m_btnWnd=new CButton();//构造按钮控件 //下面“”按钮上的字,创建子窗口|窗口最初是可见的|创建的是按键按钮 m_btnWnd->Create( “你好 ”,WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(20,20,120,60),this,201);//创建 CFont *font=this->GetFont();//获取对话框的字体 m_btnWnd->SetFont(font);//设置控件字体 return TRUE;//(程序原有的) } 代码中,Create 用来创建一个按钮控件,该函数的第一个参数用来指定该按钮的标题, 第二个参数用来指定控件的风格,第三个参数用来指定它在父窗口中的位置和大小,第四 个参数用来指定父窗口指针,最后一个参数是指定该控件的标识值。 WS_CHILD 表示按钮是作为对话框的一个子窗口来创建的。 WS_VISIBLE 是使控件可见。 BS_PUSHBUTTON 表示创建的是按键按钮。 (4)编译并运行 2、控件的数据交换和数据效验(数据成员) (198 页) 使用 ClassWizard 可以很容易地定义一个控件的成员变量及其数据范围。 例如: 上面的 CMyDlg 类的按钮控件 IDC_BUTTON1 添加并使用其成员变量 m_MyBtn,步骤如下: (1)打开上例项目,ViewClassWizardMember Variables选定 Class name 中为 CMyDlg,然后在 Control IDs 列表中点黑 IDC_BUTTON1AddVariable (或双击鼠标左键) ,弹出 Add Member Variable 对话框,如书 198 页图 5.17 写好数据成员名:m_MyBtn 下面 Category 和 Variables type 里的不动 OK 见表上已建成(如:书 199 页图 5.18) 下面是建成员变量的三个对话框图:

无标题栏窗口移动方法种种

无标题栏窗口移动方法种种

无标题栏窗口移动方法种种首先,看看在正常情况下系统是怎样来移动程序窗口的。

当使用者在程序窗口标题栏区域(非工作区)内,按下鼠标左键时将会发生下列事情:◆系统向该窗口过程函数发送WM_NCLBUTTONDOWN消息。

◆WM_NCLBUTTONDOWN消息最终将传送到窗口过程函数中的DefWindowProc()函数中去。

◆DefWindowProc()函数将根据鼠标左键按下并移动,以及HTCAPTION标识所表示鼠标按下时的位置诸多信息,来执行该消息的缺省动作即窗口随同鼠标光标一起移动的操作。

下面作为练习来测试一下,首先在窗口回调函数(即窗口过程函数)中设置下列语句:case WM_NCLBUTTONDOWNreturn 0;然后,同样是在窗口标题栏内按住鼠标左键并移动鼠标,但此时窗口却并不随同鼠标一起移动了,这是怎么回事?这是因为上述语句中设有“return 0”语句的缘故。

该语句使得WM_NCLBUTTONDOWN消息未能传递到DefWindowProc()函数,就在窗口过程函数中提前返回了,当然移动窗口的操作就无从进行了。

这也从反面印证了一个事实,那就是,最后完成移动窗口的操作将是由DefWindowProc()函数来完成的。

通过上面的分析可以勾划出这样一个操作过程:即用户在窗口标题栏内按下鼠标左键→系统发送WM_NCLBUTTONDOWN消息→DefWindowProc()函数接收消息→用户移动鼠标→DefWindowProc()函数执行窗口随同鼠标一起移动的操作。

由此得出一个结论,那就是要想实现移动窗口的操作,必须具备两个条件:一是要按下鼠标左键并移动(DefWindowProc()函数将检测这个条件);二是在按下鼠标左键时能发送WM_NCLBUTTONDOWN消息并返回HTCAPTION标识。

下面就根据以上的分析,在没有窗口标题栏的情况下,采取骗取DefWindowProc()函数的方式,来实现对无标题栏窗口实体的移动操作。

MFC中非模态对话框不响应PreTranslateMessage函数的解决方法

MFC中非模态对话框不响应PreTranslateMessage函数的解决方法

MFC中非模态对话框不响应PreTranslateMessage函数的解决方法程序员真心不容易啊,为了一个好的用户体验真可谓是操碎了心。

今天由于项目需要,需要在非模态对话框上,当鼠标处于某个位置的时候有提示框显示。

实现这个功能本来很简单,但是却遇到了一个郁闷的问题:PreTranslateMessage函数没响应。

于是各种度娘,可惜度娘非谷歌,找了一个小时终于在一个隐蔽的地方找到了解决方法。

首先我介绍下当鼠标处于特定位置的时候有提示信息显示的实现方法。

需要使用MFC的CToolTipCtrl控件。

1.首先在Dialog类中添加一个成员对象[cpp]view plain copy1.//消息提示框2. CToolTipCtrl m_toolTip;</span></span>1.//创建消息提示框2. EnableToolTips(TRUE);//enable use it3.BOOL bRet = m_toolTip.Create(this, TTS_ALWAYSTIP | WS_CHILD | WS_VISIBLE);4. m_toolTip.AddTool(this);5. m_toolTip.Activate(TRUE);6. m_toolTip.SetDelayTime(150);</span></span>3.捕获鼠标的移动消息OnMouseMove,当鼠标处在某一特定区域的时候,弹出消息提示框。

切换消息内容使用CToolTipCtrl::UpdateTipText函数。

[cpp]view plain copy1.void CDisplayPicDlg::OnMouseMove(UINT nFlags, CPoint point)2.{3.//如果鼠标在矩形所在区域,需要把箭头鼠标变成手型的4.int iSel = GetSelectCameraNo(point);5.if(-1 != iSel)6. {7. SetCursor(LoadCursor(NULL, IDC_HAND));8. m_toolTip.UpdateTipText(m_stMonitorCamera[iSel].szCamereName, this);9. }10.else//还原成箭头鼠标形式11. {12. SetCursor(LoadCursor(NULL, IDC_ARROW));13. m_toolTip.UpdateTipText("", this);14. }15.if(-1 != m_lCameraIdPre)16. {17. SetCursor(LoadCursor(NULL, IDC_ARROW) );18. }19.//.....................20.}1.BOOL CDisplayPicDlg::PreTranslateMessage(MSG* pMsg)2.{3. m_toolTip.RelayEvent(pMsg);4.return CDialog::PreTranslateMessage(pMsg);5.}6.<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>好了,做到这四部就基本完成了。

MFC标题栏及边框的自绘

MFC标题栏及边框的自绘

MFC标题栏及边框的自绘SDI 和MDI 程序中对非客户区(标题栏、左右下边界)的美化基本思路是重载CMainFrame 类的DefWindowProc()函数,并判断消息为:WM_NCPAINT,WM_NCACTIV A TE,WM_NOTIFY的时候,调用自己的绘制窗口标题栏的函数。

用GetSystemMetrics(SM_CSFRAME)和GetSystemMetrics(SM_CYFRAME)可以取得标题栏的左上角的坐标。

最大化,最小化的按钮自己画,如果不是在标准的位置,一定要记录下他们的位置,并且在WM_NCLBUTTONDOWN消息处理函数中判断是否是点击了按钮,以做出相应的处理。

系统图标也可以自己重新画。

主要任务有贴图(包括标题栏、左边界、右边界、下边界、系统图标、最大化、最小化、关闭按钮)、处理消息(屏蔽系统自带按钮、双击状态栏改变大小、鼠标停放在三个自绘按钮上时改变按钮图标、单击自绘按钮时作出相应反应)。

一、响应的消息及重载的函数响应的消息及重载的函数都在CMainFrame 类中。

响应DefWindowProc 函数,在其中判断消息是不是WM_NCPAINT、WM_MOVE、WM_NCACTIV A TE、WM_NOTIFY,若是则重画标题栏、左框架、右框架、下框架、最大化、最小化、关闭按钮(放在一个函数里)。

响应消息WM_NCHITTEST,使鼠标位于自绘按钮时返回相应hittest 值,同时屏蔽自带按钮的鼠标事件。

简言之,当鼠标位于自绘按钮时,让系统误以为鼠标位于相应按钮,而当鼠标位于系统自带按钮时,让系统误以为鼠标只是位于标题栏。

自绘图标与之类似,不再赘述。

响应消息WM_NCMOUSEMOVE,判断光标是不是位于自绘最大化、最小化、关闭按钮区域,如是则重画相应的按钮。

响应消息WM_NCLBUTTONDOWN,判断单击左键时鼠标是否位于自绘制的最大化、最小化、关闭按钮或图标区域,如是则执行相应的按钮操作。

在MFC对话框中使用ON

在MFC对话框中使用ON

在MFC对话框中使用ON最近无聊在写一个播放器,当实习右键菜单的时候遇到了一个问题,点击菜单无法接收ON_UPDATE_COMMAND_UI消息,后来经过一番学习后才明白其中的原因,以下就是解决的方法。

症状从命令用户界面处理函数(Command UI handler)改变菜单状态(启用/禁用,选择/取消选择,更改文字)在由对话框处理时没有正常工作。

void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI{pCmdUI->Enable(FALSE); //没有显示为禁用.pCmdUI->SetCheck(TRUE); // 没有文字前显示选定标记.pCmdUI->SetRadio(TRUE); // 没有在文字前显示点.pCmdUI->SetText("Close"); //没有更改菜单文字.}原因在下拉菜单显示的时候, WM_INITMENUPOPUP消息被先发送以显示菜单项。

MFC CFrameWnd::OnInitMenuPopup 函数遍历菜单项并为每个菜单项调用更新命令处理函数(如果有的话).菜单的外观被更新以反映它的状态(启用/禁用,选择/取消选择)更新用户界面机制在基于对话框的应用程序中不能工作,因为CDialog没有OnInitMenuPopup 处理函数,而使用CWnd's 默认处理函数,该函数没有为菜单项调用更新命令处理函数。

解决适用下列步骤解决此问题在消息映射中添加ON_WM_INITMENUPOPUP 项:BEGIN_MESSAGE_MAP(CTestDlg, CDialog)//{{AFX_MSG_MAP(CTestDlg)................................................//}}AFX_MSG_MAPON_WM_INITMENUPOPUP()END_MESSAGE_MAP()在你的对话框类中添加OnInitMenuPopup成员函数且复制下列代码到该函数(注意:代码基本上是从CFrameWnd::OnInitMenuPopup(在WinFrm.cpp中)复制过来的): void CTestDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu){ASSERT(pPopupMenu != NULL);// Check the enabled state of various menu items.CCmdUI state;state.m_pMenu = pPopupMenu;ASSERT(state.m_pOther == NULL);ASSERT(state.m_pParentMenu == NULL);// Determine if menu is popup in top-level menu and set m_pOther to// it if so (m_pParentMenu == NULL indicates that it is secondary popup).HMENU hParentMenu;if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)state.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup.else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL){CWnd* pParent = this;// Child Windows don't have menus--need to Go to the top!if (pParent != NULL &&(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL){int nIndexMax = ::GetMenuItemCount(hParentMenu);for (int nIndex = 0; nIndex < nIndexMax; nIndex++){if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu){// When popup is found, m_pParentMenu is containing menu.state.m_pParentMenu = CMenu::FromHandle(hParentMenu);break;}}}}state.m_nIndexMax = pPopupMenu->GetMenuItemCount();for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;state.m_nIndex++){state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);if (state.m_nID == 0)continue; // Menu separator or invalid cmd - ignore it.ASSERT(state.m_pOther == NULL);ASSERT(state.m_pMenu != NULL);if (state.m_nID == (UINT)-1){// Possibly a popup menu, route to first item of that popup.state.m_pSubMenu =pPopupMenu->GetSubMenu(state.m_nIndex);if (state.m_pSubMenu == NULL ||(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||state.m_nID == (UINT)-1){continue; // First item of popup can't be routed to.}state.DoUpdate(this, TRUE); // Popups are never auto disabled.}else{// Normal menu item.// Auto enable/disable if frame window has m_bAutoMenuEnable// set and command is _not_ a system command.state.m_pSubMenu = NULL;state.DoUpdate(this, FALSE);}// Adjust for menu deletions and additions.UINT nCount = pPopupMenu->GetMenuItemCount();if (nCount < state.m_nIndexMax){state.m_nIndex -= (state.m_nIndexMax - nCount);while (state.m_nIndex < nCount &&pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID){state.m_nIndex++;}}state.m_nIndexMax = nCount;}}状态设计上行为如此。

MFC菜单以及与菜单相关联的操作26页PPT

MFC菜单以及与菜单相关联的操作26页PPT
(b)在源文件的消息映射中用ON_COMMAND宏将菜单项的 ID号和命令消息响应函数进行关联
(c)在源文件中增加了命令消息响应函数。
它的形式跟Windows标准消息是一样的,不同的是 ON_COMMAND宏。
标准的Windows消息的路由: 直接在消息映射表中上溯,在消息映射表中查找 ,如果吻合就调用表中所记录的消息处理程序。
命令消息的路由呢?
命令消息的路由
AfxWndProc
AfxCallWndProc
WindowProc
OnWndMsg
OnCommand
OnCmdMsg
OnNotify
命令消息接收物的类型 处理次序
Frame窗口 View
1、View 2、Frame窗口对象 3、CWinApp对象 1、View本身 2、Document
右键单击弹出菜单
在VC中已做好。通过ProjectAdd To Project组 件,选择Popup Menu就可 。 选择增加一个弹出菜单到哪个窗口,不要选择框架。 要增加到视图窗口。视图窗口始终覆盖在框架上,框 架类是不能响应鼠标消息的,而右键单击是鼠标消息。
实现机制? 首先增加了一个菜单资源,然后增加了一个函数 OnContentMenu,在该函数内调用TrackPopupMenu来 绘制菜单
• 通告消息
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类 消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也 是以WM_COMMAND形式呈现。 从CCmdTarget派生的类,都可以接收到这类消息。
一个类接收一个命令消息后, 文件做了哪些修改?
(a)在类的定义中的消息映射中添加命令消息函数原 型
Document
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MFC对话框禁止移动使标题栏不响应鼠标消息通过客户区移动窗体OnNcHitTest()的实现
//这个函数允许我们对windows鼠标消息进行处理对于基类函数的返回值我们可以通过判断消息类型来进行不同的处理
//也就是说我们可以对鼠标消息做任意处理比如是菜单栏上的消息我们可以返回标题栏的值
//对应的消息类型有如下查找MSDN此函数的值有介绍
UINT CMyDlg::OnNcHitTest(CPoint point)
{
UINT nFlags= CDialog::OnNcHitTest(point); //调用基类的OnNcHitTest获得返回值if(nFlags==HTCAPTION||nFlags==HTSYSMENU) //如果鼠标消息是在标题栏上或者系统菜单栏我们就返回FALSE 不进行处理
{
return FALSE ;
}
else if(nFlags==HTCLIENT) //可以通过客户区域移动窗体但是不能通过标题栏移动return HTCAPTION ;
else
return nFlags;
}
下面是一些测试枚举值
::OnNcHitTest
afx_msg UINT OnNcHitTest( CPoint point );
返回值:下面列出的鼠标击中测试枚举值之一。

· HTBORDER 在不具有可变大小边框的窗口的边框上。

· HTBOTTOM 在窗口的水平边框的底部。

· HTBOTTOMLEFT 在窗口边框的左下角。

· HTBOTTOMRIGHT 在窗口边框的右下角。

· HTCAPTION 在标题条中。

· HTCLIENT 在客户区中。

· HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。

· HTGROWBOX 在尺寸框中。

· HTHSCROLL 在水平滚动条上。

· HTLEFT 在窗口的左边框上。

· HTMAXBUTTON 在最大化按钮上。

· HTMENU 在菜单区域。

· HTMINBUTTON 在最小化按钮上。

· HTNOWHERE 在屏幕背景或窗口之间的分隔线上。

· HTREDUCE 在最小化按钮上。

· HTRIGHT 在窗口的右边框上。

· HTSIZE 在尺寸框中。

(与HTGROWBOX相同)· HTSYSMENU 在控制菜单或子窗口的关闭按钮上。

· HTTOP 在窗口水平边框的上方。

· HTTOPLEFT 在窗口边框的左上角。

· HTTOPRIGHT 在窗口边框的右上角。

· HTTRANSPARENT 在一个被其它窗口覆盖的窗口中。

· HTVSCROLL 在垂直滚动条中。

· HTZOOM 在最大化按钮上。

相关文档
最新文档