
// Copyright (C) Recursion Company. All rights reserved.

#include "stdafx.h"
#include "vol_user_app_info.h"

CVolNativeWndCreateParam::CVolNativeWndCreateParam (CWnd* pParentWnd, const INT nLeft, const INT nTop, const INT nWidth, const INT nHeight, INT nID, INT nGroupNumber) :
        m_pParentWnd (pParentWnd),
        m_nLeft (nLeft),
        m_nTop (nTop),
        m_nWidth (nWidth),
        m_nHeight (nHeight),
        m_nID (nID),
        m_nGroupNumber (nGroupNumber)
{
	m_pParentWndObject = NULL;
    m_dwStyle = m_dwExStyle = 0;
    m_szCaption = _T ("");
    m_pVolMenu = NULL;
    m_blModalDialog = FALSE;
    m_nDialogResult = 0;
    m_hFont = NULL;
}

// 检查处理参数中没有设置 WS_BORDER 风格而创建后自动增加的情况
void CVolNativeWndCreateParam::CheckBorderStyle (CWnd* pWnd) const
{
    ASSERT (pWnd != NULL);

    if ((m_dwStyle & WS_BORDER) == 0 && (pWnd->GetStyle () & WS_BORDER) != 0)
        pWnd->ModifyStyle (WS_BORDER, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_DRAWFRAME);
}

HFONT CMfcWndObject::CheckGetFont ()
{
    if (m_hFont == NULL)
    {
        LOGFONT infFont;
        GetDefaultFontInfo (&infFont);  // 使用默认字体的信息进行初始化
        m_hFont = ::CreateFontIndirect (&infFont);
    }

    return m_hFont;
}

#define _VOL_WND_CS_VISIBLE  (1 << 0)  // 用作同步记录窗口组件的可视状态

BOOL_P ProcessVolSysMessage (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT& lResult, INT* pnGroupNumber, DWORD* pdwControlState, CVolWindowProcFilters& filters)
{
    ASSERT (pnGroupNumber != NULL && pdwControlState != NULL);

    if (lParam == _VOL_MSG_ACK)
    {
        switch (message)
        {
        case MWM_SET_WND_GROUP_NUMBER:
            *pnGroupNumber = (INT)wParam;
            lResult = _VOL_MSG_ACK;
            return TRUE;

        case MWM_RECORD_WND_VISIBLE_STATE:
            if ((BOOL_P)wParam)
                *pdwControlState |= _VOL_WND_CS_VISIBLE;
            else
                *pdwControlState &= ~_VOL_WND_CS_VISIBLE;
            lResult = _VOL_MSG_ACK;
            return TRUE;
        }

        if (wParam != NULL)
        {
            switch (message)
            {
            case MWM_GET_WND_RECORDED_VISIBLE_STATE:
                *(BOOL*)wParam = ((*pdwControlState & _VOL_WND_CS_VISIBLE) != 0);
                lResult = _VOL_MSG_ACK;
                return TRUE;

            case MWM_GET_WND_GROUP_NUMBER:
                *(INT*)wParam = *pnGroupNumber;
                lResult = _VOL_MSG_ACK;
                return TRUE;

            case MWM_REGISTER_WINDOW_PROC_FILTER:
                filters.RegisterFilter ((IVolWindowProcFilter*)wParam);
                lResult = _VOL_MSG_ACK;
                return TRUE;
        
            case MWM_UNREGISTER_WINDOW_PROC_FILTER:
                filters.UnregisterFilter ((IVolWindowProcFilter*)wParam);
                lResult = _VOL_MSG_ACK;
                return TRUE;
            }
        }
    }

    const BOOL_P blpProcessed = filters.CallFilterBeforeDefProc (hWnd, message, wParam, lParam, lResult);

    if (message == WM_NCDESTROY)
        filters.Cleanup ();

    return blpProcessed;
}

BOOL_P ProcessNativeMessage (HWND hWnd, UINT message, WPARAM& wParam, LPARAM& lParam,
        const BOOL_P blpSkipFocusMessage, IBaseEventListener* pEventListener)
{
    ASSERT (hWnd != NULL);

    if (pEventListener == NULL ||
            (blpSkipFocusMessage && (message == WM_SETFOCUS || message == WM_KILLFOCUS)))
    {
        return FALSE;
    }

    MSG msg;
    ZERO_MEM (&msg, sizeof (msg));
    msg.hwnd = hWnd;
    msg.message = message;
    msg.wParam = wParam;
    msg.lParam = lParam;

    const BOOL_P blpResult = SendNativeMessage (&msg, pEventListener);
    wParam = msg.wParam;
    lParam = msg.lParam;

    return blpResult;
}

BOOL_P SendNativeMessage (MSG* pMsg, IBaseEventListener* pEventListener)
{
    ASSERT (pMsg != NULL);

    if (pEventListener == NULL)
        return FALSE;

    // pMsg->hwnd可能会在处理OnNativeWndMsg的过程中被MFC修改
    const HWND hWnd = pMsg->hwnd;
    ASSERT (hWnd != NULL && ::IsWindow (hWnd));
    return (pEventListener->OnNativeWndMsg (pMsg) || hWnd != pMsg->hwnd || ::IsWindow (hWnd) == FALSE);
}

BOOL_P SendNativeMessage (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, IBaseEventListener* pEventListener)
{
    ASSERT (hWnd != NULL);

    if (pEventListener == NULL)
        return FALSE;

    MSG msg;
    ZERO_MEM (&msg, sizeof (msg));
    msg.hwnd = hWnd;
    msg.message = message;
    msg.wParam = wParam;
    msg.lParam = lParam;

    return SendNativeMessage (&msg, pEventListener);
}

