2013-06-07 3 views

ответ

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; 
} 
1

Вы размещаете свои языковые ресурсы в DLL. Во время выполнения вы загружаете эту DLL и указываете дескриптор DLL как hInstance, когда вы вызываете LoadAccelerators.

+0

OK. Что делать, если мои ресурсы находятся в том же .exe-файле, с которого я вызываю LoadAccelerators? – c00000fd

+0

@ c00000fd: Я никогда не пробовал, но для каждой таблицы требуется уникальное имя, поэтому вы должны указать имя/номер конкретной таблицы ускорителей, в которой вы нуждаетесь (второй параметр LoadAccelerators). –

+0

Хм. Нет, я так не думаю. Каждый идентификатор ресурса, как представляется, одинаковый для всех языков. Из того, что я могу сказать, я могу загрузить его с помощью FindResourceEx, но я не уверен, как его загрузить из памяти. Любая идея на этом фронте? – c00000fd