📄 tipdlg.cpp
字号:
// TipDlg.cpp : implementation file
//
#include "stdafx.h"
#include "c02ide.h"
#include "TipDlg.h"
//#include "C02IDEView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MYTIP_NAME "multi_tip"
#define TIMER_INITIAL 1
#define TIMER_AUTOPOP 4
#define TIMER_RESHOW 3
#define ID_BTN_TIP 152
/////////////////////////////////////////////////////////////////////////////
// CTipDlg dialog
CTipDlg::CTipDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTipDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTipDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_nTimeAutoPop=2000;
m_nTimeReShow=100;
m_nTimeInitial=800;
m_bTimerInitial=FALSE;
m_bTimerPop=FALSE;
m_hCurWnd=NULL;
m_crBg=::GetSysColor(COLOR_INFOBK);
m_crText=::GetSysColor(COLOR_INFOTEXT);
m_rcMargin.bottom=m_rcMargin.top=m_rcMargin.left=m_rcMargin.right=0;
i_ismoved=0;
}
void CTipDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTipDlg)
DDX_Control(pDX, IDC_RICHEDIT, m_editctrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTipDlg, CDialog)
//{{AFX_MSG_MAP(CTipDlg)
ON_WM_PAINT()
ON_WM_DESTROY()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTipDlg message handlers
void CTipDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rc;
GetClientRect(&rc);
HGDIOBJ hGdi=GetStockObject(ANSI_FIXED_FONT);//选择等宽字体
dc.SelectObject(hGdi);
//填充背景色
dc.FillSolidRect(&rc,m_crBg);
//绘边框
rc.bottom--;
rc.right--;
dc.MoveTo(rc.left,rc.top);
dc.LineTo(rc.right,rc.top);
dc.LineTo(rc.right,rc.bottom);
dc.LineTo(rc.left,rc.bottom);
dc.LineTo(rc.left,rc.top);
//保留区域
rc.top++;
rc.left++;
rc.right--;
rc.bottom--;
//用户定义之页边距
rc.top+=m_rcMargin.top;
rc.bottom-=m_rcMargin.bottom;
rc.left+=m_rcMargin.left;
rc.right-=m_rcMargin.right;
dc.SetTextColor(m_crText);
dc.DrawText(m_strText,strlen(m_strText),&rc,0);
// Do not call CDialog::OnPaint() for painting messages
}
void CTipDlg::Show()
{
CMDIFrameWnd * nowframe = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
CMDIChildWnd *nowchild = nowframe->MDIGetActive();
// CChildFrame *nowchild = (CChildFrame *)nowframe->MDIGetActive();
CCrystalTextView *m_pchildview = (CCrystalTextView *)nowchild->GetActiveView();
CCrystalEditView *m_pchildeditview = (CCrystalEditView *)nowchild->GetActiveView();
CPoint mpt;
GetCursorPos(&mpt);
CRect m_rect(0,0,0,0);
m_pchildview->GetWindowRect(m_rect);
// if(!m_rect.PtInRect(mpt))
// return;
GetCursorPos(&mpt);
GetWindowRect(m_rect);
// if(m_rect.PtInRect(mpt))
// return;
if(!m_hCurWnd)
return;
char *pText;
// m_map.Lookup(m_hCurWnd,(void*&)pText);
CRichEditCtrl * m_edit=(CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT);
CString str_text;
m_edit->GetWindowText(str_text);
pText=(char *)(LPCSTR)str_text;//(LPCSTR)
char tstr[1024];
if(pText==LPSTR_TEXTCALLBACK)
{
TOOLTIPTEXT ttt;
ttt.hdr.hwndFrom=m_hWnd;
ttt.hdr.idFrom=(UINT)m_hCurWnd;
ttt.hdr.code=TTN_NEEDTEXT;
ttt.uFlags=TTF_IDISHWND;
ttt.lpszText=m_strText;
GetOwner()->SendMessage(WM_NOTIFY,NULL,(LPARAM)&ttt);
}
else
strcpy(m_strText,pText);
HDC hDC=::GetDC(m_hWnd);
HGDIOBJ hGdi=GetStockObject(ANSI_FIXED_FONT);
::SelectObject(hDC, hGdi);
int len=strlen(m_strText);
if (len==0)
{
Hide();
return;
}
char *p=m_strText,*pOld,*pEnd=m_strText+len;
CSize sz(0,0),szTemp;
//以'\n'为分割符计算每一行显示尺寸,以获得最终显示尺寸
do
{
pOld=p;
p=strchr(p,'\n');
if(p)
{
strncpy(tstr,pOld,p-pOld);
tstr[p-pOld]=0;
::GetTextExtentPoint(hDC,tstr,p-pOld,&szTemp);
sz.cy+=szTemp.cy;
if(sz.cx<szTemp.cx)
sz.cx=szTemp.cx;
p++;
}
}while(p);
if(pEnd-pOld>=1)//最后字符不是'\n'//2
{
strncpy(tstr,pOld,pEnd-pOld);
::GetTextExtentPoint(hDC,tstr,pEnd-pOld,&szTemp);
sz.cy+=szTemp.cy;
if(sz.cx<szTemp.cx)
sz.cx=szTemp.cx;
}
::ReleaseDC(m_hWnd,hDC);
// sz.cx-=15;//保留宽度
sz.cy+=5;//保留高度
//否则显示不好看
// sz.cx+=m_rcMargin.top+m_rcMargin.bottom;
sz.cy+=m_rcMargin.bottom+m_rcMargin.top;
CRect rc(1,1,m_rcMargin.left-1,m_rcMargin.top-1);
rc.NormalizeRect();
CPoint pt;
::GetCursorPos(&pt);
// pt.x+=::GetSystemMetrics(SM_CXCURSOR)/2;//为避免光标遮住tip,本应获得光标热点与大小,再计算显示位置
pt.y+=::GetSystemMetrics(SM_CYCURSOR)/2;//但晓月儿查遍MSDN不知如何获得当前光标大小和热点位置,只好如此
// sz.cx=sz.cx+20;
// sz.cy=sz.cy;
// CRichEditCtrl * m_edit=(CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT);
CRect mrect(0,0,0,0);
// m_edit->GetWindowRect(mrect);
// pt.x=mrect.left;
// pt.y=mrect.top;
// sz.cx=mrect.right-mrect.left;
// sz.cy=mrect.bottom-mrect.top;
mrect.left=0;//0;//pt.x;
mrect.top=0;//0;//pt.y;
// sz.cx+=20;
// sz.cy+=20;
mrect.right=sz.cx;
mrect.bottom=sz.cy;
// m_edit->SetRect(mrect);
m_edit->MoveWindow(mrect);
CScrollBar * p_scrollctrl=NULL;
p_scrollctrl=m_edit->GetScrollBarCtrl(SB_VERT);
if(p_scrollctrl!=NULL&&m_edit->GetScrollPos(SB_VERT)==0)
{
p_scrollctrl->GetWindowRect(mrect);
sz.cx+=mrect.right-mrect.left;
}
// sz.cy+=18;
// 左上角坐标,宽度,高度
MoveWindow(pt.x,pt.y,sz.cx,sz.cy);//
//m_edit->MoveWindow(pt.x,pt.y,sz.cx,sz.cy);
ShowWindow(SW_SHOWNOACTIVATE);
UpdateWindow();
}
BOOL CTipDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
BOOL bRet=CDialog::Create(IDD, pParentWnd);
if(bRet)
{
SetOwner(pParentWnd);
CRect rc(0,0,0,0);
}
return bRet;
}
void CTipDlg::SetDelayTime(UINT nDelay)
{
m_nTimeAutoPop=nDelay;
m_nTimeReShow=nDelay;
m_nTimeInitial=nDelay;
}
void CTipDlg::SetDelayTime(DWORD dwDuration, int iTime)
{
switch(dwDuration)
{
case TTDT_AUTOPOP:
m_nTimeAutoPop=iTime;
break;
case TTDT_RESHOW:
m_nTimeReShow=iTime;
break;
case TTDT_INITIAL:
m_nTimeInitial=iTime;
break;
}
}
BOOL CTipDlg::AddTool(CWnd *pWnd, LPCTSTR lpszText)
{
char *pText;
if(m_map.Lookup(pWnd->GetSafeHwnd(),(void*&)pText))
{
m_map.RemoveKey(pWnd->GetSafeHwnd());
if(pText!=LPSTR_TEXTCALLBACK)
delete []pText;
}
if(lpszText==LPSTR_TEXTCALLBACK)
{
m_map.SetAt(pWnd->GetSafeHwnd(),(void*)lpszText);
}
else
{
pText=new char[strlen(lpszText)+1];
ASSERT(pText);
strcpy(pText,lpszText);
m_map.SetAt(pWnd->GetSafeHwnd(),pText);
if(NULL!=pText)
{
delete pText;
pText=NULL;
}
}
return TRUE;
}
int CTipDlg::GetDelayTime(DWORD dwDuration) const
{
switch(dwDuration)
{
case TTDT_AUTOPOP:
return m_nTimeAutoPop;
break;
case TTDT_RESHOW:
return m_nTimeReShow;
break;
case TTDT_INITIAL:
return m_nTimeInitial;
default:
return 0;
break;
}
}
void CTipDlg::Hide()
{
if(m_bTimerInitial)//OnTimer(1)还未执行
{
KillTimer(TIMER_INITIAL);
m_bTimerInitial=FALSE;
}
if(IsWindowVisible())
{
ShowWindow(SW_HIDE);
KillTimer(TIMER_AUTOPOP);
m_bTimerPop=FALSE;//m_bTimerPop为True必在OnTimer(TIMER_INITIAL)之后
//窗口必然可见
}
}
void CTipDlg::RelayEvent(LPMSG lpMsg)
{
CMDIFrameWnd * nowframe = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
CMDIChildWnd *nowchild = nowframe->MDIGetActive();
// CChildFrame *nowchild = (CChildFrame *)nowframe->MDIGetActive();
CCrystalTextView *m_pchildview = (CCrystalTextView *)nowchild->GetActiveView();
CCrystalEditView *m_pchildeditview = (CCrystalEditView *)nowchild->GetActiveView();
CPoint pt;
::GetCursorPos(&pt);
CRect m_rect(0,0,0,0);
// m_pchildview->GetWindowRect(m_rect);
// if(!m_rect.PtInRect(pt))
// return;
GetWindowRect(m_rect);
if(m_rect.PtInRect(pt)&&IsWindowVisible())
return;
char *pText;//,*ppreText;
static CPoint ptLast(lpMsg->pt);
CRichEditCtrl * m_edit=(CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT);
// m_edit->GetWindowText("adf\nliu\nkll\niii\nlimi\ning");
CString str_text;
m_edit->GetWindowText(str_text);
pText=(char *)(LPCSTR)str_text;//(LPCSTR)
if(!m_map.Lookup(m_pchildview->GetSafeHwnd(),(void*&)pText))
AddTool(m_pchildview,pText);
// m_map.Lookup(m_pchildview->GetSafeHwnd(),(void*&)pText)
// else if(pText!=ppreText)
// {
// DelTool(m_pchildview);
// AddTool(m_pchildview,pText);
// }
if(lpMsg->hwnd==m_hWnd)//||lpMsg->hwnd==m_btn.m_hWnd)
return;
switch(lpMsg->message)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
Hide();
break;
case WM_MOUSEMOVE:
{
if(lpMsg->pt.x=ptLast.x&&lpMsg->pt.y==ptLast.y)//不知道为什么
return;//鼠标不动还有WM_MOUSEMOVE消息只好这样屏蔽
//TRACE("\nMouseMove x:%d,y:%d",lpMsg->pt.x,lpMsg->pt.y);
//活动子窗口指针
// m_map.GetStartPosition;
CMDIFrameWnd * nowframe = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
CMDIChildWnd *nowchild = nowframe->MDIGetActive();
CC02IDEView *m_pchildview = (CC02IDEView *)nowchild->GetActiveView();
//m_editctrl.SetWindowText(m_pchildview->GetBackStr());
m_editctrl.SetWindowText("liunsdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaaa");
if(m_hCurWnd==NULL)//当前工具窗口为空
{
if(m_map.Lookup(lpMsg->hwnd,(void*&)pText))//鼠标在工具窗口内
{
//设置初始化Timer和m_hCurWnd
m_hCurWnd=lpMsg->hwnd;
SetTimer(TIMER_INITIAL,m_nTimeInitial,NULL);
m_bTimerInitial=TRUE;
}
}
else
{
if(m_hCurWnd==lpMsg->hwnd)
{
//在当前工具窗口内移动
if(!m_bTimerInitial)//还没有显示
{
//则重置初始化Timer
KillTimer(TIMER_INITIAL);
SetTimer(TIMER_INITIAL,m_nTimeInitial,NULL);
}
//否则已显示则不做任何动作
}
else
{
//移到当前工具窗口外则重置
Hide();
m_hCurWnd=NULL;
}
}
}
break;
default:
break;
}
ptLast=lpMsg->pt;
}
void CTipDlg::OnTimer(UINT nIDEvent)
{
// CMDIFrameWnd * nowframe = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// CMDIChildWnd *nowchild = nowframe->MDIGetActive();
// CC02IDEView *m_pchildview = (CC02IDEView *)nowchild->GetActiveView();
// m_editctrl.SetWindowText(
// m_pchildview->GetBackStr();
// TODO: Add your message handler code here and/or call default
TRACE("\nnIDEvent:%d",nIDEvent);
switch(nIDEvent)
{
case TIMER_INITIAL:
// m_editctrl.SetWindowText(
// m_pchildview->GetBackStr();
Show();
KillTimer(TIMER_INITIAL);
m_bTimerInitial=FALSE;
SetTimer(TIMER_AUTOPOP,m_nTimeAutoPop,NULL);
m_bTimerPop=TRUE;
break;
case TIMER_AUTOPOP:
if(i_ismoved==0)
return;
Hide();
break;
}
CDialog::OnTimer(nIDEvent);
//CWnd::OnTimer(nIDEvent);
}
void CTipDlg::OnDestroy()
{
if(m_bTimerInitial)
KillTimer(TIMER_INITIAL);
if(m_bTimerPop)
KillTimer(TIMER_AUTOPOP);
char *pText;
HWND hwnd;
for (POSITION pos = m_map.GetStartPosition(); pos != NULL;)
{
m_map.GetNextAssoc(pos,(void*&)hwnd,(void*&)pText);
if(pText!=LPSTR_TEXTCALLBACK)
{
delete []pText;
}
}
m_map.RemoveAll();
CDialog::OnDestroy();
// TODO: Add your message handler code here
}
void CTipDlg::DelTool(CWnd *pWnd)
{
char *pText;
if(m_map.Lookup(pWnd->GetSafeHwnd(),(void*&)pText))
{
m_map.RemoveKey(pWnd->GetSafeHwnd());
if(pText!=LPSTR_TEXTCALLBACK)
delete []pText;
if(pWnd->GetSafeHwnd()==m_hCurWnd)
Hide();
}
}
void CTipDlg::SetTipTextColor(COLORREF clr)
{
m_crText=clr;
}
void CTipDlg::SetTipBkColor(COLORREF clr)
{
m_crBg=clr;
}
COLORREF CTipDlg::GetTipBkColor() const
{
return m_crBg;
}
COLORREF CTipDlg::GetTipTextColor() const
{
return m_crText;
}
void CTipDlg::SetMargin(LPRECT lprc)
{
m_rcMargin.CopyRect(lprc);
}
void CTipDlg::GetMargin(LPRECT lprc) const
{
::CopyRect(lprc,&m_rcMargin);
}
BOOL CTipDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
ModifyRichtrlRect();
m_editctrl.SetBackgroundColor(FALSE,::GetSysColor(COLOR_INFOBK));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
int CTipDlg::ModifyRichtrlRect()
{
/* CRichEditCtrl * m_edit=(CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT);
CRect mrect(0,0,0,0);
m_edit->GetWindowRect(mrect);
// pt.x=mrect.left;
// pt.y=mrect.top;
sz.cx=mrect.right-mrect.left;
sz.cy=mrect.bottom-mrect.top;
*/
// mrect.left=pt.x;
// mrect.top=pt.y;
// mrect.right=pt.x+sz.cx-10;
// mrect.bottom=pt.y+sz.cy-10;
// m_edit->SetRect(mrect);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -