Я закончил проверкой, является ли удаленный процесс 32-битным или 64-битным во время выполнения, и затем записал правильную структуру в общую память перед отправкой сообщения.
Например, вот как вы можете использовать сообщение TVM_GETITEM
, даже если между вызывающим и получателем сообщения есть 32-битная <-> 64-битная комбинация:
/* This template is basically a copy of the TVITEM struct except that
* all fields which return a pointer have a variable type. This allows
* creating different types for different pointer sizes.
*/
template <typename AddrType>
struct TVITEM_3264 {
UINT mask;
AddrType hItem;
UINT state;
UINT stateMask;
AddrType pszText;
int cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
AddrType lParam;
};
typedef TVITEM_3264<UINT32> TVITEM32;
typedef TVITEM_3264<UINT64> TVITEM64;
// .... later, I can then use the above template like this:
LPARAM _itemInfo;
DWORD pid;
::GetWindowThreadProcessId( treeViewWindow, &pid );
if ( is64BitProcess( pid ) ) {
TVITEM64 itemInfo;
ZeroMemory( &itemInfo, sizeof( itemInfo ) );
itemInfo.mask = TVIF_HANDLE | TVIF_TEXT;
itemInfo.hItem = (UINT64)m_item;
itemInfo.pszText = (UINT64)(LPTSTR)sharedMem->getSharedMemory( sizeof(itemInfo) );
itemInfo.cchTextMax = MaxTextLength;
_itemInfo = (LPARAM)sharedMem->write( &itemInfo, sizeof(itemInfo) );
} else {
TVITEM32 itemInfo;
ZeroMemory( &itemInfo, sizeof( itemInfo ) );
itemInfo.mask = TVIF_HANDLE | TVIF_TEXT;
itemInfo.hItem = (UINT32)m_item;
itemInfo.pszText = (UINT32)(LPTSTR)sharedMem->getSharedMemory( sizeof(itemInfo) );
itemInfo.cchTextMax = MaxTextLength;
_itemInfo = (LPARAM)sharedMem->write( &itemInfo, sizeof(itemInfo) );
}
Функция sharedMem->getSharedMemory
- это небольшая вспомогательная функция для получения указателя на область разделяемой памяти; необязательный аргумент функции указывает значение смещения. Важно то, что область разделяемой памяти всегда должна находиться в 32-битном адресном пространстве (чтобы к ней мог обращаться даже 32-битный удаленный процесс).