Access Excel Instance and Main Window Handles

S’applique à: Excel 2013 | Office 2013 | Visual Studio

Pour programmer dans l’environnement Windows, vous devez parfois connaître le handle microsoft Excel instance ou main poignée de fenêtre. Par exemple, ces handles sont utiles lorsque vous créez et affichez des boîtes de dialogue Windows personnalisées.

Il existe deux fonctions d’API C XLL uniquement qui fournissent l’accès à ces descripteurs : la fonction xlGetInst et la fonction xlGetHwnd respectivement. Dans Win32, tous les descripteurs sont des entiers 32 bits. Toutefois, lorsque le XLOPER a été conçu, Windows était un système 16 bits. Par conséquent, la structure n’est autorisée que pour les handles 16 bits. Dans Win32, lorsqu’elles sont appelées avec Excel4 ou Excel4v, la fonction xlGetInst et la fonction xlGetHwnd retournent uniquement la partie inférieure du handle 32 bits complet.

Dans Excel 2007 et versions ultérieures, lorsque ces fonctions sont appelées avec Excel12 ou Excel12v, le XLOPER12 retourné contient le handle 32 bits complet.

L’obtention du handle de instance complet est simple dans n’importe quelle version d’Excel, car il est transmis au dllMain de rappel Windows, qui est appelé lorsque la DLL est chargée. Si vous enregistrez ce handle instance dans une variable globale, vous n’avez jamais besoin d’appeler la fonction xlGetInst.

Obtention du handle Excel principal dans Excel 2003 et versions antérieures

Pour obtenir le handle Excel main dans Excel 2003 et les versions 32 bits antérieures, vous devez d’abord appeler la fonction xlGetHwnd pour obtenir le mot faible du handle réel. Ensuite, vous devez itérer la liste des fenêtres de niveau supérieur pour rechercher une correspondance avec le mot bas retourné. Le code suivant illustre la technique.

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;
}

Voir aussi

Affichage des boîtes de dialogue dans un fichier DLL ou XLL

Fonctions de l’API C à appeler à partir d’un fichier DLL ou XLL

Développement de XLL de Excel 2013