MFC--对话框

修改对话框标题

SetWindowText("标题");

双击全屏
<span style="font-size:12px;">void CPDlg::OnLButtonDblClk(UINT nFlags, CPoint point)   
{  
 // TODO: Add your message handler code here and/or call default   
 CReceiveDlg* pTemp =(CReceiveDlg*)GetOwner();  
 if(m_bfull)  
 {  
  SetParent(pwnd);  
  MoveWindow(&m_FullScreenRect);  
 }  
 else  
 {  
  GetWindowRect(&m_FullScreenRect);  
  GetParent()->ScreenToClient(&m_FullScreenRect);  
  pwnd=GetParent();  
  SetParent(GetDesktopWindow());  
  int cx = ::GetSystemMetrics(SM_CXSCREEN);   
  int cy = ::GetSystemMetrics(SM_CYSCREEN);    
  CRect rect(0,0,cx,cy);  
  MoveWindow(&rect);   
 }  
 m_bfull=!m_bfull;  
  
 CDialog::OnLButtonDblClk(nFlags, point);  
}  </span>
非模态对话框
//创建   
CTestDlg *pDlg=new CTestDlg;  
pDlg->Create(IDD_TESTDLG,this);  
pDlg->ShowWindow(SW_SHOW);  
  
//销毁   
void CTestDlg::OnClose()  
{  
     DestroyWindow(); 
//CDialog::OnClose(); 
}  
void CTestDlg::PostNcDestroy()  
{  
     CDialog::PostNcDestroy();  
     delete this;  
}  
注意:不需要调用delete pDlg,只需调用pDlg->OnClose()。
//获取传进来的参数
CString strCmd = AfxGetApp()->m_lpCmdLine;
//非模态对话框如何退出
WM_CLOSE-》::DestroyWindow-》WM_DESTROY-》::PostQuitMessage-》WM_QUIT,到此程序退出。WM_CLOSE 消息发出的时候,用户可以根据自己的意愿来选择到底是否关闭,WM_DESTORY 是真的关闭一个窗口。WM_QUIT是退出一个应用程序。有时候程序退不出,须将PeekMessage
(&msg, hwnd, 0, 0, PM_REMOVE),改成PeekMessage(&msg, NULL, 0, 0, PM_REMOVE),因为窗口关闭了,窗口句柄无效。
exit()没有清楚对话框资源,会引起内存泄露。
movewindow 跟SetWindowPos 的区别
movewindow只是移动窗口   SetWindowPos可移动窗口,还可以设置各种风格。如:SWP_NOSIZE。
UpdateWindow()跟Invalidate()的区别
UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。2个都不等待返回值。
WM_PAINT与WM_ERASEBKGND的关系
当窗口大小变化,或者调用Invalidate(TRUE)时,会发送WM_PAINT消息,OnPaint()会响应此消息, 调用 CPaintDC dc(this);调用BeginPaint(),再发送WM_ERASEBKGND消息,OnEraseBkgnd()响应此消息,一次调用顺序是:OnEraseBkgnd()->OnPaint();如果调用Invalidate(FALSE),就只会调用OnPaint();
设置背景颜色

1、我们知道程序在运行的时候会调用OnPait函数,那么我们可以在这里设置背景颜色。

<span style="font-size:12px;">void CFlipCardsDlg::OnPaint()   
{  
if (IsIconic())  
{  
//保持不变   
}  
else  
{     
   CRect   rc;  
   GetClientRect( &rc );// 获取客户区   
   CPaintDC dc(this);  
   dc.FillSolidRect(&rc, RGB(0,160,0)); // 填充客户区颜色   
   CDialog::OnPaint();             
}  
}  
</span>

 

2、第二种方法只要一条语句,但是这里要注意这里绘制的颜色是针对程序中所有的对话框(如果是单文档的话,好像不行)
SetDialogBkColor(RGB(0,0,255),RGB(255,0,0));// 前一个RGB是背景色,后一RGB是文本颜色
该函数放在工程的APP文件的初始化函数中。

3、第三种方法,利用ClassWizard重载OnCtlColor(),即WM_CTLCOLOR消息
在要着色的对话框中申明一个变量,CBRUSH m_hbrush;然后在项目的Dlg类初始化函数中给m_hbrush赋值。
m_brush.CreateSolidBrush(RGB(0, 255, 0));
然后在OnCtlColor(...)返回该画刷就可以了,如下。

<span style="font-size:12px;">HBRUSH CFlipCardsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
{  
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);  
  
// TODO: Change any attributes of the DC here   
  switch (nCtlColor)  
  {  
   case CTLCOLOR_DLG:  
   HBRUSH aBrush;  
   aBrush = CreateSolidBrush(RGB(0, 150, 0));  
   hbr = aBrush;  
   break;  
  }  
// TODO: Return a different brush if the default is not desired   
return hbr;  
}   
</span>
对话框拉伸

#ifndef OBM_SIZE
#define OBM_SIZE 32766
#endif

Static m_wndSizeIcon;  //  放图标的静态控件

//创建如下:

m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE);
 m_bmpSizeIcon.GetBitmap(&m_bitmap);
 //  创建显示图标的静态控件并放在对话框右下角
 m_wndSizeIcon.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0);
 m_wndSizeIcon.SetBitmap(m_bmpSizeIcon);

然后在OnSize(UINT nType, int cx, int cy)里响应其他窗口的变化。

文件拖到对话框

添加WM_DROPFILES消息,选中接收此消息的控件,在“Accept files”上打钩。响应 WM_DROPFILES消息如下:

<span style="font-size:12px;">void CAVIPlayerDlg::OnDropFiles(HDROP hDropInfo)
{
	// TODO: Add your message handler code here and/or call default
	char FileName[_MAX_PATH];  
	int Sum;     //   获得拖拉的文件数目,该功能由第二个参数决定   
	Sum = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);  
	if(Sum > 0)  
	{  
		// 这里只要第一个文件   
	  DragQueryFile(hDropInfo, 0, FileName, _MAX_PATH);    
	}  
	DragFinish( hDropInfo );   //  释放应用程序为传递文件名而开辟的内存空间   
	m_sName = FileName;  //获取的最后一个的文件名
	CDialog::OnDropFiles(hDropInfo);
}
 

</span>
最小化到托盘
<span style="font-size:12px;">//准备代码如下:
void CtestDlg::toTary(void)
{
	NOTIFYICONDATA  nid;  
	nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);  
	nid.hWnd=this->m_hWnd;  
	nid.uID=IDR_MAINFRAME;  
	nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;  
	nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称  
    nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));    
	strcpy(nid.szTip,"xxx");
	Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标  
	ShowWindow(SW_HIDE);//隐藏主窗口  
}
#define WM_SHOWTASK WM_USER+1
ON_MESSAGE(WM_SHOWTASK,&CtestDlg::OnShowTask)
LRESULT CtestDlg::OnShowTask(WPARAM wParam,LPARAM lParam)
{
	if(wParam!=IDR_MAINFRAME)  
		return  1;  
	switch(lParam)  
	{  
	case  WM_LBUTTONDOWN://单击左键的处理  
		{  
			this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿  
		} 
		break;
	case WM_RBUTTONDOWN:
		{
			LPPOINT  lpoint=new  tagPOINT;  
			::GetCursorPos(lpoint);//得到鼠标位置  
			CMenu  menu;  
			menu.CreatePopupMenu();//声明一个弹出式菜单  
			//增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗
			menu.AppendMenu(MF_STRING,WM_DESTROY,_T("关闭"));  
			menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);//确定弹出式菜单的位置    
			HMENU  hmenu=menu.Detach();  //资源回收  
			menu.DestroyMenu();  
			delete  lpoint;  
		}
		break;  
	}  
	return  0;  
}
//响应最小化
void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	...
	else if (nID==SC_MINIMIZE)
	{
		toTary();
	}
	...
}</span>
打开,保存文件

CFileDialog
Parameters
bOpenFileDialog 打开还是保存
lpszDefExt 扩展名
lpszFileName 初始文件名
dwFlags 属性,OFN_ALLOWMULTISELECT为多选。
lpszFilter 过滤文件名
pParentWnd 父窗口

<span style="font-size:12px;">//打开的例子:	
 CString szFilterFDlg = "264(*.avi)|*.264|所有文件 (*.*)|*.*||";
 CFileDialog fileDlg(TRUE, ".avi",NULL, NULL,szFilterFDlg, NULL);CString filepath;
if(fileDlg.DoModal() == IDOK) 
{
	filepath = fileDlg.GetPathName();//获得文件
	...
} 
//保存的例子:
CString strtime;
CTime time=CTime::GetCurrentTime();
strtime=time.Format("%Y-%m-%d-%H-%M-%S");  	
CString szFilterFDlg = "视频文件 (*.avi)|*.avi|所有文件 (*.*)|*.*||";
CFileDialog fileDlg(FALSE, ".avi",strtime, NULL,szFilterFDlg, NULL); 
CString filepath;
if(fileDlg.DoModal() == IDOK) 
{
	filepath = fileDlg.GetPathName();//获得文件 
	...
} </span>
关闭询问

点程序右上的红叉时,会发送WM_CLOSE消息,可以修改此消息的处理函数OnClose()函数如下:

int nRst = AfxMessageBox("确认要重新连接吗?",MB_OKCANCEL | MB_ICONQUESTION);

  if (IDOK == nRst)   {    CDialog::OnClose();

  }   else   {    return;   }

对话框启动就隐藏

方法一:对话框启动后发送隐藏的自定义消息,缺点是会闪一下。

方法二:响应ON_WM_NCPAINT的函数里,ShowWindow(FALSE);缺点是右下角会出现标题。 

对话框的查找

方法一:The FindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. This function does not perform a case-sensitive search. Parameters lpClassName [in] Pointer to a null-terminated string that specifies the class name or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. lpWindowName [in] Pointer to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match. Return Values If the function succeeds, the return value is a handle to the window that has the specified class name and window name. If the function fails, the return value is NULL. To get extended error information, call GetLastError.

对话框最小化后不能恢复的问题

程序最小化后不能还原,一般原因是程序中至少存在一个Popup类型的窗口引起的,因为Popup类型的子窗口即使由于父窗口的隐藏而隐藏,其WS_VISIBLE属性仍然是可见的,当用户再次点击任务栏的程序图标时,Popup窗口会拦截系统(还原)消息,使主程序框架无法接收到系统消息,从而导致主程序无法正常还原。如果将其修改为Child类型的窗口,那么主程序的最小化和还原的功能就可以正常了。不过在实际项目中,往往就需要一个Popup类型的窗口作为子窗口(Popup类型的窗口也可以有父窗口),那么这又如何解决程序最小化后不能还原的问题呢?根据以上分析的原理,只要在主程序最小化时,相应也隐藏掉Popup窗口(ShowWindow(SW_HIDE)),这样系统消息就能够正确传递了;当主程序还原时,再将隐藏的Popup窗口显示出来,这样就既不影响程序的显示效果,又能解决问题了!

OnOk跟OnCancel的区别

CDialog::OnOK首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框;  CDialog::OnCancel只调用CDialog::EndDialog关闭对话框;   OnClose()是响应   WM_CLOSE的。

一定程度上可以说CDialog::EndDialog()和OnClose()完成类似的工作,但处理的机制不一样,前者是CDialog的对象机制,后者是WM的消息映射机制。

CDialog::EndDialog()-------->OnDestroy() OnClose()-------->OnDestroy() EndDialog()和OnClose()属于“同级别”的,所以我们在按下OK按钮的时候,程序是不会执行OnClose()的,但两种机制都必须经过OnDestroy()。

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山西茄子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值