1 /* 2 * OLEDLG library 3 * 4 * Copyright 1998 Patrik Stridvall 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include <stdarg.h> 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winerror.h" 28 #include "wingdi.h" 29 #include "winuser.h" 30 #include "oledlg.h" 31 #include "ole2.h" 32 #include "oledlg_private.h" 33 #include "resource.h" 34 35 #include "wine/debug.h" 36 37 WINE_DEFAULT_DEBUG_CHANNEL(ole); 38 39 HINSTANCE OLEDLG_hInstance = 0; 40 41 UINT cf_embed_source; 42 UINT cf_embedded_object; 43 UINT cf_link_source; 44 UINT cf_object_descriptor; 45 UINT cf_link_src_descriptor; 46 UINT cf_ownerlink; 47 UINT cf_filename; 48 UINT cf_filenamew; 49 50 UINT oleui_msg_help; 51 UINT oleui_msg_enddialog; 52 53 static void register_clipboard_formats(void) 54 { 55 /* These used to be declared in olestd.h, but that seems to have been removed from the api */ 56 static const WCHAR CF_EMBEDSOURCEW[] = { 'E','m','b','e','d',' ','S','o','u','r','c','e',0 }; 57 static const WCHAR CF_EMBEDDEDOBJECTW[] = { 'E','m','b','e','d','d','e','d',' ','O','b','j','e','c','t',0 }; 58 static const WCHAR CF_LINKSOURCEW[] = { 'L','i','n','k',' ','S','o','u','r','c','e',0 }; 59 static const WCHAR CF_OBJECTDESCRIPTORW[] = { 'O','b','j','e','c','t',' ','D','e','s','c','r','i','p','t','o','r',0 }; 60 static const WCHAR CF_LINKSRCDESCRIPTORW[] = { 'L','i','n','k',' ','S','o','u','r','c','e',' ','D','e','s','c','r','i','p','t','o','r',0 }; 61 static const WCHAR CF_OWNERLINKW[] = { 'O','w','n','e','r','L','i','n','k',0 }; 62 static const WCHAR CF_FILENAMEW[] = { 'F','i','l','e','N','a','m','e',0 }; 63 static const WCHAR CF_FILENAMEWW[] = { 'F','i','l','e','N','a','m','e','W',0 }; 64 65 /* Load in the same order as native to make debugging easier */ 66 cf_object_descriptor = RegisterClipboardFormatW(CF_OBJECTDESCRIPTORW); 67 cf_link_src_descriptor = RegisterClipboardFormatW(CF_LINKSRCDESCRIPTORW); 68 cf_embed_source = RegisterClipboardFormatW(CF_EMBEDSOURCEW); 69 cf_embedded_object = RegisterClipboardFormatW(CF_EMBEDDEDOBJECTW); 70 cf_link_source = RegisterClipboardFormatW(CF_LINKSOURCEW); 71 cf_ownerlink = RegisterClipboardFormatW(CF_OWNERLINKW); 72 cf_filename = RegisterClipboardFormatW(CF_FILENAMEW); 73 cf_filenamew = RegisterClipboardFormatW(CF_FILENAMEWW); 74 } 75 76 static void register_messages(void) 77 { 78 oleui_msg_help = RegisterWindowMessageW(SZOLEUI_MSG_HELPW); 79 oleui_msg_enddialog = RegisterWindowMessageW(SZOLEUI_MSG_ENDDIALOGW); 80 } 81 82 /*********************************************************************** 83 * DllMain 84 */ 85 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) 86 { 87 TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); 88 89 switch(fdwReason) { 90 case DLL_PROCESS_ATTACH: 91 DisableThreadLibraryCalls(hinstDLL); 92 OLEDLG_hInstance = hinstDLL; 93 register_clipboard_formats(); 94 register_messages(); 95 break; 96 } 97 return TRUE; 98 } 99 100 101 /*********************************************************************** 102 * OleUIAddVerbMenuA (OLEDLG.1) 103 */ 104 BOOL WINAPI OleUIAddVerbMenuA(IOleObject *object, LPCSTR shorttype, 105 HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax, 106 BOOL addConvert, UINT idConvert, HMENU *lphMenu) 107 { 108 WCHAR *shorttypeW = NULL; 109 BOOL ret; 110 111 TRACE("(%p, %s, %p, %d, %d, %d, %d, %d, %p)\n", object, debugstr_a(shorttype), 112 hMenu, uPos, uIDVerbMin, uIDVerbMax, addConvert, idConvert, lphMenu); 113 114 if (shorttype) 115 { 116 INT len = MultiByteToWideChar(CP_ACP, 0, shorttype, -1, NULL, 0); 117 shorttypeW = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); 118 if (shorttypeW) 119 MultiByteToWideChar(CP_ACP, 0, shorttype, -1, shorttypeW, len); 120 } 121 122 ret = OleUIAddVerbMenuW(object, shorttypeW, hMenu, uPos, uIDVerbMin, uIDVerbMax, 123 addConvert, idConvert, lphMenu); 124 HeapFree(GetProcessHeap(), 0, shorttypeW); 125 return ret; 126 } 127 128 static inline BOOL is_verb_in_range(const OLEVERB *verb, UINT idmin, UINT idmax) 129 { 130 if (idmax == 0) return TRUE; 131 return (verb->lVerb + idmin <= idmax); 132 } 133 134 static HRESULT get_next_insertable_verb(IEnumOLEVERB *enumverbs, UINT idmin, UINT idmax, OLEVERB *verb) 135 { 136 memset(verb, 0, sizeof(*verb)); 137 138 while (IEnumOLEVERB_Next(enumverbs, 1, verb, NULL) == S_OK) { 139 if (is_verb_in_range(verb, idmin, idmax) && (verb->grfAttribs & OLEVERBATTRIB_ONCONTAINERMENU)) 140 return S_OK; 141 142 CoTaskMemFree(verb->lpszVerbName); 143 memset(verb, 0, sizeof(*verb)); 144 } 145 146 return S_FALSE; 147 } 148 149 static void insert_verb_to_menu(HMENU menu, UINT idmin, const OLEVERB *verb) 150 { 151 InsertMenuW(menu, ~0, verb->fuFlags | MF_BYPOSITION | MF_STRING, verb->lVerb + idmin, verb->lpszVerbName); 152 } 153 154 /*********************************************************************** 155 * OleUIAddVerbMenuW (OLEDLG.14) 156 */ 157 BOOL WINAPI OleUIAddVerbMenuW(IOleObject *object, LPCWSTR shorttype, 158 HMENU hMenu, UINT uPos, UINT idmin, UINT idmax, BOOL addConvert, UINT idConvert, HMENU *ret_submenu) 159 { 160 IEnumOLEVERB *enumverbs = NULL; 161 LPOLESTR usertype = NULL; 162 OLEVERB firstverb, verb; 163 WCHAR *objecttype; 164 WCHAR resstrW[32]; /* should be enough */ 165 DWORD_PTR args[2]; 166 BOOL singleverb; 167 HMENU submenu; 168 WCHAR *str; 169 170 TRACE("(%p, %s, %p, %d, %d, %d, %d, %d, %p)\n", object, debugstr_w(shorttype), 171 hMenu, uPos, idmin, idmax, addConvert, idConvert, ret_submenu); 172 173 if (ret_submenu) 174 *ret_submenu = NULL; 175 176 if (!hMenu || !ret_submenu) 177 return FALSE; 178 179 /* check if we can get verbs at all */ 180 if (object) 181 IOleObject_EnumVerbs(object, &enumverbs); 182 183 LoadStringW(OLEDLG_hInstance, IDS_VERBMENU_OBJECT, resstrW, ARRAY_SIZE(resstrW)); 184 /* no object, or object without enumeration support */ 185 if (!object || !enumverbs) { 186 RemoveMenu(hMenu, uPos, MF_BYPOSITION); 187 InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING|MF_GRAYED, idmin, resstrW); 188 return FALSE; 189 } 190 191 /* root entry string */ 192 if (!shorttype && (IOleObject_GetUserType(object, USERCLASSTYPE_SHORT, &usertype) == S_OK)) 193 objecttype = usertype; 194 else 195 objecttype = (WCHAR*)shorttype; 196 197 /* iterate through verbs */ 198 199 /* find first suitable verb */ 200 get_next_insertable_verb(enumverbs, idmin, idmax, &firstverb); 201 singleverb = get_next_insertable_verb(enumverbs, idmin, idmax, &verb) != S_OK; 202 203 if (singleverb && !addConvert) { 204 LoadStringW(OLEDLG_hInstance, IDS_VERBMENU_SINGLEVERB_OBJECT, resstrW, ARRAY_SIZE(resstrW)); 205 206 args[0] = (DWORD_PTR)firstverb.lpszVerbName; 207 args[1] = (DWORD_PTR)objecttype; 208 209 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_ARGUMENT_ARRAY, 210 resstrW, 0, 0, (WCHAR*)&str, 0, (__ms_va_list*)args); 211 212 RemoveMenu(hMenu, uPos, MF_BYPOSITION); 213 InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_STRING, idmin, str); 214 CoTaskMemFree(firstverb.lpszVerbName); 215 HeapFree(GetProcessHeap(), 0, str); 216 IEnumOLEVERB_Release(enumverbs); 217 CoTaskMemFree(usertype); 218 return TRUE; 219 } 220 221 submenu = CreatePopupMenu(); 222 insert_verb_to_menu(submenu, idmin, &firstverb); 223 CoTaskMemFree(firstverb.lpszVerbName); 224 225 if (!singleverb) { 226 insert_verb_to_menu(submenu, idmin, &verb); 227 CoTaskMemFree(verb.lpszVerbName); 228 } 229 230 while (get_next_insertable_verb(enumverbs, idmin, idmax, &verb) == S_OK) { 231 insert_verb_to_menu(submenu, idmin, &verb); 232 CoTaskMemFree(verb.lpszVerbName); 233 } 234 235 /* convert verb is at the bottom of a popup, separated from verbs */ 236 if (addConvert) { 237 LoadStringW(OLEDLG_hInstance, IDS_VERBMENU_CONVERT, resstrW, ARRAY_SIZE(resstrW)); 238 InsertMenuW(submenu, ~0, MF_BYPOSITION|MF_SEPARATOR, 0, NULL); 239 InsertMenuW(submenu, ~0, MF_BYPOSITION|MF_STRING, idConvert, resstrW); 240 } 241 242 if (submenu) 243 *ret_submenu = submenu; 244 245 /* now submenu is ready, add root entry to original menu, attach submenu */ 246 LoadStringW(OLEDLG_hInstance, IDS_VERBMENU_OBJECT_WITH_NAME, resstrW, ARRAY_SIZE(resstrW)); 247 248 args[0] = (DWORD_PTR)objecttype; 249 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_ARGUMENT_ARRAY, 250 resstrW, 0, 0, (WCHAR*)&str, 0, (__ms_va_list*)args); 251 252 InsertMenuW(hMenu, uPos, MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT_PTR)submenu, str); 253 HeapFree(GetProcessHeap(), 0, str); 254 IEnumOLEVERB_Release(enumverbs); 255 CoTaskMemFree(usertype); 256 return TRUE; 257 } 258 259 /*********************************************************************** 260 * OleUICanConvertOrActivateAs (OLEDLG.2) 261 */ 262 BOOL WINAPI OleUICanConvertOrActivateAs( 263 REFCLSID rClsid, BOOL fIsLinkedObject, WORD wFormat) 264 { 265 FIXME("(%p, %d, %hd): stub\n", 266 rClsid, fIsLinkedObject, wFormat 267 ); 268 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 269 return FALSE; 270 } 271 272 /*********************************************************************** 273 * OleUIInsertObjectW (OLEDLG.20) 274 */ 275 UINT WINAPI OleUIInsertObjectW(LPOLEUIINSERTOBJECTW lpOleUIInsertObject) 276 { 277 FIXME("(%p): stub\n", lpOleUIInsertObject); 278 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 279 return OLEUI_FALSE; 280 } 281 282 /*********************************************************************** 283 * OleUIEditLinksA (OLEDLG.5) 284 */ 285 UINT WINAPI OleUIEditLinksA(LPOLEUIEDITLINKSA lpOleUIEditLinks) 286 { 287 FIXME("(%p): stub\n", lpOleUIEditLinks); 288 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 289 return OLEUI_FALSE; 290 } 291 292 /*********************************************************************** 293 * OleUIEditLinksW (OLEDLG.19) 294 */ 295 UINT WINAPI OleUIEditLinksW(LPOLEUIEDITLINKSW lpOleUIEditLinks) 296 { 297 FIXME("(%p): stub\n", lpOleUIEditLinks); 298 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 299 return OLEUI_FALSE; 300 } 301 302 /*********************************************************************** 303 * OleUIChangeIconA (OLEDLG.6) 304 */ 305 UINT WINAPI OleUIChangeIconA( 306 LPOLEUICHANGEICONA lpOleUIChangeIcon) 307 { 308 FIXME("(%p): stub\n", lpOleUIChangeIcon); 309 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 310 return OLEUI_FALSE; 311 } 312 313 /*********************************************************************** 314 * OleUIChangeIconW (OLEDLG.16) 315 */ 316 UINT WINAPI OleUIChangeIconW( 317 LPOLEUICHANGEICONW lpOleUIChangeIcon) 318 { 319 FIXME("(%p): stub\n", lpOleUIChangeIcon); 320 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 321 return OLEUI_FALSE; 322 } 323 324 /*********************************************************************** 325 * OleUIConvertA (OLEDLG.7) 326 */ 327 UINT WINAPI OleUIConvertA(LPOLEUICONVERTA lpOleUIConvert) 328 { 329 FIXME("(%p): stub\n", lpOleUIConvert); 330 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 331 return OLEUI_FALSE; 332 } 333 334 /*********************************************************************** 335 * OleUIConvertW (OLEDLG.18) 336 */ 337 UINT WINAPI OleUIConvertW(LPOLEUICONVERTW lpOleUIConvert) 338 { 339 FIXME("(%p): stub\n", lpOleUIConvert); 340 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 341 return OLEUI_FALSE; 342 } 343 344 /*********************************************************************** 345 * OleUIBusyA (OLEDLG.8) 346 */ 347 UINT WINAPI OleUIBusyA(LPOLEUIBUSYA lpOleUIBusy) 348 { 349 FIXME("(%p): stub\n", lpOleUIBusy); 350 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 351 return OLEUI_FALSE; 352 } 353 354 /*********************************************************************** 355 * OleUIBusyW (OLEDLG.15) 356 */ 357 UINT WINAPI OleUIBusyW(LPOLEUIBUSYW lpOleUIBusy) 358 { 359 FIXME("(%p): stub\n", lpOleUIBusy); 360 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 361 return OLEUI_FALSE; 362 } 363 364 /*********************************************************************** 365 * OleUIUpdateLinksA (OLEDLG.9) 366 */ 367 BOOL WINAPI OleUIUpdateLinksA( 368 LPOLEUILINKCONTAINERA lpOleUILinkCntr, 369 HWND hwndParent, LPSTR lpszTitle, INT cLinks) 370 { 371 FIXME("(%p, %p, %s, %d): stub\n", 372 lpOleUILinkCntr, hwndParent, debugstr_a(lpszTitle), cLinks 373 ); 374 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 375 return FALSE; 376 } 377 378 /*********************************************************************** 379 * OleUIUpdateLinksW (OLEDLG.23) 380 */ 381 BOOL WINAPI OleUIUpdateLinksW( 382 LPOLEUILINKCONTAINERW lpOleUILinkCntr, 383 HWND hwndParent, LPWSTR lpszTitle, INT cLinks) 384 { 385 FIXME("(%p, %p, %s, %d): stub\n", 386 lpOleUILinkCntr, hwndParent, debugstr_w(lpszTitle), cLinks 387 ); 388 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 389 return FALSE; 390 } 391 392 /*********************************************************************** 393 * OleUIPromptUserA (OLEDLG.10) 394 */ 395 INT WINAPIV OleUIPromptUserA( 396 INT nTemplate, HWND hwndParent, ...) 397 { 398 FIXME("(%d, %p, ...): stub\n", nTemplate, hwndParent); 399 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 400 return OLEUI_FALSE; 401 } 402 403 /*********************************************************************** 404 * OleUIPromptUserW (OLEDLG.13) 405 */ 406 INT WINAPIV OleUIPromptUserW( 407 INT nTemplate, HWND hwndParent, ...) 408 { 409 FIXME("(%d, %p, ...): stub\n", nTemplate, hwndParent); 410 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 411 return OLEUI_FALSE; 412 } 413 414 /*********************************************************************** 415 * OleUIObjectPropertiesA (OLEDLG.11) 416 */ 417 UINT WINAPI OleUIObjectPropertiesA( 418 LPOLEUIOBJECTPROPSA lpOleUIObjectProps) 419 { 420 FIXME("(%p): stub\n", lpOleUIObjectProps); 421 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 422 return OLEUI_FALSE; 423 } 424 425 /*********************************************************************** 426 * OleUIObjectPropertiesW (OLEDLG.21) 427 */ 428 UINT WINAPI OleUIObjectPropertiesW( 429 LPOLEUIOBJECTPROPSW lpOleUIObjectProps) 430 { 431 FIXME("(%p): stub\n", lpOleUIObjectProps); 432 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 433 return OLEUI_FALSE; 434 } 435 436 /*********************************************************************** 437 * OleUIChangeSourceA (OLEDLG.12) 438 */ 439 UINT WINAPI OleUIChangeSourceA( 440 LPOLEUICHANGESOURCEA lpOleUIChangeSource) 441 { 442 FIXME("(%p): stub\n", lpOleUIChangeSource); 443 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 444 return OLEUI_FALSE; 445 } 446 447 /*********************************************************************** 448 * OleUIChangeSourceW (OLEDLG.17) 449 */ 450 UINT WINAPI OleUIChangeSourceW( 451 LPOLEUICHANGESOURCEW lpOleUIChangeSource) 452 { 453 FIXME("(%p): stub\n", lpOleUIChangeSource); 454 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 455 return OLEUI_FALSE; 456 } 457