Compartilhar via


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

Desenvolvimento de XLLs do Excel