📄 popupwnd.cpp
字号:
// PopupWnd.cpp : implementation file
//
#include "stdafx.h"
#include "c02ide.h"
#include "PopupWnd.h"
#include "ChildFrm.h"
//#include "Error Demo.h"
#include "LocalErrors.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
/////////////////////////////////////////////////////////////////////////////
// CPopupWnd
CPopupWnd::CPopupWnd():m_rcMargin(0,0,0,0)
{
RegisterWindowClass();
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_csMessage.Empty();
// 0x02xxxxxx forces color match to system palette
// m_dwColor = 0x02A0FFFF; // gray
m_dwColor = 0x0200FFFF; // yellow
m_wAlign = 0;
m_nTimeout = 0;
m_nIDTimer = 0;
}
CPopupWnd::~CPopupWnd()
{
}
BEGIN_MESSAGE_MAP(CPopupWnd, CWnd)
//{{AFX_MSG_MAP(CPopupWnd)
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCRBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_SYSKEYDOWN()
ON_WM_TIMER()
ON_WM_MBUTTONDOWN()
ON_WM_NCMBUTTONDOWN()
//}}AFX_MSG_MAP
ON_COMMAND(ID_BTN_TIP,OnCmdTip)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPopupWnd message handlers
BOOL CPopupWnd::Create( LPCTSTR lpszTitle, DWORD dwStyle,
CPoint cPoint, CWnd* pParentWnd )
{
CBrush cBrush;
UINT nResult;
CSize cSize;
CRect cRect;
cRect.top = cPoint.y; // get the window position
cRect.left = cPoint.x;
cSize = GetMessageSize(); // get a size for the message string
cRect.right = cSize.cx + 15; // size the window to fit the text
cRect.bottom = cSize.cy + 15;
if( m_wAlign & POPUP_RIGHT )
cRect.left -= cRect.right; // position window to right of point
if( m_wAlign & POPUP_BOTTOM )
cRect.top -= cRect.bottom; // position window above point
cBrush.CreateSolidBrush( m_dwColor ); // and set a window color
// Register a custom WndClass and create a window.
// This must be done because CPopupWnd has no icon.
// LPCTSTR lpszPopupClass =
// AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW, ::LoadCursor(NULL,IDC_ARROW),
// HBRUSH(cBrush), NULL );
// DWORD
// dwStyle=ES_MULTILINE|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL
// |ES_AUTOHSCROLL|ES_AUTOVSCROLL |ES_READONLY|WS_POPUPWINDOW |WS_POPUP ;
dwStyle=ES_MULTILINE|WS_VISIBLE|WS_VSCROLL
|ES_AUTOVSCROLL|WS_POPUPWINDOW |WS_POPUP ;
/* dwStyle=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
nResult = CWnd::CreateEx(
//WS_EX_NOPARENTNOTIFY | WS_EX_TOPMOST | WS_EX_WINDOWEDGE,
NULL,
// lpszPopupClass,
MYTIP_NAME,
lpszTitle, //WS_POPUPWINDOW | WS_VISIBLE|WS_POPUP,
dwStyle,
cRect.left, cRect.top,
cRect.right, cRect.bottom,
GetSafeHwnd(), 0 );
// SetCapture(); // === note: using WS_CHILD style does not support capture ===
*/
// BOOL
nResult = CWnd::CreateEx(NULL, MYTIP_NAME, NULL, dwStyle, 0, 0, 0, 0,
pParentWnd->GetSafeHwnd(), NULL, NULL );
if(nResult)
{
SetOwner(pParentWnd);
CRect rc(0,0,0,0);
m_btn.Create(NULL,BS_PUSHBUTTON|BS_FLAT,rc,this,ID_BTN_TIP);
}
/* CRichEditCtrl * my_ctrl;
DWORD dwEditStyle=ES_MULTILINE|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL
| LBS_NOINTEGRALHEIGHT|ES_AUTOHSCROLL|ES_AUTOVSCROLL |ES_READONLY ;
if (!my_ctrl->Create( dwEditStyle, CRect(0,0,0,0), this,
IDC_TIPEDIT ))
{
TRACE(_T("Failed to create output window.\n"));
return -1;
}
*/
// if( m_nTimeout > 0 )
// m_nIDTimer = SetTimer( m_nIDTimer, m_nTimeout*1000, NULL );
return nResult;
}
void CPopupWnd::RegisterWindowClass()
{ WNDCLASS wc;
wc.cbClsExtra=0;
wc.cbWndExtra=CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.hbrBackground=HBRUSH(COLOR_WINDOW+1);
wc.hCursor=::LoadCursor(NULL,IDC_ARROW);
wc.hIcon=NULL;
wc.hInstance=::AfxGetInstanceHandle();
wc.lpfnWndProc=::DefWindowProc;
wc.lpszClassName=MYTIP_NAME;
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
::RegisterClass(&wc);
}
void CPopupWnd::OnPaint()
{
// CRect cRect;
// CPaintDC dc(this); // device context for painting
// GetClientRect( cRect );
// cRect.DeflateRect( 5, 5, 5, 5 );
// dc.SetBkColor( m_dwColor );
// dc.DrawText( m_csMessage, &cRect, DT_LEFT | DT_WORDBREAK ); // | DT_NOCLIP
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);
}
void CPopupWnd::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);
pText="liufhjg\nhjghjgh\njghjgh\njghjghjghjghj\ndsfffffsdfasdfsdf\nliming\nliming\n";//test
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);
// strcpy(m_strText,pText);
HDC hDC=::GetDC(m_hWnd);
HGDIOBJ hGdi=GetStockObject(ANSI_FIXED_FONT);
::SelectObject(hDC, hGdi);
int len=strlen(m_strText);
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>=2)//最后字符不是'\n'
{
strncpy(tstr,pOld,pEnd-pOld);
::GetTextExtentPoint(hDC,tstr,pEnd-pOld-1,&szTemp);
sz.cy+=szTemp.cy;
if(sz.cx<szTemp.cx)
sz.cx=szTemp.cx;
}
::ReleaseDC(m_hWnd,hDC);
// sz.cx+=5;//保留宽度
// 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();
// m_btn.MoveWindow(&rc);
// m_btn.ShowWindow(SW_SHOW);
CPoint pt;
::GetCursorPos(&pt);
pt.x+=::GetSystemMetrics(SM_CXCURSOR)/2;//为避免光标遮住tip,本应获得光标热点与大小,再计算显示位置
pt.y+=::GetSystemMetrics(SM_CYCURSOR)/2;//但晓月儿查遍MSDN不知如何获得当前光标大小和热点位置,只好如此
MoveWindow(pt.x,pt.y,sz.cx,sz.cy);
ShowWindow(SW_SHOWNOACTIVATE);
UpdateWindow();
}
void CPopupWnd::RelayEvent(LPMSG lpMsg)
{
char *pText;
static CPoint ptLast(lpMsg->pt);
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;
if(!m_map.Lookup(m_pchildview->GetSafeHwnd(),(void*&)pText))
AddTool(m_pchildview,"tip");
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -