適用於:Excel 2013 |Office 2013 |Visualstudio
若要在 Windows 環境中進行程式設計,有時您必須知道 Microsoft Excel 實例句柄或主視窗句柄。 例如,當您建立和顯示自定義 Windows 對話框時,這些句柄會很有用。
有兩個僅限 XLL 的 C API 函式可讓您存取這些句柄: xlGetInst 函式和 xlGetHwnd 函式。 在 Win32 中,所有句柄都是 32 位整數。 不過,在設計 XLOPER 時 ,Windows 是 16 位系統。 因此,結構只允許 16 位句柄。 在 Win32 中,使用 Excel4 或 Excel4v 呼叫時, xlGetInst 函式和 xlGetHwnd 函式只會傳回完整 32 位句柄的低部分。
在 Excel 2007 和更新版本中,使用 Excel12 或 Excel12v 呼叫這些函式時,傳回的XLOPER12包含完整的 32 位句柄。
在任何版本的 Excel 中取得完整實例句柄都很簡單,因為它會傳遞至載入 DLL 時所呼叫的 Windows 回呼 DllMain。 如果您將此實例句柄記錄在全域變數中,則永遠不需要呼叫 xlGetInst 函式。
取得 Excel 2003 和更早版本中的主要 Excel 句柄
若要取得 Excel 2003 和舊版 32 位版本中的主要 Excel 句柄,您必須先呼叫 xlGetHwnd 函式,以取得實際句柄的低字。 然後,您必須逐一查看最上層視窗的清單,以搜尋與傳回的低字組相符的專案。 下列程式代碼說明這項技術。
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;
}