Added a partial implementation of play-sound-internal for Windows. Fixed the followi...
[bpt/emacs.git] / src / w32menu.c
index 4479144..8139a0a 100644 (file)
@@ -129,8 +129,23 @@ typedef struct _widget_value
 
 static HMENU current_popup_menu;
 
-FARPROC get_menu_item_info;
-FARPROC set_menu_item_info;
+void syms_of_w32menu ();
+
+typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
+    IN HMENU,
+    IN UINT,
+    IN BOOL,
+    IN OUT LPMENUITEMINFOA
+    );
+typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
+    IN HMENU,
+    IN UINT,
+    IN BOOL,
+    IN LPCMENUITEMINFOA
+    );
+
+GetMenuItemInfoA_Proc get_menu_item_info=NULL;
+SetMenuItemInfoA_Proc set_menu_item_info=NULL;
 
 Lisp_Object Vmenu_updating_frame;
 
@@ -1591,6 +1606,26 @@ void
 initialize_frame_menubar (f)
      FRAME_PTR f;
 {
+  HMODULE user32 = GetModuleHandle ("user32.dll");
+  /*
+    Reinitialize the function pointers set_menu_item_info and
+    get_menu_item_info here.
+    Even though these function pointers are initialized in
+    syms_of_w32menu which is called from main (emacs.c),
+    we need to initialize them again here in order to prevent
+    a crash that occurs in Windows 9x (possibly only when Emacs
+    was built on Windows NT / 2000 / XP?) in add_menu_item.
+    The crash occurs when attempting to call the Win32 API
+    function SetMenuItemInfo through the function pointer.
+    It appears as if the function pointer that is obtained when
+    syms_of_w32menu is called from main is no longer valid
+    (possibly due to DLL relocation?).
+    To resolve this issue, I have placed calls to reinitialize
+    these function pointers here because this function is the
+    entry point for menu creation.
+   */
+  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
+  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
   /* This function is called before the first chance to redisplay
      the frame.  It has to be, so the frame will have the right size.  */
   FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
@@ -2355,13 +2390,12 @@ w32_free_menu_strings (hwnd)
 
 #endif /* HAVE_MENUS */
 
-\f
-syms_of_w32menu ()
+void syms_of_w32menu ()
 {
   /* See if Get/SetMenuItemInfo functions are available.  */
   HMODULE user32 = GetModuleHandle ("user32.dll");
-  get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");
-  set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
+  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
+  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
 
   staticpro (&menu_items);
   menu_items = Qnil;