/--------该类是一个从CWnd派生出来的作为另一个窗体的tooltip----/
class CMsgWnd : public CWnd
{
// Construction
public:
CMsgWnd();
void SetPostion(int x, int y);// Attributes
protected:
    CBitmap m_Bitmap;
BITMAP  bmBitmap;
BOOL    m_bFlag;
LPCTSTR lpWndCls;
HWND    m_hParentWnd;


// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMsgWnd)
//}}AFX_VIRTUAL
public:
virtual ~CMsgWnd();
         BOOL CreateMsgWindow(CWnd* pParentWnd);
// Generated message map functions
protected:
//{{AFX_MSG(CMsgWnd)
afx_msg void OnPaint();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};CMsgWnd::CMsgWnd()
{
m_Bitmap.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP_BK));
m_Bitmap.GetBitmap(&bmBitmap);
    lpWndCls = AfxRegisterWndClass(0);
}CMsgWnd::~CMsgWnd()
{
}
BEGIN_MESSAGE_MAP(CMsgWnd, CWnd)
//{{AFX_MSG_MAP(CMsgWnd)
ON_WM_PAINT()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMsgWnd message handlers
BOOL CMsgWnd::CreateMsgWindow(CWnd* pParentWnd)
{
BOOL ret = CreateEx(0, lpWndCls, "", WS_POPUP, 0, 0, bmBitmap.bmWidth, bmBitmap.bmHeight, pParentWnd->GetSafeHwnd(), NULL, NULL);
m_hParentWnd = pParentWnd->GetSafeHwnd();
if(ret)
{
SetOwner(pParentWnd);
}
return ret;
}void CMsgWnd::OnPaint() 
{
CPaintDC dc(this);
CDC dcMemory;
CRect rect;
GetClientRect(&rect);
    dcMemory.CreateCompatibleDC(NULL);
dcMemory.SelectObject(&m_Bitmap);
dc.StretchBlt(0,
0,
rect.right-rect.left,
rect.bottom-rect.top, 
&dcMemory, 
0,
0,
bmBitmap.bmWidth,    
bmBitmap.bmHeight,
SRCCOPY);
}int CMsgWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;

return 0;
}void CMsgWnd::SetPostion(int x, int y)
{
SetWindowPos(&wndTop, x, y, 350, 230, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}

解决方案 »

  1.   

    CTestWndDlg::CTestWndDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CTestWndDlg::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CTestWndDlg)
    // NOTE: the ClassWizard will add member initialization here
    pMsgWindow = NULL;
    m_bTrack = FALSE;
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }void CTestWndDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTestWndDlg)
    // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
    }BEGIN_MESSAGE_MAP(CTestWndDlg, CDialog)
    //{{AFX_MSG_MAP(CTestWndDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_DESTROY()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CTestWndDlg message handlersBOOL CTestWndDlg::OnInitDialog()
    {
    CDialog::OnInitDialog(); // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon pMsgWindow=new CMsgWnd;
    pMsgWindow->CreateMsgWindow(this);

    return TRUE;  // return TRUE  unless you set the focus to a control
    }// If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.void CTestWndDlg::OnPaint() 
    {
    if (IsIconic())
    {
    CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon
    dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
    CDialog::OnPaint();
    }
    }// The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CTestWndDlg::OnQueryDragIcon()
    {
    return (HCURSOR) m_hIcon;
    }void CTestWndDlg::OnDestroy() 
    {
    if(pMsgWindow != NULL)
    {
    delete pMsgWindow;
    pMsgWindow = NULL;
    }
    CDialog::OnDestroy();
    }void CTestWndDlg::OnMouseMove(UINT nFlags, CPoint point) 
    {
    if(pMsgWindow != NULL)
    {
    pMsgWindow->ShowWindow(SW_HIDE);
    }


    if(!m_bTrack)
    {
    TRACKMOUSEEVENT tme;
    tme.cbSize = sizeof(TRACKMOUSEEVENT);
    tme.dwFlags = TME_LEAVE | TME_HOVER;
    tme.hwndTrack = this->m_hWnd;
    tme.dwHoverTime = 200;

    m_bTrack = ::_TrackMouseEvent(&tme);
    }
    CDialog::OnMouseMove(nFlags, point);
    }LRESULT CTestWndDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    switch(message)
    {
    case WM_MOUSELEAVE:
    m_bTrack = FALSE;
    break;
    case WM_MOUSEHOVER:
    {
    // POINT pt;
    // GetCursorPos(&pt);
    // if(pt.x + 350 > ::GetSystemMetrics (SM_CXSCREEN))
    // {
    // pt.x -= 350;
    // }
    // if(pt.x < 0)
    // {
    // pt.x = 0;
    // }
    // if(pt.y + 230 > ::GetSystemMetrics (SM_CYSCREEN))
    // {
    // pt.y -= 230;
    // }
    // if(pt.y < 0)
    // {
    // pt.y = 0;
    // }
    // if(pMsgWindow != NULL)
    // {
    // pMsgWindow->SetPostion(pt.x, pt.y);
    // pMsgWindow->ShowWindow(SW_SHOWNOACTIVATE);
    // }
    }
    break;
    }

    return CDialog::WindowProc(message, wParam, lParam);
    }BOOL CTestWndDlg::PreTranslateMessage(MSG* pMsg) 
    {
    return CDialog::PreTranslateMessage(pMsg);
    }void CTestWndDlg::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    CPoint pt;
    GetCursorPos(&pt);
    if(pt.x + 350 > ::GetSystemMetrics (SM_CXSCREEN))
    {
    pt.x -= 350;
    }
    if(pt.x < 0)
    {
    pt.x = 0;
    }
    if(pt.y + 230 > ::GetSystemMetrics (SM_CYSCREEN))
    {
    pt.y -= 230;
    }
    if(pt.y < 0)
    {
    pt.y = 0;
    }
    if(pMsgWindow != NULL)
    {
    pMsgWindow->SetPostion(pt.x, pt.y);
        pMsgWindow->ShowWindow(SW_SHOWNOACTIVATE);
    } CDialog::OnLButtonDown(nFlags, point);
    }
      

  2.   

    花了近一个小时,按楼主的代码建了个测试工程,其实已经显示出来了,只不过马上又隐藏起来了而已。把上面的这两行代码按如下改一下:
    if(pt.x + 350 > ::GetSystemMetrics (SM_CXSCREEN))
    {
    pt.x -= 349;      //改这里,减小一个像素
    }
    if(pt.x < 0)
    {
    pt.x = 0;
    }
    if(pt.y + 230 > ::GetSystemMetrics (SM_CYSCREEN))
    {
    pt.y -= 229;      //改这里,也减小一个像素
    }
    吐血吧,就这么简单!
      

  3.   

    另外,如果标志m_bTrack只是为了显示这个图片窗口的话,则形同虚设,当然和它相关的代码也没有用了,写下上述代码的仁兄完成不明白_TrackMouseEvent函数的用法,建议删去与m_bTrack相关的东西及如下代码:if(!m_bTrack)
    {
    TRACKMOUSEEVENT tme;
    tme.cbSize = sizeof(TRACKMOUSEEVENT);
    tme.dwFlags = TME_LEAVE | TME_HOVER;
    tme.hwndTrack = this->m_hWnd;
    tme.dwHoverTime = 200;m_bTrack = ::_TrackMouseEvent(&tme);
    }
      

  4.   

    m_bTrack只是用来判断鼠标移开后的作用啊,比如要停留的时候设为FALSE,然后开始停留就为TRUE,停留后移开鼠标就为FALSE,如些反复,就像tooltip那样啊