关闭

MFC 禁止主窗口的移动

796人阅读 评论(0) 收藏 举报
分类:

需要拦截系统消息是ON_WM_SYSCOMMAND()

重新进行重载函数:

void CMainWindow::OnSysCommand(UINT nID, LPARAM lParam)

{
 if (nID == SC_MOVE || nID==0xF012)
 return;
 else
 CFrameWnd::OnSysCommand(nID, lParam);
}
必须注意的是在进行递归调用的使用看清是递归的父类的函数

MFC禁止改变窗口大小和移动窗口

一、禁止对话框的移动

(1)、第一种方法 为这个对话框添加系统消息过虑处理: .h中:

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

... .cpp中

BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)

... ON_WM_SYSCOMMAND()

... END_MESSAGE_MAP()

void CXXXDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

   if (nID == SC_MOVE || nID==0xF012)

     return;

  else

   CDialog::OnSysCommand(nID, lParam);

}

SC_MOVE就是0xF010。

参考帖子:http://topic.csdn.net/t/20020821/12/957952.html

(2)、第二种方法 .h中: ...

afx_msg UINT OnNcHitTest(CPoint point);

... .cpp中

BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)

... ON_WM_NCHITTEST()

... END_MESSAGE_MAP()

UINT CXXXDlg::OnNcHitTest(CPoint point)

{

   int ret = CDialog::OnNcHitTest(point);

   if( HTCAPTION == ret)

     return HTCLIENT;

  return ret;

}

二、禁止对话框改变大小 .h中:

... afx_msg UINT OnNcHitTest(CPoint point);

... .cpp中 BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)

... ON_WM_NCHITTEST()

... END_MESSAGE_MAP()

UINT CXXXDlg::OnNcHitTest(CPoint point)

{

  int ret = CDialog::OnNcHitTest(point);

   //if语句的前两行是用来禁止改变大小的,最后一行是用来禁止移动的

   if(HTTOP == ret || HTBOTTOM == ret || HTLEFT == ret ||HTRIGHT == ret || HTBOTTOMLEFT == ret || HTBOTTOMRIGHT == ret ||HTTOPLEFT == ret || HTTOPRIGHT == ret || HTCAPTION == ret)

   return HTCLIENT;

return ret;

}

 

一、C API实现方法

思路:如果用户想通过鼠标移动窗口,一定会按下鼠标左键,那么我们只要捕获到鼠标左键按下的消息,然后删除它即可。鼠标左键按下会产生两种类型的消息:WM_LBUTTONDOWN和WM_NCLBUTTONDOWN消息,那么WM_LBUTTONDOWN和WM_NCLBUTTONDOWN的区别是什么呢?先看看MSDN怎么说:

The WM_LBUTTONDOWN messageis posted when the user presses the left mouse button while thecursor is in the clientarea of a window. If the mouse is notcaptured, the message is posted to the window beneath the cursor.Otherwise, the message is posted to the window that has capturedthe mouse.

The WM_NCLBUTTONDOWN messageis posted when the user presses the left mouse button while thecursor is within the nonclientarea of a window. This message is posted tothe window that contains the cursor. If a window has captured themouse, this message is not posted.

由此可以知道:

WM_LBUTTONDOWN是在左击客户区时响应; WM_NCLBUTTONDOWN是在左击非客户区时响应。

那么什么是客户区?什么是非客户区?
标题栏,菜单就是非客户区,标题栏、菜单等以外的窗体就是客户区。

 

所以我们应该处理非客户区的WM_NCLBUTTONDOWN消息:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam)
{

  ...
  switch(message)
 {
  caseWM_COMMAND:
   wmId    =LOWORD(wParam);
   wmEvent= HIWORD(wParam);
   //Parse the menu selections:
   switch(wmId)
   {

     ...
   case WM_NCLBUTTONDOWN:
   MSG msg;
   PeekMessage(&msg, hWnd, 0,0, PM_REMOVE);
   break;
    ...
  default:
   returnDefWindowProc(hWnd, message, wParam, lParam);
   }
   return0;
}

二、接下来看看在MFC中如何实现的呢,同样也是处理非客户区的消息WM_NCLBUTTONDOWN,那么怎么去响应这个消息呢?
虚函数OnNcLButtonDown(UINT  nHitTest,  CPoint  point) 即是用来响应这个消息的,添加步骤与平时的有些不同:
Ctrl+W -> MFC ClassWizard,在出现的对话框,切换到Class Info选项卡,Class name中指定类,再在Message filter中选择Windows,点击OK。在Classname中指定类中右击Add Windows Message Headle,在New Windowsmessage/events中选定WM_NCLBUTTONDOWN,再点击Add and Edit就会出现OnNcLButtonDown。
添加绿色部分代码即可实现。
void CTestThreadDlg::OnNcLButtonDown(UINT nHitTest, CPointpoint)
{
 // TODO: Add your message handler codehere and/or call default
 if (HTCAPTION ==nHitTest) {
  return;
 }
 CDialog::OnNcLButtonDown(nHitTest,point);
}
HTCAPTION 的意思是the cursorIn's location is atitle-bar area.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:977521次
    • 积分:17615
    • 等级:
    • 排名:第540名
    • 原创:741篇
    • 转载:522篇
    • 译文:0篇
    • 评论:105条
    最新评论