popup.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 251 行

CPP
251
字号
#include "stdafx.h"
#include <objbase.h>
#include <initguid.h>
#include "Popup.h"
#include "Tools.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


///////////////////////////////////////////////////////////////////////////////
CPopup::CPopup () : m_pCaller (NULL), m_pControl (NULL), m_pEvents (NULL),
                    m_hPrevParentCtrl (NULL), m_bDestroy (false)
{
}

///////////////////////////////////////////////////////////////////////////////
bool CPopup::Display (CWnd* pControl, CWnd* pCaller, CRect& rcCaller, IPopupCtrlEvent* pEvents)
{
    if ( pControl == NULL )
    {
        delete this;
        return false;
    }
    m_pControl = pControl;
    m_pCaller = pCaller;
    m_pEvents = pEvents;

    if ( m_pEvents != NULL && !m_pEvents->OnInit() )
    {
        delete this;
        return false;
    }
    // Calculate the most appropriate position for the left-top corner of control
    // By default, at left and bottom of the caller
    CPoint pt (rcCaller.left, rcCaller.bottom);
    CWindowRect rcCtrl (m_pControl);

    // Alignment at right if necessary
    if ( pt.x + rcCtrl.Width() > ::GetSystemMetrics (SM_CXSCREEN) )
    {
        pt.x = rcCaller.right-rcCtrl.Width();
    }
    // Alignment at top if necessary
    if ( pt.y + rcCtrl.Height() > ::GetSystemMetrics (SM_CYSCREEN) )
    {
        pt.y = rcCaller.top-rcCtrl.Height();
    }
    // Adjustments to keep control into screen
    if ( pt.x + rcCtrl.Width() > ::GetSystemMetrics (SM_CXSCREEN) )
    {
        pt.x = ::GetSystemMetrics (SM_CXSCREEN)-rcCtrl.Width();
    }
    if ( pt.y + rcCtrl.Height() > ::GetSystemMetrics (SM_CYSCREEN) )
    {
        pt.y = ::GetSystemMetrics (SM_CYSCREEN)-rcCtrl.Height();
    }
    if ( pt.x < 0 ) pt.x = 0;
    if ( pt.y < 0 ) pt.y = 0;

    if ( !CMiniFrameWnd::Create (NULL, &afxChNil, WS_POPUP|(m_pCaller != NULL ? MFS_SYNCACTIVE : 0),
                                 CRect (pt.x, pt.y, pt.x+rcCtrl.Width(), pt.y+rcCtrl.Height()),
                                 m_pControl->GetParentFrame()) )
    {
        return false;
    }
    m_hPrevParentCtrl = m_pControl->SetParent (this)->GetSafeHwnd();
    m_pControl->SetWindowPos (NULL, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
    ShowWindow (SW_SHOW);

    if ( m_pEvents != NULL )
    {
        m_pEvents->OnShow();
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////
void CPopup::EndPopup( bool bAbort, bool bSetFocus )
{
   bool bDestroy = m_bDestroy;  // change
   m_bDestroy = true;           // change

   if ( m_pEvents )
      m_pEvents->OnHide( bAbort );

   ASSERT( m_pControl->m_hWnd );
   m_pControl->ShowWindow( SW_HIDE );
   ASSERT( m_hPrevParentCtrl );
   ::SetParent( m_pControl->m_hWnd, m_hPrevParentCtrl );

   // Do a local copy of the pointer because DestroyWindow deletes the
   // object and m_pCaller will not be valid after the delete.
   CWnd *pCaller = m_pCaller;

   if ( bDestroy == false )    //change
      DestroyWindow( );

   if ( bSetFocus && pCaller )
      pCaller->SetFocus( );
}


///////////////////////////////////////////////////////////////////////////////
BOOL CPopup::PreTranslateMessage (MSG* pMsg)
{
    bool bEnd = false, bAbort = false, bResult = false;
    int  nCode = doNothing;

    switch ( pMsg->message )
    {
        case WM_KEYDOWN:
            // Default action for <Escape> key
            if ( pMsg->wParam == VK_ESCAPE )
            {
                bEnd = bAbort = bResult = true;
                break;
            }
            if ( m_pEvents != NULL )
            {
                IPopupCtrlEvent* pEvents = m_pEvents;

                // Search for the interface for the correct object (referenced by pMsg->hwnd)
                if ( pMsg->hwnd != m_pControl->m_hWnd )
                {
                    pEvents = m_pEvents->GetInterfaceOf (pMsg->hwnd);
                }
                if ( pEvents != NULL )
                {
                    nCode = pEvents->OnKeyDown (pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
                }
            }
            break;

        case WM_LBUTTONDOWN:
            if ( m_pEvents != NULL )
            {
                IPopupCtrlEvent* pEvents = m_pEvents;

                // Search for the interface for the correct object
                if ( pMsg->hwnd != m_pControl->m_hWnd )
                {
                    pEvents = m_pEvents->GetInterfaceOf (pMsg->hwnd);
                }
                if ( pEvents != NULL )
                {
                    nCode = pEvents->OnLButtonDown (pMsg->wParam, CPoint ((short)LOWORD(pMsg->lParam), (short)HIWORD(pMsg->lParam)));
                }
            }
            break;
        case WM_LBUTTONDBLCLK:
            if ( m_pEvents != NULL )
            {
                IPopupCtrlEvent* pEvents = m_pEvents;

                // Search for the interface for the correct object
                if ( pMsg->hwnd != m_pControl->m_hWnd )
                {
                    pEvents = m_pEvents->GetInterfaceOf (pMsg->hwnd);
                }
                if ( pEvents != NULL )
                {
                    nCode = pEvents->OnLButtonDblClk(pMsg->wParam, CPoint ((short)LOWORD(pMsg->lParam), (short)HIWORD(pMsg->lParam)));
                }
            }
            break;
        case WM_LBUTTONUP:
            if ( m_pEvents != NULL )
            {
                IPopupCtrlEvent* pEvents = m_pEvents;

                // Search for the interface for the correct object
                if ( pMsg->hwnd != m_pControl->m_hWnd )
                {
                    pEvents = m_pEvents->GetInterfaceOf (pMsg->hwnd);
                }
                if ( pEvents != NULL )
                {
                    nCode = pEvents->OnLButtonUp (pMsg->wParam, CPoint ((short)LOWORD(pMsg->lParam), (short)HIWORD(pMsg->lParam)));
                }
            }
            break;
    }
    switch ( nCode )
    {
        case noSend:
            bResult = true;
            break;

        case end:
            bEnd = bResult = true;
            break;

        case abort:
            bEnd = bAbort = bResult = true;
            break;
    }
    if ( !bResult )
    {
        bResult = CMiniFrameWnd::PreTranslateMessage (pMsg) != 0;
    }
    if ( bEnd )
    {
        EndPopup (bAbort);
    }
    return bResult;
}

///////////////////////////////////////////////////////////////////////////////
void CPopup::PostNcDestroy ()
{
    delete this;
}

///////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP (CPopup, CMiniFrameWnd)
    //{{AFX_MSG_MAP(CPopup)
    ON_WM_ACTIVATE()
    ON_WM_CANCELMODE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP ()

IMPLEMENT_DYNCREATE (CPopup, CMiniFrameWnd);

///////////////////////////////////////////////////////////////////////////////
void CPopup::OnActivate (UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    CMiniFrameWnd::OnActivate (nState, pWndOther, bMinimized);

    if(nState == WA_INACTIVE && !m_bDestroy )
    {
        CFrameWnd* pFrame = NULL;
        bool       bSetFocus = false;

        if ( m_pCaller != NULL && (pFrame=m_pCaller->GetParentFrame()) != NULL && pWndOther != NULL )
        {
            bSetFocus = (pWndOther->m_hWnd == pFrame->m_hWnd);
        }
        EndPopup (true, bSetFocus);
    }
}

///////////////////////////////////////////////////////////////////////////////
void CPopup::OnCancelMode ()
{
    PostMessage (WM_DESTROY);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?