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

📄 wxutil.cpp

📁 basic class basic classbasic class
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
//
//--------------------------------------------------------------------------;

//
// helper classes for building multimedia filters
//

#include <streams.h>
#include <dsthread.h>
#include <dsthread.cpp>

//
//  Declare function from largeint.h we need so that PPC can build
//

//
// Enlarged integer divide - 64-bits / 32-bits > 32-bits
//

#ifndef _X86_

#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))

__inline
ULONG
WINAPI
EnlargedUnsignedDivide (
                        IN ULARGE_INTEGER Dividend,
                        IN ULONG Divisor,
                        IN PULONG Remainder
                        )
{
    // return remainder if necessary
    if (Remainder != NULL)
        *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor);
    return (ULONG)(LLtoU64(Dividend) / Divisor);
}

#else
__inline
ULONG
WINAPI
EnlargedUnsignedDivide (
                        IN ULARGE_INTEGER Dividend,
                        IN ULONG Divisor,
                        IN PULONG Remainder
                        )
{
    ULONG ulResult;
    _asm {
        mov eax,Dividend.LowPart
            mov edx,Dividend.HighPart
            mov ecx,Remainder
            div Divisor
            or  ecx,ecx
            jz  short label
            mov [ecx],edx
label:
        mov ulResult,eax
    }
    return ulResult;
}
#endif

// --- CAMEvent -----------------------
CAMEvent::CAMEvent(BOOL fManualReset)
{
    m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);
    ASSERT(m_hEvent);
}

CAMEvent::~CAMEvent()
{
    if (m_hEvent) {
        EXECUTE_ASSERT(CloseHandle(m_hEvent));
    }
}


// --- CAMMsgEvent -----------------------
// One routine.  The rest is handled in CAMEvent

BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout)
{
    // wait for the event to be signalled, or for the
    // timeout (in MS) to expire.  allow SENT messages
    // to be processed while we wait
    DWORD dwWait;
    DWORD dwStartTime;
    
    // set the waiting period.
    DWORD dwWaitTime = dwTimeout;
    
    // the timeout will eventually run down as we iterate
    // processing messages.  grab the start time so that
    // we can calculate elapsed times.
    if (dwWaitTime != INFINITE) {
        dwStartTime = timeGetTime();
    }
    
    do {
        dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE);
        if (dwWait == WAIT_OBJECT_0 + 1) {
            MSG Message;
            PeekMessage(&Message,NULL,0,0,PM_NOREMOVE);
            
            // If we have an explicit length of time to wait calculate
            // the next wake up point - which might be now.
            // If dwTimeout is INFINITE, it stays INFINITE
            if (dwWaitTime != INFINITE) {
                
                DWORD dwElapsed = timeGetTime()-dwStartTime;
                
                dwWaitTime =
                    (dwElapsed >= dwTimeout)
                    ? 0  // wake up with WAIT_TIMEOUT
                    : dwTimeout-dwElapsed;
            }
        }
    } while (dwWait == WAIT_OBJECT_0 + 1);
    
    // return TRUE if we woke on the event handle,
    //        FALSE if we timed out.
    return (dwWait == WAIT_OBJECT_0);
}

// --- CAMThread ----------------------


CAMThread::CAMThread()
: m_EventSend(TRUE)     // must be manual-reset for CheckRequest()
{
    m_hThread = NULL;
}

CAMThread::~CAMThread() {
    Close();
}


// when the thread starts, it calls this function. We unwrap the 'this'
//pointer and call ThreadProc.
DWORD WINAPI
CAMThread::InitialThreadProc(LPVOID pv)
{
    CAMThread * pThread = (CAMThread *) pv;
    
    return pThread->ThreadProc();
}

BOOL
CAMThread::Create()
{
    DWORD threadid;
    
    CAutoLock lock(&m_AccessLock);
    
    if (ThreadExists()) {
        return FALSE;
    }
    
    m_hThread = _internal_CreateThread(
        NULL,
        0,
        CAMThread::InitialThreadProc,
        this,
        0,
        &threadid);
    
    if (!m_hThread) {
        return FALSE;
    }

    return TRUE;
}

DWORD
CAMThread::CallWorker(DWORD dwParam)
{
    // lock access to the worker thread for scope of this object
    CAutoLock lock(&m_AccessLock);
    
    if (!ThreadExists()) {
        return (DWORD) E_FAIL;
    }
    
    // set the parameter
    m_dwParam = dwParam;
    
    // signal the worker thread
    m_EventSend.Set();
    
    // wait for the completion to be signalled
    m_EventComplete.Wait();
    
    // done - this is the thread's return value
    return m_dwReturnVal;
}

// Wait for a request from the client
DWORD
CAMThread::GetRequest()
{
    m_EventSend.Wait();
    return m_dwParam;
}

// is there a request?
BOOL
CAMThread::CheckRequest(DWORD * pParam)
{
    if (!m_EventSend.Check()) {
        return FALSE;
    } else {
        if (pParam) {
            *pParam = m_dwParam;
        }
        return TRUE;
    }
}

// reply to the request
void
CAMThread::Reply(DWORD dw)
{
    m_dwReturnVal = dw;
    
    // The request is now complete so CheckRequest should fail from
    // now on
    //
    // This event should be reset BEFORE we signal the client or
    // the client may Set it before we reset it and we'll then
    // reset it (!)
    
    m_EventSend.Reset();
    
    // Tell the client we're finished
    
    m_EventComplete.Set();
}

HRESULT CAMThread::CoInitializeHelper()
{
    // call CoInitializeEx and tell OLE not to create a window (this
    // thread probably won't dispatch messages and will hang on
    // broadcast msgs o/w).
    //
    // If CoInitEx is not available, threads that don't call CoCreate
    // aren't affected. Threads that do will have to handle the
    // failure. Perhaps we should fall back to CoInitialize and risk
    // hanging?
    //
    
    // older versions of ole32.dll don't have CoInitializeEx
    
    HRESULT hr = E_FAIL;
    HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll"));
    if(hOle)
    {
        typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)(
            LPVOID pvReserved, DWORD dwCoInit);
        PCoInitializeEx pCoInitializeEx =
            (PCoInitializeEx)(GetProcAddress(hOle, TEXT("CoInitializeEx")));
        if(pCoInitializeEx)
        {
#ifndef UNDER_CE
            hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE);
#else
            hr = (*pCoInitializeEx)(0, COINIT_MULTITHREADED);
#endif
        }
    }
    else
    {
        // caller must load ole32.dll
        DbgBreak("couldn't locate ole32.dll");
    }
    
    return hr;
}

// destructor for CMsgThread  - cleans up any messages left in the
// queue when the thread exited
CMsgThread::~CMsgThread()
{
    if (m_hThread != NULL) {
        WaitForSingleObject(m_hThread, INFINITE);
        EXECUTE_ASSERT(CloseHandle(m_hThread));
    }
    
    POSITION pos = m_ThreadQueue.GetHeadPosition();
    while (pos) {
        CMsg * pMsg = m_ThreadQueue.GetNext(pos);
        delete pMsg;
    }
    m_ThreadQueue.RemoveAll();
    
    if (m_hSem != NULL) {
        EXECUTE_ASSERT(CloseHandle(m_hSem));
    }
}

BOOL
CMsgThread::CreateThread(
                         )
{
    m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
    if (m_hSem == NULL) {
        return FALSE;
    }
    
    m_hThread = ::_internal_CreateThread(NULL, 0, DefaultThreadProc,
        (LPVOID)this, 0, &m_ThreadId);
    return m_hThread != NULL;
}

int CMsgThread::GetThreadPriority() {
    return ::_internal_GetThreadPriority(m_hThread);
}

BOOL CMsgThread::SetThreadPriority(int nPriority) {
    return ::_internal_SetThreadPriority(m_hThread, nPriority);
}

// This is the threads message pump.  Here we get and dispatch messages to
// clients thread proc until the client refuses to process a message.
// The client returns a non-zero value to stop the message pump, this
// value becomes the threads exit code.

DWORD WINAPI
CMsgThread::DefaultThreadProc(
                              LPVOID lpParam
                              )
{
    CMsgThread *lpThis = (CMsgThread *)lpParam;
    CMsg msg;
    LRESULT lResult;
    
    // !!!
#ifndef UNDER_CE
    CoInitialize(NULL);
#else
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif // UNDER_CE
    
    // allow a derived class to handle thread startup
    lpThis->OnThreadInit();
    
    do {
        lpThis->GetThreadMsg(&msg);
        lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags,
            msg.lpParam, msg.pEvent);
    } while (lResult == 0L);
    
    // !!!
    CoUninitialize();
    
    return (DWORD)lResult;
}


// Block until the next message is placed on the list m_ThreadQueue.
// copies the message to the message pointed to by *pmsg
void
CMsgThread::GetThreadMsg(CMsg *msg)
{
    CMsg * pmsg = NULL;
    

⌨️ 快捷键说明

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