summaryrefslogtreecommitdiff
path: root/vcl/os2/source/app/salinst.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/os2/source/app/salinst.cxx')
-rw-r--r--vcl/os2/source/app/salinst.cxx754
1 files changed, 754 insertions, 0 deletions
diff --git a/vcl/os2/source/app/salinst.cxx b/vcl/os2/source/app/salinst.cxx
new file mode 100644
index 000000000000..8a3ef0d1315f
--- /dev/null
+++ b/vcl/os2/source/app/salinst.cxx
@@ -0,0 +1,754 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#define INCL_DOSPROCESS
+
+#include <string.h>
+#include <tools/svpm.h>
+#include <process.h>
+
+#define _SV_SALINST_CXX
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+
+#define SVMODULENAME "VCL" MAKE_NUMSTR( SUPD ) __DLLEXTENSION
+
+// =======================================================================
+
+void SalSetExceptionHandler( SALEXCEPTIONPROC pProc )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalAbort( const XubString& rErrorText )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ImplSalGetCurrentThreadId()
+{
+ PTIB pptib = NULL;
+ PPIB pppib = NULL;
+
+ DosGetInfoBlocks( &pptib, &pppib );
+ return pptib->tib_ptib2->tib2_ultid;
+}
+
+// =======================================================================
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+public:
+ SalInstanceData* mpInstData;
+ ULONG mnCount;
+ ULONG mnWaitCount;
+ ULONG mnThreadId;
+
+public:
+ SalYieldMutex( SalInstanceData* pInstData );
+
+ virtual void acquire();
+ virtual void release();
+ virtual Boolean tryToAcquire();
+
+ ULONG GetAcquireCount( ULONG nThreadId );
+};
+
+// -----------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData )
+{
+ mpInstData = pInstData;
+ mnCount = 0;
+ mnThreadId = 0;
+ mnWaitCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnCount++;
+ mnThreadId = ImplSalGetCurrentThreadId();
+}
+
+// -----------------------------------------------------------------------
+
+void SalYieldMutex::release()
+{
+ ULONG nThreadId = ImplSalGetCurrentThreadId();
+ if ( mnThreadId != nThreadId )
+ OMutex::release();
+ else
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId != nThreadId )
+ {
+ NAMESPACE_VOS(OGuard) aGuard( mpInstData->mpSalWaitMutex );
+ if ( mnCount == 1 )
+ {
+ if ( mnWaitCount && WinPostMsg( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ) )
+ mnWaitCount--;
+ mnThreadId = 0;
+ }
+ mnCount--;
+ OMutex::release();
+ }
+ else
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Boolean SalYieldMutex::tryToAcquire()
+{
+ if ( OMutex::tryToAcquire() )
+ {
+ mnCount++;
+ mnThreadId = ImplSalGetCurrentThreadId();
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
+{
+ if ( nThreadId == mnThreadId )
+ return mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalYieldMutexTryToAcquire()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ return pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->tryToAcquire();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquire()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexRelease()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->release();
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+ SalData* pSalData = GetSalData();
+ ULONG nCurThreadId = ImplSalGetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ }
+ else
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+ }
+}
+
+#endif
+
+// =======================================================================
+
+void InitSalSystemData()
+{
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalYield( BOOL bWait, BOOL bMainThread, SalYieldMutex* pYieldMutex )
+{
+ QMSG aMsg;
+ QMSG aTmpMsg;
+ BOOL bDispatch = FALSE;
+ USHORT nPostReleaseWait = 0;
+ static QMSG* pMsg = NULL;
+ SalData* pSalData = GetSalData();
+
+ do
+ {
+ if ( !pMsg )
+ {
+ BOOL bQuit = FALSE;
+ if ( bWait )
+ {
+ if ( WinGetMsg( pSalData->mhAB, &aMsg, 0, 0, 0 ) )
+ pMsg = &aMsg;
+ else
+ bQuit = TRUE;
+ }
+ else
+ {
+ if ( WinPeekMsg( pSalData->mhAB, &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ if ( aMsg.msg == WM_QUIT )
+ bQuit = TRUE;
+ else
+ pMsg = &aMsg;
+ }
+ }
+
+ // ShutDown-Event ausloesen (ist immer dann der Fall,
+ // wenn wir eine Quit-Message bekommen)
+ if ( bQuit && pSalData->mpDefaultFrame )
+ {
+ SalFrame* pDefaultFrame = pSalData->mpDefaultFrame;
+ if ( pDefaultFrame->maFrameData.mpProc( pDefaultFrame->maFrameData.mpInst, pDefaultFrame,
+ SALEVENT_SHUTDOWN, 0 ) )
+ WinCancelShutdown( pSalData->mhAB, FALSE );
+ }
+
+ // ReleaseWaitYield ignorieren wir, da diese fuer andere
+ // Yield-Aufrufe gedacht sind
+ if ( pMsg )
+ {
+ if ( pMsg->msg == SAL_MSG_RELEASEWAITYIELD )
+ {
+ nPostReleaseWait++;
+ pMsg = NULL;
+ continue;
+ }
+ }
+ }
+
+ if ( pMsg )
+ {
+ // Darf ich die Message dispatchen
+ pYieldMutex->mpInstData->mpSalWaitMutex->acquire();
+ if ( pYieldMutex->tryToAcquire() )
+ {
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ bDispatch = TRUE;
+ }
+ else
+ {
+ pYieldMutex->mnWaitCount++;
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ WinGetMsg( pSalData->mhAB, &aTmpMsg, pYieldMutex->mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ if ( !pMsg )
+ bDispatch = TRUE;
+ }
+ }
+ else
+ bDispatch = TRUE;
+ }
+ while( !bDispatch );
+
+ if ( pMsg )
+ {
+ // acquire ist nicht notwendig, da dies schon in der oberen
+ // Schleife bei tryToAcquire() gemacht wurde
+ QMSG* pTmpMsg = pMsg;
+ pMsg = NULL;
+ WinDispatchMsg( pSalData->mhAB, pTmpMsg );
+ pYieldMutex->release();
+ }
+
+ while ( nPostReleaseWait )
+ {
+ WinPostMsg( pYieldMutex->mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ nPostReleaseWait--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalComWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ switch ( nMsg )
+ {
+ case SAL_MSG_STARTTIMER:
+ ImplSalStartTimer();
+ return 0;
+ case SAL_MSG_CREATEFRAME:
+ return (MRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (SalFrame*)(ULONG)nMP2, (ULONG)nMP1 );
+ case SAL_MSG_CREATEOBJECT:
+ return (MRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)(ULONG)nMP2 );
+ case SAL_MSG_THREADYIELD:
+ ImplSalYield( (BOOL)(LONG)nMP1, FALSE, (SalYieldMutex*)(LONG)nMP2 );
+ return 0;
+ }
+
+ return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+}
+
+// =======================================================================
+
+void InitSalData()
+{
+ SalData* pSalData = new SalData;
+ memset( pSalData, 0, sizeof( SalData ) );
+ SetSalData( pSalData );
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitSalData()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFontMetrics )
+ delete pSalData->mpFontMetrics;
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
+ pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance* CreateSalInstance()
+{
+ SalData* pSalData = GetSalData();
+ SalInstance* pInst = new SalInstance;
+
+ // determine Module-Handle for SVDLL
+ DosQueryModuleHandle( (PSZ)SVMODULENAME, &aSalShlData.mhMod );
+
+ // determine the os2 version
+ PM_ULONG nMayor;
+ PM_ULONG nMinor;
+ DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MAJOR, &nMayor, sizeof( nMayor ) );
+ DosQuerySysInfo( QSV_VERSION_MINOR, QSV_VERSION_MINOR, &nMinor, sizeof( nMinor ) );
+ aSalShlData.mnVersion = (USHORT)(nMayor*10 + nMinor);
+
+ pSalData->mnAppThreadId = ImplSalGetCurrentThreadId();
+
+ // register frame class
+ if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_FRAME_CLASSNAME,
+ (PFNWP)SalFrameWndProc, CS_HITTEST | CS_MOVENOTIFY,
+ SAL_FRAME_WNDEXTRA ) )
+ {
+ delete pInst;
+ return NULL;
+ }
+
+ // register frame class
+ if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_COM_CLASSNAME,
+ (PFNWP)SalComWndProc, 0, 0 ))
+ {
+ delete pInst;
+ return NULL;
+ }
+
+ HWND hComWnd = WinCreateWindow( HWND_OBJECT, (PSZ)SAL_COM_CLASSNAME,
+ "", 0, 0, 0, 0, 0,
+ HWND_OBJECT, HWND_TOP,
+ 222, NULL, NULL);
+
+ // init system data
+ InitSalSystemData();
+
+ // init instance (only one instance in this version !!!)
+ pSalData->mpFirstInstance = pInst;
+ pInst->maInstData.mhAB = pSalData->mhAB;
+ pInst->maInstData.mhMQ = pSalData->mhMQ;
+ pInst->maInstData.mnArgc = pSalData->mnArgc;
+ pInst->maInstData.mpArgv = pSalData->mpArgv;
+ pInst->maInstData.mhComWnd = hComWnd;
+
+ // AppIcon ermitteln
+ pInst->maInstData.mhAppIcon = WinLoadPointer( HWND_DESKTOP, pSalData->mhAB, 1 );
+ if ( !pInst->maInstData.mhAppIcon )
+ pInst->maInstData.mhAppIcon = ImplLoadPointer( SAL_RESID_ICON_SD );
+
+ return pInst;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroySalInstance( SalInstance* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ // (only one instance in this version !!!)
+
+#ifdef ENABLE_IME
+ // IME-Daten freigeben
+ if ( pSalData->mpIMEData )
+ ImplReleaseSALIMEData();
+#endif
+
+ // Destroy Dummy Frame
+ if ( pSalData->mpDummyFrame )
+ pInst->DestroyFrame( pSalData->mpDummyFrame );
+
+ // reset instance
+ if ( pSalData->mpFirstInstance == pInst )
+ pSalData->mpFirstInstance = NULL;
+
+ delete pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::SalInstance()
+{
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+
+ maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex);
+ maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData );
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::~SalInstance()
+{
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+ delete maInstData.mpSalWaitMutex;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInstance::AnyInput( USHORT nType )
+{
+ SalData* pSalData = GetSalData();
+ QMSG aQMSG;
+
+ if ( (nType & (INPUT_ANY)) == INPUT_ANY )
+ {
+ // Any Input
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
+ return TRUE;
+ }
+ else
+ {
+ if ( nType & INPUT_MOUSE )
+ {
+ // Test auf Mouseinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_KEYBOARD )
+ {
+ // Test auf Keyinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_CHAR, WM_CHAR, PM_NOREMOVE ) )
+ return !(SHORT1FROMMP( aQMSG.mp1 ) & KC_KEYUP);
+ }
+
+ if ( nType & INPUT_PAINT )
+ {
+ // Test auf Paintinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_PAINT, WM_PAINT, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_TIMER )
+ {
+ // Test auf Timerinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_TIMER, WM_TIMER, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_OTHER )
+ {
+ // Test auf sonstigen Input
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::Yield( BOOL bWait )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ SalData* pSalData = GetSalData();
+ ULONG nCurThreadId = ImplSalGetCurrentThreadId();
+ ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ WinSendMsg( maInstData.mhComWnd, SAL_MSG_THREADYIELD,
+ (MPARAM)bWait, (MPARAM)(void*)pYieldMutex );
+
+ n = nCount;
+ while ( n )
+ {
+ pYieldMutex->acquire();
+ n--;
+ }
+ }
+ else
+ {
+ ImplSalYield( bWait, TRUE, pYieldMutex );
+
+ n = nCount;
+ while ( n )
+ {
+ // Wenn wir den Mutex nicht bekommen, muessen wir solange
+ // warten, bis wir Ihn bekommen
+ pYieldMutex->mpInstData->mpSalWaitMutex->acquire();
+ if ( pYieldMutex->tryToAcquire() )
+ {
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ n--;
+ }
+ else
+ {
+ pYieldMutex->mnWaitCount++;
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ QMSG aTmpMsg;
+ WinGetMsg( pSalData->mhAB, &aTmpMsg, maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInstance::GetFileName()
+{
+ String aFileName( maInstData.mpArgv[0] );
+ return aFileName;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalInstance::GetCommandLineParamCount()
+{
+ return maInstData.mnArgc-1;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInstance::GetCommandLineParam( USHORT nParam )
+{
+ if ( nParam < maInstData.mnArgc-1 )
+ {
+ String aParam( maInstData.mpArgv[nParam+1] );
+ return aParam;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ ULONG nCount = pYieldMutex->GetAcquireCount( ImplSalGetCurrentThreadId() );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateFrame( SalFrame* pParent, USHORT nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalFrame*)WinSendMsg( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, (MPARAM)nSalFrameStyle, (MPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalObject*)WinSendMsg( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (MPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Start( ULONG nMS )
+{
+ // Um auf Main-Thread umzuschalten
+ SalData* pSalData = GetSalData();
+ pSalData->mnNewTimerMS = nMS;
+ if ( pSalData->mpFirstInstance )
+ {
+ if ( pSalData->mnAppThreadId != ImplSalGetCurrentThreadId() )
+ WinPostMsg( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, 0 );
+ else
+ WinSendMsg( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, 0 );
+ }
+ else
+ ImplSalStartTimer();
+}