The C-API xlGetHwnd call that retrieves the main window handle of Microsoft Excel can create problems when converting your code. This is because sizeof(HWND) on Win32 is a long but the field used to receive the HWND parameter in the XLOPER structure is a short. Consequently the high word of the actual Microsoft Excel HWND is truncated. To work around this problem call xlGetHwnd to get the low word of the actual hwnd, then iterate the list of top-level windows and look for a match with the returned low word. This code illustrates the technique:
typedef struct _EnumStruct {
HWND hwnd;
unsigned short wLoword;
} EnumStruct;
#define CLASS_NAME_BUFFER 50
/*
**
** Function: EnumProc
**
** Comments: Used to find the hWnd in the Win32 version of Excel.
** This is the callback routine that checks each hwnd.
**
** Arguments: hwnd - The hwnd of the window currently being looked at
** EnumStruct * - A structure containing loword of hwnd of
** interest and space to return full hwnd.
**
** Returns: BOOL - indicates success or failure
**
** Date Developer Action
** --------------------------------------------------------
*/
BOOL CALLBACK EnumProc(HWND hwnd, EnumStruct * pEnum)
{
// first check class of the window. Must be "XLMAIN"
char szClass[CLASS_NAME_BUFFER+1];
GetClassName(hwnd, szClass, CLASS_NAME_BUFFER);
if(!lstrcmpi(szClass, "XLMAIN"))
{
// if that is a match, check the loword of the window handle
if(LOWORD((DWORD)hwnd) == pEnum->wLoword)
{
pEnum->hwnd = hwnd;
return FALSE;
}
}
// no match continue the enumeration
return TRUE;
}
/*
**
** Function: GetHwnd
**
** Comments: Used to find the hWnd in the Win32 version of Excel.
** This routine sets up the callback and checks the results.
**
** Arguments: pHwnd - This is actually the returned hwnd
**
** Returns: BOOL - Indicating success or failure.
**
** Date Developer Action
** --------------------------------------------------------
*/
BOOL GetHwnd(HWND *pHwnd)
{
XLOPER x;
// Get the loword of the hwnd
if(Excel4(xlGetHwnd, &x, 0) == xlretSuccess)
{
EnumStruct enm;
// Set up the structure
enm.hwnd = NULL;
enm.wLoword = x.val.w;
// Start the enumeration
EnumWindows((WNDENUMPROC)EnumProc, (LPARAM) &enm);
// Check results
if(enm.hwnd != NULL)
{
*pHwnd = enm.hwnd;
return TRUE;
}
}
return FALSE;
}