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

📄 winctrl.cpp

📁 basic class basic classbasic class
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//==========================================================================;
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
//
//--------------------------------------------------------------------------;

// Video control interface base classes, December 1995

#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:
            
#ifndef UNDER_CE
        case WM_MOUSEACTIVATE:
        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:
#endif // UNDER_CE
            
        case WM_MOUSEMOVE:
            // If we pass this on we don't get any mouse clicks
            //case WM_NCHITTEST:
        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) ||
#ifndef UNDER_CE
        (WindowStyle & WS_ICONIC) ||
        (WindowStyle & WS_MAXIMIZE) ||
        (WindowStyle & WS_MINIMIZE) ||
#endif // ~UNDER_CE
        (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
    
    EXECUTE_ASSERT(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;
    
#ifndef UNDER_CE
    // Is the base window iconic
    
    if (IsIconic(m_hwnd) == TRUE) {
        *pWindowState |= SW_MINIMIZE;
    }
    
    // Has the window been maximised
    
    if (IsZoomed(m_hwnd) == TRUE) {
        *pWindowState |= SW_MAXIMIZE;
    }
#endif //~UNDER_CE
    
    // 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) {
        *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);

⌨️ 快捷键说明

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