1

我想调用LoadAccelerators,但要调用资源中的特定语言。有没有办法做到这一点?

4

2 回答 2

1

您将特定语言的资源放在 DLL 中。在运行时,您加载该 DLL 并将 DLL 的句柄指定为hInstance当您调用LoadAccelerators.

于 2013-06-07T03:35:29.953 回答
1

我做了一些逆向工程,下面是如何从内存中为特定的 LCID 加载它:

#pragma pack(push, 1) // exact fit - no padding
struct ACCEL_MEM{
    BYTE fVirt;
    BYTE byteReserved;
    WORD wKey;
    WORD wCmd;
    WORD wReserved;
};
#pragma pack(pop)

HACCEL LoadAcceleratorsIndirectWithLCID(UINT nResourceID, LCID lcid)
{
    //Open accelerators table with the 'nResourceID'
    //'nResourceID' = Resource ID to use
    //'lcid' = LCID to load resources for, or NULL to use the one from current thread
    //RETURN:
    //      = HACCEL loaded -- must be removed with DestroyAcceleratorTable(), or
    //      = NULL if error
    ASSERT(nResourceID);

    HACCEL hAccel = NULL;

    HINSTANCE hInst = ::GetModuleHandle(NULL);
    if(hInst)
    {
        //Do we have a LCID?
        if(lcid == NULL)
            lcid = ::GetThreadLocale();

        //Get language ID
        LANGID langid = LANGIDFROMLCID(lcid);

        //Try to load for specified resource
        HRSRC hResource = ::FindResourceEx(hInst, RT_ACCELERATOR, MAKEINTRESOURCE(nResourceID), langid);
        if(hResource == NULL)
        {
            //If failed, use default lcid
            hResource = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_ACCELERATOR);
        }

        if(hResource)
        {
            HGLOBAL hglb = LoadResource(hInst, hResource);
            if(hglb)
            {
                LPVOID lpsz = LockResource(hglb);
                DWORD dwcbSz = ::SizeofResource(hInst, hResource);
                if(lpsz &&
                    dwcbSz)
                {
                    ACCEL_MEM* pMem = (ACCEL_MEM*)lpsz;

                    //Count items in the table
                    int nCnt = 0;
                    ACCEL_MEM* pTest = pMem;
                    for(;; pTest++)
                    {
                        nCnt++;
                        if(pTest->fVirt & 0x80)
                            break;
                    }

                    //Reserve mem
                    ACCEL* pAccels = new ACCEL[nCnt];

                    //Parse data
                    for(int i = 0; i < nCnt; i++)
                    {
                        pAccels[i].fVirt = pMem[i].fVirt & 0x7f;
                        pAccels[i].key = pMem[i].wKey;
                        pAccels[i].cmd = pMem[i].wCmd;
                    }

                    //Create accel table
                    hAccel = ::CreateAcceleratorTable(pAccels, nCnt);

                    //Free mem
                    delete[] pAccels;
                    pAccels = NULL;
                }
            }
        }
    }

    return hAccel;
}
于 2013-06-09T06:37:25.350 回答