⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winctrl.cpp

📁 包裝ffmpeg中的codecs成為DirectShow中的transform filter
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
// File: WinCtrl.cpp
//
// Desc: DirectShow base classes - implements video control interface class.
//
// Copyright (c) 1992-2002 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


#include <streams.h>

// The control interface methods require us to be connected

#define CheckConnected(pin,code)                    \
{                                                   \
    if (pin == NULL) {                              \
        ASSERT(!TEXT("Pin not set"));               \
    } else if (pin->IsConnected() == FALSE) {       \
        return (code);                              \
    }                                               \
}

// This checks to see whether the window has a drain. An application can in
// most environments set the owner/parent of windows so that they appear in
// a compound document context (for example). In this case, the application
// would probably like to be told of any keyboard/mouse messages. Therefore
// we pass these messages on untranslated, returning TRUE if we're successful

BOOL WINAPI PossiblyEatMessage(HWND hwndDrain, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (hwndDrain != NULL && !InSendMessage())
    {
        switch (uMsg)
        {
            case WM_CHAR:
            case WM_DEADCHAR:
            case WM_KEYDOWN:
            case WM_KEYUP:
            case WM_LBUTTONDBLCLK:
            case WM_LBUTTONDOWN:
            case WM_LBUTTONUP:
            case WM_MBUTTONDBLCLK:
            case WM_MBUTTONDOWN:
            case WM_MBUTTONUP:
            case WM_MOUSEACTIVATE:
            case WM_MOUSEMOVE:
            // If we pass this on we don't get any mouse clicks
            //case WM_NCHITTEST:
            case WM_NCLBUTTONDBLCLK:
            case WM_NCLBUTTONDOWN:
            case WM_NCLBUTTONUP:
            case WM_NCMBUTTONDBLCLK:
            case WM_NCMBUTTONDOWN:
            case WM_NCMBUTTONUP:
            case WM_NCMOUSEMOVE:
            case WM_NCRBUTTONDBLCLK:
            case WM_NCRBUTTONDOWN:
            case WM_NCRBUTTONUP:
            case WM_RBUTTONDBLCLK:
            case WM_RBUTTONDOWN:
            case WM_RBUTTONUP:
            case WM_SYSCHAR:
            case WM_SYSDEADCHAR:
            case WM_SYSKEYDOWN:
            case WM_SYSKEYUP:

                DbgLog((LOG_TRACE, 2, TEXT("Forwarding %x to drain")));
                PostMessage(hwndDrain, uMsg, wParam, lParam);

                return TRUE;
        }
    }
    return FALSE;
}


// This class implements the IVideoWindow control functions (dual interface)
// we support a large number of properties and methods designed to allow the
// client (whether it be an automation controller or a C/C++ application) to
// set and get a number of window related properties such as it's position.
// We also support some methods that duplicate the properties but provide a
// more direct and efficient mechanism as many values may be changed in one

CBaseControlWindow::CBaseControlWindow(
                        CBaseFilter *pFilter,        // Owning filter
                        CCritSec *pInterfaceLock,    // Locking object
                        TCHAR *pName,                // Object description
                        LPUNKNOWN pUnk,              // Normal COM ownership
                        HRESULT *phr) :              // OLE return code

    CBaseVideoWindow(pName,pUnk),
    m_pInterfaceLock(pInterfaceLock),
    m_hwndOwner(NULL),
    m_hwndDrain(NULL),
    m_bAutoShow(TRUE),
    m_pFilter(pFilter),
    m_bCursorHidden(FALSE),
    m_pPin(NULL)
{
    ASSERT(m_pFilter);
    ASSERT(m_pInterfaceLock);
    ASSERT(phr);
    m_BorderColour = VIDEO_COLOUR;
}


// Set the title caption on the base window, we don't do any field checking
// as we really don't care what title they intend to have. We can always get
// it back again later with GetWindowText. The only other complication is to
// do the necessary string conversions between ANSI and OLE Unicode strings

STDMETHODIMP CBaseControlWindow::put_Caption(BSTR strCaption)
{
    CheckPointer(strCaption,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
#ifdef UNICODE
    SetWindowText(m_hwnd, strCaption);
#else
    CHAR Caption[CAPTION];

    WideCharToMultiByte(CP_ACP,0,strCaption,-1,Caption,CAPTION,NULL,NULL);
    SetWindowText(m_hwnd, Caption);
#endif
    return NOERROR;
}


// Get the current base window title caption, once again we do no real field
// checking. We allocate a string for the window title to be filled in with
// which ensures the interface doesn't fiddle around with getting memory. A
// BSTR is a normal C string with the length at position (-1), we use the
// WriteBSTR helper function to create the caption to try and avoid OLE32

STDMETHODIMP CBaseControlWindow::get_Caption(BSTR *pstrCaption)
{
    CheckPointer(pstrCaption,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    WCHAR WideCaption[CAPTION];

#ifdef UNICODE
    GetWindowText(m_hwnd,WideCaption,CAPTION);
#else
    // Convert the ASCII caption to a UNICODE string

    TCHAR Caption[CAPTION];
    GetWindowText(m_hwnd,Caption,CAPTION);
    MultiByteToWideChar(CP_ACP,0,Caption,-1,WideCaption,CAPTION);
#endif
    return WriteBSTR(pstrCaption,WideCaption);
}


// Set the window style using GWL_EXSTYLE

STDMETHODIMP CBaseControlWindow::put_WindowStyleEx(long WindowStyleEx)
{
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);

    // Should we be taking off WS_EX_TOPMOST

    if (GetWindowLong(m_hwnd,GWL_EXSTYLE) & WS_EX_TOPMOST) {
        if ((WindowStyleEx & WS_EX_TOPMOST) == 0) {
            SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) FALSE,(LPARAM) 0);
        }
    }

    // Likewise should we be adding WS_EX_TOPMOST

    if (WindowStyleEx & WS_EX_TOPMOST) {
        SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) TRUE,(LPARAM) 0);
        WindowStyleEx &= (~WS_EX_TOPMOST);
        if (WindowStyleEx == 0) return NOERROR;
    }
    return DoSetWindowStyle(WindowStyleEx,GWL_EXSTYLE);
}


// Gets the current GWL_EXSTYLE base window style

STDMETHODIMP CBaseControlWindow::get_WindowStyleEx(long *pWindowStyleEx)
{
    CheckPointer(pWindowStyleEx,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    return DoGetWindowStyle(pWindowStyleEx,GWL_EXSTYLE);
}


// Set the window style using GWL_STYLE

STDMETHODIMP CBaseControlWindow::put_WindowStyle(long WindowStyle)
{
    // These styles cannot be changed dynamically

    if ((WindowStyle & WS_DISABLED) ||
        (WindowStyle & WS_ICONIC) ||
        (WindowStyle & WS_MAXIMIZE) ||
        (WindowStyle & WS_MINIMIZE) ||
        (WindowStyle & WS_HSCROLL) ||
        (WindowStyle & WS_VSCROLL)) {

            return E_INVALIDARG;
    }

    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    return DoSetWindowStyle(WindowStyle,GWL_STYLE);
}


// Get the current GWL_STYLE base window style

STDMETHODIMP CBaseControlWindow::get_WindowStyle(long *pWindowStyle)
{
    CheckPointer(pWindowStyle,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    return DoGetWindowStyle(pWindowStyle,GWL_STYLE);
}


// Change the base window style or the extended styles depending on whether
// WindowLong is GWL_STYLE or GWL_EXSTYLE. We must call SetWindowPos to have
// the window displayed in it's new style after the change which is a little
// tricky if the window is not currently visible as we realise it offscreen.
// In most cases the client will call get_WindowStyle before they call this
// and then AND and OR in extra bit settings according to the requirements

HRESULT CBaseControlWindow::DoSetWindowStyle(long Style,long WindowLong)
{
    RECT WindowRect;

    // Get the window's visibility before setting the style
    BOOL bVisible = IsWindowVisible(m_hwnd);
    EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));

    // Set the new style flags for the window
    SetWindowLong(m_hwnd,WindowLong,Style);
    UINT WindowFlags = SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE;
    WindowFlags |= SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;

    // Show the window again in the current position

    if (bVisible == TRUE) {

        SetWindowPos(m_hwnd,            // Base window handle
                     HWND_TOP,          // Just a place holder
                     0,0,0,0,           // Leave size and position
                     WindowFlags);      // Just draw it again

        return NOERROR;
    }

    // Move the window offscreen so the user doesn't see the changes

    MoveWindow((HWND) m_hwnd,                     // Base window handle
               GetSystemMetrics(SM_CXSCREEN),     // Current desktop width
               GetSystemMetrics(SM_CYSCREEN),     // Likewise it's height
               WIDTH(&WindowRect),                // Use the same width
               HEIGHT(&WindowRect),               // Keep height same to
               TRUE);                             // May as well repaint

    // Now show the previously hidden window

    SetWindowPos(m_hwnd,            // Base window handle
                 HWND_TOP,          // Just a place holder
                 0,0,0,0,           // Leave size and position
                 WindowFlags);      // Just draw it again

    ShowWindow(m_hwnd,SW_HIDE);

    if (GetParent(m_hwnd)) {

        MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
    }

    MoveWindow((HWND) m_hwnd,        // Base window handle
               WindowRect.left,      // Existing x coordinate
               WindowRect.top,       // Existing y coordinate
               WIDTH(&WindowRect),   // Use the same width
               HEIGHT(&WindowRect),  // Keep height same to
               TRUE);                // May as well repaint

    return NOERROR;
}


// Get the current base window style (either GWL_STYLE or GWL_EXSTYLE)

HRESULT CBaseControlWindow::DoGetWindowStyle(long *pStyle,long WindowLong)
{
    *pStyle = GetWindowLong(m_hwnd,WindowLong);
    return NOERROR;
}


// Change the visibility of the base window, this takes the same parameters
// as the ShowWindow Win32 API does, so the client can have the window hidden
// or shown, minimised to an icon, or maximised to play in full screen mode
// We pass the request on to the base window to actually make the change

STDMETHODIMP CBaseControlWindow::put_WindowState(long WindowState)
{
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    DoShowWindow(WindowState);
    return NOERROR;
}


// Get the current window state, this function returns a subset of the SW bit
// settings available in ShowWindow, if the window is visible then SW_SHOW is
// set, if it is hidden then the SW_HIDDEN is set, if it is either minimised
// or maximised then the SW_MINIMIZE or SW_MAXIMIZE is set respectively. The
// other SW bit settings are really set commands not readable output values

STDMETHODIMP CBaseControlWindow::get_WindowState(long *pWindowState)
{
    CheckPointer(pWindowState,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    ASSERT(pWindowState);
    *pWindowState = FALSE;

    // Is the window visible, a window is termed visible if it is somewhere on
    // the current desktop even if it is completely obscured by other windows
    // so the flag is a style for each window set with the WS_VISIBLE bit

    if (IsWindowVisible(m_hwnd) == TRUE) {

        // Is the base window iconic
        if (IsIconic(m_hwnd) == TRUE) {
            *pWindowState |= SW_MINIMIZE;
        }

        // Has the window been maximised
        else if (IsZoomed(m_hwnd) == TRUE) {
            *pWindowState |= SW_MAXIMIZE;
        }

        // Window is normal
        else {
            *pWindowState |= SW_SHOW;
        }

    } else {
        *pWindowState |= SW_HIDE;
    }
    return NOERROR;
}


// This makes sure that any palette we realise in the base window (through a
// media type or through the overlay interface) is done in the background and
// is therefore mapped to existing device entries rather than taking it over
// as it will do when we this window gets the keyboard focus. An application
// uses this to make sure it doesn't have it's palette removed by the window

STDMETHODIMP CBaseControlWindow::put_BackgroundPalette(long BackgroundPalette)
{
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    CAutoLock cWindowLock(&m_WindowLock);

    // Check this is a valid automation boolean type

    if (BackgroundPalette != OATRUE) {
        if (BackgroundPalette != OAFALSE) {
            return E_INVALIDARG;
        }
    }

    // Make sure the window realises any palette it has again

    m_bBackground = (BackgroundPalette == OATRUE ? TRUE : FALSE);
    PostMessage(m_hwnd,m_RealizePalette,0,0);
    PaintWindow(FALSE);

    return NOERROR;
}


// This returns the current background realisation setting

STDMETHODIMP
CBaseControlWindow::get_BackgroundPalette(long *pBackgroundPalette)
{
    CheckPointer(pBackgroundPalette,E_POINTER);
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
    CAutoLock cWindowLock(&m_WindowLock);

    // Get the current background palette setting

    *pBackgroundPalette = (m_bBackground == TRUE ? OATRUE : OAFALSE);
    return NOERROR;
}


// Change the visibility of the base window

STDMETHODIMP CBaseControlWindow::put_Visible(long Visible)
{
    CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);

    // Check this is a valid automation boolean type

⌨️ 快捷键说明

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