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

📄 winutil.cpp

📁 包裝ffmpeg中的codecs成為DirectShow中的transform filter
💻 CPP
📖 第 1 页 / 共 5 页
字号:

        SelectPalette(m_hdc,m_hPalette,m_bBackground || bForceBackground);
        SelectPalette(m_MemoryDC,m_hPalette,m_bBackground);
    }

    //  If we grab a critical section here we can deadlock
    //  with the window thread because one of the side effects
    //  of RealizePalette is to send a WM_PALETTECHANGED message
    //  to every window in the system.  In our handling
    //  of WM_PALETTECHANGED we used to grab this CS too.
    //  The really bad case is when our renderer calls DoRealisePalette()
    //  while we're in the middle of processing a palette change
    //  for another window.
    //  So don't hold the critical section while actually realising
    //  the palette.  In any case USER is meant to manage palette
    //  handling - we shouldn't have to serialize everything as well
    ASSERT(CritCheckOut(&m_WindowLock));
    ASSERT(CritCheckOut(&m_PaletteLock));

    EXECUTE_ASSERT(RealizePalette(m_hdc) != GDI_ERROR);
    EXECUTE_ASSERT(RealizePalette(m_MemoryDC) != GDI_ERROR);

    return (GdiFlush() == FALSE ? S_FALSE : S_OK);
}


// This is the global window procedure

LRESULT CALLBACK WndProc(HWND hwnd,         // Window handle
                         UINT uMsg,         // Message ID
                         WPARAM wParam,     // First parameter
                         LPARAM lParam)     // Other parameter
{

    // Get the window long that holds our window object pointer
    // If it is NULL then we are initialising the window in which
    // case the object pointer has been passed in the window creation
    // structure.  IF we get any messages before WM_NCCREATE we will
    // pass them to DefWindowProc.

    CBaseWindow *pBaseWindow = (CBaseWindow *)GetWindowLongPtr(hwnd,0);
    if (pBaseWindow == NULL) {

        // Get the structure pointer from the create struct.
        // We can only do this for WM_NCCREATE which should be one of
        // the first messages we receive.  Anything before this will
        // have to be passed to DefWindowProc (i.e. WM_GETMINMAXINFO)

        // If the message is WM_NCCREATE we set our pBaseWindow pointer
        // and will then place it in the window structure

        // turn off WS_EX_LAYOUTRTL style for quartz windows
        if (uMsg == WM_NCCREATE) {
            SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x400000);
        }

        if ((uMsg != WM_NCCREATE)
            || (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams)))
        {
            return(DefWindowProc(hwnd, uMsg, wParam, lParam));
        }

        // Set the window LONG to be the object who created us
#ifdef DEBUG
        SetLastError(0);  // because of the way SetWindowLong works
#endif
        LONG_PTR rc = SetWindowLongPtr(hwnd, (DWORD) 0, (LONG_PTR) pBaseWindow);
#ifdef DEBUG
        if (0 == rc) {
            // SetWindowLong MIGHT have failed.  (Read the docs which admit
            // that it is awkward to work out if you have had an error.)
            LONG lasterror = GetLastError();
            ASSERT(0 == lasterror);
            // If this is not the case we have not set the pBaseWindow pointer
            // into the window structure and we will blow up.
        }
#endif

    }
    // See if this is the packet of death
    if (uMsg == MsgDestroy && uMsg != 0) {
        pBaseWindow->DoneWithWindow();
        if (pBaseWindow->m_bDoPostToDestroy) {
            EXECUTE_ASSERT(SetEvent((HANDLE)wParam));
        }
        return 0;
    }
    return pBaseWindow->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
}


// When the window size changes we adjust our member variables that
// contain the dimensions of the client rectangle for our window so
// that we come to render an image we will know whether to stretch

BOOL CBaseWindow::OnSize(LONG Width, LONG Height)
{
    m_Width = Width;
    m_Height = Height;
    return TRUE;
}


// This function handles the WM_CLOSE message

BOOL CBaseWindow::OnClose()
{
    ShowWindow(m_hwnd,SW_HIDE);
    return TRUE;
}


// This is called by the worker window thread when it receives a terminate
// message from the window object destructor to delete all the resources we
// allocated during initialisation. By the time the worker thread exits all
// processing will have been completed as the source filter disconnection
// flushes the image pending sample, therefore the GdiFlush should succeed

HRESULT CBaseWindow::UninitialiseWindow()
{
    // Have we already cleaned up

    if (m_hwnd == NULL) {
        ASSERT(m_hdc == NULL);
        ASSERT(m_MemoryDC == NULL);
        return NOERROR;
    }

    // Release the window resources

    EXECUTE_ASSERT(GdiFlush());

    if (m_hdc)
    {
        EXECUTE_ASSERT(ReleaseDC(m_hwnd,m_hdc));
        m_hdc = NULL;
    }

    if (m_MemoryDC)
    {
        EXECUTE_ASSERT(DeleteDC(m_MemoryDC));
        m_MemoryDC = NULL;
    }

    // Reset the window variables
    m_hwnd = NULL;

    return NOERROR;
}


// This is called by the worker window thread after it has created the main
// window and it wants to initialise the rest of the owner objects window
// variables such as the device contexts. We execute this function with the
// critical section still locked. Nothing in this function must generate any
// SendMessage calls to the window because this is executing on the window
// thread so the message will never be processed and we will deadlock

HRESULT CBaseWindow::InitialiseWindow(HWND hwnd)
{
    // Initialise the window variables

    ASSERT(IsWindow(hwnd));
    m_hwnd = hwnd;

    if (m_bDoGetDC)
    {
        EXECUTE_ASSERT(m_hdc = GetDC(hwnd));
        EXECUTE_ASSERT(m_MemoryDC = CreateCompatibleDC(m_hdc));

        EXECUTE_ASSERT(SetStretchBltMode(m_hdc,COLORONCOLOR));
        EXECUTE_ASSERT(SetStretchBltMode(m_MemoryDC,COLORONCOLOR));
    }

    return NOERROR;
}

HRESULT CBaseWindow::DoCreateWindow()
{
    WNDCLASS wndclass;                  // Used to register classes
    BOOL bRegistered;                   // Is this class registered
    HWND hwnd;                          // Handle to our window

    bRegistered = GetClassInfo(m_hInstance,   // Module instance
                               m_pClassName,  // Window class
                               &wndclass);                 // Info structure

    // if the window is to be used for drawing puposes and we are getting a DC
    // for the entire lifetime of the window then changes the class style to do
    // say so. If we don't set this flag then the DC comes from the cache and is
    // really bad.
    if (m_bDoGetDC)
    {
        m_ClassStyles |= CS_OWNDC;
    }

    if (bRegistered == FALSE) {

        // Register the renderer window class

        wndclass.lpszClassName = m_pClassName;
        wndclass.style         = m_ClassStyles;
        wndclass.lpfnWndProc   = WndProc;
        wndclass.cbClsExtra    = 0;
        wndclass.cbWndExtra    = sizeof(CBaseWindow *);
        wndclass.hInstance     = m_hInstance;
        wndclass.hIcon         = NULL;
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) NULL;
        wndclass.lpszMenuName  = NULL;

        RegisterClass(&wndclass);
    }

    // Create the frame window.  Pass the pBaseWindow information in the
    // CreateStruct which allows our message handling loop to get hold of
    // the pBaseWindow pointer.

    CBaseWindow *pBaseWindow = this;                      // The owner window object
    hwnd = CreateWindowEx(m_WindowStylesEx,               // Extended styles
                          m_pClassName,                   // Registered name
                          TEXT("ActiveMovie Window"),     // Window title
                          m_WindowStyles,                 // Window styles
                          CW_USEDEFAULT,                  // Start x position
                          CW_USEDEFAULT,                  // Start y position
                          DEFWIDTH,                       // Window width
                          DEFHEIGHT,                      // Window height
                          NULL,                           // Parent handle
                          NULL,                           // Menu handle
                          m_hInstance,                    // Instance handle
                          &pBaseWindow);                  // Creation data

    // If we failed signal an error to the object constructor (based on the
    // last Win32 error on this thread) then signal the constructor thread
    // to continue, release the mutex to let others have a go and exit

    if (hwnd == NULL) {
        DWORD Error = GetLastError();
        return AmHresultFromWin32(Error);
    }

    // Check the window LONG is the object who created us
    ASSERT(GetWindowLongPtr(hwnd, 0) == (LONG_PTR)this);

    // Initialise the window and then signal the constructor so that it can
    // continue and then finally unlock the object's critical section. The
    // window class is left registered even after we terminate the thread
    // as we don't know when the last window has been closed. So we allow
    // the operating system to free the class resources as appropriate

    InitialiseWindow(hwnd);

    DbgLog((LOG_TRACE, 2, TEXT("Created window class (%s) HWND(%8.8X)"),
            m_pClassName, hwnd));

    return S_OK;
}


// The base class provides some default handling and calls DefWindowProc

LRESULT CBaseWindow::OnReceiveMessage(HWND hwnd,         // Window handle
                                      UINT uMsg,         // Message ID
                                      WPARAM wParam,     // First parameter
                                      LPARAM lParam)     // Other parameter
{
    ASSERT(IsWindow(hwnd));

    if (PossiblyEatMessage(uMsg, wParam, lParam))
        return 0;

    // This is sent by the IVideoWindow SetWindowForeground method. If the
    // window is invisible we will show it and make it topmost without the
    // foreground focus. If the window is visible it will also be made the
    // topmost window without the foreground focus. If wParam is TRUE then
    // for both cases the window will be forced into the foreground focus

    if (uMsg == m_ShowStageMessage) {

        BOOL bVisible = IsWindowVisible(hwnd);
        SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
                     SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
                     (bVisible ? SWP_NOACTIVATE : 0));

        // Should we bring the window to the foreground
        if (wParam == TRUE) {
            SetForegroundWindow(hwnd);
        }
        return (LRESULT) 1;
    }

    // When we go fullscreen we have to add the WS_EX_TOPMOST style to the
    // video window so that it comes out above any task bar (this is more
    // relevant to WindowsNT than Windows95). However the SetWindowPos call
    // must be on the same thread as that which created the window. The
    // wParam parameter can be TRUE or FALSE to set and reset the topmost

    if (uMsg == m_ShowStageTop) {
        HWND HwndTop = (wParam == TRUE ? HWND_TOPMOST : HWND_NOTOPMOST);
        BOOL bVisible = IsWindowVisible(hwnd);
        SetWindowPos(hwnd, HwndTop, 0, 0, 0, 0,
                     SWP_NOMOVE | SWP_NOSIZE |
                     (wParam == TRUE ? SWP_SHOWWINDOW : 0) |
                     (bVisible ? SWP_NOACTIVATE : 0));
        return (LRESULT) 1;
    }

    // New palette stuff
    if (uMsg == m_RealizePalette) {
        ASSERT(m_hwnd == hwnd);
        return OnPaletteChange(m_hwnd,WM_QUERYNEWPALETTE);
    }

    switch (uMsg) {

        // Repaint the window if the system colours change

    case WM_SYSCOLORCHANGE:

        InvalidateRect(hwnd,NULL,FALSE);
        return (LRESULT) 1;

    // Somebody has changed the palette
    case WM_PALETTECHANGED:

        OnPaletteChange((HWND)wParam,uMsg);
        return (LRESULT) 0;

        // We are about to receive the keyboard focus so we ask GDI to realise
        // our logical palette again and hopefully it will be fully installed
        // without any mapping having to be done during any picture rendering

    case WM_QUERYNEWPALETTE:
        ASSERT(m_hwnd == hwnd);
        return OnPaletteChange(m_hwnd,uMsg);

    // do NOT fwd WM_MOVE. the parameters are the location of the parent
    // window, NOT what the renderer should be looking at.  But we need
    // to make sure the overlay is moved with the parent window, so we
    // do this.
    case WM_MOVE:
        if (IsWindowVisible(m_hwnd)) {
            PostMessage(m_hwnd,WM_PAINT,0,0);
        }
        break;

    // Store the width and height as useful base class members

    case WM_SIZE:

        OnSize(LOWORD(lParam), HIWORD(lParam));
        return (LRESULT) 0;

    // Intercept the WM_CLOSE messages to hide the window

    case WM_CLOSE:

        OnClose();
        return (LRESULT) 0;
    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}


// This handles the Windows palette change messages - if we do realise our
// palette then we return TRUE otherwise we return FALSE. If our window is
// foreground application then we should get first choice of colours in the
// system palette entries. We get best performance when our logical palette
// includes the standard VGA colours (at the beginning and end) otherwise
// GDI may have to map from our palette to the device palette while drawing

LRESULT CBaseWindow::OnPaletteChange(HWND hwnd,UINT Message)
{
    // First check we are not changing the palette during closedown

    if (m_hwnd == NULL || hwnd == NULL) {
        return (LRESULT) 0;

⌨️ 快捷键说明

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