Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpastespl.c
Go to the documentation of this file.
00001 /* 00002 * OleUIPasteSpecial implementation 00003 * 00004 * Copyright 2006 Huw Davies 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #define COBJMACROS 00022 #define NONAMELESSSTRUCT 00023 #define NONAMELESSUNION 00024 00025 #include <stdarg.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "winerror.h" 00030 #include "wingdi.h" 00031 #include "winuser.h" 00032 #include "winnls.h" 00033 #include "oledlg.h" 00034 00035 #include "oledlg_private.h" 00036 #include "resource.h" 00037 00038 #include "wine/debug.h" 00039 #include "wine/unicode.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00042 00043 typedef struct 00044 { 00045 OLEUIPASTESPECIALW *ps; 00046 DWORD flags; 00047 WCHAR *source_name; 00048 WCHAR *link_source_name; 00049 WCHAR *type_name; 00050 WCHAR *link_type_name; 00051 LPOLESTR app_name; 00052 } ps_struct_t; 00053 00054 static const struct ps_flag 00055 { 00056 DWORD flag; 00057 const char *name; 00058 } ps_flags[] = { 00059 #define PS_FLAG_ENTRY(p) {p, #p} 00060 PS_FLAG_ENTRY(PSF_SHOWHELP), 00061 PS_FLAG_ENTRY(PSF_SELECTPASTE), 00062 PS_FLAG_ENTRY(PSF_SELECTPASTELINK), 00063 PS_FLAG_ENTRY(PSF_CHECKDISPLAYASICON), 00064 PS_FLAG_ENTRY(PSF_DISABLEDISPLAYASICON), 00065 PS_FLAG_ENTRY(PSF_HIDECHANGEICON), 00066 PS_FLAG_ENTRY(PSF_STAYONCLIPBOARDCHANGE), 00067 PS_FLAG_ENTRY(PSF_NOREFRESHDATAOBJECT), 00068 {-1, NULL} 00069 #undef PS_FLAG_ENTRY 00070 }; 00071 00072 static void dump_ps_flags(DWORD flags) 00073 { 00074 char flagstr[1000] = ""; 00075 00076 const struct ps_flag *flag = ps_flags; 00077 for( ; flag->name; flag++) { 00078 if(flags & flag->flag) { 00079 strcat(flagstr, flag->name); 00080 strcat(flagstr, "|"); 00081 } 00082 } 00083 TRACE("flags %08x %s\n", flags, flagstr); 00084 } 00085 00086 static void dump_pastespecial(const OLEUIPASTESPECIALW *ps) 00087 { 00088 UINT i; 00089 dump_ps_flags(ps->dwFlags); 00090 TRACE("hwnd %p caption %s hook %p custdata %lx\n", 00091 ps->hWndOwner, debugstr_w(ps->lpszCaption), ps->lpfnHook, ps->lCustData); 00092 if(IS_INTRESOURCE(ps->lpszTemplate)) 00093 TRACE("hinst %p template %04x hresource %p\n", ps->hInstance, (WORD)(ULONG_PTR)ps->lpszTemplate, ps->hResource); 00094 else 00095 TRACE("hinst %p template %s hresource %p\n", ps->hInstance, debugstr_w(ps->lpszTemplate), ps->hResource); 00096 TRACE("dataobj %p arrpasteent %p cpasteent %d arrlinktype %p clinktype %d\n", 00097 ps->lpSrcDataObj, ps->arrPasteEntries, ps->cPasteEntries, 00098 ps->arrLinkTypes, ps->cLinkTypes); 00099 TRACE("cclsidex %d lpclsidex %p nselect %d flink %d hmetapict %p size(%d,%d)\n", 00100 ps->cClsidExclude, ps->lpClsidExclude, ps->nSelectedIndex, ps->fLink, 00101 ps->hMetaPict, ps->sizel.cx, ps->sizel.cy); 00102 for(i = 0; i < ps->cPasteEntries; i++) 00103 { 00104 TRACE("arrPasteEntries[%d]: cFormat %08x pTargetDevice %p dwAspect %d lindex %d tymed %d\n", 00105 i, ps->arrPasteEntries[i].fmtetc.cfFormat, ps->arrPasteEntries[i].fmtetc.ptd, 00106 ps->arrPasteEntries[i].fmtetc.dwAspect, ps->arrPasteEntries[i].fmtetc.lindex, 00107 ps->arrPasteEntries[i].fmtetc.tymed); 00108 TRACE("\tformat name %s result text %s flags %04x\n", debugstr_w(ps->arrPasteEntries[i].lpstrFormatName), 00109 debugstr_w(ps->arrPasteEntries[i].lpstrResultText), ps->arrPasteEntries[i].dwFlags); 00110 } 00111 for(i = 0; i < ps->cLinkTypes; i++) 00112 TRACE("arrLinkTypes[%d] %08x\n", i, ps->arrLinkTypes[i]); 00113 for(i = 0; i < ps->cClsidExclude; i++) 00114 TRACE("lpClsidExclude[%d] %s\n", i, debugstr_guid(&ps->lpClsidExclude[i])); 00115 00116 } 00117 00118 static inline WCHAR *strdupAtoW(const char *str) 00119 { 00120 DWORD len; 00121 WCHAR *ret; 00122 if(!str) return NULL; 00123 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 00124 ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00125 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); 00126 return ret; 00127 } 00128 00129 static inline WCHAR *strdupW(const WCHAR *str) 00130 { 00131 DWORD len; 00132 WCHAR *ret; 00133 if(!str) return NULL; 00134 len = lstrlenW(str) + 1; 00135 ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00136 memcpy(ret, str, len * sizeof(WCHAR)); 00137 return ret; 00138 } 00139 00140 static void get_descriptors(HWND hdlg, ps_struct_t *ps_struct) 00141 { 00142 FORMATETC fmtetc; 00143 STGMEDIUM stg; 00144 00145 fmtetc.tymed = TYMED_HGLOBAL; 00146 fmtetc.dwAspect = DVASPECT_CONTENT; 00147 fmtetc.ptd = NULL; 00148 fmtetc.lindex = -1; 00149 00150 fmtetc.cfFormat = cf_object_descriptor; 00151 if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK) 00152 { 00153 OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal); 00154 if(obj_desc->dwSrcOfCopy) 00155 ps_struct->source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy)); 00156 if(obj_desc->dwFullUserTypeName) 00157 ps_struct->type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName)); 00158 OleRegGetUserType(&obj_desc->clsid, USERCLASSTYPE_APPNAME, &ps_struct->app_name); 00159 /* Get the icon here. If dwDrawAspect & DVASCPECT_ICON call GetData(CF_METAFILEPICT), otherwise 00160 native calls OleGetIconFromClass(obj_desc->clsid) */ 00161 GlobalUnlock(stg.u.hGlobal); 00162 GlobalFree(stg.u.hGlobal); 00163 } 00164 else 00165 { 00166 /* Try to get some data using some of the other clipboard formats */ 00167 } 00168 00169 fmtetc.cfFormat = cf_link_src_descriptor; 00170 if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK) 00171 { 00172 OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal); 00173 if(obj_desc->dwSrcOfCopy) 00174 ps_struct->link_source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy)); 00175 if(obj_desc->dwFullUserTypeName) 00176 ps_struct->link_type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName)); 00177 GlobalUnlock(stg.u.hGlobal); 00178 GlobalFree(stg.u.hGlobal); 00179 } 00180 00181 if(ps_struct->source_name == NULL && ps_struct->link_source_name == NULL) 00182 { 00183 WCHAR buf[200]; 00184 LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_SRC, buf, sizeof(buf)/sizeof(WCHAR)); 00185 ps_struct->source_name = strdupW(buf); 00186 } 00187 00188 if(ps_struct->type_name == NULL && ps_struct->link_type_name == NULL) 00189 { 00190 WCHAR buf[200]; 00191 LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_TYPE, buf, sizeof(buf)/sizeof(WCHAR)); 00192 ps_struct->type_name = strdupW(buf); 00193 } 00194 } 00195 00196 static BOOL add_entry_to_lb(HWND hdlg, UINT id, OLEUIPASTEENTRYW *pe) 00197 { 00198 HWND hwnd = GetDlgItem(hdlg, id); 00199 BOOL ret = FALSE; 00200 00201 /* FIXME %s handling */ 00202 00203 /* Note that this suffers from the same bug as native, in that if a new string 00204 is a substring of an already added string, then the FINDSTRING will succeed 00205 this is probably not what we want */ 00206 if(SendMessageW(hwnd, LB_FINDSTRING, 0, (LPARAM)pe->lpstrFormatName) == -1) 00207 { 00208 LRESULT pos = SendMessageW(hwnd, LB_ADDSTRING, 0, (LPARAM)pe->lpstrFormatName); 00209 SendMessageW(hwnd, LB_SETITEMDATA, pos, (LPARAM)pe); 00210 ret = TRUE; 00211 } 00212 return ret; 00213 } 00214 00215 static DWORD init_pastelist(HWND hdlg, OLEUIPASTESPECIALW *ps) 00216 { 00217 IEnumFORMATETC *penum; 00218 HRESULT hr; 00219 FORMATETC fmts[20]; 00220 DWORD fetched, items_added = 0; 00221 00222 hr = IDataObject_EnumFormatEtc(ps->lpSrcDataObj, DATADIR_GET, &penum); 00223 if(FAILED(hr)) 00224 { 00225 WARN("Unable to create IEnumFORMATETC\n"); 00226 return 0; 00227 } 00228 00229 /* The native version grabs only the first 20 fmts and we do the same */ 00230 hr = IEnumFORMATETC_Next(penum, sizeof(fmts)/sizeof(fmts[0]), fmts, &fetched); 00231 TRACE("got %d formats hr %08x\n", fetched, hr); 00232 00233 if(SUCCEEDED(hr)) 00234 { 00235 DWORD src_fmt, req_fmt; 00236 for(req_fmt = 0; req_fmt < ps->cPasteEntries; req_fmt++) 00237 { 00238 /* This is used by update_structure() to set nSelectedIndex on exit */ 00239 ps->arrPasteEntries[req_fmt].dwScratchSpace = req_fmt; 00240 TRACE("req_fmt %x\n", ps->arrPasteEntries[req_fmt].fmtetc.cfFormat); 00241 for(src_fmt = 0; src_fmt < fetched; src_fmt++) 00242 { 00243 TRACE("\tenum'ed fmt %x\n", fmts[src_fmt].cfFormat); 00244 if(ps->arrPasteEntries[req_fmt].fmtetc.cfFormat == fmts[src_fmt].cfFormat) 00245 { 00246 add_entry_to_lb(hdlg, IDC_PS_PASTELIST, ps->arrPasteEntries + req_fmt); 00247 items_added++; 00248 break; 00249 } 00250 } 00251 } 00252 } 00253 00254 IEnumFORMATETC_Release(penum); 00255 EnableWindow(GetDlgItem(hdlg, IDC_PS_PASTE), items_added ? TRUE : FALSE); 00256 return items_added; 00257 } 00258 00259 static DWORD init_linklist(HWND hdlg, OLEUIPASTESPECIALW *ps) 00260 { 00261 HRESULT hr; 00262 DWORD supported_mask = 0; 00263 DWORD items_added = 0; 00264 int link, req_fmt; 00265 FORMATETC fmt = {0, NULL, DVASPECT_CONTENT, -1, -1}; 00266 00267 for(link = 0; link < ps->cLinkTypes && link < PS_MAXLINKTYPES; link++) 00268 { 00269 fmt.cfFormat = ps->arrLinkTypes[link]; 00270 hr = IDataObject_QueryGetData(ps->lpSrcDataObj, &fmt); 00271 if(hr == S_OK) 00272 supported_mask |= 1 << link; 00273 } 00274 TRACE("supported_mask %02x\n", supported_mask); 00275 for(req_fmt = 0; req_fmt < ps->cPasteEntries; req_fmt++) 00276 { 00277 DWORD linktypes; 00278 if(ps->arrPasteEntries[req_fmt].dwFlags & OLEUIPASTE_LINKANYTYPE) 00279 linktypes = 0xff; 00280 else 00281 linktypes = ps->arrPasteEntries[req_fmt].dwFlags & 0xff; 00282 00283 if(linktypes & supported_mask) 00284 { 00285 add_entry_to_lb(hdlg, IDC_PS_PASTELINKLIST, ps->arrPasteEntries + req_fmt); 00286 items_added++; 00287 } 00288 } 00289 00290 EnableWindow(GetDlgItem(hdlg, IDC_PS_PASTELINK), items_added ? TRUE : FALSE); 00291 return items_added; 00292 } 00293 00294 /* copies src_list_id into the display list */ 00295 static void update_display_list(HWND hdlg, UINT src_list_id) 00296 { 00297 LONG count, i, old_pos; 00298 WCHAR txt[256]; 00299 LONG item_data; 00300 HWND display_list = GetDlgItem(hdlg, IDC_PS_DISPLAYLIST); 00301 HWND list = GetDlgItem(hdlg, src_list_id); 00302 00303 old_pos = SendMessageW(display_list, LB_GETCURSEL, 0, 0); 00304 if(old_pos == -1) old_pos = 0; 00305 00306 SendMessageW(display_list, WM_SETREDRAW, 0, 0); 00307 SendMessageW(display_list, LB_RESETCONTENT, 0, 0); 00308 count = SendMessageW(list, LB_GETCOUNT, 0, 0); 00309 for(i = 0; i < count; i++) 00310 { 00311 SendMessageW(list, LB_GETTEXT, i, (LPARAM)txt); 00312 item_data = SendMessageW(list, LB_GETITEMDATA, i, 0); 00313 SendMessageW(display_list, LB_INSERTSTRING, i, (LPARAM)txt); 00314 SendMessageW(display_list, LB_SETITEMDATA, i, item_data); 00315 } 00316 old_pos = max(old_pos, count); 00317 SendMessageW(display_list, LB_SETCURSEL, 0, 0); 00318 SendMessageW(display_list, WM_SETREDRAW, 1, 0); 00319 if(GetForegroundWindow() == hdlg) 00320 SetFocus(display_list); 00321 } 00322 00323 static void init_lists(HWND hdlg, ps_struct_t *ps_struct) 00324 { 00325 DWORD pastes_added = init_pastelist(hdlg, ps_struct->ps); 00326 DWORD links_added = init_linklist(hdlg, ps_struct->ps); 00327 UINT check_id, list_id; 00328 00329 if((ps_struct->flags & (PSF_SELECTPASTE | PSF_SELECTPASTELINK)) == 0) 00330 ps_struct->flags |= PSF_SELECTPASTE; 00331 00332 if(!pastes_added && !links_added) 00333 ps_struct->flags &= ~(PSF_SELECTPASTE | PSF_SELECTPASTELINK); 00334 else if(!pastes_added && (ps_struct->flags & PSF_SELECTPASTE)) 00335 { 00336 ps_struct->flags &= ~PSF_SELECTPASTE; 00337 ps_struct->flags |= PSF_SELECTPASTELINK; 00338 } 00339 else if(!links_added && (ps_struct->flags & PSF_SELECTPASTELINK)) 00340 { 00341 ps_struct->flags &= ~PSF_SELECTPASTELINK; 00342 ps_struct->flags |= PSF_SELECTPASTE; 00343 } 00344 00345 check_id = 0; 00346 list_id = 0; 00347 if(ps_struct->flags & PSF_SELECTPASTE) 00348 { 00349 check_id = IDC_PS_PASTE; 00350 list_id = IDC_PS_PASTELIST; 00351 } 00352 else if(ps_struct->flags & PSF_SELECTPASTELINK) 00353 { 00354 check_id = IDC_PS_PASTELINK; 00355 list_id = IDC_PS_PASTELINKLIST; 00356 } 00357 00358 CheckRadioButton(hdlg, IDC_PS_PASTE, IDC_PS_PASTELINK, check_id); 00359 00360 if(list_id) 00361 update_display_list(hdlg, list_id); 00362 else 00363 EnableWindow(GetDlgItem(hdlg, IDOK), 0); 00364 } 00365 00366 static void update_src_text(HWND hdlg, const ps_struct_t *ps_struct) 00367 { 00368 WCHAR *str; 00369 00370 if(ps_struct->flags & PSF_SELECTPASTE) 00371 { 00372 if(ps_struct->source_name) 00373 str = ps_struct->source_name; 00374 else 00375 str = ps_struct->link_source_name; 00376 00377 } 00378 else 00379 { 00380 if(ps_struct->link_source_name) 00381 str = ps_struct->link_source_name; 00382 else 00383 str = ps_struct->source_name; 00384 00385 } 00386 SetDlgItemTextW(hdlg, IDC_PS_SOURCETEXT, str); 00387 } 00388 00389 static void update_as_icon(HWND hdlg, ps_struct_t *ps_struct) 00390 { 00391 HWND icon_display = GetDlgItem(hdlg, IDC_PS_ICONDISPLAY); 00392 HWND display_as_icon = GetDlgItem(hdlg, IDC_PS_DISPLAYASICON); 00393 HWND change_icon = GetDlgItem(hdlg, IDC_PS_CHANGEICON); 00394 00395 /* FIXME. No as icon handling */ 00396 ps_struct->flags &= ~PSF_CHECKDISPLAYASICON; 00397 00398 CheckDlgButton(hdlg, IDC_PS_DISPLAYASICON, ps_struct->flags & PSF_CHECKDISPLAYASICON); 00399 EnableWindow(display_as_icon, 0); 00400 ShowWindow(icon_display, SW_HIDE); 00401 EnableWindow(icon_display, 0); 00402 ShowWindow(change_icon, SW_HIDE); 00403 EnableWindow(change_icon, 0); 00404 } 00405 00406 static void update_result_text(HWND hdlg, const ps_struct_t *ps_struct) 00407 { 00408 WCHAR resource_txt[200]; 00409 UINT res_id; 00410 OLEUIPASTEENTRYW *pent; 00411 LONG cur_sel; 00412 static const WCHAR percent_s[] = {'%','s',0}; 00413 WCHAR *result_txt, *ptr; 00414 00415 cur_sel = SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETCURSEL, 0, 0); 00416 if(cur_sel == -1) return; 00417 pent = (OLEUIPASTEENTRYW*)SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETITEMDATA, cur_sel, 0); 00418 00419 if(ps_struct->flags & PSF_SELECTPASTE) 00420 { 00421 if(ps_struct->flags & PSF_CHECKDISPLAYASICON) 00422 res_id = IDS_PS_PASTE_OBJECT_AS_ICON; 00423 else 00424 res_id = IDS_PS_PASTE_DATA; 00425 } 00426 else 00427 { 00428 if(ps_struct->flags & PSF_CHECKDISPLAYASICON) 00429 res_id = IDS_PS_PASTE_LINK_OBJECT_AS_ICON; 00430 else 00431 res_id = IDS_PS_PASTE_LINK_DATA; 00432 } 00433 00434 LoadStringW(OLEDLG_hInstance, res_id, resource_txt, sizeof(resource_txt)/sizeof(WCHAR)); 00435 if((ptr = strstrW(resource_txt, percent_s))) 00436 { 00437 /* FIXME handle %s in ResultText. Sub appname if IDS_PS_PASTE_OBJECT{_AS_ICON}. Else sub appropriate type name */ 00438 size_t result_txt_len = strlenW(pent->lpstrResultText); 00439 ptrdiff_t offs = (char*)ptr - (char*)resource_txt; 00440 result_txt = HeapAlloc(GetProcessHeap(), 0, (strlenW(resource_txt) + result_txt_len - 1) * sizeof(WCHAR)); 00441 memcpy(result_txt, resource_txt, offs); 00442 memcpy((char*)result_txt + offs, pent->lpstrResultText, result_txt_len * sizeof(WCHAR)); 00443 memcpy((char*)result_txt + offs + result_txt_len * sizeof(WCHAR), ptr + 2, (strlenW(ptr + 2) + 1) * sizeof(WCHAR)); 00444 } 00445 else 00446 result_txt = resource_txt; 00447 00448 SetDlgItemTextW(hdlg, IDC_PS_RESULTTEXT, result_txt); 00449 00450 if(result_txt != resource_txt) 00451 HeapFree(GetProcessHeap(), 0, result_txt); 00452 00453 } 00454 00455 static void selection_change(HWND hdlg, ps_struct_t *ps_struct) 00456 { 00457 update_as_icon(hdlg, ps_struct); 00458 update_result_text(hdlg, ps_struct); 00459 } 00460 00461 static void mode_change(HWND hdlg, ps_struct_t *ps_struct, UINT id) 00462 { 00463 if(id == IDC_PS_PASTE) 00464 { 00465 ps_struct->flags &= ~PSF_SELECTPASTELINK; 00466 ps_struct->flags |= PSF_SELECTPASTE; 00467 } 00468 else 00469 { 00470 ps_struct->flags &= ~PSF_SELECTPASTE; 00471 ps_struct->flags |= PSF_SELECTPASTELINK; 00472 } 00473 00474 update_src_text(hdlg, ps_struct); 00475 update_display_list(hdlg, id == IDC_PS_PASTE ? IDC_PS_PASTELIST : IDC_PS_PASTELINKLIST); 00476 selection_change(hdlg, ps_struct); 00477 } 00478 00479 static void post_help_msg(HWND hdlg, ps_struct_t *ps_struct) 00480 { 00481 PostMessageW(ps_struct->ps->hWndOwner, oleui_msg_help, (WPARAM)hdlg, IDD_PASTESPECIAL); 00482 } 00483 00484 static void send_end_dialog_msg(HWND hdlg, ps_struct_t *ps_struct, UINT id) 00485 { 00486 SendMessageW(hdlg, oleui_msg_enddialog, id, 0); 00487 } 00488 00489 static void update_structure(HWND hdlg, ps_struct_t *ps_struct) 00490 { 00491 LONG cur_sel = SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETCURSEL, 0, 0); 00492 if(cur_sel != -1) 00493 { 00494 OLEUIPASTEENTRYW *pent; 00495 pent = (OLEUIPASTEENTRYW *)SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETITEMDATA, cur_sel, 0); 00496 ps_struct->ps->nSelectedIndex = pent->dwScratchSpace; 00497 } 00498 ps_struct->ps->dwFlags = ps_struct->flags; 00499 ps_struct->ps->fLink = (ps_struct->flags & PSF_SELECTPASTELINK) ? TRUE : FALSE; 00500 } 00501 00502 static void free_structure(ps_struct_t *ps_struct) 00503 { 00504 HeapFree(GetProcessHeap(), 0, ps_struct->type_name); 00505 HeapFree(GetProcessHeap(), 0, ps_struct->source_name); 00506 HeapFree(GetProcessHeap(), 0, ps_struct->link_type_name); 00507 HeapFree(GetProcessHeap(), 0, ps_struct->link_source_name); 00508 CoTaskMemFree(ps_struct->app_name); 00509 HeapFree(GetProcessHeap(), 0, ps_struct); 00510 } 00511 00512 static INT_PTR CALLBACK ps_dlg_proc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp) 00513 { 00514 /* native uses prop name "Structure", but we're not compatible 00515 with that so we'll prepend "Wine_". */ 00516 static const WCHAR prop_name[] = {'W','i','n','e','_','S','t','r','u','c','t','u','r','e',0}; 00517 ps_struct_t *ps_struct; 00518 00519 TRACE("(%p, %04x, %08lx, %08lx)\n", hdlg, msg, wp, lp); 00520 00521 ps_struct = GetPropW(hdlg, prop_name); 00522 00523 if(msg != WM_INITDIALOG) 00524 { 00525 if(!ps_struct) 00526 return 0; 00527 00528 if(ps_struct->ps->lpfnHook) 00529 { 00530 INT_PTR ret = ps_struct->ps->lpfnHook(hdlg, msg, wp, lp); 00531 if(ret) return ret; 00532 } 00533 } 00534 00535 switch(msg) 00536 { 00537 case WM_INITDIALOG: 00538 { 00539 ps_struct = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps_struct)); 00540 ps_struct->ps = (OLEUIPASTESPECIALW*)lp; 00541 ps_struct->type_name = NULL; 00542 ps_struct->source_name = NULL; 00543 ps_struct->link_type_name = NULL; 00544 ps_struct->link_source_name = NULL; 00545 ps_struct->app_name = NULL; 00546 ps_struct->flags = ps_struct->ps->dwFlags; 00547 00548 SetPropW(hdlg, prop_name, ps_struct); 00549 00550 if(!(ps_struct->ps->dwFlags & PSF_SHOWHELP)) 00551 { 00552 ShowWindow(GetDlgItem(hdlg, IDC_OLEUIHELP), SW_HIDE); 00553 EnableWindow(GetDlgItem(hdlg, IDC_OLEUIHELP), 0); 00554 } 00555 00556 if(ps_struct->ps->lpszCaption) 00557 SetWindowTextW(hdlg, ps_struct->ps->lpszCaption); 00558 00559 get_descriptors(hdlg, ps_struct); 00560 00561 init_lists(hdlg, ps_struct); 00562 00563 update_src_text(hdlg, ps_struct); 00564 00565 selection_change(hdlg, ps_struct); 00566 00567 SetFocus(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST)); 00568 00569 if(ps_struct->ps->lpfnHook) 00570 ps_struct->ps->lpfnHook(hdlg, msg, 0, 0); 00571 return FALSE; /* use new focus */ 00572 } 00573 case WM_COMMAND: 00574 switch(LOWORD(wp)) 00575 { 00576 case IDC_PS_DISPLAYLIST: 00577 switch(HIWORD(wp)) 00578 { 00579 case LBN_SELCHANGE: 00580 selection_change(hdlg, ps_struct); 00581 return FALSE; 00582 default: 00583 return FALSE; 00584 } 00585 case IDC_PS_PASTE: 00586 case IDC_PS_PASTELINK: 00587 switch(HIWORD(wp)) 00588 { 00589 case BN_CLICKED: 00590 mode_change(hdlg, ps_struct, LOWORD(wp)); 00591 return FALSE; 00592 00593 default: 00594 return FALSE; 00595 } 00596 case IDC_OLEUIHELP: 00597 switch(HIWORD(wp)) 00598 { 00599 case BN_CLICKED: 00600 post_help_msg(hdlg, ps_struct); 00601 return FALSE; 00602 default: 00603 return FALSE; 00604 } 00605 case IDOK: 00606 case IDCANCEL: 00607 switch(HIWORD(wp)) 00608 { 00609 case BN_CLICKED: 00610 send_end_dialog_msg(hdlg, ps_struct, LOWORD(wp)); 00611 return FALSE; 00612 default: 00613 return FALSE; 00614 } 00615 } 00616 return FALSE; 00617 default: 00618 if(msg == oleui_msg_enddialog) 00619 { 00620 if(wp == IDOK) 00621 update_structure(hdlg, ps_struct); 00622 EndDialog(hdlg, wp); 00623 /* native does its cleanup in WM_DESTROY */ 00624 RemovePropW(hdlg, prop_name); 00625 free_structure(ps_struct); 00626 return TRUE; 00627 } 00628 return FALSE; 00629 } 00630 00631 } 00632 00633 /*********************************************************************** 00634 * OleUIPasteSpecialA (OLEDLG.4) 00635 */ 00636 UINT WINAPI OleUIPasteSpecialA(LPOLEUIPASTESPECIALA psA) 00637 { 00638 OLEUIPASTESPECIALW ps; 00639 UINT ret; 00640 TRACE("(%p)\n", psA); 00641 00642 memcpy(&ps, psA, psA->cbStruct); 00643 00644 ps.lpszCaption = strdupAtoW(psA->lpszCaption); 00645 if(!IS_INTRESOURCE(ps.lpszTemplate)) 00646 ps.lpszTemplate = strdupAtoW(psA->lpszTemplate); 00647 00648 if(psA->cPasteEntries > 0) 00649 { 00650 DWORD size = psA->cPasteEntries * sizeof(ps.arrPasteEntries[0]); 00651 INT i; 00652 00653 ps.arrPasteEntries = HeapAlloc(GetProcessHeap(), 0, size); 00654 memcpy(ps.arrPasteEntries, psA->arrPasteEntries, size); 00655 for(i = 0; i < psA->cPasteEntries; i++) 00656 { 00657 ps.arrPasteEntries[i].lpstrFormatName = 00658 strdupAtoW(psA->arrPasteEntries[i].lpstrFormatName); 00659 ps.arrPasteEntries[i].lpstrResultText = 00660 strdupAtoW(psA->arrPasteEntries[i].lpstrResultText); 00661 } 00662 } 00663 00664 ret = OleUIPasteSpecialW(&ps); 00665 00666 if(psA->cPasteEntries > 0) 00667 { 00668 INT i; 00669 for(i = 0; i < psA->cPasteEntries; i++) 00670 { 00671 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.arrPasteEntries[i].lpstrFormatName); 00672 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.arrPasteEntries[i].lpstrResultText); 00673 } 00674 HeapFree(GetProcessHeap(), 0, ps.arrPasteEntries); 00675 } 00676 if(!IS_INTRESOURCE(ps.lpszTemplate)) 00677 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.lpszTemplate); 00678 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.lpszCaption); 00679 00680 /* Copy back the output fields */ 00681 psA->dwFlags = ps.dwFlags; 00682 psA->lpSrcDataObj = ps.lpSrcDataObj; 00683 psA->nSelectedIndex = ps.nSelectedIndex; 00684 psA->fLink = ps.fLink; 00685 psA->hMetaPict = ps.hMetaPict; 00686 psA->sizel = ps.sizel; 00687 00688 return ret; 00689 } 00690 00691 /*********************************************************************** 00692 * OleUIPasteSpecialW (OLEDLG.22) 00693 */ 00694 UINT WINAPI OleUIPasteSpecialW(LPOLEUIPASTESPECIALW ps) 00695 { 00696 LPCDLGTEMPLATEW dlg_templ = (LPCDLGTEMPLATEW)ps->hResource; 00697 UINT ret; 00698 00699 TRACE("(%p)\n", ps); 00700 00701 if(TRACE_ON(ole)) dump_pastespecial(ps); 00702 00703 if(!ps->lpSrcDataObj) 00704 OleGetClipboard(&ps->lpSrcDataObj); 00705 00706 if(ps->hInstance || !ps->hResource) 00707 { 00708 HINSTANCE hInst = ps->hInstance ? ps->hInstance : OLEDLG_hInstance; 00709 const WCHAR *name = ps->hInstance ? ps->lpszTemplate : MAKEINTRESOURCEW(IDD_PASTESPECIAL4); 00710 HRSRC hrsrc; 00711 00712 if(name == NULL) return OLEUI_ERR_LPSZTEMPLATEINVALID; 00713 hrsrc = FindResourceW(hInst, name, MAKEINTRESOURCEW(RT_DIALOG)); 00714 if(!hrsrc) return OLEUI_ERR_FINDTEMPLATEFAILURE; 00715 dlg_templ = LoadResource(hInst, hrsrc); 00716 if(!dlg_templ) return OLEUI_ERR_LOADTEMPLATEFAILURE; 00717 } 00718 00719 ret = DialogBoxIndirectParamW(OLEDLG_hInstance, dlg_templ, ps->hWndOwner, ps_dlg_proc, (LPARAM)ps); 00720 00721 return ret; 00722 } Generated on Sat May 26 2012 04:24:27 for ReactOS by
1.7.6.1
|