VC实现对话框上信息的显示

鬼谷子
VC实现对话框上信息的显示
  利用 VC的AppWizard,可以很容易地实现工具条和菜单项的ToolTip,或在状态条上显示帮助信息,但要
在对话框的控件上显示ToolTip和在状态条上显示控件信息并不容易实现。现在,我们用VC中的
WM_SETCURSOR 与TTN_NEEDTEXT消息就可达到目的。具体操作如下:  
  一、利用 VC的 MFC AppWizard 生成一个 SDI 或 MDI 的应用程序
  二、编辑对话框控件的字符串资源
  例如:IDC_DBBUTTON1 = “This is 肖天鹏的第一自制按钮\n天鹏",其中字符串“This is肖天鹏的第一自
制按钮“将在鼠标移到控件上时显示在状态条上,字符串“天鹏"将作为 ToolTip 显示。  
  三、建立消息映射
  在对话框的头文件 (*.H) 中加入以下代码:
  protected:
  void SetStatusText(UINT nID=0);
  //{{AFX_MSG(CFileOp1)
  afx_msg void OnDestroy();
  afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
  //}}AFX_MSG
  afx_msg BOOL OnTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult );
  DECLARE_MESSAGE_MAP()
  在对话框的实现文件 (*.CPP) 中加入以下代码:
  BEGIN_MESSAGE_MAP(CFileOp1, CDialog)
  //{{AFX_MSG_MAP(CFileOp1)
  ON_WM_DESTROY()
  ON_WM_SETCURSOR()
  //}}AFX_MSG_MAP
  ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnTipNotvify)
  END_MESSAGE_MAP()
  四、编辑消息处理函数
  BOOL CFileOp1::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  {// TODO: Add your message handler code here and/or call default
  if(pWnd==this)
  SetStatusText();
  else
  {TOOLTIPTEXT m_psttt;
  m_psttt.hdr.hwndFrom=m_hWnd;
  m_psttt.hdr.idFrom=pWnd->GetDlgCtrlID();
  m_psttt.hdr.code=TTN_NEEDTEXT;
  m_psttt.uFlags= TTF_IDISHWND;
  SetStatusText(pWnd->GetDlgCtrlID());
  this->SendMessage(WM_NOTIFY,m_psttt.hdr.idFrom,(LPARAM)&m_psttt); }
  return CDialog::OnSetCursor(pWnd, nHitTest, message);}
  void CFileOp1::OnDestroy()
  {SetStatusText();
  CDialog::OnDestroy();}
  void CFileOp1::SetStatusText(UINT nID)
  {if(nID==0)
  nID=AFX_IDS_IDLEMESSAGE;
  CWnd *pWnd=AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
  if(pWnd)
  {AfxGetMainWnd()->SendMessage(WM_SETMESS
AGESTRING ,nID);
  pWnd->SendMessage(WM_IDLEUPDATECMDUI);
  pWnd->UpdateWindow();}}
  BOOL CFileOp1::OnTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
  { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
  UINT nID =pNMHDR->idFrom;
  if (pTTT->uFlags & TTF_IDISHWND)
  { nID = ::GetDlgCtrlID((HWND)nID);
  if (nID)
  { TCHAR szFullText[256];
  CString StrTipText;
  AfxLoadString(nID,szFullText);
  AfxExtractSubString(StrTipText,szFullText,1,′\n′);
  if(!StrTipText.IsEmpty())
  strcpy(pTTT->lpszText,StrTipText);
  pTTT->hinst = AfxGetResourceHandle();
  return(TRUE); } }
  return(FALSE);}
  五、在 Stdafx.h 文件中加入以下指令:
  #include
  #include
  六、将该对话框作为一个 SDI 或 MDI应用程序的主框架的子窗口,生成这样一个对话框后,当你把鼠标移
到某个控件 ( 必须有相应的字符串资源 )上时,就会出现该控件的 ToolTip和状态条信息。

龙丘居士亦可怜
谈空说有夜不眠
忽闻河东师子吼
拄杖落手心茫然
小山
我也做过一个类似的类
将该类的ReLayEvent置于CWinApp的PreTranslateMessage()中
即可使用,(这一部份程序如下)为通用性我没有做成使用某种特定的取字串方式,只給了一个设制的字串涵数SetInformtion(CString &str); 你可在和适的地方加如入,比如你可在RelayEvent()中的str.Format 处得到Windows ID从而得到相应的字串。
BOOL CFormViewApp::PreTranslateMessage(MSG* pMsg)
{
CMainFrame * pwnd=(CMainFrame *)GetMainWnd();
pwnd->m_Tip.SendMessage(IDW_MTIP,0,(long)(pMsg));//sendMessage to callthe RelayEvent();
//form the pMsg you can get the m_hWnd
//and the m_id to getthe String to show on the CTip window
return CWinApp::PreTranslateMessage(pMsg);
}
class CTip : public CWnd
{
// Construction
public:
CTip();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTip)
public:
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
//}}AFX_VIRTUAL
// Implementation
public:
void ShowTip(CPoint & pt,BOOL nCmd=TRUE);
CRect m_WindowRect;
void SetBKColor(COLORREF * r);//set the Tip's bkColor
void SetInformtion(CString & Str);//set the string that Will be show on the Tip
virtual ~CTip();
// Generated message map functions
protected:
CString m_Information;
CBrush m_bkBrush;
CString m_ClassName;
//{{AFX_MSG(CTip)
afx_msg void OnPaint();
afx_msg LRESULT RelayEvent(long wParam,long lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CPoint m_OldPoint;
HWND m_CurrentOwner;
BOOL m_Statuse;
};
#define IDW_WINDOW 1111
/////////////////////////////////////////////////////////////////////////////
// CTip
CTip::CTip()
{
if(!m_bkBrush.CreateSolidBrush(RGB(156,255,156)))
return;
m_ClassName.Format("%s",::AfxRegisterWndClass(0,NULL,NULL ,NULL));
if(m_ClassName.IsEmpty())
return;
m_Information=_T("Information");
m_WindowRect.bottom=18;
m_WindowRect.left=0;
m_WindowRect.right=112;//11* 10+2
m_WindowRect.top=0;
m_Statuse=FALSE;
m_CurrentOwner=NULL;
m_OldPoint.x=20;//no mease
m_OldPoint.y=20;
}
CTip::~CTip()
{
}
BEGIN_MESSAGE_MAP(CTip, CWnd)
//{{AFX_MSG_MAP(CTip)
ON_WM_PAINT()
//}}AFX_MSG_MAP
ON_MESSAGE(101,RelayEvent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTip message handlers
BOOL CTip::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
BOOL R;
R=CWnd::Create(m_ClassName, NULL, WS_CHILD|WS_BORDER, rect, pParentWnd,IDW_WINDOW,NULL);
SetOwner(pParentWnd);
return R;
}
void CTip::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetBkMode(TRANSPARENT);
dc.FillRect(&m_WindowRect,&m_bkBrush);
m_WindowRect.DeflateRect(1,1,1,1);
dc.DrawText(m_Information,&m_WindowRect,0); // Do not call CWnd::OnPaint() for painting messages
m_WindowRect.InflateRect(1,1,1,1);
}
void CTip::SetInformtion(CString &Str)
{
ASSERT(!Str.IsEmpty());
m_Information=Str;
int nCount=m_Information.GetLength();
m_WindowRect.right=nCount*8+2;//the window will be showed with the mouse
//OnPaint(); this will not uesable so use the Redraw function
RedrawWindow();
}
void CTip::SetBKColor(COLORREF *r)
{
m_bkBrush.DeleteObject();
if(r!=NULL)// else Create a Null Brush
m_bkBrush.CreateSolidBrush(*r);
RedrawWindow();
}
void CTip::ShowTip(CPoint& pt, BOOL nCmd )
{
ASSERT(m_hWnd!=NULL);
if(!nCmd&&m_Statuse)
{
ShowWindow(SW_HIDE);
m_Statuse=FALSE;
return;
}
if(nCmd && !m_Statuse)
{
m_Statuse=TRUE;
ShowWindow(SW_SHOW);
}
MoveWindow(pt.x+15,pt.y,m_WindowRect.Width(),m_WindowRect.Height());
}
LRESULT CTip::RelayEvent(long wParam, long lParam)
{
MSG * p=(MSG *)lParam;
CMainFrame * pWnd=(CMainFrame * )(GetParent());
HWND HView=(pWnd->GetActiveView())->m_hWnd;
CPoint pt(p->pt);
pWnd->ScreenToClient(&pt);
if(p->hwnd==m_hWnd||p->hwnd==pWnd->m_hWnd||p->hwnd==HView)
{
if(m_Statuse)
{
m_CurrentOwner=NULL;
ShowTip(m_OldPoint,FALSE);
}
return 0; // Assume the parent will be the mainFrame that will not Receive the Message Information
}
CString str;
switch(p->message)
{
case WM_MOUSEMOVE:
if(m_CurrentOwner==p->hwnd) //have Focused
break;
// GetCapture();
str.Format("Message:%d,lParam :%d",p->message,p->lParam);
SetInformtion(str);
ShowTip(pt);
m_OldPoint=pt;
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_KEYDOWN:
if(m_CurrentOwner==p->hwnd)// this is not the first time the //mouse Focuse on this wnd
break;
m_CurrentOwner=p->hwnd;
// ReleaseCapture();
ShowTip(pt,FALSE);
break;
}
return 1;
}
【在 符号 的大作中提到:】
VC实现对话框上信息的显示
  利用 VC的AppWiza...

I dream i will never dreaming