// ModelessDialog.cpp : implementation file // #include "stdafx.h" #include "captionButton.h" #include "TchBaseDlg.h" #if (ADS>14) #include "acdocman.h" #endif #include "resource.h" #include "htmlhelp.h" #include "winspool.h" //#include //#pragma comment (lib,"dwmapi.lib") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define INIT_MONITOR_PT 100 #define MONITOR_PT 101 #define MOVE_WAITER 102 #define AUTOFOCUS_TIMER 103 #define MODELESSDIALOG_EVENT_TIME 30 //extern const TCHAR * GetRegLocation(); int TUTIL_IMPEXP g_nInitAutoHideTime=2000; int TUTIL_IMPEXP g_nAutoHideTime=100; int TUTIL_IMPEXP g_nAnimateStepNum=12; extern TARCH_IMPEXP BOOL g_bAutoFocus; #ifndef _GLW_UI_ #ifdef CAcUiDialog #undef CAcUiDialog #endif #endif ///////////////////////////////////////////////////////////////////////////// // CModelessDialog dialog IMPLEMENT_DYNAMIC(CModelessDialog, CAcUiDialog) CModelessDialog::CModelessDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/) : CAcUiDialog(nIDTemplate, pParent), m_bModeless(TRUE),m_bAllowAutoHide(TRUE) { //{{AFX_DATA_INIT(CModelessDialog) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_bChangeDocSwitch=FALSE; m_bHide=FALSE; m_bAutoHide=FALSE; m_pMemDC=NULL; m_pWndDC=NULL; m_pBitmap=NULL; m_nStepNum=0; m_nYStep=0; m_nCurStep=0; m_clrDraw = RGB(127, 127, 127); } BEGIN_MESSAGE_MAP(CModelessDialog, CAcUiDialog) //{{AFX_MSG_MAP(CModelessDialog) ON_WM_DESTROY() ON_WM_CREATE() ON_WM_CLOSE() ON_MESSAGE( WM_ACAD_KEEPFOCUS, onAcadKeepFocus ) ON_WM_TIMER() ON_WM_MOUSEMOVE() ON_WM_NCLBUTTONDOWN() ON_WM_CTLCOLOR() ON_WM_NCPAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CModelessDialog::OnInitDialog() { // sg delete 101020 // 下面的代码用于解决上华无模式对话框在vista、win7操作系统下,不显示对话框右上角的关闭、实时助手等按钮的问题 // 但是dwmapi.h文件,在XP系统下没有,无法编译通过 /* OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); BOOL bIsVistaOrBefore = osvi.dwMajorVersion >= 6; // vista为6 #if bIsVistaOrBefore #include #pragma comment (lib,"dwmapi.lib") DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED; DwmSetWindowAttribute(GetSafeHwnd(),DWMWA_NCRENDERING_POLICY,&ncrp,sizeof(ncrp)); #endif */ CAcUiDialog::OnInitDialog(); m_wndToolTip.Create(this); m_wndToolTip.Activate(true); m_wndToolTip.SetMaxTipWidth(250); m_wndToolTip.SetDelayTime(TTDT_AUTOPOP, 4*m_wndToolTip.GetDelayTime(TTDT_AUTOPOP)); m_bThickFrame=(GetStyle()&WS_THICKFRAME)!=0; ModifyStyle(WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,0,0); /*AddCapBtn(m_pCapBtnClose=new CCaptionButton(_T("关闭"),IDB_CLOSE,IDB_CLOSE,FALSE)); AddCapBtn(m_pCapBtnHelp=new CCaptionButton(_T("实时助手"),IDB_HELP,IDB_HELP,FALSE));*/ if(m_bModeless) { int x=0,y=0; if(ReadReg(x,y)) { CRect SubRect; GetWindowRect(&SubRect); MoveWindow(x,y,SubRect.Width(),SubRect.Height()); } if(m_bAllowAutoHide) { /* AddCapBtn(m_pCapBtnAutoHide=new CCaptionButton(_T("自动隐藏"),IDB_NO_AUTOHIDE,IDB_AUTOHIDE,true)); m_pCapBtnAutoHide->SetChecked(m_bAutoHide==TRUE); if(m_bAutoHide) SetTimer(INIT_MONITOR_PT,g_nInitAutoHideTime,NULL);*/ } #if ADS==15 if(g_bAutoFocus) SetTimer(AUTOFOCUS_TIMER,100,NULL); #endif } else { ModifyStyle(WS_MINIMIZEBOX, 0); CenterWindow(); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } BOOL CModelessDialog::ReadReg(int &x, int &y) { CRuntimeClass *pClassInfo=GetRuntimeClass(); const char *pClassName=pClassInfo->m_lpszClassName; XString sRegLoc(512); sRegLoc << GetRegLocation() << _T("\\DialogPosition"); CRegProperty regProp(sRegLoc, TString(pClassName)); regProp.SetTopRootKey(HKEY_CURRENT_USER); if(!regProp.GetValue(_T("x"),x)) return FALSE; if(!regProp.GetValue(_T("y"),y)) return FALSE; if(!regProp.GetValue(_T("AutoHide"),m_bAutoHide)) return FALSE; return TRUE; } void CModelessDialog::WriteReg(int x, int y) { CRuntimeClass *pClassInfo=GetRuntimeClass(); const char *pClassName=pClassInfo->m_lpszClassName; XString sRegLoc(512); sRegLoc << GetRegLocation() << _T("\\DialogPosition"); CRegProperty regProp(sRegLoc, TString(pClassName)); regProp.SetTopRootKey(HKEY_CURRENT_USER); regProp.SetValue(_T("x"),x); regProp.SetValue(_T("y"),y); regProp.SetValue(_T("AutoHide"),m_bAutoHide); } void CModelessDialog::OnDestroy() { if(m_bModeless) { if(!IsIconic()) { CRect rect; GetWindowRect(&rect); WriteReg(rect.TopLeft().x,rect.TopLeft().y); } } /* if(m_TimerID) { KillTimer(m_TimerID); }*/ CAcUiDialog::OnDestroy(); m_wndToolTip.DestroyWindow(); if(m_pMemDC!=NULL) { delete m_pMemDC; m_pMemDC=NULL; } if(m_pWndDC!=NULL) { delete m_pWndDC; m_pWndDC=NULL; } if(m_pBitmap!=NULL) { delete m_pBitmap; m_pBitmap=NULL; } if(m_bModeless && m_bChangeDocSwitch) { acDocManager->enableDocumentActivation(); m_bChangeDocSwitch=FALSE; } } int CModelessDialog::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CAcUiDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here #if (ADS>14) if(m_bModeless && acDocManager->isDocumentActivationEnabled() && acDocManager->disableDocumentActivation()==Acad::eOk) { m_bChangeDocSwitch=TRUE; } #endif return 0; } void CModelessDialog::OnClose() { if(m_bModeless) { //DestroyWindow(); CRect rect; GetWindowRect(&rect); WriteReg(rect.TopLeft().x,rect.TopLeft().y); /* if(m_bChangeDocSwitch) { acDocManager->enableDocumentActivation(); m_bChangeDocSwitch=FALSE; }*/ } CAcUiDialog::OnClose(); } LONG_PTR CModelessDialog::onAcadKeepFocus( UINT_PTR, LONG_PTR ) { if(g_bAutoFocus) { POINT pt; ::GetCursorPos(&pt); CRect rect; GetWindowRect(&rect); if(!(rect.PtInRect(pt))) { return FALSE; } else return TRUE; } return TRUE; } void CModelessDialog::AnimateMoveWindow(int step) { CRect rectWindow; GetWindowRect(rectWindow); if(!m_bHide)//将要最小化 { CRect rectClient; GetClientRect(rectClient); ClientToScreen(rectClient); m_nCapHeight=rectClient.top-rectWindow.top; m_nBorderHeight=rectWindow.bottom-rectClient.bottom; m_nMaxHeight=rectWindow.Height(); m_nYStep=-rectClient.Height()/step; } else { if(step!=0) m_nYStep=(m_nMaxHeight-m_nCapHeight-m_nBorderHeight)/step; else m_nYStep=0; } if((GetStyle()&WS_CHILD)!=0&&GetParent()!=NULL) GetParent()->ScreenToClient(rectWindow); m_nStepNum=step; if(m_nYStep>0) m_nCurStep=m_nStepNum; else m_nCurStep=0; if(m_nYStep!=0) { if(m_nYStep<0) { m_pWndDC=new CWindowDC(this); m_pMemDC=new CDC; m_pMemDC->CreateCompatibleDC(m_pWndDC); m_pBitmap=new CBitmap; m_pBitmap->CreateCompatibleBitmap(m_pWndDC, rectWindow.Width(), rectWindow.Height()); m_pMemDC->SelectObject(m_pBitmap); #if 0 OSVERSIONINFO osvi; ZeroMemory( &osvi, sizeof( osvi ) ); osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); BOOL bIsWindowsXPorLater = (osvi.dwMajorVersion > 5) ||( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ); if(bIsWindowsXPorLater)//win2000 { typedef BOOL (*PrintWindowFuc)(HWND,HDC,UINT); HINSTANCE hDll=GetModuleHandle(_T("winspool.exe")); if(hDll!=NULL) { PrintWindowFuc pFun=(PrintWindowFuc)::GetProcAddress(hDll,"PrintWindow"); if(pFun!=NULL) { AfxMessageBox(_T("1")); pFun(GetSafeHwnd(),m_pMemDC->m_hDC,0); return; } } hDll=GetModuleHandle(_T("winspool.drv")); if(hDll!=NULL) { PrintWindowFuc pFun=(PrintWindowFuc)::GetProcAddress(hDll,"PrintWindow"); if(pFun!=NULL) { AfxMessageBox(_T("2")); pFun(GetSafeHwnd(),m_pMemDC->m_hDC,0); return; } } } else ::SendMessage(GetSafeHwnd(),WM_PRINT,(WPARAM)m_pMemDC->m_hDC,(LPARAM)(PRF_CHILDREN|PRF_CLIENT|PRF_NONCLIENT|PRF_ERASEBKGND)); #else ::SendMessage(GetSafeHwnd(),WM_PRINT,(WPARAM)m_pMemDC->m_hDC,(LPARAM)(PRF_CHILDREN|PRF_CLIENT|PRF_NONCLIENT|PRF_ERASEBKGND)); #endif } if(m_bThickFrame) ModifyStyle(WS_THICKFRAME,0,0); SetTimer(MOVE_WAITER,1,NULL);//启动动画 } else//直接移动 { if(!m_bHide)//将要最小化 rectWindow.bottom=rectWindow.top+m_nCapHeight+m_nBorderHeight; else rectWindow.bottom=rectWindow.top+m_nMaxHeight; if(m_bThickFrame) ModifyStyle(WS_THICKFRAME,0,0); MoveWindow(rectWindow); if(m_bThickFrame) ModifyStyle(0,WS_THICKFRAME,0); m_nStepNum=0; m_nCurStep=0; } } void CModelessDialog::MaxShow() { KillTimer(MOVE_WAITER); CRect rect; GetWindowRect(rect); rect.bottom=rect.top+m_nMaxHeight; if((GetStyle()&WS_CHILD)!=0&&GetParent()!=NULL) GetParent()->ScreenToClient(rect); MoveWindow(rect,TRUE); if(m_pMemDC!=NULL) { delete m_pMemDC; m_pMemDC=NULL; } if(m_pWndDC!=NULL) { delete m_pWndDC; m_pWndDC=NULL; } if(m_pBitmap!=NULL) { delete m_pBitmap; m_pBitmap=NULL; } m_nStepNum=0; m_nCurStep=0; m_nYStep=0; m_bHide=FALSE;//进入最大状态 if(m_bThickFrame) ModifyStyle(0,WS_THICKFRAME,0); RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE|RDW_UPDATENOW|RDW_ALLCHILDREN); } void CModelessDialog::OnTimer(UINT_PTR nIDEvent) { #if ADS==15//有问题,下拉列表,待解决... //if(nIDEvent==AUTOFOCUS_TIMER)//2002用此机制实现自动恢复光标 //{ // if(g_bAutoFocus) // { // POINT pt; // ::GetCursorPos(&pt); // CRect rect; // GetWindowRect(&rect); // if(!(rect.PtInRect(pt))) // { // CWnd* pWnd=GetFocus(); // HWND hw=pWnd->GetSafeHwnd(); // if(hw==GetSafeHwnd()||IsChild(pWnd)) // { // acedGetAcadFrame()->SetFocus(); // } // } // } // return; //} #endif if(m_bAutoHide) { if(nIDEvent == INIT_MONITOR_PT) { KillTimer(INIT_MONITOR_PT); SetTimer(MONITOR_PT,g_nAutoHideTime/2,NULL); } else if(nIDEvent == MONITOR_PT)//check if mouse is still in hItem rect { POINT pt; ::GetCursorPos(&pt); CRect rect; GetWindowRect(&rect); BOOL bPtIn=rect.PtInRect(pt); if(m_nStepNum>0)//正在缩放过程中 { if((bPtIn&&m_nYStep<0)||//正在缩小,但点返回窗口 (!bPtIn&&m_nYStep>0))//正在放大,但点移出窗口 m_nYStep*=-1;//反向 } else if(bPtIn==m_bHide)//当前没有在缩放过程中,并且动作事件发生 { if(!bPtIn) { CWnd* pWnd=GetFocus(); if(pWnd==this||(pWnd!=NULL&&IsChild(pWnd)))//下拉列表 return; } static bool bWait=false; if(bWait)//正在等待缩放,启动 { bWait=false;//取消等待缩放状态 AnimateMoveWindow(g_nAnimateStepNum); } else bWait=true;//进入等待缩放状态 } } else if(nIDEvent==MOVE_WAITER&&m_nStepNum>0) { if(m_nYStep<0)//正在minimize { if(m_nCurStepScreenToClient(rectWindow); rectWindow.bottom+=m_nYStep; MoveWindow(rectWindow,TRUE); m_pWndDC->BitBlt(0,m_nCapHeight, rectWindow.Width(),rectWindow.Height()-m_nCapHeight ,m_pMemDC, 0,m_nCapHeight+m_nMaxHeight-rectWindow.Height(), SRCCOPY); CRect rect; GetClientRect(rect); ValidateRect(rect); } else//minimize over { KillTimer(MOVE_WAITER); CRect rect; GetWindowRect(rect); rect.bottom=rect.top+m_nCapHeight+m_nBorderHeight; if((GetStyle()&WS_CHILD)!=0&&GetParent()!=NULL) GetParent()->ScreenToClient(rect); MoveWindow(rect); if(m_bThickFrame) ModifyStyle(0,WS_THICKFRAME,0); m_nStepNum=0; m_nCurStep=0; m_bHide=TRUE;//进入最小状态 } } else if(m_nYStep>0)//正在maximize { if(m_nCurStep>0)//动画继续 { m_nCurStep--; CRect rectWindow; GetWindowRect(rectWindow); if((GetStyle()&WS_CHILD)!=0&&GetParent()!=NULL) GetParent()->ScreenToClient(rectWindow); rectWindow.bottom+=m_nYStep; MoveWindow(rectWindow,FALSE); m_pWndDC->BitBlt(0,m_nCapHeight, rectWindow.Width(),rectWindow.Height()-m_nCapHeight ,m_pMemDC, 0,m_nMaxHeight-rectWindow.Height()+m_nCapHeight, SRCCOPY); CRect rect; GetClientRect(rect); ValidateRect(rect); } else//Maximize over MaxShow(); } } } else CAcUiDialog::OnTimer(nIDEvent); } void CModelessDialog::LockAutoHide() { if(m_bAutoHide) { m_bAutoHide=FALSE; KillTimer(MONITOR_PT); MSG msg; while(::PeekMessage(&msg, m_hWnd, WM_TIMER, WM_TIMER, PM_REMOVE)); } } void CModelessDialog::UnlockAutoHide() { m_bAutoHide=TRUE; SetTimer(INIT_MONITOR_PT,g_nInitAutoHideTime,NULL); } XPushAutoHide::XPushAutoHide(CModelessDialog *pDlg):m_bAutoHide(FALSE) { m_pDialog=pDlg; if(m_pDialog->m_bModeless) { m_bAutoHide=pDlg->m_bAutoHide; if(m_bAutoHide) m_pDialog->LockAutoHide(); } } XPushAutoHide::~XPushAutoHide() { if(m_pDialog->m_bModeless) { if(m_bAutoHide) m_pDialog->UnlockAutoHide(); } } void CModelessDialog::OnNcLButtonDown(UINT nHitTest,CPoint point) { if(m_bHide||m_nStepNum>0) MaxShow(); CAcUiDialog::OnNcLButtonDown(nHitTest,point); } int CModelessDialog::MessageBox(LPCTSTR lpszText,LPCTSTR lpszCaption,UINT nType) { XPushAutoHide noAutoHide(this); return CAcUiDialog::MessageBox(lpszText,lpszCaption,nType); } BOOL CModelessDialog::OnCommand(WPARAM wParam,LPARAM lParam) { XPushAutoHide *pAH=NULL; UINT nID = LOWORD(wParam); HWND hWndCtrl = (HWND)lParam; int nCode = HIWORD(wParam); CWnd *pWnd=FromHandle(hWndCtrl); if(pWnd!=NULL)//控件通知 { //判断是否是下拉列表 //GetWindowLong(pWnd->GetSafeHwnd(), //if(pWnd->IsKindOf(RUNTIME_CLASS(CComboBox))) { if(nCode==CBN_CLOSEUP)//关下拉列表 pAH=new XPushAutoHide(this); } } BOOL bRet=CAcUiDialog::OnCommand(wParam,lParam); if(pAH!=NULL) delete pAH; return bRet; } BOOL CModelessDialog::PreTranslateMessage(MSG* pMsg) { if(m_bModeless && pMsg->message==WM_KEYDOWN) { CWnd *pWndPar=CWnd::FromHandle(pMsg->hwnd)->GetParent(); if(pMsg->hwnd==m_hWnd ||pWndPar && pWndPar->m_hWnd==m_hWnd) { if(pMsg->wParam==VK_ESCAPE) { PostMessage(WM_CLOSE); return TRUE; } else if(pMsg->wParam==VK_RETURN)//modified by whl on 050410 { CWnd*pWnd=CWnd::FromHandle(pMsg->hwnd); if(pWnd!=NULL&&pWnd->IsKindOf(RUNTIME_CLASS(CEdit))) { int iStyle=pWnd->GetStyle(); if((iStyle&ES_WANTRETURN)!=0&& (iStyle&ES_MULTILINE)!=0)//允许多行Edit换行操作 return CAcUiDialog::PreTranslateMessage(pMsg); } return TRUE; } } } //if(pMsg->message==WM_SIZE&&m_bAutoHide) //{ // if(!IsShowNormal()) // { // if(pMsg->message==WM_SIZE) // return TRUE;//自动缩放时不再发送WM_SIZE // } //} if (pMsg->message >= WM_MOUSEFIRST &&pMsg->message <= WM_MOUSELAST) { MSG msg; ::CopyMemory(&msg, pMsg, sizeof(MSG)); HWND hWndParent = ::GetParent(msg.hwnd); while (hWndParent && hWndParent != m_hWnd) { msg.hwnd = hWndParent; hWndParent = ::GetParent(hWndParent); } if(msg.hwnd) m_wndToolTip.RelayEvent(&msg); } return CAcUiDialog::PreTranslateMessage(pMsg); } BOOL CModelessDialog::AddTip(UINT idControl) { HINSTANCE hInstance=NULL; CWnd *pWnd = GetDlgItem(idControl); if(!pWnd) return FALSE; int nRet; CString strTip; if(!hInstance) nRet=strTip.LoadString(idControl); else { TCHAR szTemp[1024]=_T(""); nRet=::LoadString(hInstance, idControl, szTemp, 1023); if(nRet) strTip=szTemp; } if(nRet) nRet=m_wndToolTip.AddTool(pWnd,strTip); return (nRet!=0); } BOOL CModelessDialog::AddTip(UINT idControl, const TCHAR *str) { CWnd *pWnd = GetDlgItem(idControl); if(!pWnd) return FALSE; return m_wndToolTip.AddTool(pWnd,str); } HBRUSH CModelessDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CAcUiDialog::OnCtlColor(pDC, pWnd, nCtlColor); if(pWnd->IsWindowEnabled()) { CToolInfo toolInfo; if(m_wndToolTip.GetToolInfo(toolInfo, pWnd)) //pDC->SetTextColor(RGB(0,0,255)); pDC->SetTextColor(RGB(0,140,235)); } return hbr; }