Я хочу позвонить LoadAccelerators, но для конкретного языка в ресурсах. Есть ли способ сделать это?LoadAccelerators для определенного языка ресурсов
1
A
ответ
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
.
OK. Что делать, если мои ресурсы находятся в том же .exe-файле, с которого я вызываю LoadAccelerators? – c00000fd
@ c00000fd: Я никогда не пробовал, но для каждой таблицы требуется уникальное имя, поэтому вы должны указать имя/номер конкретной таблицы ускорителей, в которой вы нуждаетесь (второй параметр LoadAccelerators). –
Хм. Нет, я так не думаю. Каждый идентификатор ресурса, как представляется, одинаковый для всех языков. Из того, что я могу сказать, я могу загрузить его с помощью FindResourceEx, но я не уверен, как его загрузить из памяти. Любая идея на этом фронте? – c00000fd