MFC一些常用消息处理

目标:

  • 窗体的形状要是任意的,取自于位图形状。
  • 在任务栏不显示图标,且在托盘处有显示,并能有消息处理,比如右键单击有菜单可以控制。
  • 程序退出时,托盘处不能遗留图标。
  • 窗体可以控制在最顶层。
  • 窗体可任意拖动
  • 。。。

1.让窗体为图片中形状的窗体图片修改如下:

背景色 → (0,0,255) 其他颜色当然可,最好是(255,0,0)(0,255,0)(0,0,255)这三种色。

步骤:

1.建一个MFC应用程序基于对话框,比如MyPet. (生成三个类CAboutDlg,CMyPetApp,CMyPetDlg)

2.CMyPetDlg添加变量:

 HBITMAP hBitmap;  CBitmap m_bitmap;  CString m_strBkBmp; //为他初始设定一个值比如"res\\1.bmp"

函数void SetupRegion(CDC *pDC, CBitmap &cBitmap, COLORREF TransColor );根据位图设定窗体区域。(函数代码在下面的附录里)

在BOOL CMyPetDlg::OnInitDialog()中加入:

 hBitmap = (HBITMAP)::LoadImage(::AfxGetInstanceHandle(),m_strBkBmp, IMAGE_BITMAP,0,0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);  m_bitmap.Attach(hBitmap);  BITMAP bm;  m_bitmap.GetBitmap(&bm);  CRect rect;  GetWindowRect(&rect);  rect.right = rect.left + bm.bmWidth;  rect.bottom = rect.top + bm.bmHeight;  MoveWindow(&rect);  CClientDC dc(this);  SetupRegion(&dc,m_bitmap,RGB(0,0,255)); //设置区域,将背景透明色不显示

此时完成窗体形状的设计。不过对话框的风格是要改变一下才行的。在属性中将Border设置为None.

现在生成的只有位图形状的窗体,却没有位图的显示。在OnPaint()中要加如以下代码:

void CMyPetDlg::OnPaint() {  if (IsIconic())  {   ...;  }  else  {

  CPaintDC dc(this);   CDC picDC;   picDC.CreateCompatibleDC(&picDC);

  CBitmap * pOldBmp;   pOldBmp = picDC.SelectObject(&m_bitmap);

  BITMAP bm;   m_bitmap.GetBitmap(&bm);   dc.BitBlt (0,0,bm.bmWidth ,bm.bmHeight,&picDC,0,0,SRCCOPY);   dc.SelectObject(pOldBmp);
 } }

图片显示出来了!

2.程序在任务栏无图标,在托盘有图标:

步骤:

1.为类CMyPetDlg添加变量

NOTIFYICONDATA nid;

2.去掉在任务栏显示的图标

 //使任务栏中不显示图标  DWORD dwExStyle=GetExStyle();  dwExStyle =(~WS_EX_APPWINDOW & dwExStyle) | WS_EX_TOOLWINDOW;
 SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,dwExStyle);

3.托盘图标显示

在CMyPetDlg::OnInitDialog()调用Tray();

// // 托盘图标显示 // void CMyPetDlg::Tray(void) {  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_SHOWTRAY; //自定义的消息名称  nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));  lstrcpy(nid.szTip, "我的小秘书~" ); //信息提示条为"我的小秘书~"     Shell_NotifyIcon(NIM_ADD,&nid); //在托盘区添加图标  ShowWindow(SW_HIDE); //隐藏主窗口 }

自定义的消息WM_SHOWTRAY:

在StdAfx.h里加入#define WM_SHOWTRAY (WM_USER+100)

为类CMyPetDlg添加WM_SHOWTRAY处理函数

 afx_msg LRESULT OnShowTray(WPARAM wParam, LPARAM lParam);

在类CMyPetDlg实现文件里消息映射里加

 ON_MESSAGE(WM_SHOWTRAY, OnShowTray)

实现OnShowTray函数(代码在下面附录里)

4.程序退出自动将图标删除,将OnCancel()重写

// // 程序退出处理 // void CMyPetDlg::OnCancel() {  // TODO: 在此添加命令处理程序代码  Shell_NotifyIcon(NIM_DELETE, &nid); //此时删除的nid与之前的是同一个NOTIFYICONDATA结构,否则删不掉,要鼠标再移上去一次才消失  EndDialog(IDCANCEL); }

3.为窗体添加右击菜单处理

注意:首先要重载对话框中的OnInitMenuPopup()函数,在对话框中使用CFrameWnd::OnInitMenuPopup()的函数,否则,菜单命令无法实现。将函数重写后代码在下面的附录里。

步骤:

1.重写函数OnInitMenuPopup()

2.处理WM_NCRBUTTONDOWN消息

// // 右键消息处理 // void CMyPetDlg::OnNcRButtonDown(UINT nHitTest, CPoint point) {  // TODO: 在此添加消息处理程序代码和/或调用默认值  CMenu MenuPop;  CMenu *pMenu;  CPoint pt;  pt = point;  MenuPop.LoadMenu(IDR_MENU2); //自己定义的一个菜单  pMenu = MenuPop.GetSubMenu(0);  pMenu->SetDefaultItem(ID_POP_TOP); //将ID_POP_TOP设置为默认的选择(加粗)  pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  pt.x, pt.y, this);

 CDialog::OnNcRButtonDown(nHitTest, point); }

4.使窗体被任意拖动

 1.处理WM_NCHITTEST消息

// // 非客户区拖动 // UINT CMyPetDlg::OnNcHitTest(CPoint point) {  // TODO: 在此添加消息处理程序代码和/或调用默认值  UINT nResult = CDialog::OnNcHitTest(point);

 return nResult == HTCLIENT ? HTCAPTION : nResult; }

5.设置动画光标

1.为类CMyPetDlg添加变量

 HCURSOR m_hCursor; //光标句柄  CString m_strCursor; //光标的路径,初始化为"res\\1.ani"

2.处理WM_SETCURSOR消息

// 设置光标

BOOL CMyPetDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {  // TODO: 在此添加消息处理程序代码和/或调用默认值  if(!m_hCursor)  {   m_hCursor = LoadCursorFromFile(m_strCursor);  }  SetCursor(m_hCursor);  //return CDialog::OnSetCursor(pWnd, nHitTest, message);  return TRUE; }

6.使窗体置于顶层

1.添加变量

BOOL m_bTopMost; //初始为FALSE

// // 是否置于顶层 // void CMyPetDlg::OnPopTop() {  // TODO: 在此添加命令处理程序代码  CRect rect;  GetWindowRect(&rect);  if(!m_bTopMost)  {   ::SetWindowPos(m_hWnd,HWND_TOPMOST,rect.left,rect.top,rect.Width(),rect.Height(),    SWP_SHOWWINDOW);  }  else  {   ::SetWindowPos(m_hWnd,HWND_NOTOPMOST,rect.left,rect.top,rect.Width(),rect.Height(),    SWP_SHOWWINDOW);   }  m_bTopMost = ! m_bTopMost; }

void CMyPetDlg::OnUpdatePopTop(CCmdUI *pCmdUI) {  // TODO: 在此添加命令更新用户界面处理程序代码  pCmdUI->SetCheck(m_bTopMost); }

7.最小化处理

1.添加变量

BOOL m_bIsMin; //是否已最小化初始为FALSE

2.菜单项消息处理

// // 最小最大处理 // void CMyPetDlg::OnPopMin() {  // TODO: 在此添加命令处理程序代码  if(!m_bIsMin)  {   ShowWindow(SW_HIDE);  }  else   ShowWindow(SW_SHOW);  m_bIsMin = ! m_bIsMin; }

void CMyPetDlg::OnUpdatePopMin(CCmdUI *pCmdUI) {  // TODO: 在此添加命令更新用户界面处理程序代码  if(m_bIsMin) //如果之前强调的那个消息没被重写,这些内容也都是无法实现的   pCmdUI->SetText(_T( "最大化" ));  else   pCmdUI->SetText(_T( "最小化" )); }

原文地址:https://www.cnblogs.com/haoyuanyuan/p/2879099.html