Qual é uma alternativa ao GWL_USERDATA para armazenar um ponteiro de objeto?
Pergunta
Nos aplicativos Windows em que trabalho, temos uma estrutura personalizada que fica diretamente acima do Win32 (não pergunte).Quando criamos uma janela, nossa prática normal é colocar this
na área de dados do usuário da janela via SetWindowLong(hwnd, GWL_USERDATA, this)
, o que nos permite ter um retorno de chamada semelhante ao MFC ou um sistema totalmente integrado WndProc
, dependendo.O problema é que isso não funcionará no Win64, já que LONG tem apenas 32 bits de largura.Qual é a melhor solução para esse problema que funcione em sistemas de 32 e 64 bits?
Solução
SetWindowLongPtr foi criado para substituir SetWindowLong nestes casos.Seu parâmetro LONG_PTR permite armazenar um ponteiro para compilações de 32 ou 64 bits.
LONG_PTR SetWindowLongPtr(
HWND hWnd,
int nIndex,
LONG_PTR dwNewLong
);
Lembre-se de que as constantes também mudaram, então o uso agora fica assim:
SetWindowLongPtr(hWnd, GWLP_USERDATA, this);
Também não esqueça que agora para recuperar o ponteiro, você deve usar GetWindowLongPtr:
LONG_PTR GetWindowLongPtr(
HWND hWnd,
int nIndex
);
E o uso ficaria assim (novamente, com constantes alteradas):
LONG_PTR lpUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
MyObject* pMyObject = (MyObject*)lpUserData;
Outras dicas
A outra alternativa é SetProp/RemoveProp (quando você está subclassificando uma janela que já usa GWLP_USERDATA)
Outra boa alternativa é o estilo ATL do WNDPROC, para obter mais informações sobre isso, consulte