1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: WinImplHelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
38 #include <rtl/ustrbuf.hxx>
39 #include "AutoBuffer.hxx"
40 #include "WinImplHelper.hxx"
41 #include <com/sun/star/uno/Sequence.hxx>
43 //------------------------------------------------------------
44 // namespace directives
45 //------------------------------------------------------------
48 using rtl::OUStringBuffer
;
49 using ::com::sun::star::lang::IllegalArgumentException
;
50 using ::com::sun::star::uno::Reference
;
51 using ::com::sun::star::uno::XInterface
;
52 using ::com::sun::star::uno::Any
;
53 using ::com::sun::star::uno::Sequence
;
55 //------------------------------------------------------------
57 //------------------------------------------------------------
59 const rtl::OUString TILDE
= OUString::createFromAscii( "~" );
60 const sal_Unicode TILDE_SIGN
= L
'~';
61 const rtl::OUString AMPERSAND
= OUString::createFromAscii( "&" );
62 const sal_Unicode AMPERSAND_SIGN
= L
'&';
64 //------------------------------------------------------------
65 // OS NAME Platform Major Minor
67 // Windows NT 3.51 VER_PLATFORM_WIN32_NT 3 51
68 // Windows NT 4.0 VER_PLATFORM_WIN32_NT 4 0
69 // Windows 2000 VER_PLATFORM_WIN32_NT 5 0
70 // Windows XP VER_PLATFORM_WIN32_NT 5 1
71 // Windows Vista VER_PLATFORM_WIN32_NT 6 0
72 // Windows 7 VER_PLATFORM_WIN32_NT 6 1
73 // Windows 95 VER_PLATFORM_WIN32_WINDOWS 4 0
74 // Windows 98 VER_PLATFORM_WIN32_WINDOWS 4 10
75 // Windows ME VER_PLATFORM_WIN32_WINDOWS 4 90
76 //------------------------------------------------------------
78 bool SAL_CALL
IsWindowsVersion(unsigned int PlatformId
, unsigned int MajorVersion
, int MinorVersion
= -1)
81 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
83 if(!GetVersionEx(&osvi
))
86 bool bRet
= (PlatformId
== osvi
.dwPlatformId
) &&
87 (MajorVersion
== osvi
.dwMajorVersion
);
89 if (MinorVersion
> -1)
91 (sal::static_int_cast
< unsigned int >(MinorVersion
) ==
97 //------------------------------------------------------------
98 // determine if we are running under Vista or newer OS
99 //------------------------------------------------------------
101 bool SAL_CALL
IsWindowsVistaOrNewer()
104 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
106 if(!GetVersionEx(&osvi
))
109 bool bRet
= (VER_PLATFORM_WIN32_NT
== osvi
.dwPlatformId
) &&
110 (osvi
.dwMajorVersion
>= 6);
113 (osvi
.dwMinorVersion
>=
114 sal::static_int_cast
< unsigned int >(0));
119 //------------------------------------------------------------
120 // determine if we are running under Windows 7
121 //------------------------------------------------------------
123 bool SAL_CALL
IsWindows7()
125 return IsWindowsVersion(VER_PLATFORM_WIN32_NT
, 6, 1);
128 //------------------------------------------------------------
129 // determine if we are running under Windows Vista
130 //------------------------------------------------------------
132 bool SAL_CALL
IsWindowsVista()
134 return IsWindowsVersion(VER_PLATFORM_WIN32_NT
, 6, 0);
137 //------------------------------------------------------------
138 // determine if we are running under Windows XP
139 //------------------------------------------------------------
141 bool SAL_CALL
IsWindowsXP()
143 return IsWindowsVersion(VER_PLATFORM_WIN32_NT
, 5, 1);
146 //------------------------------------------------------------
147 // determine if we are running under Windows 2000
148 //------------------------------------------------------------
150 bool SAL_CALL
IsWindows2000()
152 return IsWindowsVersion(VER_PLATFORM_WIN32_NT
, 5, 0);
155 //------------------------------------------------------------
157 //------------------------------------------------------------
159 bool SAL_CALL
IsWindows98()
161 return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS
, 4, 10);
164 //------------------------------------------------------------
166 //------------------------------------------------------------
168 bool SAL_CALL
IsWindowsME()
170 return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS
, 4, 90);
173 //------------------------------------------------------------
175 //------------------------------------------------------------
177 bool SAL_CALL
IsWindows2000Platform()
179 // POST: return true if we are at least on Windows 2000
181 // WRONG!: return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5);
184 ZeroMemory(&osvi
, sizeof(osvi
));
185 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
187 if ( osvi
.dwMajorVersion
>= 5 )
194 //------------------------------------------------------------
196 //------------------------------------------------------------
198 void SAL_CALL
ListboxAddString( HWND hwnd
, const OUString
& aString
)
200 LRESULT rc
= SendMessageW(
201 hwnd
, CB_ADDSTRING
, 0, reinterpret_cast< LPARAM
>(aString
.getStr( )) );
202 (void) rc
; // avoid warning
203 OSL_ASSERT( (CB_ERR
!= rc
) && (CB_ERRSPACE
!= rc
) );
206 //------------------------------------------------------------
208 //------------------------------------------------------------
210 OUString SAL_CALL
ListboxGetString( HWND hwnd
, sal_Int32 aPosition
)
212 OSL_ASSERT( IsWindow( hwnd
) );
217 SendMessageW( hwnd
, CB_GETLBTEXTLEN
, aPosition
, 0 );
219 if ( (CB_ERR
!= lItem
) && (lItem
> 0) )
221 // message returns the len of a combobox item
222 // without trailing '\0' that's why += 1
225 CAutoUnicodeBuffer
aBuff( lItem
);
229 hwnd
, CB_GETLBTEXT
, aPosition
,
230 reinterpret_cast<LPARAM
>(&aBuff
) );
232 OSL_ASSERT( lRet
!= CB_ERR
);
234 if ( CB_ERR
!= lRet
)
235 aString
= OUString( aBuff
, lRet
);
241 //------------------------------------------------------------
243 //------------------------------------------------------------
245 void SAL_CALL
ListboxAddItem( HWND hwnd
, const Any
& aItem
, const Reference
< XInterface
>& rXInterface
, sal_Int16 aArgPos
)
246 throw( IllegalArgumentException
)
248 OSL_ASSERT( IsWindow( hwnd
) );
250 if ( !aItem
.hasValue( ) ||
251 aItem
.getValueType( ) != getCppuType((OUString
*)0) )
252 throw IllegalArgumentException(
253 OUString::createFromAscii( "invalid value type or any has no value" ),
260 ListboxAddString( hwnd
, cbItem
);
263 //------------------------------------------------------------
265 //------------------------------------------------------------
267 void SAL_CALL
ListboxAddItems( HWND hwnd
, const Any
& aItemList
, const Reference
< XInterface
>& rXInterface
, sal_Int16 aArgPos
)
268 throw( IllegalArgumentException
)
270 OSL_ASSERT( IsWindow( hwnd
) );
272 if ( !aItemList
.hasValue( ) ||
273 aItemList
.getValueType( ) != getCppuType((Sequence
<OUString
>*)0) )
274 throw IllegalArgumentException(
275 OUString::createFromAscii( "invalid value type or any has no value" ),
279 Sequence
< OUString
> aStringList
;
280 aItemList
>>= aStringList
;
282 sal_Int32 nItemCount
= aStringList
.getLength( );
283 for( sal_Int32 i
= 0; i
< nItemCount
; i
++ )
285 ListboxAddString( hwnd
, aStringList
[i
] );
289 //------------------------------------------------------------
291 //------------------------------------------------------------
293 void SAL_CALL
ListboxDeleteItem( HWND hwnd
, const Any
& aPosition
, const Reference
< XInterface
>& rXInterface
, sal_Int16 aArgPos
)
294 throw( IllegalArgumentException
)
296 OSL_ASSERT( IsWindow( hwnd
) );
298 if ( !aPosition
.hasValue( ) ||
299 ( (aPosition
.getValueType( ) != getCppuType((sal_Int32
*)0)) &&
300 (aPosition
.getValueType( ) != getCppuType((sal_Int16
*)0)) &&
301 (aPosition
.getValueType( ) != getCppuType((sal_Int8
*)0)) ) )
302 throw IllegalArgumentException(
303 OUString::createFromAscii( "invalid value type or any has no value" ),
310 LRESULT lRet
= SendMessage( hwnd
, CB_DELETESTRING
, nPos
, 0 );
312 // if the return value is CB_ERR the given
313 // index was not correct
314 if ( CB_ERR
== lRet
)
315 throw IllegalArgumentException(
316 OUString::createFromAscii( "inavlid item position" ),
321 //------------------------------------------------------------
323 //------------------------------------------------------------
325 void SAL_CALL
ListboxDeleteItems( HWND hwnd
, const Any
&, const Reference
< XInterface
>&, sal_Int16
)
326 throw( IllegalArgumentException
)
328 OSL_ASSERT( IsWindow( hwnd
) );
334 // the return value on success is the number
335 // of remaining elements in the listbox
336 lRet
= SendMessageW( hwnd
, CB_DELETESTRING
, 0, 0 );
338 while ( (lRet
!= CB_ERR
) && (lRet
> 0) );
341 //------------------------------------------------------------
343 //------------------------------------------------------------
345 void SAL_CALL
ListboxSetSelectedItem( HWND hwnd
, const Any
& aPosition
, const Reference
< XInterface
>& rXInterface
, sal_Int16 aArgPos
)
346 throw( IllegalArgumentException
)
348 OSL_ASSERT( IsWindow( hwnd
) );
350 if ( !aPosition
.hasValue( ) ||
351 ( (aPosition
.getValueType( ) != getCppuType((sal_Int32
*)0)) &&
352 (aPosition
.getValueType( ) != getCppuType((sal_Int16
*)0)) &&
353 (aPosition
.getValueType( ) != getCppuType((sal_Int8
*)0)) ) )
354 throw IllegalArgumentException(
355 OUString::createFromAscii( "invalid value type or any has no value" ),
363 throw IllegalArgumentException(
364 OUString::createFromAscii("invalid index"),
368 LRESULT lRet
= SendMessageW( hwnd
, CB_SETCURSEL
, nPos
, 0 );
370 if ( (CB_ERR
== lRet
) && (-1 != nPos
) )
371 throw IllegalArgumentException(
372 OUString::createFromAscii("invalid index"),
377 //------------------------------------------------------------
379 //------------------------------------------------------------
381 Any SAL_CALL
ListboxGetItems( HWND hwnd
)
383 OSL_ASSERT( IsWindow( hwnd
) );
385 LRESULT nItemCount
= SendMessageW( hwnd
, CB_GETCOUNT
, 0, 0 );
387 Sequence
< OUString
> aItemList
;
389 if ( CB_ERR
!= nItemCount
)
391 aItemList
.realloc( nItemCount
);
393 for ( sal_Int32 i
= 0; i
< nItemCount
; i
++ )
395 aItemList
[i
] = ListboxGetString( hwnd
, i
);
405 //------------------------------------------------------------
407 //------------------------------------------------------------
409 Any SAL_CALL
ListboxGetSelectedItem( HWND hwnd
)
411 OSL_ASSERT( IsWindow( hwnd
) );
413 LRESULT idxItem
= SendMessageW( hwnd
, CB_GETCURSEL
, 0, 0 );
416 aAny
<<= ListboxGetString( hwnd
, idxItem
);
421 //------------------------------------------------------------
423 //------------------------------------------------------------
425 Any SAL_CALL
ListboxGetSelectedItemIndex( HWND hwnd
)
427 OSL_ASSERT( IsWindow( hwnd
) );
429 LRESULT idxItem
= SendMessageW( hwnd
, CB_GETCURSEL
, 0, 0 );
432 aAny
<<= static_cast< sal_Int32
>( idxItem
);
437 //------------------------------------------------------------
439 //------------------------------------------------------------
441 Any SAL_CALL
CheckboxGetState( HWND hwnd
)
443 OSL_ASSERT( IsWindow( hwnd
) );
445 LRESULT lChkState
= SendMessageW( hwnd
, BM_GETCHECK
, 0, 0 );
446 sal_Bool bChkState
= (lChkState
== BST_CHECKED
) ? sal_True
: sal_False
;
448 aAny
.setValue( &bChkState
, getCppuType((sal_Bool
*)0) );
452 //------------------------------------------------------------
454 //------------------------------------------------------------
456 void SAL_CALL
CheckboxSetState(
457 HWND hwnd
, const ::com::sun::star::uno::Any
& aState
, const Reference
< XInterface
>& rXInterface
, sal_Int16 aArgPos
)
458 throw( IllegalArgumentException
)
460 OSL_ASSERT( IsWindow( hwnd
) );
462 if ( !aState
.hasValue( ) ||
463 aState
.getValueType( ) != getCppuType((sal_Bool
*)0) )
464 throw IllegalArgumentException(
465 OUString::createFromAscii( "invalid value type or any has no value" ),
469 sal_Bool bCheckState
= *reinterpret_cast< const sal_Bool
* >( aState
.getValue( ) );
470 WPARAM wParam
= bCheckState
? BST_CHECKED
: BST_UNCHECKED
;
471 SendMessageW( hwnd
, BM_SETCHECK
, wParam
, 0 );
474 //------------------------------------------------------------
476 //------------------------------------------------------------
478 sal_uInt32 SAL_CALL
_wcslenex( const sal_Unicode
* pStr
)
483 const sal_Unicode
* pTemp
= pStr
;
484 sal_uInt32 strLen
= 0;
485 while( *pTemp
|| *(pTemp
+ 1) )
494 //------------------------------------------------------------
496 //------------------------------------------------------------
498 void Replace( const OUString
& aLabel
, sal_Unicode OldChar
, sal_Unicode NewChar
, OUStringBuffer
& aBuffer
)
500 OSL_ASSERT( aLabel
.getLength( ) );
501 OSL_ASSERT( aBuffer
.getCapacity( ) >= (aLabel
.getLength( )) );
504 const sal_Unicode
* pCurrent
= aLabel
.getStr( );
505 const sal_Unicode
* pNext
= aLabel
.getStr( ) + 1;
506 const sal_Unicode
* pEnd
= aLabel
.getStr( ) + aLabel
.getLength( );
508 while( pCurrent
< pEnd
)
510 OSL_ASSERT( pNext
<= pEnd
);
511 OSL_ASSERT( (i
>= 0) && (i
< aBuffer
.getCapacity( )) );
513 if ( OldChar
== *pCurrent
)
515 if ( OldChar
== *pNext
)
517 // two OldChars in line will
518 // be replaced by one
520 aBuffer
.insert( i
, *pCurrent
);
528 // one OldChar will be replace
530 aBuffer
.insert( i
, NewChar
);
533 else if ( *pCurrent
== NewChar
)
535 // a NewChar will be replaced by
538 aBuffer
.insert( i
++, *pCurrent
);
539 aBuffer
.insert( i
, *pCurrent
);
543 aBuffer
.insert( i
, *pCurrent
);
552 //------------------------------------------------------------
553 // converts a soffice label to a windows label
554 // the following rules for character replacements
559 //------------------------------------------------------------
561 OUString
SOfficeToWindowsLabel( const rtl::OUString
& aSOLabel
)
563 OUString aWinLabel
= aSOLabel
;
565 if ( (aWinLabel
.indexOf( TILDE
) > -1) || (aWinLabel
.indexOf( AMPERSAND
) > -1) )
567 sal_Int32 nStrLen
= aWinLabel
.getLength( );
569 // in the worst case the new string is
570 // doubled in length, maybe some waste
571 // of memory but how long is a label
573 rtl::OUStringBuffer
aBuffer( nStrLen
* 2 );
575 Replace( aWinLabel
, TILDE_SIGN
, AMPERSAND_SIGN
, aBuffer
);
577 aWinLabel
= aBuffer
.makeStringAndClear( );
583 //------------------------------------------------------------
584 // converts a windows label to a soffice label
585 // the following rules for character replacements
590 //------------------------------------------------------------
592 OUString
WindowsToSOfficeLabel( const rtl::OUString
& aWinLabel
)
594 OUString aSOLabel
= aWinLabel
;
596 if ( (aSOLabel
.indexOf( TILDE
) > -1) || (aSOLabel
.indexOf( AMPERSAND
) > -1) )
598 sal_Int32 nStrLen
= aSOLabel
.getLength( );
600 // in the worst case the new string is
601 // doubled in length, maybe some waste
602 // of memory but how long is a label
604 rtl::OUStringBuffer
aBuffer( nStrLen
* 2 );
606 Replace( aSOLabel
, AMPERSAND_SIGN
, TILDE_SIGN
, aBuffer
);
608 aSOLabel
= aBuffer
.makeStringAndClear( );