⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdichild.cpp

📁 以前给一个印刷厂开发的业务管理软件
💻 CPP
字号:
// MDIChild.cpp: implementation of the CMDIChild class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "SDI.h"
#include "MDIChild.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//PMDICHILD m_pMDIChild = NULL;		// 窗口的 CLASSXP 结构指针

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
PMDICHILD CMDIChild::m_pMDIChild = NULL;

CMDIChild::CMDIChild()
{
}

CMDIChild::~CMDIChild()
{

}
//把子窗口加入,管理链表
int CMDIChild::ADD(CView *pView, LPCSTR lpName, UINT nType)
//int CMDIChild::ADD(UINT nID, CWND *pView, LPCSTR lpName, UINT nType)
{
  PMDICHILD pChild, pParent;
  HWND hWnd;
  
  
  pParent=GetClassParent();      //取出父窗口
  if(!pParent) return -2;
  pChild = GetClassChild(lpName);

  if(!pChild)      //新建
  {
    if(pView==NULL)return -1;      //不能新增空窗口
	// 分配存储空间,增加一个节点
    hWnd = pView->GetSafeHwnd();
	pChild = (PMDICHILD) new MDICHILD;
	memset(pChild,0, sizeof(MDICHILD));
	if(!pChild) return -1;

	pChild->pNext = (PMDICHILD)m_pMDIChild;
    m_pMDIChild = pChild;
	pChild->hView = hWnd;
	pChild->hParent = pParent->hView;
	memcpy(pChild->szName,lpName, MDI_MAXNAME);
	pChild->wpPrev = (WNDPROC )SetWindowLong(hWnd,GWL_WNDPROC,(LONG)MDIChildProc);
	if(!pChild->wpPrev) //失败
	{
	   DelClassChild(pChild->hView);
	   return -3;
	}
    DrawTitle(pParent->hView);
	pView->CenterWindow();
    pView->ShowWindow(nType);
	SetActive(pChild->hView, NULL, MDI_AC_STAND); //设置表链状态
	return 0;
  }
  if(pChild->hView != pParent->pData->hViewActive)
  {
  SetActive(pChild->hView, NULL, MDI_AC_STAND);
  SetWindowPos(pChild->hView, NULL,0,0,0,0,
	           SWP_NOSIZE|SWP_NOREPOSITION|SWP_SHOWWINDOW|
			   SWP_NOMOVE);
  }
  return 1;
}
//把子窗口从管理链表中删除
//把子窗口从管理链表中删除
BOOL CMDIChild::DelClassChild(CWnd *pWnd)
{
	return DelClassChild(pWnd->GetSafeHwnd());
}
BOOL CMDIChild::DelClassChild(HWND hWnd)
{
  PMDICHILD pChild, pDel = NULL, pParent;
			// 循环查找待删除节点的上一个节点
  pDel = GetClassChild(hWnd);
  // 获取待删除的节点指针
  if (pDel != NULL)
	{
		// 如果待删除的节点就是 m_pMDIChild 节点
	    if(pDel->hParent==NULL)return FALSE; //禁止删除父窗口
		if (pDel == m_pMDIChild)
		{
			m_pMDIChild = pDel->pNext;
			pChild = pDel->pNext;
		}
		else
		{
			// 循环查找待删除节点的上一个节点
			for (pChild = (PMDICHILD)m_pMDIChild; pChild != NULL; pChild = pChild->pNext)
			{
				// 如果找到
				if (pChild->pNext == pDel)
				{
					// 使链表跳过待删除的节点
					pChild->pNext = pDel->pNext;
					break;
				}
			}
		}

		// 取消窗口子类化并重画窗口
		SetWindowLong(hWnd, GWL_WNDPROC, (LONG) pDel->wpPrev);

		// 删除堆内存
		if(pDel->pData)	delete pDel->pData;
		delete pDel;
		pParent = GetClassParent();
		if(pParent)
	    SetActive(pParent->pData->hViewPre, NULL, MDI_AC_FRUSHNEW|
		      MDI_AC_SETOLD|MDI_AC_SETNEW); //激活其它子窗口
		return TRUE;
	}
   return FALSE;  
}
//子窗口信息
LRESULT CALLBACK CMDIChild::MDIChildProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LONG lReturn;
  PMDICHILD pChild, pParent;
  PMDIDATA pData = NULL;
  POINTS point;
//  RECT Rect;
  LPMINMAXINFO lpmmi;
  UINT umessage = uMsg;
  pChild = (PMDICHILD)GetClassChild(hWnd);
  if (!pChild) return 0;
  pParent =(PMDICHILD)GetClassParent();
  if(pParent) pData = pParent->pData;
  if(pParent && pData)
  {
     switch(uMsg)
	 {//限制最大化的位置
	 case WM_GETMINMAXINFO:
          lpmmi = (LPMINMAXINFO) lParam;
          lpmmi->ptMaxPosition.x =pData->rcMaxSize.left;
          lpmmi->ptMaxPosition.y =pData->rcMaxSize.top;
          lpmmi->ptMaxSize.x = pData->rcMaxSize.right-pData->rcMaxSize.left;
          lpmmi->ptMaxSize.y = pData->rcMaxSize.bottom-pData->rcMaxSize.top;
		  break;
	 case WM_NCLBUTTONDOWN :
		  if (wParam == HTCAPTION)
		  {
		     if(IsZoomed(hWnd))
			 {
				 return 0;
			 }
		  }
		  break;
//计算含边框下的位移
      case WM_MOVE:   //限制移动区域
		     point.x = (int)(short) LOWORD(lParam);    // horizontal position 
             point.y = (int)(short) HIWORD(lParam);    // vertical position 
	         point.y = point.y - GetSystemMetrics(SM_CYDLGFRAME)-
				       GetSystemMetrics(SM_CYBORDER) -
	                   GetSystemMetrics(SM_CYCAPTION);
			 point.x -= GetSystemMetrics(SM_CXDLGFRAME);
			 if (point.y < pData->rcMaxSize.top)//限制顶部
			 {   

                 SetWindowPos (hWnd,NULL, point.x, pData->rcMaxSize.top,
					           0 , 0,
			                   SWP_NOSIZE|SWP_NOZORDER);
				 return 0;
			     
			 }
			 break;
     case WM_ACTIVATEAPP://跳转到其它程式时
		      DrawTitle(pParent->hView, wParam);
		      return 0;
       case WM_ACTIVATE: 
	     if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
		 {//子窗口激活处理
			 if(pData->hViewActive != hWnd) //发生改变
			 {
			  pData->hViewPre =  pData->hViewActive;
			  pData->hViewActive = hWnd;
			  DrawTitle(pData->hViewPre, FALSE);
			  break;
			 }
			 DrawTitle(hWnd);
			 return 0;
		 }
		 else
		 {//子窗口禁止激活
			 if(pParent->hView == (HWND)lParam) //跳转到主窗口
			 {
			    DrawTitle(hWnd);
		        return 0;
			 }
		 }
          break;
	 }
  }
  lReturn = (LONG)CallWindowProc(pChild->wpPrev, hWnd, uMsg, wParam, lParam);

  if (umessage == WM_NCDESTROY)  //窗口消毁时,自动删除表链
  {
	SetActive(pData->hViewPre, NULL, MDI_AC_FRUSHNEW|
		      MDI_AC_SETOLD|MDI_AC_SETNEW); //激活其它子窗口
	//DrawTitle(pData->hViewPre);

	DelClassChild(pChild->hView);
  }
  return lReturn;
}
//主窗口信息
LRESULT CALLBACK CMDIChild::MDIMainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LONG lReturn;
  PMDICHILD pChild, pParent;
  PMDIDATA pData = NULL;
  pParent =(PMDICHILD)GetClassParent();
  if(!pParent) 
	  return 0;
  else
      pData = pParent->pData;
  if(pData)
  {
  switch(uMsg)
  {
//禁止改变窗口大小,只可以最小化和最大化
	 case WM_NCLBUTTONDBLCLK :
	 case WM_NCRBUTTONDBLCLK :
		  lReturn = SendMessage(hWnd, WM_NCHITTEST, 0, lParam);
		  if(lReturn==HTCAPTION || lReturn==HTSYSMENU)return 0;
		  break;
	 case WM_NCLBUTTONDOWN :
	 case WM_NCRBUTTONDOWN :
		  lReturn = SendMessage(hWnd, WM_NCHITTEST, 0, lParam);
		  if(lReturn==HTSYSMENU||lReturn==HTZOOM || lReturn==HTMAXBUTTON)return 0;
		  break;
     case WM_ACTIVATE: 
	     if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
		 {//主窗口激活
             //SendMessage(pData->hViewActive, WM_ACTIVATE,WA_CLICKACTIVE,0);
             DrawTitle(pData->hViewActive); //激活子窗口
			 return 0;
		 }
		 else
		 {//主窗口禁止激活
			 pChild = GetClassChild((HWND)lParam);
			 if(pChild) //转到子窗口
			 {
				DrawTitle(hWnd);
                return 0;
			 }
			 else       //重绘子窗口
			 {
				DrawTitle(pData->hViewActive,FALSE);
			 }
		 }
		 break;
       
  }//end switch
  }//end if
  lReturn = (LONG)CallWindowProc(pParent->wpPrev, hWnd, uMsg, wParam, lParam);
  if (uMsg == WM_NCDESTROY)   //窗口消毁时,自动删除表链
	DelClassChild(pParent->hView);
  return lReturn;
}
//取子窗口
PMDICHILD CMDIChild::GetClassChild(HWND hWnd)
{
  PMDICHILD pChild;
			// 循环查找待删除节点的上一个节点
  for (pChild = (PMDICHILD)m_pMDIChild; pChild != NULL; pChild=pChild->pNext)
	if (pChild->hView == hWnd)
		return pChild;

   return NULL;  
}

//取子窗口
PMDICHILD CMDIChild::GetClassChild(LPCSTR lpName)
{
  PMDICHILD pChild;
			// 循环查找待删除节点的上一个节点
  for (pChild = (PMDICHILD)m_pMDIChild; pChild != NULL; pChild=pChild->pNext)
  {
	if((memcmp(pChild->szName,lpName, MDI_MAXNAME))==0)
		return pChild;
  }
   return NULL;  
}
//取父窗口
PMDICHILD CMDIChild::GetClassParent()
{
  PMDICHILD pChild;
			// 循环查找待删除节点的上一个节点
  for (pChild = (PMDICHILD)m_pMDIChild; pChild != NULL; pChild=pChild->pNext)
	if (pChild->hParent == NULL)
		return pChild;

   return NULL;  
}
//初期化父窗口,只有父窗口的hParent=NULL
//pRect是子窗口的活动区域FOR Screen
//还没实现限制子窗口的活动区域
int CMDIChild::InitMainWnd(CWnd *pWnd, RECT *pRect)
{
  PMDICHILD pChild;
  PMDIDATA  pData;
  RECT RectDef;
  POINT point;
  HWND hWnd;
  if(pWnd==NULL)return -1;
  hWnd = pWnd->GetSafeHwnd();
  if(GetClassChild(hWnd)) return 1;
//显示最大化  
  if(!pWnd->IsZoomed())
	  pWnd->ShowWindow(SW_MAXIMIZE);
//除去最大化按钮
//  pWnd->ModifyStyle(WS_MAXIMIZEBOX,NULL);
//设置活动区域
  if(pRect==NULL)
  {
	pWnd->GetClientRect(&RectDef);
	point.x = 0; point.y = 0;
	ClientToScreen(hWnd, &point);
	RectDef.left += point.x; RectDef.top += point.y;
	RectDef.right += point.x; RectDef.bottom += point.y;
	pRect = &RectDef;
  }

//新建,分配存储空间,增加一个节点
  pData = (PMDIDATA) new MDIDATA;
  memset(pData,0, sizeof(MDIDATA));
  if(!pData) return -1;
  pChild = (PMDICHILD) new MDICHILD;
  memset(pChild,0, sizeof(MDICHILD));
  if(!pChild) {delete pData; return -1;}

  pChild->pNext = (PMDICHILD)m_pMDIChild;
  m_pMDIChild = pChild;
  pChild->hView = hWnd;
  pChild->hParent = NULL;
  pChild->wpPrev = (WNDPROC )SetWindowLong(hWnd,GWL_WNDPROC,(LONG)MDIMainProc);
  if (!pChild->wpPrev) //安装失败
  {
    delete m_pMDIChild->pData;
	delete m_pMDIChild;
	m_pMDIChild = NULL;
	return -1;
  }
  pChild->pData = pData;
  SetRect(&pData->rcMaxSize,pRect->left,pRect->top,
	       pRect->right ,pRect->bottom);
  return 0;
  
}
//删除
BOOL CMDIChild::UninitMainWnd(void)
{
 return TRUE;
}
//设置子窗口活动区域
BOOL CMDIChild::SetActiveRect(RECT *pRect)
{
    PMDICHILD pParent;
    pParent=GetClassParent();      //取出父窗口
    if(!pParent) return FALSE;
    SetRect(&pParent->pData->rcMaxSize,
		    pRect->left , pRect->top,
			pRect->right, pRect->bottom);
	return FALSE;
}
//管理活动窗口表链
void CMDIChild::SetActive(HWND hNew, HWND hOld, UINT nType)
{
    PMDICHILD pParent;
    pParent=GetClassParent();      //取出父窗口
    if(!pParent) return ;
	if(nType & MDI_AC_RESTOREOLD)
	  pParent->pData->hViewPre = pParent->pData->hViewActive;
	if(nType & MDI_AC_SETOLD)
	  pParent->pData->hViewPre = hOld;
	if(nType & MDI_AC_SETNEW)
	  pParent->pData->hViewActive = hNew;
	if(nType & MDI_AC_FRUSHOLD)
	  SendMessage(pParent->pData->hViewPre, WM_NCACTIVATE,FALSE,0);
	if(nType & MDI_AC_FRUSHNEW)
		DrawTitle(hNew);
//	  SendMessage(hNew, WM_NCACTIVATE,TRUE,0);
}
//重绘窗口标题栏
LRESULT CMDIChild::DrawTitle(HWND hWnd, BOOL bActive)
{
 return SendMessage(hWnd, WM_NCACTIVATE,bActive,0); 
// return SendMessage(hWnd, WM_NCPAINT,1,0); 
//  return SendMessage(hWnd, WM_NCACTIVATE,bActive,0); 
}
//在主窗口OnPreCreateWindow()中设置窗口为最大化
void CMDIChild::SetOnPreCreateWindow(CREATESTRUCT *cs)
{
/*	cs->style &= ~WS_MAXIMIZEBOX;    //除去最大化按钮
	cs->x = 0;
	cs->y = 0;
    cs->cx=GetSystemMetrics(SM_CXSCREEN/2);
//225等于窗口最大化且满屏
    cs->cy=GetSystemMetrics(SM_CYSCREEN/2)-225; 
*/
}
//重排所有子窗口
void CMDIChild::InitialUpdateFrame()
{
  PMDICHILD pChild;
  PMDICHILD pParent;
  RECT *pRect;
  pParent=GetClassParent();      //取出父窗口
  if(!pParent) return ;
  HWND hActive = pParent->pData->hViewActive;
  pRect = &pParent->pData->rcMaxSize;
   for (pChild = (PMDICHILD)m_pMDIChild; pChild != NULL; pChild=pChild->pNext)
   {
	if (pChild->hParent && pChild->hView != hActive)
	{
      SetWindowPos(pChild->hView, NULL,
		       pRect->left,pRect->top,0,0,
	           SWP_NOSIZE|SWP_NOREPOSITION|SWP_SHOWWINDOW);
	  //	ShowWindow(pChild->hView, SW_SHOW);
	}
   }
  if(hActive)
  {
      SetWindowPos(hActive, NULL,
		       pRect->left,pRect->top,0,0,
	           SWP_NOSIZE|SWP_NOREPOSITION|SWP_SHOWWINDOW);
//	ShowWindow(hActive, SW_SHOW);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -