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