1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 //------------------------------------------------------------------------
29 // includes
30 //------------------------------------------------------------------------
31 
32 #include <osl/diagnose.h>
33 #include "AutoBuffer.hxx"
34 #include "WinImplHelper.hxx"
35 #include <com/sun/star/uno/Sequence.hxx>
36 
37 #include <systools/win32/user9x.h>
38 
39 //------------------------------------------------------------
40 // namespace directives
41 //------------------------------------------------------------
42 
43 using rtl::OUString;
44 using ::com::sun::star::lang::IllegalArgumentException;
45 using ::com::sun::star::uno::Reference;
46 using ::com::sun::star::uno::XInterface;
47 using ::com::sun::star::uno::Any;
48 using ::com::sun::star::uno::Sequence;
49 
50 //------------------------------------------------------------
51 // determine if we are running under Win2000
52 //------------------------------------------------------------
53 
54 sal_Bool SAL_CALL IsWin2000( )
55 {
56 	OSVERSIONINFOEX osvi;
57 	BOOL bOsVersionInfoEx;
58 	sal_Bool bRet = sal_False;
59 
60 	osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
61 	bOsVersionInfoEx = GetVersionEx( ( OSVERSIONINFO* )&osvi );
62 	if( !bOsVersionInfoEx )
63 	{
64 		// if OSVERSIONINFOEX doesn't work
65 		osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
66 		if( !GetVersionEx( ( OSVERSIONINFO* )&osvi ) )
67 			return sal_False;
68 	}
69 
70 	if( ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId ) && ( osvi.dwMajorVersion >= 5 ) )
71 		bRet = sal_True;
72 
73 	return bRet;
74 }
75 
76 //------------------------------------------------------------
77 //
78 //------------------------------------------------------------
79 
80 void SAL_CALL ListboxAddString( HWND hwnd, const OUString& aString )
81 {
82     LRESULT rc = SendMessageW(
83         hwnd, CB_ADDSTRING, 0, reinterpret_cast< LPARAM >(aString.getStr( )) );
84 
85     OSL_ASSERT( (CB_ERR != rc) && (CB_ERRSPACE != rc) );
86 }
87 
88 //------------------------------------------------------------
89 //
90 //------------------------------------------------------------
91 
92 OUString SAL_CALL ListboxGetString( HWND hwnd, sal_Int32 aPosition )
93 {
94     OSL_ASSERT( IsWindow( hwnd ) );
95 
96     OUString aString;
97 
98 	LRESULT lItem =
99         SendMessageW( hwnd, CB_GETLBTEXTLEN, aPosition, 0 );
100 
101 	if ( (CB_ERR != lItem) && (lItem > 0) )
102 	{
103 	    // message returns the len of a combobox item
104 		// without trailing '\0' that's why += 1
105 		lItem++;
106 
107         CAutoUnicodeBuffer aBuff( lItem );
108 
109 		LRESULT lRet =
110             SendMessageW(
111                 hwnd, CB_GETLBTEXT, aPosition,
112                 reinterpret_cast<LPARAM>(&aBuff) );
113 
114         OSL_ASSERT( lRet != CB_ERR );
115 
116 	    if ( CB_ERR != lRet )
117             aString = OUString( aBuff, lRet );
118     }
119 
120     return aString;
121 }
122 
123 //------------------------------------------------------------
124 //
125 //------------------------------------------------------------
126 
127 void SAL_CALL ListboxAddItem( HWND hwnd, const Any& aItem, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
128     throw( IllegalArgumentException )
129 {
130     OSL_ASSERT( IsWindow( hwnd ) );
131 
132     if ( !aItem.hasValue( ) ||
133          aItem.getValueType( ) != getCppuType((OUString*)0) )
134          throw IllegalArgumentException(
135             OUString::createFromAscii( "invalid value type or any has no value" ),
136             rXInterface,
137             aArgPos );
138 
139     OUString cbItem;
140     aItem >>= cbItem;
141 
142     ListboxAddString( hwnd, cbItem );
143 }
144 
145 //------------------------------------------------------------
146 //
147 //------------------------------------------------------------
148 
149 void SAL_CALL ListboxAddItems( HWND hwnd, const Any& aItemList, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
150     throw( IllegalArgumentException )
151 {
152     OSL_ASSERT( IsWindow( hwnd ) );
153 
154     if ( !aItemList.hasValue( ) ||
155          aItemList.getValueType( ) != getCppuType((Sequence<OUString>*)0) )
156          throw IllegalArgumentException(
157             OUString::createFromAscii( "invalid value type or any has no value" ),
158             rXInterface,
159             aArgPos );
160 
161     Sequence< OUString > aStringList;
162     aItemList >>= aStringList;
163 
164     sal_Int32 nItemCount = aStringList.getLength( );
165     for( sal_Int32 i = 0; i < nItemCount; i++ )
166     {
167         ListboxAddString( hwnd, aStringList[i] );
168     }
169 }
170 
171 //------------------------------------------------------------
172 //
173 //------------------------------------------------------------
174 
175 void SAL_CALL ListboxDeleteItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
176     throw( IllegalArgumentException )
177 {
178     OSL_ASSERT( IsWindow( hwnd ) );
179 
180     if ( !aPosition.hasValue( ) ||
181          ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) &&
182            (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) &&
183            (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) )
184          throw IllegalArgumentException(
185             OUString::createFromAscii( "invalid value type or any has no value" ),
186             rXInterface,
187             aArgPos );
188 
189     sal_Int32 nPos;
190     aPosition >>= nPos;
191 
192     LRESULT lRet = SendMessage( hwnd, CB_DELETESTRING, nPos, 0 );
193 
194     // if the return value is CB_ERR the given
195     // index was not correct
196     if ( CB_ERR == lRet )
197         throw IllegalArgumentException(
198             OUString::createFromAscii( "inavlid item position" ),
199             rXInterface,
200             aArgPos );
201 }
202 
203 //------------------------------------------------------------
204 //
205 //------------------------------------------------------------
206 
207 void SAL_CALL ListboxDeleteItems( HWND hwnd, const Any& /*unused*/, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
208     throw( IllegalArgumentException )
209 {
210     OSL_ASSERT( IsWindow( hwnd ) );
211 
212     LRESULT lRet = 0;
213 
214     do
215     {
216         // the return value on success is the number
217         // of remaining elements in the listbox
218         lRet = SendMessageW( hwnd, CB_DELETESTRING, 0, 0 );
219     }
220     while ( (lRet != CB_ERR) && (lRet > 0) );
221 }
222 
223 //------------------------------------------------------------
224 //
225 //------------------------------------------------------------
226 
227 void SAL_CALL ListboxSetSelectedItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
228     throw( IllegalArgumentException )
229 {
230     OSL_ASSERT( IsWindow( hwnd ) );
231 
232      if ( !aPosition.hasValue( ) ||
233          ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) &&
234            (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) &&
235            (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) )
236          throw IllegalArgumentException(
237             OUString::createFromAscii( "invalid value type or any has no value" ),
238             rXInterface,
239             aArgPos );
240 
241     sal_Int32 nPos;
242     aPosition >>= nPos;
243 
244     if ( nPos < -1 )
245         throw IllegalArgumentException(
246             OUString::createFromAscii("invalid index"),
247             rXInterface,
248             aArgPos );
249 
250     LRESULT lRet = SendMessageW( hwnd, CB_SETCURSEL, nPos, 0 );
251 
252     if ( (CB_ERR == lRet) && (-1 != nPos) )
253         throw IllegalArgumentException(
254             OUString::createFromAscii("invalid index"),
255             rXInterface,
256             aArgPos );
257 }
258 
259 //------------------------------------------------------------
260 //
261 //------------------------------------------------------------
262 
263 Any SAL_CALL ListboxGetItems( HWND hwnd )
264 {
265     OSL_ASSERT( IsWindow( hwnd ) );
266 
267     LRESULT nItemCount = SendMessageW( hwnd, CB_GETCOUNT, 0, 0 );
268 
269     Sequence< OUString > aItemList;
270 
271     if ( CB_ERR != nItemCount )
272     {
273         aItemList.realloc( nItemCount );
274 
275         for ( sal_Int32 i = 0; i < nItemCount; i++ )
276         {
277             aItemList[i] = ListboxGetString( hwnd, i );
278         }
279     }
280 
281     Any aAny;
282     aAny <<= aItemList;
283 
284     return aAny;
285 }
286 
287 //------------------------------------------------------------
288 //
289 //------------------------------------------------------------
290 
291 Any SAL_CALL ListboxGetSelectedItem( HWND hwnd )
292 {
293     OSL_ASSERT( IsWindow( hwnd ) );
294 
295     LRESULT idxItem = SendMessageW( hwnd, CB_GETCURSEL, 0, 0 );
296 
297     Any aAny;
298     aAny <<= ListboxGetString( hwnd, idxItem );
299 
300     return aAny;
301 }
302 
303 //------------------------------------------------------------
304 //
305 //------------------------------------------------------------
306 
307 Any SAL_CALL CheckboxGetState( HWND hwnd )
308 {
309     OSL_ASSERT( IsWindow( hwnd ) );
310 
311     LRESULT lChkState = SendMessageW( hwnd, BM_GETCHECK, 0, 0 );
312     sal_Bool bChkState = (lChkState == BST_CHECKED) ? sal_True : sal_False;
313     Any aAny;
314     aAny.setValue( &bChkState, getCppuType((sal_Bool*)0) );
315     return aAny;
316 }
317 
318 //------------------------------------------------------------
319 //
320 //------------------------------------------------------------
321 
322 void SAL_CALL CheckboxSetState(
323     HWND hwnd, const ::com::sun::star::uno::Any& aState, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
324     throw( IllegalArgumentException )
325 {
326     OSL_ASSERT( IsWindow( hwnd ) );
327 
328     if ( !aState.hasValue( ) ||
329          aState.getValueType( ) != getCppuType((sal_Bool*)0) )
330          throw IllegalArgumentException(
331             OUString::createFromAscii( "invalid value type or any has no value" ),
332             rXInterface,
333             aArgPos );
334 
335     sal_Bool bCheckState = *reinterpret_cast< const sal_Bool* >( aState.getValue( ) );
336     WPARAM wParam = bCheckState ? BST_CHECKED : BST_UNCHECKED;
337     SendMessageW( hwnd, BM_SETCHECK, wParam, 0 );
338 }
339 
340 //------------------------------------------------------------
341 //
342 //------------------------------------------------------------
343 
344 sal_uInt32 SAL_CALL _wcslenex( const sal_Unicode* pStr )
345 {
346     if ( !pStr )
347         return 0;
348 
349     const sal_Unicode* pTemp = pStr;
350     sal_uInt32 strLen = 0;
351     while( *pTemp || *(pTemp + 1) )
352     {
353         pTemp++;
354         strLen++;
355     }
356 
357     return strLen;
358 }
359