ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pastespl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.