summaryrefslogtreecommitdiff
path: root/fpicker
diff options
context:
space:
mode:
authorTino Rachui <tra@openoffice.org>2001-07-09 11:58:25 +0000
committerTino Rachui <tra@openoffice.org>2001-07-09 11:58:25 +0000
commita89ca4c6c1f71428dffa71f67c18a4d84cad49fe (patch)
tree1dec963a26423cd64c17d6a0360ea2a04d3c2724 /fpicker
parent099c4fe04c39af1ccecdeec0652fef05fbe16ea0 (diff)
took over changes from sysui
Diffstat (limited to 'fpicker')
-rw-r--r--fpicker/source/win32/filepicker/FileOpenDlg.cxx141
-rw-r--r--fpicker/source/win32/filepicker/FileOpenDlg.hxx25
-rw-r--r--fpicker/source/win32/filepicker/WinFileOpenImpl.cxx166
-rw-r--r--fpicker/source/win32/filepicker/WinFileOpenImpl.hxx6
4 files changed, 257 insertions, 81 deletions
diff --git a/fpicker/source/win32/filepicker/FileOpenDlg.cxx b/fpicker/source/win32/filepicker/FileOpenDlg.cxx
index fa40c98fcc49..9a57e8e42303 100644
--- a/fpicker/source/win32/filepicker/FileOpenDlg.cxx
+++ b/fpicker/source/win32/filepicker/FileOpenDlg.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: FileOpenDlg.cxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: tra $ $Date: 2001-06-28 11:13:15 $
+ * last change: $Author: tra $ $Date: 2001-07-09 12:58:25 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -88,25 +88,24 @@ using rtl::OUString;
// constants
//------------------------------------------------------------------------
-// we choose such large buffers because the size of
-// an single line edit field can be up to 32k; if
-// a user has a multi selection FilePicker and selects
-// a lot of files in a large directory we may reach this
-// limit and don't want to get out of memory;
-// another much more elegant way would be to subclass the
-// FileOpen dialog and overload the BM_CLICK event of the
-// OK button so that we determine the size of the text
-// currently in the edit field and resize our buffer
-// appropriately - in the future we will do this
-const size_t MAX_FILENAME_BUFF_SIZE = 32000;
-const size_t MAX_FILETITLE_BUFF_SIZE = 32000;
-const size_t MAX_FILTER_BUFF_SIZE = 4096;
-
-//------------------------------------------------------------------------
-// static member declaration
-//------------------------------------------------------------------------
+namespace /* private */
+{
+ // we choose such large buffers because the size of
+ // an single line edit field can be up to 32k; if
+ // a user has a multi selection FilePicker and selects
+ // a lot of files in a large directory we may reach this
+ // limit and don't want to get out of memory;
+ // another much more elegant way would be to subclass the
+ // FileOpen dialog and overload the BM_CLICK event of the
+ // OK button so that we determine the size of the text
+ // currently in the edit field and resize our buffer
+ // appropriately - in the future we will do this
+ const size_t MAX_FILENAME_BUFF_SIZE = 32000;
+ const size_t MAX_FILETITLE_BUFF_SIZE = 32000;
+ const size_t MAX_FILTER_BUFF_SIZE = 4096;
-CFileOpenDialog* CFileOpenDialog::s_fileOpenDlgInst;
+ const char* CURRENT_INSTANCE = "CurrInst";
+};
//------------------------------------------------------------------------
//
@@ -144,7 +143,8 @@ CFileOpenDialog::CFileOpenDialog(
OFN_ENABLEHOOK |
OFN_HIDEREADONLY |
OFN_PATHMUSTEXIST |
- OFN_FILEMUSTEXIST;
+ OFN_FILEMUSTEXIST |
+ OFN_OVERWRITEPROMPT;
// it is a little hack but how else could
// we get a parent window (using a vcl window?)
@@ -173,10 +173,6 @@ CFileOpenDialog::CFileOpenDialog(
// set a pointer to myself as ofn parameter
m_ofn.lCustData = reinterpret_cast< long > ( this );
-
- // initialize the static member to reconnect
- // to the instance from callback methods
- s_fileOpenDlgInst = this;
}
//------------------------------------------------------------------------
@@ -631,6 +627,7 @@ sal_uInt32 SAL_CALL CFileOpenDialog::onWMNotify( HWND hwndChild, LPOFNOTIFYW lpO
break;
case CDN_TYPECHANGE:
+ m_ofn.nFilterIndex = lpOfNotify->lpOFN->nFilterIndex;
onTypeChanged( lpOfNotify->lpOFN->nFilterIndex );
break;
}
@@ -647,6 +644,8 @@ void SAL_CALL CFileOpenDialog::handleInitDialog( HWND hwndDlg, HWND hwndChild )
m_hwndFileOpenDlg = hwndDlg;
m_hwndFileOpenDlgChild = hwndChild;
+ OSL_ASSERT( GetParent( hwndChild ) == hwndDlg );
+
// calling virtual function which the
// client can overload
onInitDialog( hwndDlg, hwndChild );
@@ -659,25 +658,99 @@ void SAL_CALL CFileOpenDialog::handleInitDialog( HWND hwndDlg, HWND hwndChild )
unsigned int CALLBACK CFileOpenDialog::ofnHookProc(
HWND hChildDlg, unsigned int uiMsg, WPARAM wParam, LPARAM lParam )
{
- CFileOpenDialog* pImpl = CFileOpenDialog::s_fileOpenDlgInst;
- OSL_ASSERT( pImpl );
+ HWND hwndDlg = GetParent( hChildDlg );
+ CFileOpenDialog* pImpl = NULL;
switch( uiMsg )
{
case WM_INITDIALOG:
- pImpl->handleInitDialog(
- GetParent( hChildDlg ),
- hChildDlg );
+ {
+ _OPENFILENAMEW* lpofn = reinterpret_cast< _OPENFILENAMEW* >( lParam );
+ pImpl = reinterpret_cast< CFileOpenDialog* >( lpofn->lCustData );
+ OSL_ASSERT( pImpl );
+
+ // subclass the base dialog for WM_NCDESTROY processing
+ pImpl->m_pfnBaseDlgProc =
+ reinterpret_cast< DLGPROC >(
+ SetWindowLong( hwndDlg,
+ DWL_DLGPROC,
+ reinterpret_cast< DWORD >( CFileOpenDialog::BaseDlgProc ) ) );
+
+ // connect the instance handle to the window
+ SetPropA( hwndDlg, CURRENT_INSTANCE, pImpl );
+
+ pImpl->handleInitDialog( hwndDlg, hChildDlg );
+ }
return 0;
case WM_NOTIFY:
- return pImpl->onWMNotify(
- hChildDlg, reinterpret_cast< LPOFNOTIFYW >( lParam ) );
+ {
+ pImpl = getCurrentInstance( hwndDlg );
+ return pImpl->onWMNotify(
+ hChildDlg, reinterpret_cast< LPOFNOTIFYW >( lParam ) );
+ }
case WM_COMMAND:
- return pImpl->onCtrlCommand(
- hChildDlg, LOWORD( wParam ), HIWORD( lParam ) );
+ {
+ pImpl = getCurrentInstance( hwndDlg );
+ OSL_ASSERT( pImpl );
+
+ return pImpl->onCtrlCommand(
+ hChildDlg, LOWORD( wParam ), HIWORD( lParam ) );
+ }
}
return 0;
}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+unsigned int CALLBACK CFileOpenDialog::BaseDlgProc(
+ HWND hWnd, WORD wMessage, WPARAM wParam, LPARAM lParam )
+{
+ unsigned int lResult = 0;
+ CFileOpenDialog* pImpl = NULL;
+
+ switch( wMessage )
+ {
+ case WM_NCDESTROY:
+
+ // RemoveProp returns the saved value on success
+ pImpl = reinterpret_cast< CFileOpenDialog* >(
+ RemovePropA( hWnd, CURRENT_INSTANCE ) );
+ OSL_ASSERT( pImpl );
+
+ // fall through in order to call the
+ // base dlg proc
+ default:
+ if ( !pImpl )
+ {
+ pImpl = getCurrentInstance( hWnd );
+ OSL_ASSERT( pImpl );
+ }
+
+ // !!! we use CallWindowProcA
+ lResult = CallWindowProcA(
+ reinterpret_cast< WNDPROC >( pImpl->m_pfnBaseDlgProc ),
+ hWnd, wMessage, wParam, lParam );
+
+ break;
+
+ } // switch
+
+ return lResult;
+
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFileOpenDialog* CFileOpenDialog::getCurrentInstance( HWND hwnd )
+{
+ OSL_ASSERT( IsWindow( hwnd ) );
+ return reinterpret_cast< CFileOpenDialog* >(
+ GetPropA( hwnd, CURRENT_INSTANCE ) );
+} \ No newline at end of file
diff --git a/fpicker/source/win32/filepicker/FileOpenDlg.hxx b/fpicker/source/win32/filepicker/FileOpenDlg.hxx
index 0f9542b3d68f..11211e65b08e 100644
--- a/fpicker/source/win32/filepicker/FileOpenDlg.hxx
+++ b/fpicker/source/win32/filepicker/FileOpenDlg.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: FileOpenDlg.hxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: tra $ $Date: 2001-06-28 11:13:03 $
+ * last change: $Author: tra $ $Date: 2001-07-09 12:58:25 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -309,16 +309,12 @@ protected:
HWND m_hwndFileOpenDlg;
HWND m_hwndFileOpenDlgChild;
-#if (_WIN32_WINNT >= 0x0500)
_OPENFILENAMEW m_ofn;
-#else
- OPENFILENAMEW m_ofn;
-#endif
- // to reconnect to the instance
- // !!! implies that only one instance
- // at a time is supported
- static CFileOpenDialog* s_fileOpenDlgInst;
+ // we connect the instance with the dialog window using
+ // SetProp, with this function we can reconnect from
+ // callback functions to this instance
+ static CFileOpenDialog* getCurrentInstance( HWND hwnd );
private:
// FileOpen or FileSaveDialog
@@ -332,6 +328,8 @@ private:
CAutoUnicodeBuffer m_fileTitleBuffer;
CAutoUnicodeBuffer m_helperBuffer;
+ DLGPROC m_pfnBaseDlgProc;
+
// callback function
static unsigned int CALLBACK ofnHookProc(
HWND hChildDlg, // handle to child dialog box
@@ -340,6 +338,13 @@ private:
LPARAM lParam // message parameter
);
+ // we have to subclass the dialog in order
+ // to clean up the window property we are
+ // using to connect the window with a class
+ // instance in WM_NCDESTROY
+ static unsigned int CALLBACK BaseDlgProc(
+ HWND hWnd, WORD wMessage, WPARAM wParam, LPARAM lParam );
+
private:
// avoid copy and assignment
diff --git a/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx b/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx
index 773cdd45ab5e..d8b923764e30 100644
--- a/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx
+++ b/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: WinFileOpenImpl.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: tra $ $Date: 2001-07-02 08:09:57 $
+ * last change: $Author: tra $ $Date: 2001-07-09 12:58:25 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -126,6 +126,14 @@
#include "..\misc\resourceprovider.hxx"
#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _THREAD_HXX_
+#include <osl/thread.hxx>
+#endif
+
//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------
@@ -158,6 +166,17 @@ enum ECW_ACTION_T
CACHE_CONTROL_VALUES
};
+struct EnumParam
+{
+ ECW_ACTION_T m_action;
+ CWinFileOpenImpl* m_instance;
+
+ EnumParam( ECW_ACTION_T action, CWinFileOpenImpl* instance ):
+ m_action( action ),
+ m_instance( instance )
+ {}
+};
+
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
@@ -432,7 +451,7 @@ OUString SAL_CALL CWinFileOpenImpl::getCurrentFilter( ) throw(RuntimeException)
//=================================================================================================================
void SAL_CALL CWinFileOpenImpl::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue )
- throw(RuntimeException)
+ throw(IllegalArgumentException, RuntimeException)
{
if ( m_bInExecuteMode )
{
@@ -482,7 +501,7 @@ void SAL_CALL CWinFileOpenImpl::setValue( sal_Int16 aControlId, sal_Int16 aContr
//-----------------------------------------------------------------------------------------
Any SAL_CALL CWinFileOpenImpl::getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
- throw(RuntimeException)
+ throw(IllegalArgumentException, RuntimeException)
{
Any aAny;
@@ -540,7 +559,7 @@ Any SAL_CALL CWinFileOpenImpl::getValue( sal_Int16 aControlId, sal_Int16 aContro
//-----------------------------------------------------------------------------------------
void SAL_CALL CWinFileOpenImpl::enableControl( sal_Int16 ControlID, sal_Bool bEnable )
- throw(RuntimeException)
+ throw(IllegalArgumentException, RuntimeException)
{
HWND hwndCtrl = GetHwndDlgItem( ControlID );
@@ -558,7 +577,7 @@ void SAL_CALL CWinFileOpenImpl::enableControl( sal_Int16 ControlID, sal_Bool bEn
//-----------------------------------------------------------------------------------------
void SAL_CALL CWinFileOpenImpl::setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel )
- throw (RuntimeException)
+ throw (IllegalArgumentException, RuntimeException)
{
HWND hwndCtrl = GetHwndDlgItem( aControlId );
@@ -578,7 +597,7 @@ void SAL_CALL CWinFileOpenImpl::setLabel( sal_Int16 aControlId, const ::rtl::OUS
//-----------------------------------------------------------------------------------------
OUString SAL_CALL CWinFileOpenImpl::getLabel( sal_Int16 aControlId )
- throw (RuntimeException)
+ throw (IllegalArgumentException, RuntimeException)
{
HWND hwndCtrl = GetHwndDlgItem( aControlId );
@@ -735,15 +754,15 @@ sal_Int16 SAL_CALL CWinFileOpenImpl::getFocused( )
unsigned int CALLBACK CWinFileOpenImpl::SubClassFunc(
HWND hWnd, WORD wMessage, WPARAM wParam, LPARAM lParam )
{
+ unsigned int lResult = 0;
+
CWinFileOpenImpl* pImpl =
- dynamic_cast< CWinFileOpenImpl* >( s_fileOpenDlgInst );
+ dynamic_cast< CWinFileOpenImpl* >(
+ getCurrentInstance( hWnd ) );
OSL_ASSERT( pImpl );
- unsigned int lResult = 0;
-
switch( wMessage )
{
-
case WM_HELP:
{
FilePickerEvent evt;
@@ -752,7 +771,6 @@ unsigned int CALLBACK CWinFileOpenImpl::SubClassFunc(
break;
default:
-
// !!! we use CallWindowProcA
lResult = CallWindowProcA(
reinterpret_cast< WNDPROC >( pImpl->m_pfnOldDlgProc ),
@@ -781,22 +799,11 @@ void SAL_CALL CWinFileOpenImpl::InitControlState( HWND hWnd )
for ( /* empty */; iter != iter_end; ++iter )
{
- try
- {
- if ( GetDlgCtrlID( hWnd ) == iter->m_controlId )
- setValue(
- iter->m_controlId,
- iter->m_controlAction,
- iter->m_Value );
- }
- catch( ... )
- {
- // if setValue throws an exception
- // we catch and ignore it because it may
- // be that there are some invalid or old
- // items in the cache
- OSL_ASSERT( sal_False );
- }
+ if ( GetDlgCtrlID( hWnd ) == iter->m_controlId )
+ setValue(
+ iter->m_controlId,
+ iter->m_controlAction,
+ iter->m_Value );
}
//-----------------------------------------
@@ -863,15 +870,14 @@ sal_Bool SAL_CALL CWinFileOpenImpl::HasPreview( HWND hWnd )
BOOL CALLBACK CWinFileOpenImpl::EnumChildWndProc( HWND hWnd, LPARAM lParam )
{
- ECW_ACTION_T action = (ECW_ACTION_T)lParam;
- CWinFileOpenImpl* pImpl =
- dynamic_cast< CWinFileOpenImpl* >( s_fileOpenDlgInst );
+ EnumParam* enumParam = (EnumParam*)lParam;
+ CWinFileOpenImpl* pImpl = enumParam->m_instance;
OSL_ASSERT( pImpl );
BOOL bRet = TRUE;
- switch( action )
+ switch( enumParam->m_action )
{
case CHECK_PREVIEW:
if ( pImpl->HasPreview( hWnd ) )
@@ -885,6 +891,10 @@ BOOL CALLBACK CWinFileOpenImpl::EnumChildWndProc( HWND hWnd, LPARAM lParam )
case CACHE_CONTROL_VALUES:
pImpl->CacheControlState( hWnd );
break;
+
+ default:
+ // should not end here
+ OSL_ASSERT( sal_False );
}
return bRet;
@@ -898,10 +908,13 @@ sal_uInt32 SAL_CALL CWinFileOpenImpl::onFileOk()
{
// fill the control value cache
m_ControlCache.clear( );
+
+ EnumParam enumParam( CACHE_CONTROL_VALUES, this );
+
EnumChildWindows(
m_hwndFileOpenDlgChild,
CWinFileOpenImpl::EnumChildWndProc,
- (LPARAM) CACHE_CONTROL_VALUES );
+ (LPARAM)&enumParam );
return 0;
}
@@ -955,10 +968,12 @@ void SAL_CALL CWinFileOpenImpl::onInitDone()
// we check if the checkbox is present and if so
// create a preview window
+ EnumParam enumParam( CHECK_PREVIEW, this );
+
EnumChildWindows(
m_hwndFileOpenDlgChild,
CWinFileOpenImpl::EnumChildWndProc,
- (LPARAM) CHECK_PREVIEW );
+ (LPARAM)&enumParam );
// create and display the preview control
@@ -1043,10 +1058,15 @@ void SAL_CALL CWinFileOpenImpl::onInitDone()
}
// initialize controls from cache
+ enumParam.m_action = INIT_CONTROL_VALUES;
+ enumParam.m_instance = this;
+
EnumChildWindows(
m_hwndFileOpenDlgChild,
CWinFileOpenImpl::EnumChildWndProc,
- (LPARAM) INIT_CONTROL_VALUES );
+ (LPARAM)&enumParam );
+
+ SetDefaultExtension( );
}
//-----------------------------------------------------------------
@@ -1066,6 +1086,8 @@ void SAL_CALL CWinFileOpenImpl::onFolderChanged()
void SAL_CALL CWinFileOpenImpl::onTypeChanged( sal_uInt32 nFilterIndex )
{
+ SetDefaultExtension( );
+
FilePickerEvent evt;
evt.ElementId = LISTBOX_FILTER;
evt.Source = static_cast< XFilePicker* >( m_FilePicker );
@@ -1079,6 +1101,8 @@ void SAL_CALL CWinFileOpenImpl::onTypeChanged( sal_uInt32 nFilterIndex )
sal_uInt32 SAL_CALL CWinFileOpenImpl::onCtrlCommand(
HWND hwndDlg, sal_uInt16 ctrlId, sal_uInt16 notifyCode )
{
+ SetDefaultExtension( );
+
if ( ctrlId < ctlFirst )
{
FilePickerEvent evt;
@@ -1147,4 +1171,76 @@ HWND SAL_CALL CWinFileOpenImpl::GetHwndDlgItem( sal_Int16 ctrlId, sal_Bool bIncl
}
return hwndCtrl;
+}
+
+//-----------------------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL CWinFileOpenImpl::SetDefaultExtension( )
+{
+ // !!! HACK !!!
+
+ OSVERSIONINFOA OSVerInfo;
+
+ OSVerInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFOA );
+ GetVersionExA( &OSVerInfo );
+
+ // if windows 95/98
+ sal_Bool bIsWin9x = ( VER_PLATFORM_WIN32_WINDOWS == OSVerInfo.dwPlatformId );
+
+ HWND hwndChkSaveWithExt = GetDlgItem( m_hwndFileOpenDlgChild, 100 );
+
+ if ( hwndChkSaveWithExt )
+ {
+ Any aAny = CheckboxGetState( hwndChkSaveWithExt );
+ sal_Bool bChecked = *reinterpret_cast< const sal_Bool* >( aAny.getValue( ) );
+
+ if ( bChecked )
+ {
+ sal_uInt32 nIndex = getSelectedFilterIndex( );
+
+ OUString currentFilter;
+ if ( nIndex > 0 )
+ {
+ // filter index of the base class starts with 1
+ sal_Bool bRet = m_filterContainer->getFilter( nIndex - 1, currentFilter );
+
+ if ( currentFilter.getLength( ) )
+ {
+ OUString FilterExt;
+ m_filterContainer->getFilter( currentFilter, FilterExt );
+
+ sal_Int32 posOfPoint = FilterExt.indexOf( L'.' );
+ const sal_Unicode* pFirstExtStart = FilterExt.getStr( ) + posOfPoint + 1;
+
+ sal_Int32 posOfSemiColon = FilterExt.indexOf( L';' ) - 1;
+ if ( posOfSemiColon < 0 )
+ posOfSemiColon = FilterExt.getLength( ) - 1;
+
+ FilterExt = OUString( pFirstExtStart, posOfSemiColon - posOfPoint );
+
+ if ( bIsWin9x )
+ {
+ rtl::OString tmp = rtl::OUStringToOString( FilterExt, osl_getThreadTextEncoding( ) );
+
+ SendMessageA( m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, (LPARAM)( tmp.getStr( ) ) );
+ }
+ else
+ {
+ SendMessageW( m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, (LPARAM)( FilterExt.getStr( ) ) );
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( bIsWin9x )
+ SendMessageA( m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, (LPARAM)"" );
+ else
+ SendMessageW( m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, (LPARAM)L"");
+ }
+ }
+
+ // !!! HACK !!!
} \ No newline at end of file
diff --git a/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx b/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx
index d9a1a2a4d23d..f1680d6c8f8d 100644
--- a/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx
+++ b/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: WinFileOpenImpl.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: tra $ $Date: 2001-07-02 08:09:57 $
+ * last change: $Author: tra $ $Date: 2001-07-09 12:58:25 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -244,6 +244,8 @@ private:
// the function return 0 on failure
HWND SAL_CALL GetHwndDlgItem( sal_Int16 ctrlId, sal_Bool bIncludeStdCtrls = sal_True );
+ void SAL_CALL SetDefaultExtension( );
+
static unsigned int CALLBACK SubClassFunc( HWND hWnd, WORD wMessage, WPARAM wParam, LPARAM lParam );
static BOOL CALLBACK EnumChildWndProc( HWND hWnd, LPARAM lParam );