Don't display the context menu on a double click.
[wine] / dlls / oleaut32 / ole2disp.c
1 /*
2  *      OLE2DISP library
3  *
4  *      Copyright 1995  Martin von Loewis
5  */
6 #include <string.h>
7 #include "windef.h"
8 #include "wingdi.h"
9 #include "winuser.h"
10 #include "winerror.h"
11 #include "olectl.h"
12 #include "oleauto.h"
13 #include "heap.h"
14 #include "ldt.h"
15 #include "debugtools.h"
16
17 DEFAULT_DEBUG_CHANNEL(ole);
18
19 /* This implementation of the BSTR API is 16-bit only. It
20    represents BSTR as a 16:16 far pointer, and the strings
21    as ISO-8859 */
22
23 /******************************************************************************
24  *              BSTR_AllocBytes [Internal]
25  */
26 static BSTR16 BSTR_AllocBytes(int n)
27 {
28     void *ptr = SEGPTR_ALLOC(n);
29     return (BSTR16)SEGPTR_GET(ptr);
30 }
31
32 /******************************************************************************
33  * BSTR_Free [INTERNAL]
34  */
35 static void BSTR_Free(BSTR16 in)
36 {
37     SEGPTR_FREE( PTR_SEG_TO_LIN(in) );
38 }
39
40 /******************************************************************************
41  * BSTR_GetAddr [INTERNAL]
42  */
43 static void* BSTR_GetAddr(BSTR16 in)
44 {
45     return in ? PTR_SEG_TO_LIN(in) : 0;
46 }
47
48 /******************************************************************************
49  *              SysAllocString16        [OLE2DISP.2]
50  */
51 BSTR16 WINAPI SysAllocString16(LPCOLESTR16 in)
52 {
53         BSTR16 out=BSTR_AllocBytes(strlen(in)+1);
54         if(!out)return 0;
55         strcpy(BSTR_GetAddr(out),in);
56         return out;
57 }
58
59 /******************************************************************************
60  *              SysAllocString32        [OLEAUT32.2]
61  */
62 BSTR WINAPI SysAllocString(LPCOLESTR in)
63 {
64     /* Delegate this to the SysAllocStringLen32 method. */
65     return SysAllocStringLen(in, lstrlenW(in));
66 }
67
68 /******************************************************************************
69  *              SysReAllocString16      [OLE2DISP.3]
70  */
71 INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPCOLESTR16 in)
72 {
73         BSTR16 new=SysAllocString16(in);
74         BSTR_Free(*old);
75         *old=new;
76         return 1;
77 }
78
79 /******************************************************************************
80  *              SysReAllocString32      [OLEAUT32.3]
81  */
82 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
83 {
84     /*
85      * Sanity check
86      */
87     if (old==NULL) 
88       return 0;
89
90     /*
91      * Make sure we free the old string.
92      */
93     if (*old!=NULL)      
94       SysFreeString(*old);
95
96     /*
97      * Allocate the new string
98      */
99     *old = SysAllocString(in);
100
101      return 1;
102 }
103
104 /******************************************************************************
105  *              SysAllocStringLen16     [OLE2DISP.4]
106  */
107 BSTR16 WINAPI SysAllocStringLen16(const char *in, int len)
108 {
109         BSTR16 out=BSTR_AllocBytes(len+1);
110
111         if (!out)
112                 return 0;
113
114     /*
115      * Copy the information in the buffer.
116      * Since it is valid to pass a NULL pointer here, we'll initialize the
117      * buffer to nul if it is the case.
118      */
119     if (in != 0)
120         strcpy(BSTR_GetAddr(out),in);
121     else
122       memset(BSTR_GetAddr(out), 0, len+1);
123
124         return out;
125 }
126
127 /******************************************************************************
128  *             SysAllocStringLen32     [OLEAUT32.4]
129  *
130  * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
131  * section, he describes the DWORD value placed before the BSTR data type.
132  * he describes it as a "DWORD count of characters". By experimenting with
133  * a windows application, this count seems to be a DWORD count of bytes in
134  * the string. Meaning that the count is double the number of wide 
135  * characters in the string.
136  */
137 BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
138 {
139     DWORD  bufferSize;
140     DWORD* newBuffer;
141     WCHAR* stringBuffer;
142
143     /*
144      * Find the lenth of the buffer passed-in in bytes.
145      */
146     bufferSize = len * sizeof (WCHAR);
147
148     /*
149      * Allocate a new buffer to hold the string.
150      * dont't forget to keep an empty spot at the begining of the
151      * buffer for the character count and an extra character at the
152      * end for the NULL.
153      */
154     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
155                                  0,
156                                  bufferSize + sizeof(WCHAR) + sizeof(DWORD));
157
158     /*
159      * If the memory allocation failed, return a null pointer.
160      */
161     if (newBuffer==0)
162       return 0;
163
164     /*
165      * Copy the length of the string in the placeholder.
166      */
167     *newBuffer = bufferSize;
168
169     /*
170      * Skip the byte count.
171      */
172     newBuffer++;
173
174     /*
175      * Copy the information in the buffer.
176      * Since it is valid to pass a NULL pointer here, we'll initialize the
177      * buffer to nul if it is the case.
178      */
179     if (in != 0)
180       memcpy(newBuffer, in, bufferSize);
181     else
182       memset(newBuffer, 0, bufferSize);
183
184     /*
185      * Make sure that there is a nul character at the end of the
186      * string.
187      */
188     stringBuffer = (WCHAR*)newBuffer;
189     stringBuffer[len] = L'\0';
190
191     return (LPWSTR)stringBuffer;
192 }
193
194 /******************************************************************************
195  *              SysReAllocStringLen16   [OLE2DISP.5]
196  */
197 int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len)
198 {
199         BSTR16 new=SysAllocStringLen16(in,len);
200         BSTR_Free(*old);
201         *old=new;
202         return 1;
203 }
204
205  
206 /******************************************************************************
207  *             SysReAllocStringLen32   [OLEAUT32.5]
208  */
209 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
210 {
211     /*
212      * Sanity check
213      */
214     if (old==NULL) 
215       return 0;
216
217     /*
218      * Make sure we free the old string.
219      */
220     if (*old!=NULL)      
221       SysFreeString(*old);
222
223     /*
224      * Allocate the new string
225      */
226     *old = SysAllocStringLen(in, len);
227
228     return 1;
229 }
230
231 /******************************************************************************
232  *              SysFreeString16 [OLE2DISP.6]
233  */
234 void WINAPI SysFreeString16(BSTR16 in)
235 {
236         BSTR_Free(in);
237 }
238
239 /******************************************************************************
240  *              SysFreeString32 [OLEAUT32.6]
241  */
242 void WINAPI SysFreeString(BSTR in)
243 {
244     DWORD* bufferPointer;
245     
246     /* NULL is a valid parameter */
247     if(!in) return;
248
249     /*
250      * We have to be careful when we free a BSTR pointer, it points to
251      * the beginning of the string but it skips the byte count contained
252      * before the string.
253      */
254     bufferPointer = (DWORD*)in;
255
256     bufferPointer--;
257
258     /*
259      * Free the memory from it's "real" origin.
260      */
261     HeapFree(GetProcessHeap(), 0, bufferPointer);
262 }
263
264 /******************************************************************************
265  *              SysStringLen16  [OLE2DISP.7]
266  */
267 int WINAPI SysStringLen16(BSTR16 str)
268 {
269         return strlen(BSTR_GetAddr(str));
270 }
271
272 /******************************************************************************
273  *             SysStringLen32  [OLEAUT32.7]
274  *
275  * The Windows documentation states that the length returned by this function
276  * is not necessarely the same as the length returned by the _lstrlenW method.
277  * It is the same number that was passed in as the "len" parameter if the
278  * string was allocated with a SysAllocStringLen method call.
279  */
280 int WINAPI SysStringLen(BSTR str)
281 {
282     DWORD* bufferPointer;
283
284      if (!str) return 0;
285     /*
286      * The length of the string (in bytes) is contained in a DWORD placed 
287      * just before the BSTR pointer
288      */
289     bufferPointer = (DWORD*)str;
290
291     bufferPointer--;
292
293     return (int)(*bufferPointer/sizeof(WCHAR));
294 }
295
296 /******************************************************************************
297  *             SysStringByteLen  [OLEAUT32.149]
298  *
299  * The Windows documentation states that the length returned by this function
300  * is not necessarely the same as the length returned by the _lstrlenW method.
301  * It is the same number that was passed in as the "len" parameter if the
302  * string was allocated with a SysAllocStringLen method call.
303  */
304 int WINAPI SysStringByteLen(BSTR str)
305 {
306   return SysStringLen(str)*sizeof(WCHAR);
307 }
308
309 /******************************************************************************
310  * CreateDispTypeInfo [OLE2DISP.31]
311  */
312 HRESULT WINAPI CreateDispTypeInfo16(
313         INTERFACEDATA *pidata,
314         LCID lcid,
315         ITypeInfo **pptinfo
316 ) {
317         FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
318         return 0;
319 }
320
321 /******************************************************************************
322  * RegisterActiveObject [OLE2DISP.35]
323  */
324 HRESULT WINAPI RegisterActiveObject16(
325         IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
326 ) {
327         FIXME("(%p,%s,0x%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
328         return 0;
329 }
330
331 /******************************************************************************
332  *              OleTranslateColor       [OLEAUT32.421]
333  *
334  * Converts an OLE_COLOR to a COLORREF.
335  * See the documentation for conversion rules.
336  * pColorRef can be NULL. In that case the user only wants to test the 
337  * conversion.
338  */
339 HRESULT WINAPI OleTranslateColor(
340   OLE_COLOR clr,
341   HPALETTE  hpal,
342   COLORREF* pColorRef)
343 {
344   COLORREF colorref;
345   BYTE b = HIBYTE(HIWORD(clr));
346
347   TRACE("(%08lx, %d, %p):stub\n", clr, hpal, pColorRef);
348
349   /*
350    * In case pColorRef is NULL, provide our own to simplify the code.
351    */
352   if (pColorRef == NULL)
353     pColorRef = &colorref;
354
355   switch (b)
356   {
357     case 0x00:
358     {
359       if (hpal != 0)
360         *pColorRef =  PALETTERGB(GetRValue(clr),
361                                  GetGValue(clr),
362                                  GetBValue(clr));
363       else
364         *pColorRef = clr;
365
366       break;
367     }
368
369     case 0x01:
370     {
371       if (hpal != 0)
372       {
373         PALETTEENTRY pe;
374         /*
375          * Validate the palette index.
376          */
377         if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
378           return E_INVALIDARG;
379       }
380
381       *pColorRef = clr;
382
383       break;
384     }
385
386     case 0x02:
387       *pColorRef = clr;
388       break;
389
390     case 0x80:
391     {
392       int index = LOBYTE(LOWORD(clr));
393
394       /*
395        * Validate GetSysColor index.
396        */
397       if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
398         return E_INVALIDARG;
399
400       *pColorRef =  GetSysColor(index);
401
402       break;
403     }
404
405     default:
406       return E_INVALIDARG;
407   }
408
409   return S_OK;
410 }
411
412 /******************************************************************************
413  *             SysAllocStringByteLen     [OLEAUT32.150]
414  *
415  */
416 BSTR WINAPI SysAllocStringByteLen(char *in, int len)
417 {
418     DWORD* newBuffer;
419     char* stringBuffer;
420
421     /*
422      * Allocate a new buffer to hold the string.
423      * dont't forget to keep an empty spot at the begining of the
424      * buffer for the character count and an extra character at the
425      * end for the NULL.
426      */
427     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
428                                  0,
429                                  len + sizeof(WCHAR) + sizeof(DWORD));
430
431     /*
432      * If the memory allocation failed, return a null pointer.
433      */
434     if (newBuffer==0)
435       return 0;
436
437     /*
438      * Copy the length of the string in the placeholder.
439      */
440     *newBuffer = len;
441
442     /*
443      * Skip the byte count.
444      */
445     newBuffer++;
446
447     /*
448      * Copy the information in the buffer.
449      * Since it is valid to pass a NULL pointer here, we'll initialize the
450      * buffer to nul if it is the case.
451      */
452     if (in != 0)
453       memcpy(newBuffer, in, len);
454
455     /*
456      * Make sure that there is a nul character at the end of the
457      * string.
458      */
459     stringBuffer = (char *)newBuffer;
460     stringBuffer[len] = 0;
461     stringBuffer[len+1] = 0;
462
463     return (LPWSTR)stringBuffer;
464 }
465
466