1 /*
2 * Copyright 2005-2007 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "mshtml_private.h"
20
21 #define NSCMD_COPY "cmd_copy"
22 #define NSCMD_SELECTALL "cmd_selectAll"
23
do_ns_command(HTMLDocument * This,const char * cmd,nsICommandParams * nsparam)24 void do_ns_command(HTMLDocument *This, const char *cmd, nsICommandParams *nsparam)
25 {
26 nsICommandManager *cmdmgr;
27 nsresult nsres;
28
29 TRACE("(%p)\n", This);
30
31 if(!This->doc_obj || !This->doc_obj->nscontainer)
32 return;
33
34 nsres = get_nsinterface((nsISupports*)This->doc_obj->nscontainer->webbrowser, &IID_nsICommandManager, (void**)&cmdmgr);
35 if(NS_FAILED(nsres)) {
36 ERR("Could not get nsICommandManager: %08x\n", nsres);
37 return;
38 }
39
40 nsres = nsICommandManager_DoCommand(cmdmgr, cmd, nsparam, This->window->nswindow);
41 if(NS_FAILED(nsres))
42 ERR("DoCommand(%s) failed: %08x\n", debugstr_a(cmd), nsres);
43
44 nsICommandManager_Release(cmdmgr);
45 }
46
get_clipboard_commands(HTMLDocument * doc)47 static nsIClipboardCommands *get_clipboard_commands(HTMLDocument *doc)
48 {
49 nsIClipboardCommands *clipboard_commands;
50 nsIDocShell *doc_shell;
51 nsresult nsres;
52
53 nsres = get_nsinterface((nsISupports*)doc->window->nswindow, &IID_nsIDocShell, (void**)&doc_shell);
54 if(NS_FAILED(nsres)) {
55 ERR("Could not get nsIDocShell interface\n");
56 return NULL;
57 }
58
59 nsres = nsIDocShell_QueryInterface(doc_shell, &IID_nsIClipboardCommands, (void**)&clipboard_commands);
60 nsIDocShell_Release(doc_shell);
61 if(NS_FAILED(nsres)) {
62 ERR("Could not get nsIClipboardCommands interface\n");
63 return NULL;
64 }
65
66 return clipboard_commands;
67 }
68
69 /**********************************************************
70 * IOleCommandTarget implementation
71 */
72
impl_from_IOleCommandTarget(IOleCommandTarget * iface)73 static inline HTMLDocument *impl_from_IOleCommandTarget(IOleCommandTarget *iface)
74 {
75 return CONTAINING_RECORD(iface, HTMLDocument, IOleCommandTarget_iface);
76 }
77
exec_open(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)78 static HRESULT exec_open(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
79 {
80 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
81 return E_NOTIMPL;
82 }
83
exec_new(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)84 static HRESULT exec_new(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
85 {
86 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
87 return E_NOTIMPL;
88 }
89
exec_save(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)90 static HRESULT exec_save(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
91 {
92 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
93 return E_NOTIMPL;
94 }
95
exec_save_as(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)96 static HRESULT exec_save_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
97 {
98 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
99 return E_NOTIMPL;
100 }
101
exec_save_copy_as(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)102 static HRESULT exec_save_copy_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
103 {
104 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
105 return E_NOTIMPL;
106 }
107
set_head_text(nsIPrintSettings * settings,LPCWSTR template,BOOL head,int pos)108 static nsresult set_head_text(nsIPrintSettings *settings, LPCWSTR template, BOOL head, int pos)
109 {
110 if(head) {
111 switch(pos) {
112 case 0:
113 return nsIPrintSettings_SetHeaderStrLeft(settings, template);
114 case 1:
115 return nsIPrintSettings_SetHeaderStrRight(settings, template);
116 case 2:
117 return nsIPrintSettings_SetHeaderStrCenter(settings, template);
118 }
119 }else {
120 switch(pos) {
121 case 0:
122 return nsIPrintSettings_SetFooterStrLeft(settings, template);
123 case 1:
124 return nsIPrintSettings_SetFooterStrRight(settings, template);
125 case 2:
126 return nsIPrintSettings_SetFooterStrCenter(settings, template);
127 }
128 }
129
130 return NS_OK;
131 }
132
set_print_template(nsIPrintSettings * settings,LPCWSTR template,BOOL head)133 static void set_print_template(nsIPrintSettings *settings, LPCWSTR template, BOOL head)
134 {
135 PRUnichar nstemplate[200]; /* FIXME: Use dynamic allocation */
136 PRUnichar *p = nstemplate;
137 LPCWSTR ptr=template;
138 int pos=0;
139
140 while(*ptr) {
141 if(*ptr != '&') {
142 *p++ = *ptr++;
143 continue;
144 }
145
146 switch(*++ptr) {
147 case '&':
148 *p++ = '&';
149 *p++ = '&';
150 ptr++;
151 break;
152 case 'b': /* change align */
153 ptr++;
154 *p = 0;
155 set_head_text(settings, nstemplate, head, pos);
156 p = nstemplate;
157 pos++;
158 break;
159 case 'd': { /* short date */
160 SYSTEMTIME systime;
161 GetLocalTime(&systime);
162 GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &systime, NULL, p,
163 sizeof(nstemplate)-(p-nstemplate)*sizeof(WCHAR));
164 p += strlenW(p);
165 ptr++;
166 break;
167 }
168 case 'p': /* page number */
169 *p++ = '&';
170 *p++ = 'P';
171 ptr++;
172 break;
173 case 'P': /* page count */
174 *p++ = '?'; /* FIXME */
175 ptr++;
176 break;
177 case 'u':
178 *p++ = '&';
179 *p++ = 'U';
180 ptr++;
181 break;
182 case 'w':
183 /* FIXME: set window title */
184 ptr++;
185 break;
186 default:
187 *p++ = '&';
188 *p++ = *ptr++;
189 }
190 }
191
192 *p = 0;
193 set_head_text(settings, nstemplate, head, pos);
194
195 while(++pos < 3)
196 set_head_text(settings, p, head, pos);
197 }
198
set_default_templates(nsIPrintSettings * settings)199 static void set_default_templates(nsIPrintSettings *settings)
200 {
201 WCHAR buf[64];
202
203 static const PRUnichar empty[] = {0};
204
205 nsIPrintSettings_SetHeaderStrLeft(settings, empty);
206 nsIPrintSettings_SetHeaderStrRight(settings, empty);
207 nsIPrintSettings_SetHeaderStrCenter(settings, empty);
208 nsIPrintSettings_SetFooterStrLeft(settings, empty);
209 nsIPrintSettings_SetFooterStrRight(settings, empty);
210 nsIPrintSettings_SetFooterStrCenter(settings, empty);
211
212 if(LoadStringW(get_shdoclc(), IDS_PRINT_HEADER_TEMPLATE, buf,
213 sizeof(buf)/sizeof(WCHAR)))
214 set_print_template(settings, buf, TRUE);
215
216
217 if(LoadStringW(get_shdoclc(), IDS_PRINT_FOOTER_TEMPLATE, buf,
218 sizeof(buf)/sizeof(WCHAR)))
219 set_print_template(settings, buf, FALSE);
220
221 }
222
exec_print(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)223 static HRESULT exec_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
224 {
225 nsIWebBrowserPrint *nsprint;
226 nsIPrintSettings *settings;
227 nsresult nsres;
228
229 TRACE("(%p)->(%d %s %p)\n", This, nCmdexecopt, debugstr_variant(pvaIn), pvaOut);
230
231 if(pvaOut)
232 FIXME("unsupported pvaOut\n");
233
234 if(!This->doc_obj->nscontainer)
235 return S_OK;
236
237 nsres = get_nsinterface((nsISupports*)This->doc_obj->nscontainer->webbrowser, &IID_nsIWebBrowserPrint,
238 (void**)&nsprint);
239 if(NS_FAILED(nsres)) {
240 ERR("Could not get nsIWebBrowserPrint: %08x\n", nsres);
241 return S_OK;
242 }
243
244 #ifdef __REACTOS__
245 // returning here fixes CORE-16884. Maybe use this until printing works.
246 ERR("Aborting print, to work around CORE-16884\n");
247 nsIWebBrowserPrint_Release(nsprint);
248 return S_OK;
249 #endif
250
251 nsres = nsIWebBrowserPrint_GetGlobalPrintSettings(nsprint, &settings);
252 if(NS_FAILED(nsres))
253 ERR("GetCurrentPrintSettings failed: %08x\n", nsres);
254
255 set_default_templates(settings);
256
257 if(pvaIn) {
258 switch(V_VT(pvaIn)) {
259 case VT_BYREF|VT_ARRAY: {
260 VARIANT *opts;
261 DWORD opts_cnt;
262
263 if(V_ARRAY(pvaIn)->cDims != 1)
264 WARN("cDims = %d\n", V_ARRAY(pvaIn)->cDims);
265
266 SafeArrayAccessData(V_ARRAY(pvaIn), (void**)&opts);
267 opts_cnt = V_ARRAY(pvaIn)->rgsabound[0].cElements;
268
269 if(opts_cnt >= 1) {
270 switch(V_VT(opts)) {
271 case VT_BSTR:
272 TRACE("setting footer %s\n", debugstr_w(V_BSTR(opts)));
273 set_print_template(settings, V_BSTR(opts), TRUE);
274 break;
275 case VT_NULL:
276 break;
277 default:
278 WARN("opts = %s\n", debugstr_variant(opts));
279 }
280 }
281
282 if(opts_cnt >= 2) {
283 switch(V_VT(opts+1)) {
284 case VT_BSTR:
285 TRACE("setting footer %s\n", debugstr_w(V_BSTR(opts+1)));
286 set_print_template(settings, V_BSTR(opts+1), FALSE);
287 break;
288 case VT_NULL:
289 break;
290 default:
291 WARN("opts[1] = %s\n", debugstr_variant(opts+1));
292 }
293 }
294
295 if(opts_cnt >= 3)
296 FIXME("Unsupported opts_cnt %d\n", opts_cnt);
297
298 SafeArrayUnaccessData(V_ARRAY(pvaIn));
299 break;
300 }
301 default:
302 FIXME("unsupported arg %s\n", debugstr_variant(pvaIn));
303 }
304 }
305
306 nsres = nsIWebBrowserPrint_Print(nsprint, settings, NULL);
307 if(NS_FAILED(nsres))
308 ERR("Print failed: %08x\n", nsres);
309
310 nsIWebBrowserPrint_Release(nsprint);
311
312 return S_OK;
313 }
314
exec_print_preview(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)315 static HRESULT exec_print_preview(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
316 {
317 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
318 return E_NOTIMPL;
319 }
320
exec_page_setup(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)321 static HRESULT exec_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
322 {
323 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
324 return E_NOTIMPL;
325 }
326
exec_spell(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)327 static HRESULT exec_spell(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
328 {
329 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
330 return E_NOTIMPL;
331 }
332
exec_properties(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)333 static HRESULT exec_properties(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
334 {
335 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
336 return E_NOTIMPL;
337 }
338
exec_cut(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)339 static HRESULT exec_cut(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
340 {
341 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
342 return E_NOTIMPL;
343 }
344
exec_copy(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)345 static HRESULT exec_copy(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
346 {
347 TRACE("(%p)->(%d %s %p)\n", This, nCmdexecopt, debugstr_variant(pvaIn), pvaOut);
348
349 do_ns_command(This, NSCMD_COPY, NULL);
350 return S_OK;
351 }
352
exec_paste(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)353 static HRESULT exec_paste(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
354 {
355 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
356 return E_NOTIMPL;
357 }
358
exec_paste_special(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)359 static HRESULT exec_paste_special(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
360 {
361 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
362 return E_NOTIMPL;
363 }
364
exec_undo(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)365 static HRESULT exec_undo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
366 {
367 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
368 return E_NOTIMPL;
369 }
370
exec_rendo(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)371 static HRESULT exec_rendo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
372 {
373 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
374 return E_NOTIMPL;
375 }
376
exec_select_all(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * in,VARIANT * out)377 static HRESULT exec_select_all(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *in, VARIANT *out)
378 {
379 TRACE("(%p)\n", This);
380
381 if(in || out)
382 FIXME("unsupported args\n");
383
384 if(This->doc_obj->nscontainer)
385 do_ns_command(This, NSCMD_SELECTALL, NULL);
386
387 update_doc(This, UPDATE_UI);
388 return S_OK;
389 }
390
exec_clear_selection(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)391 static HRESULT exec_clear_selection(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
392 {
393 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
394 return E_NOTIMPL;
395 }
396
exec_zoom(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)397 static HRESULT exec_zoom(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
398 {
399 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
400 return E_NOTIMPL;
401 }
402
exec_get_zoom_range(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)403 static HRESULT exec_get_zoom_range(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
404 {
405 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
406 return E_NOTIMPL;
407 }
408
409 typedef struct {
410 task_t header;
411 HTMLOuterWindow *window;
412 }refresh_task_t;
413
refresh_proc(task_t * _task)414 static void refresh_proc(task_t *_task)
415 {
416 refresh_task_t *task = (refresh_task_t*)_task;
417 HTMLOuterWindow *window = task->window;
418
419 TRACE("%p\n", window);
420
421 window->readystate = READYSTATE_UNINITIALIZED;
422
423 if(window->doc_obj && window->doc_obj->client_cmdtrg) {
424 VARIANT var;
425
426 V_VT(&var) = VT_I4;
427 V_I4(&var) = 0;
428 IOleCommandTarget_Exec(window->doc_obj->client_cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL);
429 }
430
431 load_uri(task->window, task->window->uri, BINDING_REFRESH|BINDING_NOFRAG);
432 }
433
refresh_destr(task_t * _task)434 static void refresh_destr(task_t *_task)
435 {
436 refresh_task_t *task = (refresh_task_t*)_task;
437
438 IHTMLWindow2_Release(&task->window->base.IHTMLWindow2_iface);
439 heap_free(task);
440 }
441
exec_refresh(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)442 static HRESULT exec_refresh(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
443 {
444 refresh_task_t *task;
445 HRESULT hres;
446
447 TRACE("(%p)->(%d %s %p)\n", This, nCmdexecopt, debugstr_variant(pvaIn), pvaOut);
448
449 if(This->doc_obj->client) {
450 IOleCommandTarget *olecmd;
451
452 hres = IOleClientSite_QueryInterface(This->doc_obj->client, &IID_IOleCommandTarget, (void**)&olecmd);
453 if(SUCCEEDED(hres)) {
454 hres = IOleCommandTarget_Exec(olecmd, &CGID_DocHostCommandHandler, 2300, nCmdexecopt, pvaIn, pvaOut);
455 IOleCommandTarget_Release(olecmd);
456 if(SUCCEEDED(hres))
457 return S_OK;
458 }
459 }
460
461 if(!This->window)
462 return E_UNEXPECTED;
463
464 task = heap_alloc(sizeof(*task));
465 if(!task)
466 return E_OUTOFMEMORY;
467
468 IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
469 task->window = This->window;
470
471 return push_task(&task->header, refresh_proc, refresh_destr, This->window->task_magic);
472 }
473
exec_stop(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)474 static HRESULT exec_stop(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
475 {
476 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
477 return E_NOTIMPL;
478 }
479
exec_stop_download(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)480 static HRESULT exec_stop_download(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
481 {
482 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
483 return E_NOTIMPL;
484 }
485
exec_find(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)486 static HRESULT exec_find(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
487 {
488 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
489 return E_NOTIMPL;
490 }
491
exec_delete(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)492 static HRESULT exec_delete(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
493 {
494 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
495 return E_NOTIMPL;
496 }
497
exec_enable_interaction(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)498 static HRESULT exec_enable_interaction(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
499 {
500 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
501 return E_NOTIMPL;
502 }
503
exec_on_unload(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)504 static HRESULT exec_on_unload(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
505 {
506 TRACE("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
507
508 /* Tests show that we have nothing more to do here */
509
510 if(pvaOut) {
511 V_VT(pvaOut) = VT_BOOL;
512 V_BOOL(pvaOut) = VARIANT_TRUE;
513 }
514
515 return S_OK;
516 }
517
exec_show_page_setup(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)518 static HRESULT exec_show_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
519 {
520 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
521 return E_NOTIMPL;
522 }
523
exec_show_print(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)524 static HRESULT exec_show_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
525 {
526 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
527 return E_NOTIMPL;
528 }
529
exec_close(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)530 static HRESULT exec_close(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
531 {
532 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
533 return E_NOTIMPL;
534 }
535
exec_set_print_template(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)536 static HRESULT exec_set_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
537 {
538 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
539 return E_NOTIMPL;
540 }
541
exec_get_print_template(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)542 static HRESULT exec_get_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
543 {
544 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
545 return E_NOTIMPL;
546 }
547
exec_optical_zoom(HTMLDocument * This,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)548 static HRESULT exec_optical_zoom(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
549 {
550 TRACE("(%p)->(%d %s %p)\n", This, nCmdexecopt, debugstr_variant(pvaIn), pvaOut);
551
552 if(!pvaIn || V_VT(pvaIn) != VT_I4) {
553 FIXME("Unsupported argument %s\n", debugstr_variant(pvaIn));
554 return E_NOTIMPL;
555 }
556
557 set_viewer_zoom(This->doc_obj->nscontainer, (float)V_I4(pvaIn)/100);
558 return S_OK;
559 }
560
query_mshtml_copy(HTMLDocument * This,OLECMD * cmd)561 static HRESULT query_mshtml_copy(HTMLDocument *This, OLECMD *cmd)
562 {
563 FIXME("(%p)\n", This);
564 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
565 return S_OK;
566 }
567
exec_mshtml_copy(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)568 static HRESULT exec_mshtml_copy(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
569 {
570 TRACE("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
571
572 if(This->doc_obj->usermode == EDITMODE)
573 return editor_exec_copy(This, cmdexecopt, in, out);
574
575 do_ns_command(This, NSCMD_COPY, NULL);
576 return S_OK;
577 }
578
query_mshtml_cut(HTMLDocument * This,OLECMD * cmd)579 static HRESULT query_mshtml_cut(HTMLDocument *This, OLECMD *cmd)
580 {
581 FIXME("(%p)\n", This);
582 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
583 return S_OK;
584 }
585
exec_mshtml_cut(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)586 static HRESULT exec_mshtml_cut(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
587 {
588 nsIClipboardCommands *clipboard_commands;
589 nsresult nsres;
590
591 TRACE("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
592
593 if(This->doc_obj->usermode == EDITMODE)
594 return editor_exec_cut(This, cmdexecopt, in, out);
595
596 clipboard_commands = get_clipboard_commands(This);
597 if(!clipboard_commands)
598 return E_UNEXPECTED;
599
600 nsres = nsIClipboardCommands_CutSelection(clipboard_commands);
601 nsIClipboardCommands_Release(clipboard_commands);
602 if(NS_FAILED(nsres)) {
603 ERR("Paste failed: %08x\n", nsres);
604 return E_FAIL;
605 }
606
607 return S_OK;
608 }
609
query_mshtml_paste(HTMLDocument * This,OLECMD * cmd)610 static HRESULT query_mshtml_paste(HTMLDocument *This, OLECMD *cmd)
611 {
612 FIXME("(%p)\n", This);
613 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
614 return S_OK;
615 }
616
exec_mshtml_paste(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)617 static HRESULT exec_mshtml_paste(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
618 {
619 nsIClipboardCommands *clipboard_commands;
620 nsresult nsres;
621
622 TRACE("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
623
624 if(This->doc_obj->usermode == EDITMODE)
625 return editor_exec_paste(This, cmdexecopt, in, out);
626
627 clipboard_commands = get_clipboard_commands(This);
628 if(!clipboard_commands)
629 return E_UNEXPECTED;
630
631 nsres = nsIClipboardCommands_Paste(clipboard_commands);
632 nsIClipboardCommands_Release(clipboard_commands);
633 if(NS_FAILED(nsres)) {
634 ERR("Paste failed: %08x\n", nsres);
635 return E_FAIL;
636 }
637
638 return S_OK;
639 }
640
query_selall_status(HTMLDocument * This,OLECMD * cmd)641 static HRESULT query_selall_status(HTMLDocument *This, OLECMD *cmd)
642 {
643 TRACE("(%p)->(%p)\n", This, cmd);
644
645 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
646 return S_OK;
647 }
648
exec_browsemode(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)649 static HRESULT exec_browsemode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
650 {
651 WARN("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
652
653 if(in || out)
654 FIXME("unsupported args\n");
655
656 This->doc_obj->usermode = BROWSEMODE;
657
658 return S_OK;
659 }
660
exec_editmode(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)661 static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
662 {
663 TRACE("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
664
665 if(in || out)
666 FIXME("unsupported args\n");
667
668 return setup_edit_mode(This->doc_obj);
669 }
670
exec_htmleditmode(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)671 static HRESULT exec_htmleditmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
672 {
673 FIXME("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
674 return S_OK;
675 }
676
exec_baselinefont3(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)677 static HRESULT exec_baselinefont3(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
678 {
679 FIXME("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
680 return S_OK;
681 }
682
exec_respectvisibility_indesign(HTMLDocument * This,DWORD cmdexecopt,VARIANT * in,VARIANT * out)683 static HRESULT exec_respectvisibility_indesign(HTMLDocument *This, DWORD cmdexecopt,
684 VARIANT *in, VARIANT *out)
685 {
686 TRACE("(%p)->(%x %s %p)\n", This, cmdexecopt, debugstr_variant(in), out);
687
688 /* This is turned on by default in Gecko. */
689 if(!in || V_VT(in) != VT_BOOL || !V_BOOL(in))
690 FIXME("Unsupported argument %s\n", debugstr_variant(in));
691
692 return S_OK;
693 }
694
query_enabled_stub(HTMLDocument * This,OLECMD * cmd)695 static HRESULT query_enabled_stub(HTMLDocument *This, OLECMD *cmd)
696 {
697 switch(cmd->cmdID) {
698 case IDM_PRINT:
699 FIXME("CGID_MSHTML: IDM_PRINT\n");
700 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
701 break;
702 case IDM_BLOCKDIRLTR:
703 FIXME("CGID_MSHTML: IDM_BLOCKDIRLTR\n");
704 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
705 break;
706 case IDM_BLOCKDIRRTL:
707 FIXME("CGID_MSHTML: IDM_BLOCKDIRRTL\n");
708 cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
709 break;
710 }
711
712 return S_OK;
713 }
714
715 static const struct {
716 OLECMDF cmdf;
717 HRESULT (*func)(HTMLDocument*,DWORD,VARIANT*,VARIANT*);
718 } exec_table[] = {
719 {0},
720 { OLECMDF_SUPPORTED, exec_open }, /* OLECMDID_OPEN */
721 { OLECMDF_SUPPORTED, exec_new }, /* OLECMDID_NEW */
722 { OLECMDF_SUPPORTED, exec_save }, /* OLECMDID_SAVE */
723 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_save_as }, /* OLECMDID_SAVEAS */
724 { OLECMDF_SUPPORTED, exec_save_copy_as }, /* OLECMDID_SAVECOPYAS */
725 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_print }, /* OLECMDID_PRINT */
726 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_print_preview }, /* OLECMDID_PRINTPREVIEW */
727 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_page_setup }, /* OLECMDID_PAGESETUP */
728 { OLECMDF_SUPPORTED, exec_spell }, /* OLECMDID_SPELL */
729 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_properties }, /* OLECMDID_PROPERTIES */
730 { OLECMDF_SUPPORTED, exec_cut }, /* OLECMDID_CUT */
731 { OLECMDF_SUPPORTED, exec_copy }, /* OLECMDID_COPY */
732 { OLECMDF_SUPPORTED, exec_paste }, /* OLECMDID_PASTE */
733 { OLECMDF_SUPPORTED, exec_paste_special }, /* OLECMDID_PASTESPECIAL */
734 { OLECMDF_SUPPORTED, exec_undo }, /* OLECMDID_UNDO */
735 { OLECMDF_SUPPORTED, exec_rendo }, /* OLECMDID_REDO */
736 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_select_all }, /* OLECMDID_SELECTALL */
737 { OLECMDF_SUPPORTED, exec_clear_selection }, /* OLECMDID_CLEARSELECTION */
738 { OLECMDF_SUPPORTED, exec_zoom }, /* OLECMDID_ZOOM */
739 { OLECMDF_SUPPORTED, exec_get_zoom_range }, /* OLECMDID_GETZOOMRANGE */
740 {0},
741 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_refresh }, /* OLECMDID_REFRESH */
742 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_stop }, /* OLECMDID_STOP */
743 {0},{0},{0},{0},{0},{0},
744 { OLECMDF_SUPPORTED, exec_stop_download }, /* OLECMDID_STOPDOWNLOAD */
745 {0},
746 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_find }, /* OLECMDID_FIND */
747 { OLECMDF_SUPPORTED, exec_delete }, /* OLECMDID_DELETE */
748 {0},{0},
749 { OLECMDF_SUPPORTED, exec_enable_interaction }, /* OLECMDID_ENABLE_INTERACTION */
750 { OLECMDF_SUPPORTED, exec_on_unload }, /* OLECMDID_ONUNLOAD */
751 {0},{0},{0},{0},{0},
752 { OLECMDF_SUPPORTED, exec_show_page_setup }, /* OLECMDID_SHOWPAGESETUP */
753 { OLECMDF_SUPPORTED, exec_show_print }, /* OLECMDID_SHOWPRINT */
754 {0},{0},
755 { OLECMDF_SUPPORTED, exec_close }, /* OLECMDID_CLOSE */
756 {0},{0},{0},
757 { OLECMDF_SUPPORTED, exec_set_print_template }, /* OLECMDID_SETPRINTTEMPLATE */
758 { OLECMDF_SUPPORTED, exec_get_print_template }, /* OLECMDID_GETPRINTTEMPLATE */
759 {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
760 { 0, /* not reported as supported */ exec_optical_zoom } /* OLECMDID_OPTICAL_ZOOM */
761 };
762
763 static const cmdtable_t base_cmds[] = {
764 {IDM_COPY, query_mshtml_copy, exec_mshtml_copy},
765 {IDM_PASTE, query_mshtml_paste, exec_mshtml_paste},
766 {IDM_CUT, query_mshtml_cut, exec_mshtml_cut},
767 {IDM_SELECTALL, query_selall_status, exec_select_all},
768 {IDM_BROWSEMODE, NULL, exec_browsemode},
769 {IDM_EDITMODE, NULL, exec_editmode},
770 {IDM_PRINT, query_enabled_stub, exec_print},
771 {IDM_HTMLEDITMODE, NULL, exec_htmleditmode},
772 {IDM_BASELINEFONT3, NULL, exec_baselinefont3},
773 {IDM_BLOCKDIRLTR, query_enabled_stub, NULL},
774 {IDM_BLOCKDIRRTL, query_enabled_stub, NULL},
775 {IDM_RESPECTVISIBILITY_INDESIGN, NULL, exec_respectvisibility_indesign},
776 {0,NULL,NULL}
777 };
778
OleCommandTarget_QueryInterface(IOleCommandTarget * iface,REFIID riid,void ** ppv)779 static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv)
780 {
781 HTMLDocument *This = impl_from_IOleCommandTarget(iface);
782 return htmldoc_query_interface(This, riid, ppv);
783 }
784
OleCommandTarget_AddRef(IOleCommandTarget * iface)785 static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface)
786 {
787 HTMLDocument *This = impl_from_IOleCommandTarget(iface);
788 return htmldoc_addref(This);
789 }
790
OleCommandTarget_Release(IOleCommandTarget * iface)791 static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface)
792 {
793 HTMLDocument *This = impl_from_IOleCommandTarget(iface);
794 return htmldoc_release(This);
795 }
796
query_from_table(HTMLDocument * This,const cmdtable_t * cmdtable,OLECMD * cmd)797 static HRESULT query_from_table(HTMLDocument *This, const cmdtable_t *cmdtable, OLECMD *cmd)
798 {
799 const cmdtable_t *iter = cmdtable;
800
801 cmd->cmdf = 0;
802
803 while(iter->id && iter->id != cmd->cmdID)
804 iter++;
805
806 if(!iter->id || !iter->query)
807 return OLECMDERR_E_NOTSUPPORTED;
808
809 return iter->query(This, cmd);
810 }
811
OleCommandTarget_QueryStatus(IOleCommandTarget * iface,const GUID * pguidCmdGroup,ULONG cCmds,OLECMD prgCmds[],OLECMDTEXT * pCmdText)812 static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
813 ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
814 {
815 HTMLDocument *This = impl_from_IOleCommandTarget(iface);
816 HRESULT hres;
817
818 TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
819
820 if(pCmdText)
821 FIXME("Unsupported pCmdText\n");
822 if(!cCmds)
823 return S_OK;
824
825 if(!pguidCmdGroup) {
826 ULONG i;
827
828 for(i=0; i<cCmds; i++) {
829 if(prgCmds[i].cmdID < OLECMDID_OPEN || prgCmds[i].cmdID >= sizeof(exec_table)/sizeof(*exec_table)) {
830 WARN("Unsupported cmdID = %d\n", prgCmds[i].cmdID);
831 prgCmds[i].cmdf = 0;
832 }else {
833 if(prgCmds[i].cmdID == OLECMDID_OPEN || prgCmds[i].cmdID == OLECMDID_NEW) {
834 IOleCommandTarget *cmdtrg = NULL;
835 OLECMD olecmd;
836
837 prgCmds[i].cmdf = OLECMDF_SUPPORTED;
838 if(This->doc_obj->client) {
839 hres = IOleClientSite_QueryInterface(This->doc_obj->client, &IID_IOleCommandTarget,
840 (void**)&cmdtrg);
841 if(SUCCEEDED(hres)) {
842 olecmd.cmdID = prgCmds[i].cmdID;
843 olecmd.cmdf = 0;
844
845 hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &olecmd, NULL);
846 if(SUCCEEDED(hres) && olecmd.cmdf)
847 prgCmds[i].cmdf = olecmd.cmdf;
848 }
849 }else {
850 ERR("This->client == NULL, native would crash\n");
851 }
852 }else {
853 prgCmds[i].cmdf = exec_table[prgCmds[i].cmdID].cmdf;
854 TRACE("cmdID = %d returning %x\n", prgCmds[i].cmdID, prgCmds[i].cmdf);
855 }
856 }
857 }
858
859 return (prgCmds[cCmds-1].cmdf & OLECMDF_SUPPORTED) ? S_OK : OLECMDERR_E_NOTSUPPORTED;
860 }
861
862 if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
863 ULONG i;
864
865 for(i=0; i<cCmds; i++) {
866 hres = query_from_table(This, base_cmds, prgCmds+i);
867 if(hres == OLECMDERR_E_NOTSUPPORTED)
868 hres = query_from_table(This, editmode_cmds, prgCmds+i);
869 if(hres == OLECMDERR_E_NOTSUPPORTED)
870 FIXME("CGID_MSHTML: unsupported cmdID %d\n", prgCmds[i].cmdID);
871 }
872
873 return (prgCmds[cCmds-1].cmdf & OLECMDF_SUPPORTED) ? S_OK : OLECMDERR_E_NOTSUPPORTED;
874 }
875
876 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
877 return OLECMDERR_E_UNKNOWNGROUP;
878 }
879
exec_from_table(HTMLDocument * This,const cmdtable_t * cmdtable,DWORD cmdid,DWORD cmdexecopt,VARIANT * in,VARIANT * out)880 static HRESULT exec_from_table(HTMLDocument *This, const cmdtable_t *cmdtable, DWORD cmdid,
881 DWORD cmdexecopt, VARIANT *in, VARIANT *out)
882 {
883 const cmdtable_t *iter = cmdtable;
884
885 while(iter->id && iter->id != cmdid)
886 iter++;
887
888 if(!iter->id || !iter->exec)
889 return OLECMDERR_E_NOTSUPPORTED;
890
891 return iter->exec(This, cmdexecopt, in, out);
892 }
893
OleCommandTarget_Exec(IOleCommandTarget * iface,const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)894 static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
895 DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
896 {
897 HTMLDocument *This = impl_from_IOleCommandTarget(iface);
898
899 if(!pguidCmdGroup) {
900 if(nCmdID < OLECMDID_OPEN || nCmdID >= sizeof(exec_table)/sizeof(*exec_table) || !exec_table[nCmdID].func) {
901 WARN("Unsupported cmdID = %d\n", nCmdID);
902 return OLECMDERR_E_NOTSUPPORTED;
903 }
904
905 return exec_table[nCmdID].func(This, nCmdexecopt, pvaIn, pvaOut);
906 }else if(IsEqualGUID(&CGID_Explorer, pguidCmdGroup)) {
907 FIXME("unsupported nCmdID %d of CGID_Explorer group\n", nCmdID);
908 TRACE("%p %p\n", pvaIn, pvaOut);
909 return OLECMDERR_E_NOTSUPPORTED;
910 }else if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) {
911 FIXME("unsupported nCmdID %d of CGID_ShellDocView group\n", nCmdID);
912 return OLECMDERR_E_NOTSUPPORTED;
913 }else if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
914 HRESULT hres = exec_from_table(This, base_cmds, nCmdID, nCmdexecopt, pvaIn, pvaOut);
915 if(hres == OLECMDERR_E_NOTSUPPORTED)
916 hres = exec_from_table(This, editmode_cmds, nCmdID,
917 nCmdexecopt, pvaIn, pvaOut);
918 if(hres == OLECMDERR_E_NOTSUPPORTED)
919 FIXME("unsupported nCmdID %d of CGID_MSHTML group\n", nCmdID);
920
921 return hres;
922 }
923
924 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
925 return OLECMDERR_E_UNKNOWNGROUP;
926 }
927
928 static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
929 OleCommandTarget_QueryInterface,
930 OleCommandTarget_AddRef,
931 OleCommandTarget_Release,
932 OleCommandTarget_QueryStatus,
933 OleCommandTarget_Exec
934 };
935
show_context_menu(HTMLDocumentObj * This,DWORD dwID,POINT * ppt,IDispatch * elem)936 void show_context_menu(HTMLDocumentObj *This, DWORD dwID, POINT *ppt, IDispatch *elem)
937 {
938 HMENU menu_res, menu;
939 DWORD cmdid;
940
941 if(This->hostui && S_OK == IDocHostUIHandler_ShowContextMenu(This->hostui,
942 dwID, ppt, (IUnknown*)&This->basedoc.IOleCommandTarget_iface, elem))
943 return;
944
945 menu_res = LoadMenuW(get_shdoclc(), MAKEINTRESOURCEW(IDR_BROWSE_CONTEXT_MENU));
946 menu = GetSubMenu(menu_res, dwID);
947
948 cmdid = TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
949 ppt->x, ppt->y, 0, This->hwnd, NULL);
950 DestroyMenu(menu_res);
951
952 if(cmdid)
953 IOleCommandTarget_Exec(&This->basedoc.IOleCommandTarget_iface, &CGID_MSHTML, cmdid, 0,
954 NULL, NULL);
955 }
956
HTMLDocument_OleCmd_Init(HTMLDocument * This)957 void HTMLDocument_OleCmd_Init(HTMLDocument *This)
958 {
959 This->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl;
960 }
961