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

📄 mouhid.cpp

📁 YLP270的Windows CE5.0 bsp源码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }

    ValidateHidMouse(pHidMouse);
    
    switch(dwMsg) {
        case HID_CLOSE_DEVICE:
            // Free all of our resources.
            WaitForSingleObject(pHidMouse->hThread, INFINITE);
            CloseHandle(pHidMouse->hThread);
            pHidMouse->hThread = NULL;

            // Send ups for each button that is still down.
            SetButtonFlags(&dwFlags, pHidMouse->puPrevUsages, pHidMouse->dwMaxUsages,
                g_rgdwUsageToUpButton, dim(g_rgdwUsageToUpButton));
            MouseEvent(dwFlags, 0, 0, 0);
            
            FreeHidMouse(pHidMouse);
            fRet = TRUE;
            break;

        default:
            DEBUGMSG(ZONE_ERROR, (_T("%s: Unhandled message %u\r\n"), pszFname));
            break;
    };

EXIT:
    return fRet;
}
#ifdef DEBUG
// Match function with typedef.
static LPHID_CLIENT_NOTIFICATIONS g_pfnDeviceNotifications = HIDDeviceNotifications;
#endif


// Allocate the usage lists for this mouse. The lists are allocated in 
// a single block and then divided up.
static
BOOL
AllocateUsageLists(
    PHID_MOUSE pHidMouse,
    size_t cbUsages
    )
{
    SETFNAME(_T("AllocateUsageLists"));

    BOOL fRet = FALSE;
    size_t cbTotal;
    PBYTE pbStart;
    DWORD dwIdx;
    PUSAGE *rgppUsages[] = {
        &pHidMouse->puPrevUsages,
        &pHidMouse->puCurrUsages,
        &pHidMouse->puBreakUsages,
        &pHidMouse->puMakeUsages
    };
    
    DEBUGCHK(pHidMouse != NULL);

    // Allocate a block of memory for all the usage lists
    cbTotal = cbUsages * dim(rgppUsages);
    pbStart = (PBYTE) LocalAlloc(LPTR, cbTotal);
    
    if (pbStart == NULL) {
       DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
       goto EXIT;
    }

    // Divide the block.
    for (dwIdx = 0; dwIdx < dim(rgppUsages); ++dwIdx) {
        *rgppUsages[dwIdx] = (PUSAGE) (pbStart + (cbUsages * dwIdx));
    }

    fRet = TRUE;

EXIT:
    return fRet;
}


// Find out if this mouse has a wheel or Z axis
static
void
DetermineWheelUsage(
    PHID_MOUSE pHidMouse
    )
{
    static const USAGE rgWheelUsages[] = {
        HID_USAGE_GENERIC_WHEEL,
        HID_USAGE_GENERIC_Z,
    };
    
    NTSTATUS status;
    HIDP_VALUE_CAPS hidpValueCaps;
    USHORT cValueCaps;
    DWORD dwIdx;    
    
    PREFAST_DEBUGCHK(pHidMouse != NULL);

    for (dwIdx = 0; dwIdx < dim(rgWheelUsages); ++dwIdx) 
    {
        USAGE usageCurr = rgWheelUsages[dwIdx];
        cValueCaps = 1;  // Only one structure to fill
        
        status = HidP_GetSpecificValueCaps(
            HidP_Input,
            HID_USAGE_PAGE_GENERIC, 
            0, 
            usageCurr, 
            &hidpValueCaps, 
            &cValueCaps, 
            pHidMouse->phidpPreparsedData);

        if (NT_SUCCESS(status)) {
            // We found our wheel axis
            pHidMouse->usageWheel = usageCurr;
            break;
        }
    }

    if (dwIdx == dim(rgWheelUsages)) {
        // We did not find a wheel axis
        pHidMouse->usageWheel = HAS_NO_WHEEL;
    }    
}


// Set the mouse_event button flags for this list of usages.
static
void
SetButtonFlags(
    PDWORD pdwFlags,
    PUSAGE pUsages,
    DWORD dwMaxUsages,
    const DWORD *pdwUsageMappings, // Array of usage->flags to use
    DWORD cdwUsageMappings // Count of usage->flags mappings
    )
{
    DWORD dwIdx;

    DEBUGCHK(pdwFlags != NULL);
    PREFAST_DEBUGCHK(pUsages != NULL);
    DEBUGCHK(pdwUsageMappings != NULL);
    
    for (dwIdx = 0; dwIdx < dwMaxUsages; ++dwIdx) {
        const USAGE usage = pUsages[dwIdx];

		if (usage == 0) {
		    // No more set usages
			break;
		}
        else if (usage < cdwUsageMappings) {
            *pdwFlags |= pdwUsageMappings[usage];
        }
        // else this is a button we do not handle.
    }    
}


// Determine the movement on the axis defined by usage. Store it in pDelta.
static
NTSTATUS
GetAxisMovement(
    PHID_MOUSE pHidMouse,
    USAGE usage, // X, Y, Z, or Wheel
    PCHAR pbHidPacket,
    DWORD cbHidPacket,
    PLONG pDelta
    )
{
    SETFNAME(_T("GetAxisMovement"));
    
    NTSTATUS status;
    
    PREFAST_DEBUGCHK(pHidMouse != NULL);
    DEBUGCHK(pbHidPacket != NULL);
    PREFAST_DEBUGCHK(pDelta != NULL);
    
    status = HidP_GetScaledUsageValue(
        HidP_Input,
        HID_USAGE_PAGE_GENERIC,
        0,
        usage,
        pDelta,
        pHidMouse->phidpPreparsedData,
        pbHidPacket,
        cbHidPacket);

    if (status == HIDP_STATUS_BAD_LOG_PHY_VALUES) {
        // Bad physical max/min detected.
        DEBUGMSG(ZONE_ERROR, (_T("%s: Bad physical max/min for mouse axis usage 0x%x\r\n"),
            pszFname, usage));
        *pDelta = 0;
    }

    return status;
}


// Take a report generated by the device and convert it to a mouse_event
static
void
ProcessMouseReport(
    PHID_MOUSE pHidMouse,
    PCHAR pbHidPacket,
    DWORD cbHidPacket
    )
{
    SETFNAME(_T("ProcessMouseReport"));

    NTSTATUS status;
    ULONG uCurrUsages;
    DWORD cbUsageList;
    DWORD dwFlags;
    LONG dx, dy, dz;
    
    PREFAST_DEBUGCHK(pHidMouse != NULL);
    DEBUGCHK(pbHidPacket != NULL);

    DEBUGCHK(dim(g_rgdwUsageToDownButton) == dim(g_rgdwUsageToUpButton));

    ValidateHidMouse(pHidMouse);

    dwFlags = dx = dy = dz = 0;
    
    uCurrUsages = pHidMouse->dwMaxUsages;
    cbUsageList = uCurrUsages * sizeof(USAGE);

    //        
    // Handle mouse buttons
    //

    // Get the usage list from this packet.
    status = HidP_GetUsages(
        HidP_Input,
        HID_USAGE_PAGE_BUTTON,
        0,
        pHidMouse->puCurrUsages,
        &uCurrUsages, // IN OUT parameter
        pHidMouse->phidpPreparsedData,
        pbHidPacket,
        cbHidPacket);
    
    if (NT_SUCCESS(status)) {
        status = HidP_UsageListDifference(
            pHidMouse->puPrevUsages,
            pHidMouse->puCurrUsages,
            pHidMouse->puBreakUsages,
            pHidMouse->puMakeUsages,
            pHidMouse->dwMaxUsages);

        if (NT_SUCCESS(status)) {
            // Determine which buttons went up and down.
            SetButtonFlags(&dwFlags, pHidMouse->puBreakUsages, pHidMouse->dwMaxUsages,
                g_rgdwUsageToUpButton, dim(g_rgdwUsageToUpButton));
            SetButtonFlags(&dwFlags, pHidMouse->puMakeUsages, pHidMouse->dwMaxUsages,
                g_rgdwUsageToDownButton, dim(g_rgdwUsageToDownButton));
        }
    }
    // else maybe we do not have any buttons (HIDP_STATUS_USAGE_NOT_FOUND)

    //
    // Handle mouse axis movement
    //
    GetAxisMovement(pHidMouse, HID_USAGE_GENERIC_X, pbHidPacket, cbHidPacket, &dx);
    GetAxisMovement(pHidMouse, HID_USAGE_GENERIC_Y, pbHidPacket, cbHidPacket, &dy);

    if ((dx != 0) || (dy != 0)) {
        dwFlags |= MOUSEEVENTF_MOVE;
    }

    if (pHidMouse->usageWheel != HAS_NO_WHEEL) {
        GetAxisMovement(pHidMouse, pHidMouse->usageWheel, pbHidPacket, cbHidPacket, &dz);

        if (dz != 0) {
            dz *= WHEEL_DELTA;
            dwFlags |= MOUSEEVENTF_WHEEL;
        }
    }

    if (dwFlags) {
        // Send this mouse event
        MouseEvent(dwFlags, dx, dy, dz);
    }

    // Save the current usages.
    memcpy(pHidMouse->puPrevUsages, pHidMouse->puCurrUsages, cbUsageList);
}


// Send the mouse event to GWES
static
void
MouseEvent(
    DWORD dwFlags,
    DWORD dx,
    DWORD dy,
    DWORD dwData
    )
{
    SETFNAME(_T("MouseEvent"));
    BOOL fSendEventToSystem = TRUE;

    DEBUGMSG(ZONE_USAGES, (_T("%s: HID: dx %4d, dy %4d, dwData %4d, flags 0x%04x\r\n"), pszFname,
        dx, dy, dwData, dwFlags));
    
    if (g_fUseMouseHook) {
       // See if any mouse hook app, such as Transcriber wants the mouse event
       fSendEventToSystem = !DriverMouseHook(dwFlags, dx, dy, dwData);
    }
    
    if (fSendEventToSystem) {
        mouse_event(dwFlags, dx, dy, dwData, 0);
    }
}


// Free the memory used by pHidKbd
void
FreeHidMouse(
    PHID_MOUSE pHidMouse
    )
{
    PREFAST_DEBUGCHK(pHidMouse != NULL);
    DEBUGCHK(pHidMouse->hThread == NULL); // We do not close the thread handle
    
    if (pHidMouse->puPrevUsages != NULL) LocalFree(pHidMouse->puPrevUsages);
    LocalFree(pHidMouse);    
}


#ifdef DEBUG

// Validate a PHID_KBD structure
static
void
ValidateHidMouse(
    PHID_MOUSE pHidMouse
    )
{    
    DWORD cbUsageList;
    
    PREFAST_DEBUGCHK(pHidMouse != NULL);
    DEBUGCHK(pHidMouse->dwSig == HID_MOUSE_SIG);
    DEBUGCHK(pHidMouse->hDevice != NULL);
    DEBUGCHK(pHidMouse->pHidFuncs != NULL);
    DEBUGCHK(pHidMouse->phidpPreparsedData != NULL);
    DEBUGCHK(pHidMouse->hidpCaps.UsagePage == HID_USAGE_PAGE_GENERIC);
    DEBUGCHK(pHidMouse->hidpCaps.Usage == HID_USAGE_GENERIC_MOUSE);
    if (pHidMouse->fhThreadInited == TRUE) {
        DEBUGCHK(pHidMouse->hThread != NULL);
    }

    cbUsageList = pHidMouse->dwMaxUsages * sizeof(*pHidMouse->puPrevUsages);
    DEBUGCHK(pHidMouse->puPrevUsages != NULL);
    DEBUGCHK(LocalSize(pHidMouse->puPrevUsages) >= cbUsageList * 4);
    DEBUGCHK((DWORD) pHidMouse->puCurrUsages == ((DWORD) pHidMouse->puPrevUsages) + cbUsageList);
    DEBUGCHK((DWORD) pHidMouse->puBreakUsages == ((DWORD) pHidMouse->puCurrUsages) + cbUsageList);
    DEBUGCHK((DWORD) pHidMouse->puMakeUsages == ((DWORD) pHidMouse->puBreakUsages) + cbUsageList);

    DEBUGCHK( (pHidMouse->usageWheel == HID_USAGE_GENERIC_WHEEL) ||
              (pHidMouse->usageWheel == HID_USAGE_GENERIC_Z)     ||
              (pHidMouse->usageWheel == HAS_NO_WHEEL) );
}

#endif // DEBUG


⌨️ 快捷键说明

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