Acessar a instância do Excel e as alças da janela principal
Aplica-se a: Excel 2013 | Office 2013 | Visual Studio
Para o programa no ambiente do Windows, às vezes é preciso conhecer a alça da instância do Microsoft Excel ou a alça da janela principal. Por exemplo, essas alças são úteis quando você está criando e exibindo as caixas de diálogo personalizadas do Windows.
Há duas funções de API de C somente XLL que fornecem acesso a essas alças; a função xlGetInst e a função xlGetHwnd, respectivamente. No Win32, todas as alças são números inteiros de 32 bits. No entanto, quando o XLOPER foi criado, o Windows era um sistema de 16 bits. Portanto, a estrutura só permitia alças de 16 bits. No Win32, quando chamada com o Excel4 ou o Excel4v, a função xlGetInst e a função xlGetHwnd retornavam apenas a parte inferior da alça completa de 32 bits.
No Excel 2007 e nas versões posteriores, quando essas funções são chamadas com Excel12 ou Excel12v, o XLOPER12 retornado contém alça completa de 32 bits.
Obter a alça de instância completa é um processo simples em qualquer versão do Excel, e ela é passada para o retorno do Windows DllMain, que é chamado quando a DLL é carregada. Se você gravar esta alça de instância em uma variável global, nunca vai precisar chamar a função xlGetInst.
Obtenção da Alça Principal do Excel no Excel 2003 e versões anteriores
Para obter a alça principal do Excel no Excel 2003 e nas versões anteriores de 32 bits, você precisa primeiro chamar a função xlGetHwnd para obter a palavra inferior da alça real. Em seguida, você deve iterar lista de janelas de nível superior para procurar uma correspondência com a palavra inferior retornada. O código a seguir ilustra a técnica.
typedef struct _EnumStruct
{
HWND hwnd; // Return value for Excel main hWnd.
unsigned short wLoword; //Contains LowWord of the Excel main hWnd
} EnumStruct;
#define CLASS_NAME_BUFFER 50
BOOL CALLBACK EnumProc(HWND hwnd, EnumStruct * pEnum)
{
// First check the class of the window. Must be "XLMAIN".
char rgsz[CLASS_NAME_BUFFER];
GetClassName(hwnd, rgsz, CLASS_NAME_BUFFER);
if (!lstrcmpi(rgsz, "XLMAIN"))
{
// If that hits, check the loword of the window handle.
if (LOWORD((DWORD) hwnd) == pEnum->wLoword)
{
// We have a match, return Excel main hWnd.
pEnum->hwnd = hwnd;
return FALSE;
}
}
// No match - continue the enumeration.
return TRUE;
}
BOOL GetHwnd(HWND * pHwnd)
{
XLOPER x;
//
// xlGetHwnd only returns the LoWord of Excel hWnd
// so all the windows have to be enumerated to see
// which match the LoWord returned by xlGetHwnd.
//
if (Excel4(xlGetHwnd, &x, 0) == xlretSuccess)
{
EnumStruct enm;
enm.hwnd = NULL;
enm.wLoword = x.val.w;
EnumWindows((WNDENUMPROC) EnumProc, (LPARAM) &enm);
if (enm.hwnd != NULL)
{
*pHwnd = enm.hwnd;
return TRUE;
}
}
return FALSE;
}
Confira também
Exibir caixas de diálogo de dentro de uma DLL ou XLL
Funções da API de C que podem ser chamadas apenas de uma DLL ou XLL