[Wine-patches] [eterwine] oledlg: Implement OleUIAddVerbMenuA/W functions
Konstantin Kondratyuk
kondratyuk на etersoft.ru
Ср Сен 14 14:17:32 MSD 2011
Переделка патчей Виталика для баги #6864.
--
Best regards,
Konstantin Kondratyuk.
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.etersoft.ru/pipermail/wine-patches/attachments/20110914/b2ecf529/attachment-0001.html>
----------- следующая часть -----------
From 7bb879fb32cc2c673d9b45c45705d0fc38368c11 Mon Sep 17 00:00:00 2001
From: Vitaly Lipatov <lav на etersoft.ru>
Date: Wed, 14 Sep 2011 13:50:59 +0400
Subject: [PATCH 1/2] oledlg: Implement OleUIAddVerbMenuA/W functions
---
dlls/oledlg/oledlg.rc | 3 +
dlls/oledlg/oledlg_main.c | 133 ++++++++++++++++++++++++++++++++++++++++-----
dlls/oledlg/resource.h | 3 +
3 files changed, 125 insertions(+), 14 deletions(-)
diff --git a/dlls/oledlg/oledlg.rc b/dlls/oledlg/oledlg.rc
index 864fd06..b11e256 100644
--- a/dlls/oledlg/oledlg.rc
+++ b/dlls/oledlg/oledlg.rc
@@ -27,6 +27,9 @@ STRINGTABLE
IDS_BROWSE "Browse"
IDS_NOTOLEMOD "File does not appear to be a valid OLE module. Unable to register OLE control."
IDS_NOTOLEMODCAPTION "Add Control"
+ IDS_OBJECT "Object: "
+ IDS_NOOBJECT "No OLE object"
+ IDS_CONVERTING "Converting..."
}
STRINGTABLE
diff --git a/dlls/oledlg/oledlg_main.c b/dlls/oledlg/oledlg_main.c
index 6033231..9e81db6 100644
--- a/dlls/oledlg/oledlg_main.c
+++ b/dlls/oledlg/oledlg_main.c
@@ -2,6 +2,7 @@
* OLEDLG library
*
* Copyright 1998 Patrik Stridvall
+ * Copyright 2008 Vitaly Lipatov (Etersoft)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,9 +26,14 @@
#include "winerror.h"
#include "wingdi.h"
#include "winuser.h"
+
+#define COBJMACROS
#include "oledlg.h"
#include "ole2.h"
+#include "oleidl.h"
#include "oledlg_private.h"
+#include "wine/unicode.h"
+#include "resource.h"
#include "wine/debug.h"
@@ -101,36 +107,135 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
/***********************************************************************
* OleUIAddVerbMenuA (OLEDLG.1)
+ * See OleUIAddVerbMenuW description
*/
BOOL WINAPI OleUIAddVerbMenuA(
LPOLEOBJECT lpOleObj, LPCSTR lpszShortType,
HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
BOOL bAddConvert, UINT idConvert, HMENU *lphMenu)
{
- FIXME("(%p, %s, %p, %d, %d, %d, %d, %d, %p): stub\n",
- lpOleObj, debugstr_a(lpszShortType),
- hMenu, uPos, uIDVerbMin, uIDVerbMax,
- bAddConvert, idConvert, lphMenu
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPWSTR newstr = NULL;
+ BOOL ret = FALSE;
+
+ if (lpszShortType) {
+ INT len = MultiByteToWideChar( CP_ACP, 0, lpszShortType, -1, NULL, 0 );
+ newstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if (newstr)
+ MultiByteToWideChar( CP_ACP, 0, lpszShortType, -1, newstr, len );
+ }
+ ret = OleUIAddVerbMenuW(
+ lpOleObj, newstr,
+ hMenu, uPos, uIDVerbMin, uIDVerbMax,
+ bAddConvert, idConvert, lphMenu);
+ HeapFree( GetProcessHeap(), 0, newstr );
+ return ret;
}
/***********************************************************************
* OleUIAddVerbMenuW (OLEDLG.14)
+ * Adds Object menu for the OLE object
+ *
+ * PARAMS
+ * lpOleObj [I ] pointer to the OLE object
+ * lpszShortType [I ] short name of the object or NULL if it is unknown
+ * hMenu [I ] menu handle
+ * uPos [I ] menu item position
+ * uIDVerbMin, [I ] min Verb ID
+ * uIDVerbMax, [I ] max Verb ID (0 if it's not used)
+ * bAddConvert [I ] TRUE if the item "Converting" is needed in the bottom of menu
+ * idConvert [I ] ID of the item "Converting"
+ * lphMenu [IO] pointer to the popup menu, if created
+ *
+ * NOTES
+ * If lpOleObj is NULL, then a default disabled menu item is created.
+ *
+ * RETURNS
+ * TRUE if at least one verb was added to the menu
+ * FALSE if disabled default menu item was created
+ *
+ * TODO
+ * Check if OLE object has no verbs
*/
BOOL WINAPI OleUIAddVerbMenuW(
LPOLEOBJECT lpOleObj, LPCWSTR lpszShortType,
HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
BOOL bAddConvert, UINT idConvert, HMENU *lphMenu)
{
- FIXME("(%p, %s, %p, %d, %d, %d, %d, %d, %p): stub\n",
- lpOleObj, debugstr_w(lpszShortType),
- hMenu, uPos, uIDVerbMin, uIDVerbMax,
- bAddConvert, idConvert, lphMenu
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ HRESULT hr;
+ IEnumOLEVERB *pEnumVerbs;
+ HMENU popup = NULL;
+
+ FIXME("(%p, %s, %p, %d, %d, %d, %d, %d, %p): stub\n",
+ lpOleObj, debugstr_w(lpszShortType),
+ hMenu, uPos, uIDVerbMin, uIDVerbMax,
+ bAddConvert, idConvert, lphMenu );
+
+ if (!lpOleObj) {
+ WCHAR buf[MAX_PATH];
+ TRACE("Create disabled menu entry\n");
+ LoadStringW(OLEDLG_hInstance, IDS_NOOBJECT, buf, MAX_PATH);
+ DeleteMenu(hMenu, uPos, MF_BYPOSITION);
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING|MF_DISABLED, uIDVerbMin, buf);
+ return FALSE;
+ }
+
+ hr = IOleObject_EnumVerbs(lpOleObj, &pEnumVerbs);
+ if (hr == S_OK) {
+ int num; /* Number of menu entries */
+ OLEVERB oleVerb;
+ /* FIXME: there is OLE_S_USEREG, OLEOBJ_E_NOVERBS also */
+ for (num = 0; IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK ; num++)
+ CoTaskMemFree(oleVerb.lpszVerbName);
+ IEnumOLEVERB_Reset(pEnumVerbs);
+
+ /* It destroys popup menu also */
+ if (num)
+ DeleteMenu(hMenu, uPos, MF_BYPOSITION);
+
+ /* If there is a few entries or converting entry needed */
+ if (num > 1 || bAddConvert) {
+ WCHAR menustr[MAX_PATH];
+ int len;
+ /* Prepare menu entry for popup menu */
+ LoadStringW(OLEDLG_hInstance, IDS_OBJECT, menustr, MAX_PATH);
+ len = strlenW(menustr);
+ if (lpszShortType)
+ strcpyW(menustr+len, lpszShortType);
+ else {
+ LPOLESTR lpszUserType;
+ IOleObject_GetUserType(lpOleObj, 0, &lpszUserType);
+ TRACE("Get UserType: %s\n", debugstr_w(lpszUserType));
+ strcpyW(menustr+len, lpszUserType);
+ CoTaskMemFree(lpszUserType);
+ }
+
+ popup = CreatePopupMenu();
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT_PTR)popup, menustr);
+ uPos = -1;
+ hMenu = popup;
+ }
+
+ while (IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK) {
+ TRACE("lVerb=%d VerbName=%s fuFlags=%x\n", oleVerb.lVerb,
+ debugstr_w(oleVerb.lpszVerbName), oleVerb.fuFlags);
+ if (uIDVerbMax && (oleVerb.lVerb > uIDVerbMax-uIDVerbMin))
+ break;
+ InsertMenuW(hMenu, uPos, oleVerb.fuFlags|MF_BYPOSITION|MF_STRING, oleVerb.lVerb+uIDVerbMin, oleVerb.lpszVerbName);
+ /* FIXME: Is it really needed and documented? */
+ CoTaskMemFree(oleVerb.lpszVerbName);
+ }
+
+ /* Converting entry may be only in popup menu */
+ if (popup && bAddConvert) {
+ WCHAR buf[MAX_PATH];
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
+ if (LoadStringW(OLEDLG_hInstance, IDS_CONVERTING, buf, MAX_PATH))
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING, idConvert, buf);
+ }
+ IEnumOLEVERB_Release(pEnumVerbs);
+ }
+ *lphMenu = popup;
+ return TRUE;
}
/***********************************************************************
diff --git a/dlls/oledlg/resource.h b/dlls/oledlg/resource.h
index 13ca052..2d8f6d6 100644
--- a/dlls/oledlg/resource.h
+++ b/dlls/oledlg/resource.h
@@ -25,6 +25,9 @@
#define IDS_BROWSE 103
#define IDS_NOTOLEMOD 104
#define IDS_NOTOLEMODCAPTION 105
+#define IDS_OBJECT 2000
+#define IDS_NOOBJECT 2001
+#define IDS_CONVERTING 2002
#define UIINSERTOBJECT 129
--
1.7.6.1
----------- следующая часть -----------
From d8f9d9c2f135f77a0bf3de4ef7ec2dd97a033981 Mon Sep 17 00:00:00 2001
From: Vitaly Lipatov <lav на etersoft.ru>
Date: Wed, 14 Sep 2011 14:13:43 +0400
Subject: [PATCH 2/2] oledlg: Restructured OleUIAddVerbMenuW, rearrange buf
using, cleanup code
---
dlls/oledlg/oledlg_main.c | 135 ++++++++++++++++++++++++++------------------
1 files changed, 80 insertions(+), 55 deletions(-)
diff --git a/dlls/oledlg/oledlg_main.c b/dlls/oledlg/oledlg_main.c
index 9e81db6..0901bb8 100644
--- a/dlls/oledlg/oledlg_main.c
+++ b/dlls/oledlg/oledlg_main.c
@@ -133,7 +133,7 @@ BOOL WINAPI OleUIAddVerbMenuA(
/***********************************************************************
* OleUIAddVerbMenuW (OLEDLG.14)
- * Adds Object menu for the OLE object
+ * Add Object menu for the OLE object
*
* PARAMS
* lpOleObj [I ] pointer to the OLE object
@@ -144,7 +144,7 @@ BOOL WINAPI OleUIAddVerbMenuA(
* uIDVerbMax, [I ] max Verb ID (0 if it's not used)
* bAddConvert [I ] TRUE if the item "Converting" is needed in the bottom of menu
* idConvert [I ] ID of the item "Converting"
- * lphMenu [IO] pointer to the popup menu, if created
+ * lphMenu [IO] fill with pointer to the popup menu, if created
*
* NOTES
* If lpOleObj is NULL, then a default disabled menu item is created.
@@ -153,8 +153,6 @@ BOOL WINAPI OleUIAddVerbMenuA(
* TRUE if at least one verb was added to the menu
* FALSE if disabled default menu item was created
*
- * TODO
- * Check if OLE object has no verbs
*/
BOOL WINAPI OleUIAddVerbMenuW(
LPOLEOBJECT lpOleObj, LPCWSTR lpszShortType,
@@ -162,79 +160,106 @@ BOOL WINAPI OleUIAddVerbMenuW(
BOOL bAddConvert, UINT idConvert, HMENU *lphMenu)
{
HRESULT hr;
+ WCHAR menustr[MAX_PATH];
IEnumOLEVERB *pEnumVerbs;
HMENU popup = NULL;
+ OLEVERB oleVerb;
+ int numVerbs = 0;
- FIXME("(%p, %s, %p, %d, %d, %d, %d, %d, %p): stub\n",
+ TRACE("(%p, %s, %p, %d, %d, %d, %d, %d, %p)\n",
lpOleObj, debugstr_w(lpszShortType),
hMenu, uPos, uIDVerbMin, uIDVerbMax,
bAddConvert, idConvert, lphMenu );
- if (!lpOleObj) {
- WCHAR buf[MAX_PATH];
- TRACE("Create disabled menu entry\n");
- LoadStringW(OLEDLG_hInstance, IDS_NOOBJECT, buf, MAX_PATH);
+ if (lpOleObj) {
+ hr = IOleObject_EnumVerbs(lpOleObj, &pEnumVerbs);
+/* FIXME: how to get clsid?
+ if (hr == OLE_S_USEREG)
+ hr = OleRegEnumVerbs(&lpOleObj->clsid, &pEnumVerbs);
+*/
+/* FIXME: set correct last error
+ if (hr != S_OK)
+ SetLastError(OLEOBJ_E_NOVERBS);
+*/
+ } else
+ hr = OLEOBJ_E_NOVERBS;
+
+ if (hr != S_OK) {
+ TRACE("Create disabled menu entry (oleObject is missed or without verbs)\n");
+ LoadStringW(OLEDLG_hInstance, IDS_NOOBJECT, menustr, MAX_PATH);
DeleteMenu(hMenu, uPos, MF_BYPOSITION);
- InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING|MF_DISABLED, uIDVerbMin, buf);
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING|MF_DISABLED, uIDVerbMin, menustr);
return FALSE;
}
- hr = IOleObject_EnumVerbs(lpOleObj, &pEnumVerbs);
- if (hr == S_OK) {
- int num; /* Number of menu entries */
- OLEVERB oleVerb;
- /* FIXME: there is OLE_S_USEREG, OLEOBJ_E_NOVERBS also */
- for (num = 0; IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK ; num++)
- CoTaskMemFree(oleVerb.lpszVerbName);
- IEnumOLEVERB_Reset(pEnumVerbs);
-
- /* It destroys popup menu also */
- if (num)
- DeleteMenu(hMenu, uPos, MF_BYPOSITION);
-
- /* If there is a few entries or converting entry needed */
- if (num > 1 || bAddConvert) {
- WCHAR menustr[MAX_PATH];
- int len;
- /* Prepare menu entry for popup menu */
- LoadStringW(OLEDLG_hInstance, IDS_OBJECT, menustr, MAX_PATH);
- len = strlenW(menustr);
- if (lpszShortType)
- strcpyW(menustr+len, lpszShortType);
- else {
- LPOLESTR lpszUserType;
- IOleObject_GetUserType(lpOleObj, 0, &lpszUserType);
+ /* Count number of verbs */
+ for (; IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK ; numVerbs++)
+ CoTaskMemFree(oleVerb.lpszVerbName);
+ IEnumOLEVERB_Reset(pEnumVerbs);
+
+ /* Destroy current menu entry or popup menu */
+ if (numVerbs)
+ DeleteMenu(hMenu, uPos, MF_BYPOSITION);
+
+ /* If there is a few entries or converting entry needed, create popup menu */
+ if (numVerbs > 1 || bAddConvert) {
+ int len;
+ /* Prepare menu entry for popup menu */
+ LoadStringW(OLEDLG_hInstance, IDS_OBJECT, menustr, MAX_PATH);
+ len = strlenW(menustr);
+ if (lpszShortType)
+ strcpyW(menustr+len, lpszShortType);
+ else {
+ LPOLESTR lpszUserType;
+ hr = IOleObject_GetUserType(lpOleObj, 0, &lpszUserType);
+/* FIXME
+ if (hr == OLE_S_USEREG)
+ hr = OleRegEnumVerbs(clsid, USERCLASSTYPE_SHORT, &lpszUserType);
+*/
+ if ( hr == S_OK) {
TRACE("Get UserType: %s\n", debugstr_w(lpszUserType));
strcpyW(menustr+len, lpszUserType);
CoTaskMemFree(lpszUserType);
}
-
- popup = CreatePopupMenu();
+ }
+ popup = CreatePopupMenu();
+ if (popup) {
InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT_PTR)popup, menustr);
uPos = -1;
hMenu = popup;
}
+ }
- while (IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK) {
- TRACE("lVerb=%d VerbName=%s fuFlags=%x\n", oleVerb.lVerb,
- debugstr_w(oleVerb.lpszVerbName), oleVerb.fuFlags);
- if (uIDVerbMax && (oleVerb.lVerb > uIDVerbMax-uIDVerbMin))
- break;
- InsertMenuW(hMenu, uPos, oleVerb.fuFlags|MF_BYPOSITION|MF_STRING, oleVerb.lVerb+uIDVerbMin, oleVerb.lpszVerbName);
- /* FIXME: Is it really needed and documented? */
- CoTaskMemFree(oleVerb.lpszVerbName);
- }
+ /* Create menu items from available verbs */
+ while (IEnumOLEVERB_Next(pEnumVerbs, 1, &oleVerb, NULL) == S_OK) {
+ UINT itemID = oleVerb.lVerb+uIDVerbMin;
+ DWORD flags = oleVerb.fuFlags|MF_BYPOSITION|MF_STRING;
+ TRACE("lVerb=%d VerbName=%s fuFlags=%x\n", oleVerb.lVerb,
+ debugstr_w(oleVerb.lpszVerbName), oleVerb.fuFlags);
- /* Converting entry may be only in popup menu */
- if (popup && bAddConvert) {
- WCHAR buf[MAX_PATH];
- InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
- if (LoadStringW(OLEDLG_hInstance, IDS_CONVERTING, buf, MAX_PATH))
- InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING, idConvert, buf);
- }
- IEnumOLEVERB_Release(pEnumVerbs);
+ if (uIDVerbMax && (itemID > uIDVerbMax))
+ break;
+
+ /* Skip if should not be placed on the menu */
+ if (!(oleVerb.grfAttribs & OLEVERBATTRIB_ONCONTAINERMENU))
+ continue;
+ if (flags & (MF_BITMAP|MF_OWNERDRAW|MF_POPUP))
+ continue;
+
+ InsertMenuW(hMenu, uPos, flags, itemID, oleVerb.lpszVerbName);
+ CoTaskMemFree(oleVerb.lpszVerbName);
}
- *lphMenu = popup;
+ IEnumOLEVERB_Release(pEnumVerbs);
+
+ /* Converting entry may be only in popup menu */
+ if (popup && bAddConvert) {
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
+ if (LoadStringW(OLEDLG_hInstance, IDS_CONVERTING, menustr, MAX_PATH))
+ InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING, idConvert, menustr);
+ }
+
+ if (popup && lphMenu)
+ *lphMenu = popup;
return TRUE;
}
--
1.7.6.1
Подробная информация о списке рассылки Wine-patches