/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #define INCL_DOS #define INCL_PM #define INCL_WIN #define VCL_OS2 #include #include #include // ======================================================================= #define _SV_SALFRAME_CXX #ifndef DEBUG_HXX #include #endif #define private public #include "os2/sallang.hxx" #include "os2/salids.hrc" #include "os2/saldata.hxx" #include "os2/salinst.h" #include "os2/salgdi.h" #include "os2/salframe.h" #include "os2/saltimer.h" #include #include #include #if OSL_DEBUG_LEVEL>10 extern "C" int debug_printf(const char *f, ...); static sal_Bool _bCapture; #else #define debug_printf( ...) { 1; } #endif // ======================================================================= #undef WinEnableMenuItem #define WinEnableMenuItem(hwndMenu,id,fEnable) \ ((PM_BOOL)WinSendMsg (hwndMenu, MM_SETITEMATTR, MPFROM2SHORT (id, TRUE), \ MPFROM2SHORT (MIA_DISABLED, \ ((USHORT)(fEnable) ? 0 : MIA_DISABLED)))) // ======================================================================= HPOINTER ImplLoadPointer( ULONG nId ); static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ); static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ); static void ImplSalCalcFrameSize( HWND hWnd, LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ); static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame, LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ); MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 ); // ======================================================================= static LanguageType eImplKeyboardLanguage = LANGUAGE_DONTKNOW; sal_Bool Os2SalFrame::mbInReparent = FALSE; ULONG Os2SalFrame::mnInputLang = 0; // ======================================================================= // define a new flag #define SWP_CENTER (SWP_NOAUTOCLOSE<<4) #define SWP_SHOWMAXIMIZED (SWP_ACTIVATE | SWP_SHOW | SWP_MAXIMIZE) #define SWP_SHOWMINIMIZED (SWP_ACTIVATE | SWP_SHOW | SWP_MINIMIZE) #define SWP_SHOWNORMAL (SWP_ACTIVATE | SWP_SHOW | SWP_RESTORE) static LONG nScreenHeight = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN); static LONG nScreenWidth = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); sal_Bool APIENTRY _WinQueryWindowRect( HWND hwnd, PRECTL prclDest) { sal_Bool rc = WinQueryWindowRect( hwnd, prclDest); ULONG tmp = prclDest->yBottom; prclDest->yBottom = prclDest->yTop; prclDest->yTop = tmp; return rc; } sal_Bool APIENTRY _WinQueryPointerPos (HWND hwndDesktop, PPOINTL pptl) { sal_Bool rc = WinQueryPointerPos( hwndDesktop, pptl); pptl->y = nScreenHeight - pptl->y; return rc; } sal_Bool APIENTRY _WinQueryWindowPos( Os2SalFrame* pFrame, PSWP pswp) { SWP swpOwner; sal_Bool rc = WinQueryWindowPos( pFrame->mhWndFrame, pswp); #if OSL_DEBUG_LEVEL>1 debug_printf( "> WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n", pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy); #endif Os2SalFrame* pParentFrame = pFrame->mpParentFrame; //YD adjust to owner coordinates if ( pParentFrame ) { POINTL ptlOwner = {0}; // coords are relative to screen, map to parent frame client area ptlOwner.x = pswp->x; ptlOwner.y = pswp->y; WinMapWindowPoints( HWND_DESKTOP, pParentFrame->mhWndClient, &ptlOwner, 1); pswp->x = ptlOwner.x; pswp->y = ptlOwner.y; // get parent client area size WinQueryWindowPos( pParentFrame->mhWndClient, &swpOwner); } else { // no owner info, use DESKTOP???? swpOwner.cx = nScreenWidth; swpOwner.cy = nScreenHeight; } // invert Y coordinate pswp->y = swpOwner.cy - (pswp->y + pswp->cy); #if OSL_DEBUG_LEVEL>1 debug_printf( "< WinQueryWindowPos hwnd %x at %d,%d (%dx%d)\n", pFrame->mhWndFrame, pswp->x, pswp->y, pswp->cx, pswp->cy); #endif return rc; } sal_Bool APIENTRY _WinSetWindowPos( Os2SalFrame* pFrame, HWND hwndInsertBehind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl) { SWP swpOwner = {0}; POINTL ptlOwner = {0}; HWND hParent = NULL; #if OSL_DEBUG_LEVEL>1 debug_printf( ">WinSetWindowPos hwnd %x at %d,%d (%dx%d) fl 0x%08x\n", pFrame->mhWndFrame, x, y, cx, cy, fl); #endif // first resize window if requested if ( (fl & SWP_SIZE) ) { ULONG flag = SWP_SIZE; LONG nX = 0, nY = 0; LONG frameFrameX, frameFrameY, frameCaptionY; ImplSalCalcFrameSize( pFrame, frameFrameX, frameFrameY, frameCaptionY ); // if we change y size, we need to move the window down // because os2 window origin is lower left corner if (pFrame->maGeometry.nHeight != cy) { SWP aSWP; WinQueryWindowPos( pFrame->mhWndFrame, &aSWP); nX = aSWP.x; nY = aSWP.y - (cy + 2*frameFrameY + frameCaptionY - aSWP.cy); flag |= SWP_MOVE; } WinSetWindowPos( pFrame->mhWndFrame, NULL, nX, nY, cx+2*frameFrameX, cy+2*frameFrameY+frameCaptionY, flag); fl = fl & ~SWP_SIZE; } else // otherwise get current size { SWP swp = {0}; WinQueryWindowPos( pFrame->mhWndClient, &swp); cx = swp.cx; cy = swp.cy; } // get parent window handle Os2SalFrame* pParentFrame = pFrame->mpParentFrame; // use desktop if parent is not defined hParent = pParentFrame ? pParentFrame->mhWndClient : HWND_DESKTOP; // if parent is not visible, use desktop as reference hParent = WinIsWindowVisible( hParent) ? hParent : HWND_DESKTOP; WinQueryWindowPos( hParent, &swpOwner); //YD adjust to owner coordinates only when moving and not centering //if (!(fl & SWP_CENTER) && (fl & SWP_MOVE)) if ((fl & SWP_MOVE)) { // if SWP_CENTER is specified, change position to parent center if (fl & SWP_CENTER) { ptlOwner.x = (swpOwner.cx - cx) / 2; ptlOwner.y = (swpOwner.cy - cy) / 2; #if OSL_DEBUG_LEVEL>0 debug_printf( "_WinSetWindowPos SWP_CENTER\n"); #endif fl = fl & ~SWP_CENTER; } else { // coords are relative to parent frame client area, map to screen // map Y to OS/2 system coordinates ptlOwner.x = x; ptlOwner.y = swpOwner.cy - (y + cy); #if OSL_DEBUG_LEVEL>0 debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) OS2\n", hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy); #endif } // map from client area to screen WinMapWindowPoints( hParent, HWND_DESKTOP, &ptlOwner, 1); x = ptlOwner.x; y = ptlOwner.y; #if OSL_DEBUG_LEVEL>0 debug_printf( "_WinSetWindowPos owner 0x%x at %d,%d (%dx%d) MAPPED OS2\n", hParent, ptlOwner.x, ptlOwner.y, swpOwner.cx, swpOwner.cy); #endif } #if OSL_DEBUG_LEVEL>0 debug_printf( "mhWndFrame, x, y, cx, cy, fl); #endif return WinSetWindowPos( pFrame->mhWndFrame, hwndInsertBehind, x, y, 0, 0, fl); } // ======================================================================= #if OSL_DEBUG_LEVEL > 0 static void dumpWindowInfo( char* fnc, HWND hwnd) { SWP aSWP; HWND hwnd2; char szTitle[256]; #if 0 _WinQueryWindowPos( hwnd, &aSWP ); strcpy(szTitle,""); WinQueryWindowText(hwnd, sizeof(szTitle), szTitle); debug_printf( "%s: window %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); hwnd2 = WinQueryWindow(hwnd, QW_PARENT); _WinQueryWindowPos( hwnd2, &aSWP ); strcpy(szTitle,""); WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle); debug_printf( "%s: parent %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); hwnd2 = WinQueryWindow(hwnd, QW_OWNER); _WinQueryWindowPos( hwnd2, &aSWP ); strcpy(szTitle,""); WinQueryWindowText(hwnd2, sizeof(szTitle), szTitle); debug_printf( "%s: owner %08x at %d,%d (size %dx%d) '%s'\n", fnc, hwnd2, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, szTitle); #endif } #endif // ======================================================================= #ifdef ENABLE_IME struct ImplSalIMEProc { ULONG nOrd; PFN* pProc; }; #define SAL_IME_PROC_COUNT 12 // ----------------------------------------------------------------------- static SalIMEData* GetSalIMEData() { SalData* pSalData = GetSalData(); if ( !pSalData->mbIMEInit ) { pSalData->mbIMEInit = TRUE; HMODULE hMod = 0; if ( 0 == DosLoadModule( NULL, 0, "OS2IM", &hMod ) ) { SalIMEData* pIMEData = new SalIMEData; sal_Bool bError = FALSE; ImplSalIMEProc aProcAry[SAL_IME_PROC_COUNT] = { { 101, (PFN*)&(pIMEData->mpAssocIME) }, { 104, (PFN*)&(pIMEData->mpGetIME) }, { 106, (PFN*)&(pIMEData->mpReleaseIME) }, { 117, (PFN*)&(pIMEData->mpSetConversionFont) }, { 144, (PFN*)&(pIMEData->mpSetConversionFontSize) }, { 118, (PFN*)&(pIMEData->mpGetConversionString) }, { 122, (PFN*)&(pIMEData->mpGetResultString) }, { 115, (PFN*)&(pIMEData->mpSetCandidateWin) }, { 130, (PFN*)&(pIMEData->mpQueryIMEProperty) }, { 131, (PFN*)&(pIMEData->mpRequestIME) }, { 128, (PFN*)&(pIMEData->mpSetIMEMode) }, { 127, (PFN*)&(pIMEData->mpQueryIMEMode) } }; pIMEData->mhModIME = hMod; for ( USHORT i = 0; i < SAL_IME_PROC_COUNT; i++ ) { if ( 0 != DosQueryProcAddr( pIMEData->mhModIME, aProcAry[i].nOrd, 0, aProcAry[i].pProc ) ) { bError = TRUE; break; } } if ( bError ) { DosFreeModule( pIMEData->mhModIME ); delete pIMEData; } else pSalData->mpIMEData = pIMEData; } } return pSalData->mpIMEData; } // ----------------------------------------------------------------------- void ImplReleaseSALIMEData() { SalData* pSalData = GetSalData(); if ( pSalData->mpIMEData ) { DosFreeModule( pSalData->mpIMEData->mhModIME ); delete pSalData->mpIMEData; } } #endif // ======================================================================= static void ImplSaveFrameState( Os2SalFrame* pFrame ) { // Position, Groesse und Status fuer GetWindowState() merken if ( !pFrame->mbFullScreen ) { SWP aSWP; sal_Bool bVisible = WinIsWindowVisible( pFrame->mhWndFrame); // Query actual state (maState uses screen coords) WinQueryWindowPos( pFrame->mhWndFrame, &aSWP ); if ( aSWP.fl & SWP_MINIMIZE ) { #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MINIMIZED\n", pFrame->mhWndFrame); #endif pFrame->maState.mnState |= SAL_FRAMESTATE_MINIMIZED; if ( bVisible ) pFrame->mnShowState = SWP_SHOWMAXIMIZED; } else if ( aSWP.fl & SWP_MAXIMIZE ) { #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::GetWindowState %08x SAL_FRAMESTATE_MAXIMIZED\n", pFrame->mhWndFrame); #endif pFrame->maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED; pFrame->maState.mnState |= SAL_FRAMESTATE_MAXIMIZED; if ( bVisible ) pFrame->mnShowState = SWP_SHOWMINIMIZED; pFrame->mbRestoreMaximize = TRUE; } else { LONG nFrameX, nFrameY, nCaptionY; ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); // to be consistent with Unix, the frame state is without(!) decoration long nTopDeco = nFrameY + nCaptionY; long nLeftDeco = nFrameX; long nBottomDeco = nFrameY; long nRightDeco = nFrameX; pFrame->maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED); // subtract decoration, store screen coords pFrame->maState.mnX = aSWP.x+nLeftDeco; pFrame->maState.mnY = nScreenHeight - (aSWP.y+aSWP.cy)+nTopDeco; pFrame->maState.mnWidth = aSWP.cx-nLeftDeco-nRightDeco; pFrame->maState.mnHeight = aSWP.cy-nTopDeco-nBottomDeco; #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::GetWindowState %08x (%dx%d) at %d,%d VCL\n", pFrame->mhWndFrame, pFrame->maState.mnWidth,pFrame->maState.mnHeight,pFrame->maState.mnX,pFrame->maState.mnY); #endif if ( bVisible ) pFrame->mnShowState = SWP_SHOWNORMAL; pFrame->mbRestoreMaximize = FALSE; //debug_printf( "ImplSaveFrameState: window %08x at %d,%d (size %dx%d)\n", // pFrame->mhWndFrame, // pFrame->maState.mnX, pFrame->maState.mnY, pFrame->maState.mnWidth, pFrame->maState.mnHeight); } } } // ----------------------------------------------------------------------- long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* ) { return 0; } // ----------------------------------------------------------------------- static void ImplSalCalcFrameSize( HWND hWnd, LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( !pFrame ) return; return ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); } static void ImplSalCalcFrameSize( const Os2SalFrame* pFrame, LONG& nFrameX, LONG& nFrameY, LONG& nCaptionY ) { if ( pFrame->mbSizeBorder ) { nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER ); nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ); } else if ( pFrame->mbFixBorder ) { nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXDLGFRAME ); nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ); } else if ( pFrame->mbBorder ) { nFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER ); nFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ); } else { nFrameX = 0; nFrameY = 0; } if ( pFrame->mbCaption ) nCaptionY = WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ); else nCaptionY = 0; #if OSL_DEBUG_LEVEL>0 //if (_bCapture) debug_printf("ImplSalCalcFrameSize 0x%08x x=%d y=%d t=%d\n", pFrame->mhWndFrame, nFrameX, nFrameY, nCaptionY); #endif } // ----------------------------------------------------------------------- static void ImplSalCalcFullScreenSize( const Os2SalFrame* pFrame, LONG& rX, LONG& rY, LONG& rDX, LONG& rDY ) { // set window to screen size LONG nFrameX, nFrameY, nCaptionY; LONG rScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); LONG rScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); // Framegroessen berechnen ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY ); rX = -nFrameX; rY = -(nFrameY+nCaptionY); rDX = rScreenDX+(nFrameX*2); rDY = rScreenDY+(nFrameY*2)+nCaptionY; } // ----------------------------------------------------------------------- static void ImplSalFrameFullScreenPos( Os2SalFrame* pFrame, sal_Bool bAlways = FALSE ) { SWP aSWP; _WinQueryWindowPos( pFrame, &aSWP ); if ( bAlways || !(aSWP.fl & SWP_MINIMIZE) ) { // set window to screen size LONG nX; LONG nY; LONG nWidth; LONG nHeight; ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight ); _WinSetWindowPos( pFrame, 0, nX, nY, nWidth, nHeight, SWP_MOVE | SWP_SIZE ); } } // ----------------------------------------------------------------------- // Uebersetzungstabelle von System-Keycodes in StarView-Keycodes #define KEY_TAB_SIZE (VK_ENDDRAG+1) static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] = { // StarView-Code System-Code Index 0, // 0x00 0, // VK_BUTTON1 0x01 0, // VK_BUTTON2 0x02 0, // VK_BUTTON3 0x03 0, // VK_BREAK 0x04 KEY_BACKSPACE, // VK_BACKSPACE 0x05 KEY_TAB, // VK_TAB 0x06 KEY_TAB, // VK_BACKTAB 0x07 KEY_RETURN, // VK_NEWLINE 0x08 0, // VK_SHIFT 0x09 0, // VK_CTRL 0x0A 0, // VK_ALT 0x0B 0, // VK_ALTGRAF 0x0C 0, // VK_PAUSE 0x0D 0, // VK_CAPSLOCK 0x0E KEY_ESCAPE, // VK_ESC 0x0F KEY_SPACE, // VK_SPACE 0x10 KEY_PAGEUP, // VK_PAGEUP 0x11 KEY_PAGEDOWN, // VK_PAGEDOWN 0x12 KEY_END, // VK_END 0x13 KEY_HOME, // VK_HOME 0x14 KEY_LEFT, // VK_LEFT 0x15 KEY_UP, // VK_UP 0x16 KEY_RIGHT, // VK_RIGHT 0x17 KEY_DOWN, // VK_DOWN 0x18 0, // VK_PRINTSCRN 0x19 KEY_INSERT, // VK_INSERT 0x1A KEY_DELETE, // VK_DELETE 0x1B 0, // VK_SCRLLOCK 0x1C 0, // VK_NUMLOCK 0x1D KEY_RETURN, // VK_ENTER 0x1E 0, // VK_SYSRQ 0x1F KEY_F1, // VK_F1 0x20 KEY_F2, // VK_F2 0x21 KEY_F3, // VK_F3 0x22 KEY_F4, // VK_F4 0x23 KEY_F5, // VK_F5 0x24 KEY_F6, // VK_F6 0x25 KEY_F7, // VK_F7 0x26 KEY_F8, // VK_F8 0x27 KEY_F9, // VK_F9 0x28 KEY_F10, // VK_F10 0x29 KEY_F11, // VK_F11 0x2A KEY_F12, // VK_F12 0x2B KEY_F13, // VK_F13 0x2C KEY_F14, // VK_F14 0x2D KEY_F15, // VK_F15 0x2E KEY_F16, // VK_F16 0x2F KEY_F17, // VK_F17 0x30 KEY_F18, // VK_F18 0x31 KEY_F19, // VK_F19 0x32 KEY_F20, // VK_F20 0x33 KEY_F21, // VK_F21 0x34 KEY_F22, // VK_F22 0x35 KEY_F23, // VK_F23 0x36 KEY_F24, // VK_F24 0x37 0 // VK_ENDDRAG 0x38 }; // ======================================================================= SalFrame* ImplSalCreateFrame( Os2SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle ) { SalData* pSalData = GetSalData(); Os2SalFrame* pFrame = new Os2SalFrame; HWND hWndFrame; HWND hWndClient; ULONG nFrameFlags = FCF_NOBYTEALIGN | FCF_SCREENALIGN; ULONG nFrameStyle = 0; ULONG nClientStyle = WS_CLIPSIBLINGS; sal_Bool bSubFrame = FALSE; #if OSL_DEBUG_LEVEL>0 debug_printf(">ImplSalCreateFrame hWndParent 0x%x, nSalFrameStyle 0x%x\n", hWndParent, nSalFrameStyle); #endif if ( hWndParent ) { bSubFrame = TRUE; pFrame->mbNoIcon = TRUE; } // determine creation data (bei Moveable nehmen wir DLG-Border, damit // es besser aussieht) if ( nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE ) nFrameFlags |= FCF_CLOSEBUTTON; if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE ) { pFrame->mbCaption = TRUE; nFrameStyle = WS_ANIMATE; nFrameFlags |= FCF_SYSMENU | FCF_TITLEBAR | FCF_DLGBORDER; if ( !hWndParent ) nFrameFlags |= FCF_MINBUTTON; if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE ) { pFrame->mbSizeBorder = TRUE; nFrameFlags |= FCF_SIZEBORDER; if ( !hWndParent ) nFrameFlags |= FCF_MAXBUTTON; } else pFrame->mbFixBorder = TRUE; // add task list style if not a tool window if ( !(nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) { nFrameFlags |= FCF_TASKLIST; } } if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW ) { pFrame->mbNoIcon = TRUE; // YD gives small caption -> nExSysStyle |= WS_EX_TOOLWINDOW; } if ( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT ) { //nExSysStyle |= WS_EX_TOOLWINDOW; pFrame->mbFloatWin = TRUE; } //if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP ) // nExSysStyle |= WS_EX_TOPMOST; // init frame data pFrame->mnStyle = nSalFrameStyle; // determine show style pFrame->mnShowState = SWP_SHOWNORMAL; // create frame //YD FIXME this is a potential bug with multiple threads and cuncurrent //window creation, because this field is accessed in //WM_CREATE to get window data, pSalData->mpCreateFrame = pFrame; //YD FIXME if SAL_FRAME_CHILD is specified, use hWndParent as parent handle... hWndFrame = WinCreateStdWindow( HWND_DESKTOP, nFrameStyle, &nFrameFlags, (PSZ)(bSubFrame ? SAL_SUBFRAME_CLASSNAME : SAL_FRAME_CLASSNAME), NULL, nClientStyle, 0, 0, &hWndClient ); debug_printf("ImplSalCreateFrame hWndParent 0x%x, hWndFrame 0x%x, hWndClient 0x%x\n", hWndParent, hWndFrame, hWndClient); if ( !hWndFrame ) { delete pFrame; return NULL; } // Parent setzen (Owner) if ( hWndParent != 0 && hWndParent != HWND_DESKTOP ) WinSetOwner( hWndFrame, hWndParent ); Os2SalFrame* pParentFrame = GetWindowPtr( hWndParent ); if ( pParentFrame ) pFrame->mpParentFrame = pParentFrame; // since os2 windows always have a close button, always set icon WinSendMsg( hWndFrame, WM_SETICON, (MPARAM)pInst->mhAppIcon, (MPARAM)0 ); // If we have an Window with an Caption Bar and without // an MaximizeBox, we change the SystemMenu if ( (nFrameFlags & (FCF_TITLEBAR | FCF_MAXBUTTON)) == (FCF_TITLEBAR) ) { HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU ); if ( hSysMenu ) { if ( !(nFrameFlags & (FCF_MINBUTTON | FCF_MAXBUTTON)) ) WinEnableMenuItem(hSysMenu, SC_RESTORE, FALSE); if ( !(nFrameFlags & FCF_MINBUTTON) ) WinEnableMenuItem(hSysMenu, SC_MINIMIZE, FALSE); if ( !(nFrameFlags & FCF_MAXBUTTON) ) WinEnableMenuItem(hSysMenu, SC_MAXIMIZE, FALSE); if ( !(nFrameFlags & FCF_SIZEBORDER) ) WinEnableMenuItem(hSysMenu, SC_SIZE, FALSE); } } if ( (nFrameFlags & FCF_SYSMENU) && !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) ) { HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU ); if ( hSysMenu ) { WinEnableMenuItem(hSysMenu, SC_CLOSE, FALSE); } } // ticket#124 subclass frame window: we need to intercept TRACK message aSalShlData.mpFrameProc = WinSubclassWindow( hWndFrame, SalFrameSubClassWndProc); // init OS/2 frame data pFrame->mhAB = pInst->mhAB; // YD 18/08 under OS/2, invisible frames have size 0,0 at 0,0, so // we need to set an initial size/position manually SWP aSWP; memset( &aSWP, 0, sizeof( aSWP ) ); WinQueryTaskSizePos( pInst->mhAB, 0, &aSWP ); WinSetWindowPos( hWndFrame, NULL, aSWP.x, aSWP.y, aSWP.cx, aSWP.cy, SWP_MOVE | SWP_SIZE); #ifdef ENABLE_IME // Input-Context einstellen SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { pFrame->mhIMEContext = 0; if ( 0 != pIMEData->mpAssocIME( hWndClient, pFrame->mhIMEContext, &pFrame->mhDefIMEContext ) ) pFrame->mhDefIMEContext = 0; } else { pFrame->mhIMEContext = 0; pFrame->mhDefIMEContext = 0; } #endif RECTL rectl; _WinQueryWindowRect( hWndClient, &rectl ); pFrame->mnWidth = rectl.xRight; pFrame->mnHeight = rectl.yBottom; debug_printf( "ImplSalCreateFrame %dx%d\n", pFrame->mnWidth, pFrame->mnHeight); ImplSaveFrameState( pFrame ); pFrame->mbDefPos = TRUE; UpdateFrameGeometry( hWndFrame, pFrame ); if( pFrame->mnShowState == SWP_SHOWMAXIMIZED ) { // #96084 set a useful internal window size because // the window will not be maximized (and the size updated) before show() SetMaximizedFrameGeometry( hWndFrame, pFrame ); } #if OSL_DEBUG_LEVEL > 1 dumpWindowInfo( "mpFirstFrame; pSalData->mpFirstFrame = this; } // ----------------------------------------------------------------------- Os2SalFrame::~Os2SalFrame() { SalData* pSalData = GetSalData(); // destroy DC if ( mpGraphics ) { ImplSalDeInitGraphics( mpGraphics ); WinReleasePS( mpGraphics->mhPS ); delete mpGraphics; } // destroy system frame WinDestroyWindow( mhWndFrame ); // remove frame from framelist if ( this == pSalData->mpFirstFrame ) pSalData->mpFirstFrame = mpNextFrame; else { Os2SalFrame* pTempFrame = pSalData->mpFirstFrame; while ( pTempFrame->mpNextFrame != this ) pTempFrame = pTempFrame->mpNextFrame; pTempFrame->mpNextFrame = mpNextFrame; } } // ----------------------------------------------------------------------- static HDC ImplWinGetDC( HWND hWnd ) { HDC hDC = WinQueryWindowDC( hWnd ); if ( !hDC ) hDC = WinOpenWindowDC( hWnd ); return hDC; } // ----------------------------------------------------------------------- SalGraphics* Os2SalFrame::GetGraphics() { if ( mbGraphics ) return NULL; if ( !mpGraphics ) { SalData* pSalData = GetSalData(); mpGraphics = new Os2SalGraphics; mpGraphics->mhPS = WinGetPS( mhWndClient ); mpGraphics->mhDC = ImplWinGetDC( mhWndClient ); mpGraphics->mhWnd = mhWndClient; mpGraphics->mnHeight = mnHeight; mpGraphics->mbPrinter = FALSE; mpGraphics->mbVirDev = FALSE; mpGraphics->mbWindow = TRUE; mpGraphics->mbScreen = TRUE; ImplSalInitGraphics( mpGraphics ); mbGraphics = TRUE; } else mbGraphics = TRUE; return mpGraphics; } // ----------------------------------------------------------------------- void Os2SalFrame::ReleaseGraphics( SalGraphics* ) { mbGraphics = FALSE; } // ----------------------------------------------------------------------- sal_Bool Os2SalFrame::PostEvent( void* pData ) { return (sal_Bool)WinPostMsg( mhWndClient, SAL_MSG_USEREVENT, 0, (MPARAM)pData ); } // ----------------------------------------------------------------------- void Os2SalFrame::SetTitle( const XubString& rTitle ) { // set window title ByteString title( rTitle, gsl_getSystemTextEncoding() ); debug_printf("Os2SalFrame::SetTitle %x '%s'\n", mhWndFrame, title.GetBuffer() ); WinSetWindowText( mhWndFrame, title.GetBuffer() ); } // ----------------------------------------------------------------------- void Os2SalFrame::SetIcon( USHORT nIcon ) { debug_printf("Os2SalFrame::SetIcon\n"); // If we have a window without an Icon (for example a dialog), ignore this call if ( mbNoIcon ) return; // 0 means default (class) icon HPOINTER hIcon = NULL; if ( !nIcon ) nIcon = 1; ImplLoadSalIcon( nIcon, hIcon ); DBG_ASSERT( hIcon , "Os2SalFrame::SetIcon(): Could not load icon !" ); // Icon setzen WinSendMsg( mhWndFrame, WM_SETICON, (MPARAM)hIcon, (MPARAM)0 ); } // ----------------------------------------------------------------------- SalFrame* Os2SalFrame::GetParent() const { //debug_printf("Os2SalFrame::GetParent\n"); return GetWindowPtr( WinQueryWindow(mhWndFrame, QW_OWNER) ); } // ----------------------------------------------------------------------- static void ImplSalShow( HWND hWnd, ULONG bVisible, ULONG bNoActivate ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( !pFrame ) return; if ( bVisible ) { pFrame->mbDefPos = FALSE; pFrame->mbOverwriteState = TRUE; pFrame->mbInShow = TRUE; #if OSL_DEBUG_LEVEL > 0 debug_printf( "ImplSalShow hwnd %x visible flag %d, no activate: flag %d\n", hWnd, bVisible, bNoActivate); #endif if( bNoActivate ) WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_SHOW); else WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, pFrame->mnShowState); pFrame->mbInShow = FALSE; // Direct Paint only, if we get the SolarMutx if ( ImplSalYieldMutexTryToAcquire() ) { WinUpdateWindow( hWnd ); ImplSalYieldMutexRelease(); } } else { #if OSL_DEBUG_LEVEL > 0 debug_printf( "ImplSalShow hwnd %x HIDE\n"); #endif WinSetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_HIDE); } } // ----------------------------------------------------------------------- void Os2SalFrame::SetExtendedFrameStyle( SalExtStyle nExtStyle ) { } // ----------------------------------------------------------------------- void Os2SalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate ) { // Post this Message to the window, because this only works // in the thread of the window, which has create this window. // We post this message to avoid deadlocks if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) WinPostMsg( mhWndFrame, SAL_MSG_SHOW, (MPARAM)bVisible, (MPARAM)bNoActivate ); else ImplSalShow( mhWndFrame, bVisible, bNoActivate ); } // ----------------------------------------------------------------------- void Os2SalFrame::Enable( sal_Bool bEnable ) { WinEnableWindow( mhWndFrame, bEnable ); } // ----------------------------------------------------------------------- void Os2SalFrame::SetMinClientSize( long nWidth, long nHeight ) { debug_printf("Os2SalFrame::SetMinClientSize\n"); mnMinWidth = nWidth; mnMinHeight = nHeight; } void Os2SalFrame::SetMaxClientSize( long nWidth, long nHeight ) { debug_printf("Os2SalFrame::SetMaxClientSize\n"); mnMaxWidth = nWidth; mnMaxHeight = nHeight; } // ----------------------------------------------------------------------- void Os2SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, USHORT nFlags ) { // calculation frame size USHORT nEvent = 0; ULONG nPosFlags = 0; #if OSL_DEBUG_LEVEL > 0 //dumpWindowInfo( "-Os2SalFrame::SetPosSize", mhWndFrame); debug_printf( ">Os2SalFrame::SetPosSize go to %d,%d (%dx%d) VCL\n",nX,nY,nWidth,nHeight); #endif SWP aSWP; _WinQueryWindowPos( this, &aSWP ); sal_Bool bVisible = WinIsWindowVisible( mhWndFrame ); if ( !bVisible ) { if ( mbFloatWin ) mnShowState = SWP_SHOW; else mnShowState = SWP_SHOWNORMAL; } else { if ( (aSWP.fl & SWP_MINIMIZE) || (aSWP.fl & SWP_MAXIMIZE) ) WinSetWindowPos(mhWndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE ); } if ( (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) ) { nPosFlags |= SWP_MOVE; #if OSL_DEBUG_LEVEL > 0 debug_printf( "-Os2SalFrame::SetPosSize MOVE to %d,%d\n", nX, nY); #endif //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" ); nEvent = SALEVENT_MOVE; } if ( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) ) { nPosFlags |= SWP_SIZE; #if OSL_DEBUG_LEVEL > 0 debug_printf( "-Os2SalFrame::SetPosSize SIZE to %d,%d\n", nWidth,nHeight); #endif nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; } // Default-Position, dann zentrieren, ansonsten Position beibehalten if ( mbDefPos && !(nPosFlags & SWP_MOVE)) { // calculate bottom left corner of frame mbDefPos = FALSE; nPosFlags |= SWP_MOVE | SWP_CENTER; nEvent = SALEVENT_MOVERESIZE; #if OSL_DEBUG_LEVEL > 10 debug_printf( "-Os2SalFrame::SetPosSize CENTER\n"); debug_printf( "-Os2SalFrame::SetPosSize default position to %d,%d\n", nX, nY); #endif } // Adjust Window in the screen sal_Bool bCheckOffScreen = TRUE; // but don't do this for floaters or ownerdraw windows that are currently moved interactively if( (mnStyle & SAL_FRAME_STYLE_FLOAT) && !(mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) bCheckOffScreen = FALSE; if( mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) { // may be the window is currently being moved (mouse is captured), then no check is required if( mhWndClient == WinQueryCapture( HWND_DESKTOP) ) bCheckOffScreen = FALSE; else bCheckOffScreen = TRUE; } if( bCheckOffScreen ) { if ( nX+nWidth > nScreenWidth ) nX = nScreenWidth - nWidth; if ( nY+nHeight > nScreenHeight ) nY = nScreenHeight - nHeight; if ( nX < 0 ) nX = 0; if ( nY < 0 ) nY = 0; } // bring floating windows always to top // do not change zorder, otherwise tooltips will bring main window to top (ticket:14) //if( (mnStyle & SAL_FRAME_STYLE_FLOAT) ) // nPosFlags |= SWP_ZORDER; // do not change z-order // set new position _WinSetWindowPos( this, HWND_TOP, nX, nY, nWidth, nHeight, nPosFlags); // | SWP_RESTORE UpdateFrameGeometry( mhWndFrame, this ); // Notification -- really ??? if( nEvent ) CallCallback( nEvent, NULL ); #if OSL_DEBUG_LEVEL > 0 dumpWindowInfo( "0 debug_printf("Os2SalFrame::SetParent mhWndFrame 0x%08x to 0x%08x\n", static_cast(this)->mhWndFrame, static_cast(pNewParent)->mhWndClient); #endif Os2SalFrame::mbInReparent = TRUE; //rc = WinSetParent(static_cast(this)->mhWndFrame, // static_cast(pNewParent)->mhWndClient, TRUE); rc = WinSetOwner(static_cast(this)->mhWndFrame, static_cast(pNewParent)->mhWndClient); mpParentFrame = static_cast(pNewParent); Os2SalFrame::mbInReparent = FALSE; } bool Os2SalFrame::SetPluginParent( SystemParentData* pNewParent ) { APIRET rc; if ( pNewParent->hWnd == 0 ) { pNewParent->hWnd = HWND_DESKTOP; } Os2SalFrame::mbInReparent = TRUE; rc = WinSetOwner(static_cast(this)->mhWndFrame, pNewParent->hWnd); Os2SalFrame::mbInReparent = FALSE; return true; } // ----------------------------------------------------------------------- void Os2SalFrame::GetWorkArea( RECTL &rRect ) { rRect.xLeft = rRect.yTop = 0; rRect.xRight = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN )-1; rRect.yBottom = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN )-1; } // ----------------------------------------------------------------------- void Os2SalFrame::GetWorkArea( Rectangle &rRect ) { RECTL aRect; GetWorkArea( aRect); rRect.nLeft = aRect.xLeft; rRect.nRight = aRect.xRight; // win -1; rRect.nTop = aRect.yTop; rRect.nBottom = aRect.yBottom; // win -1; } // ----------------------------------------------------------------------- void Os2SalFrame::GetClientSize( long& rWidth, long& rHeight ) { rWidth = maGeometry.nWidth; rHeight = maGeometry.nHeight; } // ----------------------------------------------------------------------- void Os2SalFrame::SetWindowState( const SalFrameState* pState ) { LONG nX; LONG nY; LONG nWidth; LONG nHeight; ULONG nPosSize = 0; #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::SetWindowState\n"); debug_printf("Os2SalFrame::SetWindowState %08x (%dx%d) at %d,%d VCL\n", mhWndFrame, pState->mnWidth,pState->mnHeight,pState->mnX,pState->mnY); #endif sal_Bool bVisible = WinIsWindowVisible( mhWndFrame ); // get screen coordinates SWP aSWP; WinQueryWindowPos( mhWndFrame, &aSWP ); LONG nFrameX, nFrameY, nCaptionY; ImplSalCalcFrameSize( this, nFrameX, nFrameY, nCaptionY ); long nTopDeco = nFrameY + nCaptionY; long nLeftDeco = nFrameX; long nBottomDeco = nFrameY; long nRightDeco = nFrameX; // Fenster-Position/Groesse in den Bildschirm einpassen if ((pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y)) ) nPosSize |= SWP_MOVE; if ((pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)) ) nPosSize |= SWP_SIZE; if ( pState->mnMask & SAL_FRAMESTATE_MASK_X ) nX = (int)pState->mnX - nLeftDeco; else nX = aSWP.x; // keep Y inverted since height is still unknown, will invert later if ( pState->mnMask & SAL_FRAMESTATE_MASK_Y ) nY = (int)pState->mnY - nTopDeco; else nY = nScreenHeight - (aSWP.y+aSWP.cy); if ( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH ) nWidth = (int)pState->mnWidth + nLeftDeco + nRightDeco; else nWidth = aSWP.cx; if ( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT ) nHeight = (int)pState->mnHeight + nTopDeco + nBottomDeco; else nHeight = aSWP.cy; #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::SetWindowState (%dx%d) at %d,%d\n", nWidth,nHeight,nX,nY); #endif // Adjust Window in the screen: // if it does not fit into the screen do nothing, ie default pos/size will be used // if there is an overlap with the screen border move the window while keeping its size //if( nWidth > nScreenWidth || nHeight > nScreenHeight ) // nPosSize |= (SWP_NOMOVE | SWP_NOSIZE); if ( nX+nWidth > nScreenWidth ) nX = (nScreenWidth) - nWidth; if ( nY+nHeight > nScreenHeight ) nY = (nScreenHeight) - nHeight; if ( nX < 0 ) nX = 0; if ( nY < 0 ) nY = 0; // Restore-Position setzen SWP aPlacement; WinQueryWindowPos( mhWndFrame, &aPlacement ); // Status setzen bVisible = WinIsWindowVisible( mhWndFrame); sal_Bool bUpdateHiddenFramePos = FALSE; if ( !bVisible ) { aPlacement.fl = SWP_HIDE; if ( mbOverwriteState ) { if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) { if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) mnShowState = SWP_SHOWMINIMIZED; else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) { mnShowState = SWP_SHOWMAXIMIZED; bUpdateHiddenFramePos = TRUE; } else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) mnShowState = SWP_SHOWNORMAL; } } } else { if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) { if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) { //if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) // aPlacement.flags |= WPF_RESTORETOMAXIMIZED; aPlacement.fl = SWP_SHOWMINIMIZED; } else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) aPlacement.fl = SWP_SHOWMAXIMIZED; else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) aPlacement.fl = SWP_RESTORE; } } // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch // umgesetzt werden muss, dann SetWindowPos() benutzen, da // SetWindowPlacement() die TaskBar mit einrechnet if ( !(aPlacement.fl & SWP_MINIMIZE) && !( aPlacement.fl & SWP_MAXIMIZE ) && (!bVisible || (aPlacement.fl == SWP_RESTORE)) ) { if( bUpdateHiddenFramePos ) { // #96084 set a useful internal window size because // the window will not be maximized (and the size updated) before show() SetMaximizedFrameGeometry( mhWndFrame, this ); } else WinSetWindowPos( mhWndFrame, 0, nX, nScreenHeight - (nY+nHeight), nWidth, nHeight, nPosSize); } else { if( (nPosSize & (SWP_MOVE|SWP_SIZE)) ) { aPlacement.x = nX; aPlacement.y = nScreenHeight-(nY+nHeight); aPlacement.cx = nWidth; aPlacement.cy = nHeight; } WinSetWindowPos( mhWndFrame, 0, aPlacement.x, aPlacement.y, aPlacement.cx, aPlacement.cy, aPlacement.fl ); } #if OSL_DEBUG_LEVEL>0 debug_printf("Os2SalFrame::SetWindowState DONE\n"); #endif } // ----------------------------------------------------------------------- sal_Bool Os2SalFrame::GetWindowState( SalFrameState* pState ) { if ( maState.mnWidth && maState.mnHeight ) { *pState = maState; // #94144# allow Minimize again, should be masked out when read from configuration // 91625 - Don't save minimize //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) ) if ( !(pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) ) pState->mnState |= SAL_FRAMESTATE_NORMAL; return TRUE; } return FALSE; } // ----------------------------------------------------------------------- void Os2SalFrame::SetScreenNumber( unsigned int nNewScreen ) { #if 0 WinSalSystem* pSys = static_cast(ImplGetSalSystem()); if( pSys ) { const std::vector& rMonitors = pSys->getMonitors(); size_t nMon = rMonitors.size(); if( nNewScreen < nMon ) { Point aOldMonPos, aNewMonPos( rMonitors[nNewScreen].m_aArea.TopLeft() ); Point aCurPos( maGeometry.nX, maGeometry.nY ); for( size_t i = 0; i < nMon; i++ ) { if( rMonitors[i].m_aArea.IsInside( aCurPos ) ) { aOldMonPos = rMonitors[i].m_aArea.TopLeft(); break; } } mnDisplay = nNewScreen; maGeometry.nScreenNumber = nNewScreen; SetPosSize( aNewMonPos.X() + (maGeometry.nX - aOldMonPos.X()), aNewMonPos.Y() + (maGeometry.nY - aOldMonPos.Y()), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); } } #endif } // ----------------------------------------------------------------------- // native menu implementation - currently empty void Os2SalFrame::DrawMenuBar() { } void Os2SalFrame::SetMenu( SalMenu* pSalMenu ) { } // ----------------------------------------------------------------------- void Os2SalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay ) { if ( mbFullScreen == bFullScreen ) return; mbFullScreen = bFullScreen; if ( bFullScreen ) { // save old position memset( &maFullScreenRect, 0, sizeof( SWP ) ); _WinQueryWindowPos( this, &maFullScreenRect ); // set window to screen size ImplSalFrameFullScreenPos( this, TRUE ); } else { _WinSetWindowPos( this, 0, maFullScreenRect.x, maFullScreenRect.y, maFullScreenRect.cx, maFullScreenRect.cy, SWP_MOVE | SWP_SIZE ); } } // ----------------------------------------------------------------------- void Os2SalFrame::StartPresentation( sal_Bool bStart ) { // SysSetObjectData("","Autolockup=no"); oder OS2.INI: PM_Lockup } // ----------------------------------------------------------------------- void Os2SalFrame::SetAlwaysOnTop( sal_Bool bOnTop ) { mbAllwayOnTop = bOnTop; #if 0 HWND hWnd; if ( bOnTop ) hWnd = HWND_TOPMOST; else hWnd = HWND_NOTOPMOST; SetWindowPos( mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); #endif } // ----------------------------------------------------------------------- static void ImplSalToTop( HWND hWnd, ULONG nFlags ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); #if OSL_DEBUG_LEVEL>0 debug_printf("ImplSalToTop hWnd %08x, nFlags %x\n", hWnd, nFlags); #endif // if window is minimized, first restore it SWP aSWP; WinQueryWindowPos( hWnd, &aSWP ); if ( aSWP.fl & SWP_MINIMIZE ) WinSetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_RESTORE ); if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK ) WinSetWindowPos( pFrame->mhWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER); if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) { ULONG nStyle; if ( pFrame->mbRestoreMaximize ) nStyle = SWP_MAXIMIZE; else nStyle = SWP_RESTORE; WinSetWindowPos( pFrame->mhWndFrame, NULL, 0, 0, 0, 0, nStyle ); } WinSetFocus( HWND_DESKTOP, pFrame->mhWndClient ); } // ----------------------------------------------------------------------- void Os2SalFrame::ToTop( USHORT nFlags ) { nFlags &= ~SAL_FRAME_TOTOP_GRABFOCUS; // this flag is not needed on win32 // Post this Message to the window, because this only works // in the thread of the window, which has create this window. // We post this message to avoid deadlocks if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) WinPostMsg( mhWndFrame, SAL_MSG_TOTOP, (MPARAM)nFlags, 0 ); else ImplSalToTop( mhWndFrame, nFlags ); } // ----------------------------------------------------------------------- void Os2SalFrame::SetPointer( PointerStyle ePointerStyle ) { struct ImplPtrData { HPOINTER mhPointer; ULONG mnSysId; ULONG mnOwnId; }; static ImplPtrData aImplPtrTab[POINTER_COUNT] = { { 0, SPTR_ARROW, 0 }, // POINTER_ARROW { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL { 0, SPTR_WAIT, 0 }, // POINTER_WAIT { 0, SPTR_TEXT, 0 }, // POINTER_BEAM { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE { 0, SPTR_SIZENS, 0 }, // POINTER_NSIZE { 0, SPTR_SIZENS, 0 }, // POINTER_SSIZE { 0, SPTR_SIZEWE, 0 }, // POINTER_WSIZE { 0, SPTR_SIZEWE, 0 }, // POINTER_ESIZE { 0, SPTR_SIZENWSE, 0 }, // POINTER_NWSIZE { 0, SPTR_SIZENESW, 0 }, // POINTER_NESIZE { 0, SPTR_SIZENESW, 0 }, // POINTER_SWSIZE { 0, SPTR_SIZENWSE, 0 }, // POINTER_SESIZE { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_NSIZE { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_SSIZE { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES { 0, SPTR_ILLEGAL, 0 }, // POINTER_NOTALLOWED { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE }, // POINTER_AUTOSCROLL_NSWE { 0, 0, SAL_RESID_POINTER_AIRBRUSH }, // POINTER_AIRBRUSH { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL }, // POINTER_TEXT_VERTICAL { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE }, // POINTER_PIVOT_DELETE // --> FME 2004-07-30 #i32329# Enhanced table selection { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S }, // POINTER_TAB_SELECT_S { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E }, // POINTER_TAB_SELECT_E { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE }, // POINTER_TAB_SELECT_SE { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W }, // POINTER_TAB_SELECT_W { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW }, // POINTER_TAB_SELECT_SW // <-- // --> FME 2004-08-16 #i20119# Paintbrush tool { 0, 0, SAL_RESID_POINTER_PAINTBRUSH } // POINTER_PAINTBRUSH // <-- }; #if POINTER_COUNT != 94 #error New Pointer must be defined! #endif //debug_printf("Os2SalFrame::SetPointer\n"); // Mousepointer loaded ? if ( !aImplPtrTab[ePointerStyle].mhPointer ) { if ( aImplPtrTab[ePointerStyle].mnOwnId ) aImplPtrTab[ePointerStyle].mhPointer = ImplLoadSalCursor( (ULONG)aImplPtrTab[ePointerStyle].mnOwnId ); else aImplPtrTab[ePointerStyle].mhPointer = WinQuerySysPointer( HWND_DESKTOP, aImplPtrTab[ePointerStyle].mnSysId, FALSE ); } if (aImplPtrTab[ePointerStyle].mhPointer == 0) { debug_printf( "SetPointer ePointerStyle %d unknown\n", ePointerStyle); aImplPtrTab[ePointerStyle].mhPointer = SPTR_ICONERROR; } // Unterscheidet sich der Mauspointer, dann den neuen setzen if ( mhPointer != aImplPtrTab[ePointerStyle].mhPointer ) { mhPointer = aImplPtrTab[ePointerStyle].mhPointer; WinSetPointer( HWND_DESKTOP, mhPointer ); } } // ----------------------------------------------------------------------- void Os2SalFrame::CaptureMouse( sal_Bool bCapture ) { #if OSL_DEBUG_LEVEL>10 _bCapture=bCapture; debug_printf("Os2SalFrame::CaptureMouse bCapture %d\n", bCapture); #endif if ( bCapture ) WinSetCapture( HWND_DESKTOP, mhWndClient ); else WinSetCapture( HWND_DESKTOP, 0 ); } // ----------------------------------------------------------------------- void Os2SalFrame::SetPointerPos( long nX, long nY ) { POINTL aPt; aPt.x = nX; aPt.y = mnHeight - nY - 1; // convert sal coords to sys WinMapWindowPoints( mhWndClient, HWND_DESKTOP, &aPt, 1 ); WinSetPointerPos( HWND_DESKTOP, aPt.x, aPt.y ); } // ----------------------------------------------------------------------- void Os2SalFrame::Flush() { } // ----------------------------------------------------------------------- void Os2SalFrame::Sync() { } // ----------------------------------------------------------------------- void Os2SalFrame::SetInputContext( SalInputContext* pContext ) { #ifdef ENABLE_IME SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { HWND hWnd = mhWndClient; HIMI hIMI = 0; pIMEData->mpGetIME( hWnd, &hIMI ); if ( hIMI ) { ULONG nInputMode; ULONG nConversionMode; if ( 0 == pIMEData->mpQueryIMEMode( hIMI, &nInputMode, &nConversionMode ) ) { if ( pContext->mnOptions & SAL_INPUTCONTEXT_TEXT ) { nInputMode &= ~IMI_IM_IME_DISABLE; if ( pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT_OFF ) nInputMode &= ~IMI_IM_IME_ON; // !!! Da derzeit ueber das OS2-IME-UI der IME-Mode nicht einschaltbar ist !!! // if ( SAL_INPUTCONTEXT_EXTTEXTINPUT_ON ) nInputMode |= IMI_IM_IME_ON; } else nInputMode |= IMI_IM_IME_DISABLE; pIMEData->mpSetIMEMode( hIMI, nInputMode, nConversionMode ); } pIMEData->mpReleaseIME( hWnd, hIMI ); } } #endif } // ----------------------------------------------------------------------- #if 0 void Os2SalFrame::UpdateExtTextInputArea() { #ifdef ENABLE_IME #endif } #endif // ----------------------------------------------------------------------- void Os2SalFrame::EndExtTextInput( USHORT nFlags ) { #ifdef ENABLE_IME SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { HWND hWnd = mhWndClient; HIMI hIMI = 0; pIMEData->mpGetIME( hWnd, &hIMI ); if ( hIMI ) { ULONG nIndex; if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE ) nIndex = CNV_COMPLETE; else nIndex = CNV_CANCEL; pIMEData->mpRequestIME( hIMI, REQ_CONVERSIONSTRING, nIndex, 0 ); pIMEData->mpReleaseIME( hWnd, hIMI ); } } #endif } // ----------------------------------------------------------------------- XubString Os2SalFrame::GetKeyName( USHORT nCode ) { if ( eImplKeyboardLanguage == LANGUAGE_DONTKNOW ) eImplKeyboardLanguage = MsLangId::getSystemLanguage(); XubString aKeyCode; XubString aCode; const sal_Unicode** pLangTab = ImplGetLangTab( eImplKeyboardLanguage ); if ( nCode & KEY_SHIFT ) aKeyCode = pLangTab[LSTR_KEY_SHIFT]; if ( nCode & KEY_MOD1 ) { if ( aKeyCode.Len() == 0 ) aKeyCode = pLangTab[LSTR_KEY_CTRL]; else { aKeyCode += '+'; aKeyCode += pLangTab[LSTR_KEY_CTRL]; } } if ( nCode & KEY_MOD2 ) { if ( aKeyCode.Len() == 0 ) aKeyCode = pLangTab[LSTR_KEY_ALT]; else { aKeyCode += '+'; aKeyCode += pLangTab[LSTR_KEY_ALT]; } } USHORT nKeyCode = nCode & 0x0FFF; if ( (nKeyCode >= KEY_0) && (nKeyCode <= KEY_9) ) aCode = sal::static_int_cast('0' + (nKeyCode - KEY_0)); else if ( (nKeyCode >= KEY_A) && (nKeyCode <= KEY_Z) ) aCode = sal::static_int_cast('A' + (nKeyCode - KEY_A)); else if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F26) ) { aCode += 'F'; if ( (nKeyCode >= KEY_F1) && (nKeyCode <= KEY_F9) ) { aCode += sal::static_int_cast('1' + (nKeyCode - KEY_F1)); } else if ( (nKeyCode >= KEY_F10) && (nKeyCode <= KEY_F19) ) { aCode += '1'; aCode += sal::static_int_cast('0' + (nKeyCode - KEY_F10)); } else { aCode += '2'; aCode += sal::static_int_cast('0' + (nKeyCode - KEY_F20)); } } else { switch ( nKeyCode ) { case KEY_DOWN: aCode = pLangTab[LSTR_KEY_DOWN]; break; case KEY_UP: aCode = pLangTab[LSTR_KEY_UP]; break; case KEY_LEFT: aCode = pLangTab[LSTR_KEY_LEFT]; break; case KEY_RIGHT: aCode = pLangTab[LSTR_KEY_RIGHT]; break; case KEY_HOME: aCode = pLangTab[LSTR_KEY_HOME]; break; case KEY_END: aCode = pLangTab[LSTR_KEY_END]; break; case KEY_PAGEUP: aCode = pLangTab[LSTR_KEY_PAGEUP]; break; case KEY_PAGEDOWN: aCode = pLangTab[LSTR_KEY_PAGEDOWN]; break; case KEY_RETURN: aCode = pLangTab[LSTR_KEY_RETURN]; break; case KEY_ESCAPE: aCode = pLangTab[LSTR_KEY_ESC]; break; case KEY_TAB: aCode = pLangTab[LSTR_KEY_TAB]; break; case KEY_BACKSPACE: aCode = pLangTab[LSTR_KEY_BACKSPACE]; break; case KEY_SPACE: aCode = pLangTab[LSTR_KEY_SPACE]; break; case KEY_INSERT: aCode = pLangTab[LSTR_KEY_INSERT]; break; case KEY_DELETE: aCode = pLangTab[LSTR_KEY_DELETE]; break; case KEY_ADD: aCode += '+'; break; case KEY_SUBTRACT: aCode += '-'; break; case KEY_MULTIPLY: aCode += '*'; break; case KEY_DIVIDE: aCode += '/'; break; case KEY_POINT: aCode += '.'; break; case KEY_COMMA: aCode += ','; break; case KEY_LESS: aCode += '<'; break; case KEY_GREATER: aCode += '>'; break; case KEY_EQUAL: aCode += '='; break; } } if ( aCode.Len() ) { if ( aKeyCode.Len() == 0 ) aKeyCode = aCode; else { aKeyCode += '+'; aKeyCode += aCode; } } return aKeyCode; } // ----------------------------------------------------------------------- XubString Os2SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode ) { return GetKeyName( nKeyCode ); } // ----------------------------------------------------------------------- inline long ImplOS2ColorToSal( long nOS2Color ) { return MAKE_SALCOLOR( (PM_BYTE)( nOS2Color>>16), (PM_BYTE)(nOS2Color>>8), (PM_BYTE)nOS2Color ); } // ----------------------------------------------------------------------- static USHORT ImplMouseSysValueToSAL( int iSysValue, USHORT& rCode, USHORT& rClicks, sal_Bool& rDown ) { LONG lValue = WinQuerySysValue( HWND_DESKTOP, iSysValue ); rCode = 0; rClicks = 1; rDown = TRUE; switch ( lValue & 0xFFFF ) { case WM_BUTTON1UP: case WM_BUTTON1CLICK: rCode = MOUSE_LEFT; rDown = FALSE; break; case WM_BUTTON1DOWN: case WM_BUTTON1MOTIONSTART: rCode = MOUSE_LEFT; break; case WM_BUTTON1DBLCLK: rCode = MOUSE_LEFT; rClicks = 2; break; case WM_BUTTON2UP: case WM_BUTTON2CLICK: rCode = MOUSE_RIGHT; rDown = FALSE; break; case WM_BUTTON2DOWN: case WM_BUTTON2MOTIONSTART: rCode = MOUSE_RIGHT; break; case WM_BUTTON2DBLCLK: rCode = MOUSE_RIGHT; rClicks = 2; break; case WM_BUTTON3UP: case WM_BUTTON3CLICK: rCode = MOUSE_MIDDLE; rDown = FALSE; break; case WM_BUTTON3DOWN: case WM_BUTTON3MOTIONSTART: rCode = MOUSE_MIDDLE; break; case WM_BUTTON3DBLCLK: rCode = MOUSE_MIDDLE; rClicks = 2; break; } if ( !rCode ) return FALSE; lValue = (lValue & 0xFFFF0000) >> 16; if ( lValue != 0xFFFF ) { if ( lValue & KC_SHIFT ) rCode |= KEY_SHIFT; if ( lValue & KC_CTRL ) rCode |= KEY_MOD1; if ( lValue & KC_ALT ) rCode |= KEY_MOD2; } return TRUE; } // ----------------------------------------------------------------------- static sal_Bool ImplSalIsSameColor( const Color& rColor1, const Color& rColor2 ) { ULONG nWrong = 0; nWrong += Abs( (short)rColor1.GetRed()-(short)rColor2.GetRed() ); nWrong += Abs( (short)rColor1.GetGreen()-(short)rColor2.GetGreen() ); nWrong += Abs( (short)rColor1.GetBlue()-(short)rColor2.GetBlue() ); return (nWrong < 30); } // ----------------------------------------------------------------------- static sal_Bool ImplOS2NameFontToVCLFont( const char* pFontName, Font& rFont ) { char aNumBuf[10]; int nNumBufLen = 0; while ( *pFontName && (*pFontName != '.') && (nNumBufLen < sizeof(aNumBuf)-1) ) { aNumBuf[nNumBufLen] = *pFontName; nNumBufLen++; pFontName++; } aNumBuf[nNumBufLen] = '\0'; pFontName++; while ( *pFontName == ' ' ) pFontName++; int nFontHeight = atoi( aNumBuf ); int nFontNameLen = strlen( pFontName ); if ( nFontHeight && nFontNameLen ) { rFont.SetFamily( FAMILY_DONTKNOW ); rFont.SetWeight( WEIGHT_NORMAL ); rFont.SetItalic( ITALIC_NONE ); // search for a style embedded in the name, e.g. 'WarpSans Bold' // because we need to split the style from the family name if (strstr( pFontName, " Bold") || strstr( pFontName, " Italic") || strstr( pFontName, "-Normal")) { char* fontName = strdup( pFontName); char* style = strstr( fontName, " Bold"); if (style) rFont.SetWeight( WEIGHT_BOLD ); if (!style) style = strstr( fontName, " Italic"); if (style) rFont.SetItalic( ITALIC_NORMAL ); if (!style) style = strstr( fontName, "-Normal"); // store style, skip whitespace char rFont.SetStyleName( ::rtl::OStringToOUString ( style+1, gsl_getSystemTextEncoding()) ); // truncate name *style = 0; // store family name rFont.SetName( ::rtl::OStringToOUString ( fontName, gsl_getSystemTextEncoding()) ); free( fontName); } else { rFont.SetName( ::rtl::OStringToOUString (pFontName, gsl_getSystemTextEncoding()) ); rFont.SetStyleName( ::rtl::OStringToOUString ("", gsl_getSystemTextEncoding()) ); } rFont.SetSize( Size( 0, nFontHeight ) ); return TRUE; } else return FALSE; } // ----------------------------------------------------------------------- void Os2SalFrame::UpdateSettings( AllSettings& rSettings ) { static char aControlPanel[] = "PM_ControlPanel"; static char aSystemFonts[] = "PM_SystemFonts"; char aDummyStr[] = ""; // --- Mouse setting --- USHORT nCode; USHORT nClicks; sal_Bool bDown; MouseSettings aMouseSettings = rSettings.GetMouseSettings(); aMouseSettings.SetDoubleClickTime( WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) ); if ( ImplMouseSysValueToSAL( SV_BEGINDRAG, nCode, nClicks, bDown ) ) aMouseSettings.SetStartDragCode( nCode ); if ( ImplMouseSysValueToSAL( SV_CONTEXTMENU, nCode, nClicks, bDown ) ) { aMouseSettings.SetContextMenuCode( nCode ); aMouseSettings.SetContextMenuClicks( nClicks ); aMouseSettings.SetContextMenuDown( bDown ); } aMouseSettings.SetButtonStartRepeat( WinQuerySysValue( HWND_DESKTOP, SV_FIRSTSCROLLRATE ) ); aMouseSettings.SetButtonRepeat( WinQuerySysValue( HWND_DESKTOP, SV_SCROLLRATE ) ); rSettings.SetMouseSettings( aMouseSettings ); // --- Style settings --- StyleSettings aStyleSettings = rSettings.GetStyleSettings(); // General settings LONG nDisplayTime = PrfQueryProfileInt( HINI_PROFILE, (PSZ)aControlPanel, (PSZ)"LogoDisplayTime", -1 ); ULONG nSalDisplayTime; if ( nDisplayTime < 0 ) nSalDisplayTime = LOGO_DISPLAYTIME_STARTTIME; else if ( !nDisplayTime ) nSalDisplayTime = LOGO_DISPLAYTIME_NOLOGO; else nSalDisplayTime = (ULONG)nDisplayTime; aStyleSettings.SetLogoDisplayTime( nSalDisplayTime ); aStyleSettings.SetCursorBlinkTime( WinQuerySysValue( HWND_DESKTOP, SV_CURSORRATE ) ); ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions(); if ( WinQuerySysValue( HWND_DESKTOP, SV_DYNAMICDRAG ) ) nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT; else nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT); aStyleSettings.SetDragFullOptions( nDragFullOptions ); // Size settings aStyleSettings.SetScrollBarSize( WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL ) ); aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) ); // Color settings aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) ); aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) ); aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) ); aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) ); aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) ); aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) ); aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) ); aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) ); aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) ); aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) ); aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) ); aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); aStyleSettings.SetMenuBarTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() ); aStyleSettings.SetRadioCheckTextColor( aStyleSettings.GetButtonTextColor() ); aStyleSettings.SetGroupTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0 ) ) ); aStyleSettings.SetLabelTextColor( aStyleSettings.GetGroupTextColor() ); aStyleSettings.SetInfoTextColor( aStyleSettings.GetGroupTextColor() ); aStyleSettings.SetWindowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOW, 0 ) ) ); aStyleSettings.SetActiveTabColor( aStyleSettings.GetWindowColor() ); aStyleSettings.SetWindowTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWTEXT, 0 ) ) ); aStyleSettings.SetFieldColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ENTRYFIELD, 0 ) ) ); aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() ); aStyleSettings.SetDisableColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUDISABLEDTEXT, 0 ) ) ); aStyleSettings.SetHighlightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEBACKGROUND, 0 ) ) ); aStyleSettings.SetHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEFOREGROUND, 0 ) ) ); Color aMenuHighColor = ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0 ) ); if ( ImplSalIsSameColor( aMenuHighColor, aStyleSettings.GetMenuColor() ) ) { aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) ); aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) ); } else { aStyleSettings.SetMenuHighlightColor( aMenuHighColor ); aStyleSettings.SetMenuHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITE, 0 ) ) ); } // Checked-Color berechnen Color aColor1 = aStyleSettings.GetFaceColor(); Color aColor2 = aStyleSettings.GetLightColor(); PM_BYTE nRed = (PM_BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2); PM_BYTE nGreen = (PM_BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2); PM_BYTE nBlue = (PM_BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2); aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) ); // Fonts updaten Font aFont; char aFontNameBuf[255]; aFont = aStyleSettings.GetMenuFont(); if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"Menus", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) { if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) { #if 0 // Add Workplace Sans if not already listed if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) { XubString aFontName = aFont.GetName(); aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); aFont.SetName( aFontName ); aFont.SetSize( Size( 0, 9 ) ); } #endif aStyleSettings.SetMenuFont( aFont ); } } aFont = aStyleSettings.GetIconFont(); if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"IconText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) { if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) aStyleSettings.SetIconFont( aFont ); } aFont = aStyleSettings.GetTitleFont(); if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowTitles", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) { if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) { // Add Workplace Sans if not already listed if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) { XubString aFontName = aFont.GetName(); aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); aFont.SetName( aFontName ); aFont.SetSize( Size( 0, 9 ) ); aFont.SetWeight( WEIGHT_BOLD ); aFont.SetItalic( ITALIC_NONE ); } aStyleSettings.SetTitleFont( aFont ); aStyleSettings.SetFloatTitleFont( aFont ); } } aFont = aStyleSettings.GetAppFont(); if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 ) { if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) ) { Font aHelpFont = aFont; aHelpFont.SetName( (sal_Unicode*)L"Helv;WarpSans" ); aHelpFont.SetSize( Size( 0, 8 ) ); aHelpFont.SetWeight( WEIGHT_NORMAL ); aHelpFont.SetItalic( ITALIC_NONE ); aStyleSettings.SetHelpFont( aHelpFont ); // Add Workplace Sans if not already listed if ( aFont.GetName().Search( (sal_Unicode*)L"WorkPlace Sans" ) == STRING_NOTFOUND ) { XubString aFontName = aFont.GetName(); aFontName.Insert( (sal_Unicode*)L"WorkPlace Sans;", 0 ); aFont.SetName( aFontName ); aFont.SetSize( Size( 0, 9 ) ); } aStyleSettings.SetAppFont( aFont ); aStyleSettings.SetToolFont( aFont ); aStyleSettings.SetLabelFont( aFont ); aStyleSettings.SetInfoFont( aFont ); aStyleSettings.SetRadioCheckFont( aFont ); aStyleSettings.SetPushButtonFont( aFont ); aStyleSettings.SetFieldFont( aFont ); aStyleSettings.SetGroupFont( aFont ); } } rSettings.SetStyleSettings( aStyleSettings ); } // ----------------------------------------------------------------------- SalBitmap* Os2SalFrame::SnapShot() { debug_printf("Os2SalFrame::SnapShot\n"); return NULL; } // ----------------------------------------------------------------------- const SystemEnvData* Os2SalFrame::GetSystemData() const { return &maSysData; } // ----------------------------------------------------------------------- void Os2SalFrame::Beep( SoundType eSoundType ) { static ULONG aImplSoundTab[5] = { WA_NOTE, // SOUND_DEFAULT WA_NOTE, // SOUND_INFO WA_WARNING, // SOUND_WARNING WA_ERROR, // SOUND_ERROR WA_NOTE // SOUND_QUERY }; #if 0 #if SOUND_COUNT != 5 #error New Sound must be defined! #endif #endif debug_printf("Os2SalFrame::Beep %d\n", eSoundType); WinAlarm( HWND_DESKTOP, aImplSoundTab[eSoundType] ); } // ----------------------------------------------------------------------- SalFrame::SalPointerState Os2SalFrame::GetPointerState() { SalPointerState aState; aState.mnState = 0; // MausModus feststellen und setzen if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 ) aState.mnState |= MOUSE_LEFT; if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 ) aState.mnState |= MOUSE_RIGHT; if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 ) aState.mnState |= MOUSE_MIDDLE; // Modifier-Tasten setzen if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) aState.mnState |= KEY_SHIFT; if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) aState.mnState |= KEY_MOD1; if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) aState.mnState |= KEY_MOD2; POINTL pt; _WinQueryPointerPos( HWND_DESKTOP, &pt ); aState.maPos = Point( pt.x - maGeometry.nX, pt.y - maGeometry.nY ); return aState; } // ----------------------------------------------------------------------- void Os2SalFrame::SetBackgroundBitmap( SalBitmap* ) { } // ----------------------------------------------------------------------- void SalTestMouseLeave() { SalData* pSalData = GetSalData(); if ( pSalData->mhWantLeaveMsg && !::WinQueryCapture( HWND_DESKTOP ) ) { POINTL aPt; WinQueryPointerPos( HWND_DESKTOP, &aPt ); if ( pSalData->mhWantLeaveMsg != WinWindowFromPoint( HWND_DESKTOP, &aPt, TRUE ) ) WinSendMsg( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MPFROM2SHORT( aPt.x, aPt.y ) ); } } // ----------------------------------------------------------------------- static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) { SalMouseEvent aMouseEvt; long nRet; USHORT nEvent; sal_Bool bCall = TRUE; USHORT nFlags = SHORT2FROMMP( nMP2 ); Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( !pFrame ) return 0; aMouseEvt.mnX = (short)SHORT1FROMMP( nMP1 ); aMouseEvt.mnY = pFrame->mnHeight - (short)SHORT2FROMMP( nMP1 ) - 1; aMouseEvt.mnCode = 0; aMouseEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); // MausModus feststellen und setzen if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 ) aMouseEvt.mnCode |= MOUSE_LEFT; if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 ) aMouseEvt.mnCode |= MOUSE_RIGHT; if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 ) aMouseEvt.mnCode |= MOUSE_MIDDLE; // Modifier-Tasten setzen if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) aMouseEvt.mnCode |= KEY_SHIFT; if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) aMouseEvt.mnCode |= KEY_MOD1; if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) aMouseEvt.mnCode |= KEY_MOD2; switch ( nMsg ) { case WM_MOUSEMOVE: { SalData* pSalData = GetSalData(); // Da bei Druecken von Modifier-Tasten die MouseEvents // nicht zusammengefast werden (da diese durch KeyEvents // unterbrochen werden), machen wir dieses hier selber if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) ) { QMSG aTempMsg; if ( WinPeekMsg( pSalData->mhAB, &aTempMsg, pFrame->mhWndClient, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) ) { if ( (aTempMsg.msg == WM_MOUSEMOVE) && (aTempMsg.mp2 == nMP2) ) return 1; } } // Test for MouseLeave if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != pFrame->mhWndClient) ) { POINTL aMousePoint; WinQueryMsgPos( pFrame->mhAB, &aMousePoint ); WinSendMsg( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MPFROM2SHORT( aMousePoint.x, aMousePoint.y ) ); } pSalData->mhWantLeaveMsg = pFrame->mhWndClient; // Start MouseLeave-Timer if ( !pSalData->mpMouseLeaveTimer ) { pSalData->mpMouseLeaveTimer = new AutoTimer; pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT ); pSalData->mpMouseLeaveTimer->Start(); // We dont need to set a timeout handler, because we test // for mouseleave in the timeout callback } aMouseEvt.mnButton = 0; nEvent = SALEVENT_MOUSEMOVE; } break; case SAL_MSG_MOUSELEAVE: { SalData* pSalData = GetSalData(); if ( pSalData->mhWantLeaveMsg == pFrame->mhWndClient ) { pSalData->mhWantLeaveMsg = 0; if ( pSalData->mpMouseLeaveTimer ) { delete pSalData->mpMouseLeaveTimer; pSalData->mpMouseLeaveTimer = NULL; } // Mouse-Coordinaates are relativ to the screen POINTL aPt; aPt.x = (short)SHORT1FROMMP( nMP2 ); aPt.y = (short)SHORT2FROMMP( nMP2 ); WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 ); aPt.y = pFrame->mnHeight - aPt.y - 1; aMouseEvt.mnX = aPt.x; aMouseEvt.mnY = aPt.y; aMouseEvt.mnButton = 0; nEvent = SALEVENT_MOUSELEAVE; } else bCall = FALSE; } break; case WM_BUTTON1DBLCLK: case WM_BUTTON1DOWN: aMouseEvt.mnButton = MOUSE_LEFT; nEvent = SALEVENT_MOUSEBUTTONDOWN; break; case WM_BUTTON2DBLCLK: case WM_BUTTON2DOWN: aMouseEvt.mnButton = MOUSE_RIGHT; nEvent = SALEVENT_MOUSEBUTTONDOWN; break; case WM_BUTTON3DBLCLK: case WM_BUTTON3DOWN: aMouseEvt.mnButton = MOUSE_MIDDLE; nEvent = SALEVENT_MOUSEBUTTONDOWN; break; case WM_BUTTON1UP: aMouseEvt.mnButton = MOUSE_LEFT; nEvent = SALEVENT_MOUSEBUTTONUP; break; case WM_BUTTON2UP: aMouseEvt.mnButton = MOUSE_RIGHT; nEvent = SALEVENT_MOUSEBUTTONUP; break; case WM_BUTTON3UP: aMouseEvt.mnButton = MOUSE_MIDDLE; nEvent = SALEVENT_MOUSEBUTTONUP; break; } // check if this window was destroyed - this might happen if we are the help window // and sent a mouse leave message to the application which killed the help window, ie ourself if( !WinIsWindow( pFrame->mhAB, hWnd ) ) return 0; #if OSL_DEBUG_LEVEL>10 //if (_bCapture) debug_printf("ImplHandleMouseMsg mouse %d,%d\n",aMouseEvt.mnX,aMouseEvt.mnY); #endif if ( bCall ) { if ( nEvent == SALEVENT_MOUSEBUTTONDOWN ) WinUpdateWindow( pFrame->mhWndClient ); // --- RTL --- (mirror mouse pos) //if( Application::GetSettings().GetLayoutRTL() ) // aMouseEvt.mnX = pFrame->maGeometry.nWidth-1-aMouseEvt.mnX; nRet = pFrame->CallCallback( nEvent, &aMouseEvt ); if ( nMsg == WM_MOUSEMOVE ) { WinSetPointer( HWND_DESKTOP, pFrame->mhPointer ); nRet = TRUE; } } else nRet = 0; return nRet; } // ----------------------------------------------------------------------- static long ImplHandleWheelMsg( HWND hWnd, UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) { ImplSalYieldMutexAcquireWithWait(); long nRet = 0; Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { // Mouse-Coordinaates are relativ to the screen POINTL aPt; WinQueryMsgPos( pFrame->mhAB, &aPt ); WinMapWindowPoints( HWND_DESKTOP, pFrame->mhWndClient, &aPt, 1 ); aPt.y = pFrame->mnHeight - aPt.y - 1; SalWheelMouseEvent aWheelEvt; aWheelEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); aWheelEvt.mnX = aPt.x; aWheelEvt.mnY = aPt.y; aWheelEvt.mnCode = 0; bool bNeg = (SHORT2FROMMP(nMP2) == SB_LINEDOWN || SHORT2FROMMP(nMP2) == SB_PAGEDOWN ); aWheelEvt.mnDelta = bNeg ? -120 : 120; aWheelEvt.mnNotchDelta = bNeg ? -1 : 1; if (SHORT2FROMMP(nMP2) == SB_PAGEUP || SHORT2FROMMP(nMP2) == SB_PAGEDOWN) aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; else aWheelEvt.mnScrollLines = 1; if( nMsg == WM_HSCROLL ) aWheelEvt.mbHorz = TRUE; // Modifier-Tasten setzen if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 ) aWheelEvt.mnCode |= KEY_SHIFT; if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) aWheelEvt.mnCode |= KEY_MOD1; if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 ) aWheelEvt.mnCode |= KEY_MOD2; nRet = pFrame->CallCallback( SALEVENT_WHEELMOUSE, &aWheelEvt ); } ImplSalYieldMutexRelease(); return nRet; } // ----------------------------------------------------------------------- static USHORT ImplSalGetKeyCode( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 ) { USHORT nKeyFlags = SHORT1FROMMP( aMP1 ); UCHAR nCharCode = (UCHAR)SHORT1FROMMP( aMP2 ); USHORT nKeyCode = (UCHAR)SHORT2FROMMP( aMP2 ); UCHAR nScanCode = (UCHAR)CHAR4FROMMP( aMP1 ); USHORT rSVCode = 0; // Ist virtueller KeyCode gesetzt und befindet sich der KeyCode in der // Tabelle, dann mappen if ( (nKeyFlags & KC_VIRTUALKEY) && (nKeyCode < KEY_TAB_SIZE) ) rSVCode = aImplTranslateKeyTab[nKeyCode]; // Wenn kein KeyCode ermittelt werden konnte, versuchen wir aus dem // CharCode einen zu erzeugen if ( !rSVCode && nCharCode ) { // Bei 0-9, a-z und A-Z auch KeyCode setzen if ( (nCharCode >= '0') && (nCharCode <= '9') && (!rSVCode || !(nKeyFlags & KC_SHIFT)) ) rSVCode = KEYGROUP_NUM + (nCharCode-'0'); else if ( (nCharCode >= 'a') && (nCharCode <= 'z') ) rSVCode = KEYGROUP_ALPHA + (nCharCode-'a'); else if ( (nCharCode >= 'A') && (nCharCode <= 'Z') ) rSVCode = KEYGROUP_ALPHA + (nCharCode-'A'); else { switch ( nCharCode ) { case '+': rSVCode = KEY_ADD; break; case '-': rSVCode = KEY_SUBTRACT; break; case '*': rSVCode = KEY_MULTIPLY; break; case '/': rSVCode = KEY_DIVIDE; break; case '.': rSVCode = KEY_POINT; break; case ',': rSVCode = KEY_COMMA; break; case '<': rSVCode = KEY_LESS; break; case '>': rSVCode = KEY_GREATER; break; case '=': rSVCode = KEY_EQUAL; break; } } } // "Numlock-Hack": we want to get correct keycodes from the numpad if ( (nCharCode >= '0') && (nCharCode <= '9') && !(nKeyFlags & KC_SHIFT) ) rSVCode = KEYGROUP_NUM + (nCharCode-'0'); if ( nCharCode == ',' ) rSVCode = KEY_COMMA; if ( nCharCode == '.' ) rSVCode = KEY_POINT; return rSVCode; } // ----------------------------------------------------------------------- static void ImplUpdateInputLang( Os2SalFrame* pFrame ) { sal_Bool bLanguageChange = FALSE; ULONG nLang = 0; APIRET rc; UconvObject uconv_object = NULL; LocaleObject locale_object = NULL; UniChar *pinfo_item; // we do not support change of input language while working, // so exit if already defined (mnInputLang is a static class field) if (pFrame->mnInputLang) return; // get current locale rc = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"", &locale_object); // get Win32 locale id and sublanguage (hex uni string) rc = UniQueryLocaleItem(locale_object, LOCI_xWinLocale, &pinfo_item); // convert uni string to integer rc = UniStrtoul(locale_object, pinfo_item, &pinfo_item, 16, &nLang); rc = UniFreeMem(pinfo_item); #if OSL_DEBUG_LEVEL>10 debug_printf("ImplUpdateInputLang nLang %04x\n", nLang); char char_buffer[256]; rc = UniCreateUconvObject((UniChar *)L"", &uconv_object); rc = UniQueryLocaleItem(locale_object, LOCI_sKeyboard, &pinfo_item); rc = UniStrFromUcs(uconv_object, char_buffer, pinfo_item, sizeof(char_buffer)); debug_printf("Keyboard name is: %s\n", char_buffer ); rc = UniFreeMem(pinfo_item); #endif rc = UniFreeLocaleObject(locale_object); // keep input lang up-to-date #if OSL_DEBUG_LEVEL>10 debug_printf("ImplUpdateInputLang pFrame %08x lang changed from %d to %d\n", pFrame, pFrame->mnInputLang, nLang); #endif pFrame->mnInputLang = nLang; } static sal_Unicode ImplGetCharCode( Os2SalFrame* pFrame, USHORT nKeyFlags, sal_Char nCharCode, UCHAR nScanCode ) { ImplUpdateInputLang( pFrame ); #if OSL_DEBUG_LEVEL>10 debug_printf("ImplGetCharCode nCharCode %c, %04x\n", nCharCode, nCharCode); #endif return OUString( &nCharCode, 1, gsl_getSystemTextEncoding()).toChar(); } // ----------------------------------------------------------------------- LanguageType Os2SalFrame::GetInputLanguage() { if( !mnInputLang ) ImplUpdateInputLang( this ); if( !mnInputLang ) return LANGUAGE_DONTKNOW; else return (LanguageType) mnInputLang; } // ----------------------------------------------------------------------- sal_Bool Os2SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& ) { // not supported yet return FALSE; } // ----------------------------------------------------------------------- static sal_Unicode ImplConvertKey( Os2SalFrame* pFrame, MPARAM aMP1, MPARAM aMP2 ) { USHORT nKeyFlags = SHORT1FROMMP( aMP1 ); UCHAR nCharCode = (UCHAR)SHORT1FROMMP( aMP2 ); USHORT nKeyCode = (UCHAR)SHORT2FROMMP( aMP2 ); UCHAR nScanCode = (UCHAR)CHAR4FROMMP( aMP1 ); sal_Unicode rSVCharCode = 0; // Ist Character-Code gesetzt // !!! Bei CTRL/ALT ist KC_CHAR nicht gesetzt, jedoch moechten wir // !!! dann auch einen CharCode und machen die Behandlung deshalb // !!! selber if ( (nKeyFlags & KC_CHAR) || (nKeyFlags & KC_CTRL) || (nKeyFlags & KC_ALT) ) rSVCharCode = ImplGetCharCode( pFrame, nKeyFlags, nCharCode, nScanCode); // ret unicode return rSVCharCode; } // ----------------------------------------------------------------------- static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg, MPARAM nMP1, MPARAM nMP2 ) { static USHORT nLastOS2KeyChar = 0; static sal_Unicode nLastChar = 0; USHORT nRepeat = CHAR3FROMMP( nMP1 ) - 1; SHORT nFlags = SHORT1FROMMP( nMP1 ); USHORT nModCode = 0; USHORT nSVCode = 0; USHORT nOS2KeyCode = (UCHAR)SHORT2FROMMP( nMP2 ); sal_Unicode nSVCharCode = 0; long nRet = 0; Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( !pFrame ) return 0; // determine modifiers if ( nFlags & KC_SHIFT ) nModCode |= KEY_SHIFT; if ( nFlags & KC_CTRL ) nModCode |= KEY_MOD1; if ( nFlags & KC_ALT ) nModCode |= KEY_MOD2; // Bei Shift, Control und Alt schicken wir einen KeyModChange-Event if ( (nOS2KeyCode == VK_SHIFT) || (nOS2KeyCode == VK_CTRL) || (nOS2KeyCode == VK_ALT) || (nOS2KeyCode == VK_ALTGRAF) ) { SalKeyModEvent aModEvt; aModEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); aModEvt.mnCode = nModCode; #if OSL_DEBUG_LEVEL>10 debug_printf("SALEVENT_KEYMODCHANGE\n"); #endif nRet = pFrame->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); } else { nSVCode = ImplSalGetKeyCode( pFrame, nMP1, nMP2 ); nSVCharCode = ImplConvertKey( pFrame, nMP1, nMP2 ); #if OSL_DEBUG_LEVEL>10 debug_printf("nSVCode %04x nSVCharCode %04x\n",nSVCode,nSVCharCode ); #endif // Fuer Java muessen wir bei KeyUp einen CharCode liefern if ( nFlags & KC_KEYUP ) { if ( !nSVCharCode ) { if ( nLastOS2KeyChar == nOS2KeyCode ) { nSVCharCode = nLastChar; nLastOS2KeyChar = 0; nLastChar = 0; } } else { nLastOS2KeyChar = 0; nLastChar = 0; } } else { nLastOS2KeyChar = nOS2KeyCode; nLastChar = nSVCharCode; } if ( nSVCode || nSVCharCode ) { SalKeyEvent aKeyEvt; aKeyEvt.mnCode = nSVCode; aKeyEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); aKeyEvt.mnCode |= nModCode; aKeyEvt.mnCharCode = nSVCharCode; aKeyEvt.mnRepeat = nRepeat; #if OSL_DEBUG_LEVEL>10 debug_printf( (nFlags & KC_KEYUP) ? "SALEVENT_KEYUP\n" : "SALEVENT_KEYINPUT\n"); #endif nRet = pFrame->CallCallback( (nFlags & KC_KEYUP) ? SALEVENT_KEYUP : SALEVENT_KEYINPUT, &aKeyEvt ); } } return nRet; } // ----------------------------------------------------------------------- static bool ImplHandlePaintMsg( HWND hWnd ) { sal_Bool bMutex = FALSE; if ( ImplSalYieldMutexTryToAcquire() ) bMutex = TRUE; // if we don't get the mutex, we can also change the clip region, // because other threads doesn't use the mutex from the main // thread --> see GetGraphics() Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine // Paint-Region anliegt if ( WinQueryUpdateRect( hWnd, NULL ) ) { // Call BeginPaint/EndPaint to query the rect and send // this Notofication to rect HPS hPS; RECTL aUpdateRect; hPS = WinBeginPaint( hWnd, NULLHANDLE, &aUpdateRect ); WinEndPaint( hPS ); // Paint if ( bMutex ) { SalPaintEvent aPEvt( aUpdateRect.xLeft, pFrame->mnHeight - aUpdateRect.yTop, aUpdateRect.xRight- aUpdateRect.xLeft, aUpdateRect.yTop - aUpdateRect.yBottom ); pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); } else { RECTL* pRect = new RECTL; WinCopyRect( pFrame->mhAB, pRect, &aUpdateRect ); WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 ); } } } if ( bMutex ) ImplSalYieldMutexRelease(); return bMutex ? true : false; } // ----------------------------------------------------------------------- static void ImplHandlePaintMsg2( HWND hWnd, RECTL* pRect ) { // Paint if ( ImplSalYieldMutexTryToAcquire() ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { SalPaintEvent aPEvt( pRect->xLeft, pFrame->mnHeight - pRect->yTop, pRect->xRight - pRect->xLeft, pRect->yTop - pRect->yBottom ); pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); } ImplSalYieldMutexRelease(); delete pRect; } else WinPostMsg( hWnd, SAL_MSG_POSTPAINT, (MPARAM)pRect, 0 ); } // ----------------------------------------------------------------------- static void SetMaximizedFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ) { // calculate and set frame geometry of a maximized window - useful if the window is still hidden RECTL aRect; pFrame->GetWorkArea( aRect); // a maximized window has no other borders than the caption pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0; pFrame->maGeometry.nTopDecoration = pFrame->mbCaption ? WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) : 0; aRect.yTop += pFrame->maGeometry.nTopDecoration; pFrame->maGeometry.nX = aRect.xLeft; pFrame->maGeometry.nY = aRect.yBottom; pFrame->maGeometry.nWidth = aRect.xRight - aRect.xLeft + 1; pFrame->maGeometry.nHeight = aRect.yBottom - aRect.yTop + 1; } static void UpdateFrameGeometry( HWND hWnd, Os2SalFrame* pFrame ) { if( !pFrame ) return; //SalFrame has a //maGeometry member that holds absolute screen positions (and needs to be //updated if the window is moved by the way). // reset data memset(&pFrame->maGeometry, 0, sizeof(SalFrameGeometry) ); SWP swp; LONG nFrameX, nFrameY, nCaptionY; // get frame size WinQueryWindowPos(pFrame->mhWndFrame, &swp); if (swp.fl & SWP_MINIMIZE) return; // map from client area to screen ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY); pFrame->maGeometry.nTopDecoration = nFrameY + nCaptionY; pFrame->maGeometry.nLeftDecoration = nFrameX; pFrame->maGeometry.nRightDecoration = nFrameX; pFrame->maGeometry.nBottomDecoration = nFrameY; // position of client area, not of frame corner! pFrame->maGeometry.nX = swp.x + nFrameX; pFrame->maGeometry.nY = nScreenHeight - (swp.y + swp.cy) + nFrameY + nCaptionY; int nWidth = swp.cx - pFrame->maGeometry.nRightDecoration - pFrame->maGeometry.nLeftDecoration; int nHeight = swp.cy - pFrame->maGeometry.nBottomDecoration - pFrame->maGeometry.nTopDecoration; // clamp to zero pFrame->maGeometry.nHeight = nHeight < 0 ? 0 : nHeight; pFrame->maGeometry.nWidth = nWidth < 0 ? 0 : nWidth; #if OSL_DEBUG_LEVEL>0 debug_printf( "UpdateFrameGeometry: hwnd %x, frame %x at %d,%d (%dx%d)\n", hWnd, pFrame->mhWndFrame, pFrame->maGeometry.nX, pFrame->maGeometry.nY, pFrame->maGeometry.nWidth,pFrame->maGeometry.nHeight); #endif } // ----------------------------------------------------------------------- static void ImplHandleMoveMsg( HWND hWnd) { if ( ImplSalYieldMutexTryToAcquire() ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { UpdateFrameGeometry( hWnd, pFrame ); if ( WinIsWindowVisible( hWnd )) pFrame->mbDefPos = FALSE; // Gegen moegliche Rekursionen sichern if ( !pFrame->mbInMoveMsg ) { // Fenster im FullScreenModus wieder einpassen pFrame->mbInMoveMsg = TRUE; if ( pFrame->mbFullScreen ) ImplSalFrameFullScreenPos( pFrame ); pFrame->mbInMoveMsg = FALSE; } // Status merken ImplSaveFrameState( pFrame ); // Call Hdl //#93851 if we call this handler, VCL floating windows are not updated correctly //ImplCallMoveHdl( hWnd ); } ImplSalYieldMutexRelease(); } else WinPostMsg( hWnd, SAL_MSG_POSTMOVE, 0, 0 ); } // ----------------------------------------------------------------------- static void ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { UpdateFrameGeometry( hWnd, pFrame ); pFrame->mbDefPos = FALSE; pFrame->mnWidth = (short)SHORT1FROMMP( nMP2 ); pFrame->mnHeight = (short)SHORT2FROMMP( nMP2 ); if ( pFrame->mpGraphics ) pFrame->mpGraphics->mnHeight = (int)SHORT2FROMMP(nMP2); // Status merken ImplSaveFrameState( pFrame ); pFrame->CallCallback( SALEVENT_RESIZE, 0 ); if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow ) WinUpdateWindow( pFrame->mhWndClient ); } } // ----------------------------------------------------------------------- static long ImplHandleFocusMsg( Os2SalFrame* pFrame, MPARAM nMP2 ) { if ( pFrame && !Os2SalFrame::mbInReparent ) { if ( SHORT1FROMMP( nMP2 ) ) { if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow ) WinUpdateWindow( pFrame->mhWndClient ); return pFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); } else { return pFrame->CallCallback( SALEVENT_LOSEFOCUS, 0 ); } } } // ----------------------------------------------------------------------- static void ImplHandleCloseMsg( HWND hWnd ) { if ( ImplSalYieldMutexTryToAcquire() ) { Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { pFrame->CallCallback( SALEVENT_CLOSE, 0 ); } ImplSalYieldMutexRelease(); } else WinPostMsg( hWnd, WM_CLOSE, 0, 0 ); } // ----------------------------------------------------------------------- inline void ImplHandleUserEvent( HWND hWnd, MPARAM nMP2 ) { ImplSalYieldMutexAcquireWithWait(); Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { pFrame->CallCallback( SALEVENT_USEREVENT, (void*)nMP2 ); } ImplSalYieldMutexRelease(); } // ----------------------------------------------------------------------- static int SalImplHandleProcessMenu( Os2SalFrame* pFrame, ULONG nMsg, MPARAM nMP1, MPARAM nMP2) { long nRet = 0; debug_printf("SalImplHandleProcessMenu\n"); #if 0 DWORD err=0; if( !HIWORD(wParam) ) { // Menu command WORD nId = LOWORD(wParam); if( nId ) // zero for separators { SalMenuEvent aMenuEvt; aMenuEvt.mnId = nId; WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( pFrame->mSelectedhMenu, nId, FALSE ); if( pSalMenuItem ) aMenuEvt.mpMenu = pSalMenuItem->mpMenu; else aMenuEvt.mpMenu = NULL; nRet = pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt ); } } #endif //return (nRet != 0); return (nRet == 0); } // ----------------------------------------------------------------------- static void ImplHandleInputLangChange( HWND hWnd ) { ImplSalYieldMutexAcquireWithWait(); // Feststellen, ob wir IME unterstuetzen Os2SalFrame* pFrame = GetWindowPtr( hWnd ); #if 0 if ( pFrame && pFrame->mbIME && pFrame->mhDefIMEContext ) { HWND hWnd = pFrame->mhWnd; HKL hKL = (HKL)lParam; UINT nImeProps = ImmGetProperty( hKL, IGP_PROPERTY ); pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0; pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0; pFrame->mbHandleIME = !pFrame->mbSpezIME; } #endif // trigger input language and codepage update UINT nLang = pFrame->mnInputLang; ImplUpdateInputLang( pFrame ); debug_printf("ImplHandleInputLangChange new language 0x%04x\n",pFrame->mnInputLang); // notify change if( nLang != pFrame->mnInputLang ) pFrame->CallCallback( SALEVENT_INPUTLANGUAGECHANGE, 0 ); ImplSalYieldMutexRelease(); } // ----------------------------------------------------------------------- #ifdef ENABLE_IME static long ImplHandleIMEStartConversion( Os2SalFrame* pFrame ) { long nRet = FALSE; SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { HWND hWnd = pFrame->mhWndClient; HIMI hIMI = 0; pIMEData->mpGetIME( hWnd, &hIMI ); if ( hIMI ) { ULONG nProp; if ( 0 != pIMEData->mpQueryIMEProperty( hIMI, QIP_PROPERTY, &nProp ) ) pFrame->mbHandleIME = FALSE; else { pFrame->mbHandleIME = !(nProp & PRP_SPECIALUI); } if ( pFrame->mbHandleIME ) { /* Windows-Code, der noch nicht angepasst wurde !!! // Cursor-Position ermitteln und aus der die Default-Position fuer // das Composition-Fenster berechnen SalCursorPosEvent aCursorPosEvt; pFrame->CallCallback( pFrame->mpInst, pFrame, SALEVENT_CURSORPOS, (void*)&aCursorPosEvt ); COMPOSITIONFORM aForm; memset( &aForm, 0, sizeof( aForm ) ); if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight ) aForm.dwStyle |= CFS_DEFAULT; else { aForm.dwStyle |= CFS_POINT; aForm.ptCurrentPos.x = aCursorPosEvt.mnX; aForm.ptCurrentPos.y = aCursorPosEvt.mnY; } ImmSetCompositionWindow( hIMC, &aForm ); // Den InputContect-Font ermitteln und diesem dem Composition-Fenster // bekannt machen */ pFrame->mbConversionMode = TRUE; pFrame->CallCallback( SALEVENT_STARTEXTTEXTINPUT, (void*)NULL ); nRet = TRUE; } pIMEData->mpReleaseIME( hWnd, hIMI ); } } return nRet; } // ----------------------------------------------------------------------- static long ImplHandleIMEConversion( Os2SalFrame* pFrame, MPARAM nMP2Param ) { long nRet = FALSE; SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { HWND hWnd = pFrame->mhWndClient; HIMI hIMI = 0; ULONG nMP2 = (ULONG)nMP2Param; pIMEData->mpGetIME( hWnd, &hIMI ); if ( hIMI ) { if ( nMP2 & (IMR_RESULT_RESULTSTRING | IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR | IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) ) { SalExtTextInputEvent aEvt; aEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); aEvt.mpTextAttr = NULL; aEvt.mnCursorPos = 0; aEvt.mnDeltaStart = 0; aEvt.mbOnlyCursor = FALSE; aEvt.mbCursorVisible = TRUE; ULONG nBufLen = 0; xub_Unicode* pBuf = NULL; ULONG nAttrBufLen = 0; PM_BYTE* pAttrBuf = NULL; sal_Bool bLastCursor = FALSE; if ( nMP2 & IMR_RESULT_RESULTSTRING ) { pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, 0, &nBufLen ); if ( nBufLen > 0 ) { pBuf = new xub_Unicode[nBufLen]; pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, pBuf, &nBufLen ); } bLastCursor = TRUE; aEvt.mbCursorVisible = TRUE; } else if ( nMP2 & (IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR | IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) ) { pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen ); if ( nBufLen > 0 ) { pBuf = new xub_Unicode[nBufLen]; pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, pBuf, &nBufLen ); } pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, 0, &nAttrBufLen ); if ( nAttrBufLen > 0 ) { pAttrBuf = new PM_BYTE[nAttrBufLen]; pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, pAttrBuf, &nAttrBufLen ); } /* !!! Wir bekommen derzeit nur falsche Daten, deshalb zeigen wir derzeit !!! auch keine Cursor an ULONG nTempBufLen; ULONG nCursorPos = 0; ULONG nCursorAttr = 0; ULONG nChangePos = 0; nTempBufLen = sizeof( ULONG ); pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen ); nTempBufLen = sizeof( ULONG ); pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORATTR, &nCursorAttr, &nTempBufLen ); nTempBufLen = sizeof( ULONG ); pIMEData->mpGetConversionString( hIMI, IMR_CONV_CHANGESTART, &nChangePos, &nTempBufLen ); aEvt.mnCursorPos = nCursorPos; aEvt.mnDeltaStart = nChangePos; if ( nCursorAttr & CP_CURSORATTR_INVISIBLE ) aEvt.mbCursorVisible = FALSE; */ aEvt.mnCursorPos = 0; aEvt.mnDeltaStart = 0; aEvt.mbCursorVisible = FALSE; if ( (nMP2 == IMR_CONV_CURSORPOS) || (nMP2 == IMR_CONV_CURSORATTR) ) aEvt.mbOnlyCursor = TRUE; } USHORT* pSalAttrAry = NULL; if ( pBuf ) { aEvt.maText = XubString( pBuf, (USHORT)nBufLen ); delete [] pBuf; if ( pAttrBuf ) { USHORT nTextLen = aEvt.maText.Len(); if ( nTextLen ) { pSalAttrAry = new USHORT[nTextLen]; memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) ); for ( USHORT i = 0; (i < nTextLen) && (i < nAttrBufLen); i++ ) { PM_BYTE nOS2Attr = pAttrBuf[i]; USHORT nSalAttr; if ( nOS2Attr == CP_ATTR_TARGET_CONVERTED ) nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; else if ( nOS2Attr == CP_ATTR_CONVERTED ) nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE; else if ( nOS2Attr == CP_ATTR_TARGET_NOTCONVERTED ) nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; else if ( nOS2Attr == CP_ATTR_INPUT_ERROR ) nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; else /* ( nOS2Attr == CP_ATTR_INPUT ) */ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; pSalAttrAry[i] = nSalAttr; } aEvt.mpTextAttr = pSalAttrAry; } delete [] pAttrBuf; } if ( bLastCursor ) aEvt.mnCursorPos = aEvt.maText.Len(); } pIMEData->mpReleaseIME( hWnd, hIMI ); // Handler rufen und wenn wir ein Attribute-Array haben, danach // wieder zerstoeren pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); if ( pSalAttrAry ) delete [] pSalAttrAry; } else pIMEData->mpReleaseIME( hWnd, hIMI ); } nRet = TRUE; } return nRet; } // ----------------------------------------------------------------------- inline long ImplHandleIMEEndConversion( Os2SalFrame* pFrame ) { pFrame->mbConversionMode = FALSE; pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL ); return TRUE; } // ----------------------------------------------------------------------- static void ImplHandleIMEOpenCandidate( Os2SalFrame* pFrame ) { pFrame->mbCandidateMode = TRUE; long nRet = FALSE; SalIMEData* pIMEData = GetSalIMEData(); if ( pIMEData ) { HWND hWnd = pFrame->mhWndClient; HIMI hIMI = 0; pIMEData->mpGetIME( hWnd, &hIMI ); if ( hIMI ) { ULONG nBufLen = 0; pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen ); if ( nBufLen > 0 ) { /* !!! Wir bekommen derzeit nur falsche Daten steht der Cursor immer bei 0 ULONG nTempBufLen = sizeof( ULONG ); ULONG nCursorPos = 0; pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen ); */ ULONG nCursorPos = 0; SalExtTextInputPosEvent aEvt; aEvt.mnTime = WinQueryMsgTime( pFrame->mhAB ); aEvt.mnFirstPos = nCursorPos; aEvt.mnChars = nBufLen-nCursorPos; aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars]; memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) ); pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt ); long nMinLeft = aEvt.mpPosAry[0].mnX; long nMinTop = aEvt.mpPosAry[0].mnY; long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight; long nMaxRight = nMinLeft; USHORT i = 0; while ( i < aEvt.mnChars ) { // Solange wir uns auf der gleichen Zeile bewegen, // ermitteln wir die Rechteck-Grenzen if ( !aEvt.mpPosAry[i].mnHeight || (aEvt.mpPosAry[i].mnY < nMaxBottom-1) ) { if ( aEvt.mpPosAry[i].mnX < nMinLeft ) nMinLeft = aEvt.mpPosAry[i].mnX; if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight ) nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth; if ( aEvt.mpPosAry[i].mnY < nMinTop ) nMinTop = aEvt.mpPosAry[i].mnY; i++; } else break; } CANDIDATEPOS aForm; aForm.ulIndex = 0; aForm.ulStyle = CPS_EXCLUDE; aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX; aForm.ptCurrentPos.y = pFrame->mnHeight - (nMaxBottom+1) - 1; aForm.rcArea.xLeft = nMinLeft; aForm.rcArea.yBottom = pFrame->mnHeight - nMaxBottom - 1; aForm.rcArea.xRight = nMaxRight+1; aForm.rcArea.yTop = pFrame->mnHeight - nMinTop - 1; pIMEData->mpSetCandidateWin( hIMI, &aForm ); delete aEvt.mpPosAry; } pIMEData->mpReleaseIME( hWnd, hIMI ); } } } // ----------------------------------------------------------------------- inline void ImplHandleIMECloseCandidate( Os2SalFrame* pFrame ) { pFrame->mbCandidateMode = FALSE; } #endif // ----------------------------------------------------------------------- MRESULT EXPENTRY SalFrameWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 ) { Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( hWnd ); MRESULT nRet = (MRESULT)0; sal_Bool bDef = TRUE; bool bCheckTimers= false; #if OSL_DEBUG_LEVEL>10 if (nMsg!=WM_TIMER && nMsg!=WM_MOUSEMOVE) debug_printf( "SalFrameWndProc hWnd 0x%x nMsg 0x%x\n", hWnd, nMsg); #endif switch( nMsg ) { case WM_MOUSEMOVE: case WM_BUTTON1DOWN: case WM_BUTTON2DOWN: case WM_BUTTON3DOWN: case WM_BUTTON1DBLCLK: case WM_BUTTON2DBLCLK: case WM_BUTTON3DBLCLK: case WM_BUTTON1UP: case WM_BUTTON2UP: case WM_BUTTON3UP: case SAL_MSG_MOUSELEAVE: // ButtonUp/Down nie an die WinDefWindowProc weiterleiten, weil sonst // die Message an den Owner weitergeleitet wird ImplSalYieldMutexAcquireWithWait(); bDef = !ImplHandleMouseMsg( hWnd, nMsg, nMP1, nMP2 ); ImplSalYieldMutexRelease(); break; case WM_CHAR: if ( pFrame->mbConversionMode ) bDef = FALSE; else bDef = !ImplHandleKeyMsg( hWnd, nMsg, nMP1, nMP2 ); break; case WM_ERASEBACKGROUND: nRet = (MRESULT)FALSE; bDef = FALSE; break; case WM_PAINT: bCheckTimers = ImplHandlePaintMsg( hWnd ); bDef = FALSE; break; case SAL_MSG_POSTPAINT: ImplHandlePaintMsg2( hWnd, (RECTL*)nMP1 ); bCheckTimers = true; bDef = FALSE; break; case WM_MOVE: case SAL_MSG_POSTMOVE: ImplHandleMoveMsg( hWnd ); bDef = FALSE; break; case WM_SIZE: if ( ImplSalYieldMutexTryToAcquire() ) { ImplHandleSizeMsg( hWnd, nMP2 ); ImplSalYieldMutexRelease(); } else WinPostMsg( hWnd, SAL_MSG_POSTSIZE, nMP1, nMP2 ); break; case SAL_MSG_POSTSIZE: ImplHandleSizeMsg( hWnd, nMP2 ); break; case WM_MINMAXFRAME: if ( ImplSalYieldMutexTryToAcquire() ) { PSWP pswp = (PSWP) nMP1; ImplHandleSizeMsg( hWnd, MPFROM2SHORT( pswp->cx, pswp->cy) ); ImplSalYieldMutexRelease(); } else WinPostMsg( hWnd, SAL_MSG_POSTSIZE, 0, nMP2 ); break; case WM_CALCVALIDRECTS: return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP); case WM_SETFOCUS: if ( ImplSalYieldMutexTryToAcquire() ) { ImplHandleFocusMsg( pFrame, nMP2 ); ImplSalYieldMutexRelease(); } else WinPostMsg( hWnd, SAL_MSG_POSTFOCUS, 0, nMP2 ); break; case SAL_MSG_POSTFOCUS: ImplHandleFocusMsg( pFrame, nMP2 ); break; case WM_TRANSLATEACCEL: { // Da uns OS/2 zu viele Tasten abfaegnt, unternehmen wir etwas, // damit wir Shift+F1, Shift+F10 und Shift+Enter bekommen PQMSG pMsg = (PQMSG)nMP1; USHORT nKeyFlags = SHORT1FROMMP( pMsg->mp1 ); USHORT nKeyCode = (UCHAR)SHORT2FROMMP( pMsg->mp2 ); if ( !(nKeyFlags & KC_KEYUP) && (nKeyFlags & KC_VIRTUALKEY) && (nKeyFlags & KC_SHIFT) && (nKeyCode != VK_ESC) ) return (MRESULT)FALSE; if ( nKeyCode == VK_F1 ) return (MRESULT)FALSE; } break; case WM_CREATE: { HWND hWndFrame = WinQueryWindow(hWnd, QW_PARENT); if (hWndFrame == 0) debug_printf(" WARNING NULL FRAME!!\n"); SalData* pSalData = GetSalData(); // Window-Instanz am Windowhandle speichern pFrame = pSalData->mpCreateFrame; pSalData->mpCreateFrame = NULL; SetWindowPtr( hWnd, pFrame ); SetWindowPtr( hWndFrame, pFrame); // HWND schon hier setzen, da schon auf den Instanzdaten // gearbeitet werden kann, wenn Messages waehrend // CreateWindow() gesendet werden pFrame->mhWndClient = hWnd; pFrame->mhWndFrame = hWndFrame; pFrame->maSysData.hWnd = hWnd; } break; case WM_CLOSE: ImplHandleCloseMsg( hWnd ); bDef = FALSE; break; case WM_SYSVALUECHANGED: if ( pFrame->mbFullScreen ) ImplSalFrameFullScreenPos( pFrame ); // kein break, da der Rest auch noch verarbeitet werden soll case PL_ALTERED: case WM_SYSCOLORCHANGE: ImplSalYieldMutexAcquire(); pFrame->CallCallback( SALEVENT_SETTINGSCHANGED, 0 ); ImplSalYieldMutexRelease(); break; case SAL_MSG_USEREVENT: ImplHandleUserEvent( hWnd, nMP2 ); bDef = FALSE; break; case SAL_MSG_TOTOP: ImplSalToTop( hWnd, (ULONG)nMP1 ); bDef = FALSE; break; case SAL_MSG_SHOW: ImplSalShow( hWnd, (ULONG)nMP1, (ULONG)nMP2 ); bDef = FALSE; break; case WM_KBDLAYERCHANGED: debug_printf("hWnd 0x%08x WM_KBDLAYERCHANGED\n", hWnd); ImplHandleInputLangChange( hWnd ); break; case WM_HSCROLL: case WM_VSCROLL: ImplHandleWheelMsg( hWnd, nMsg, nMP1, nMP2 ); bDef = FALSE; break; case WM_COMMAND: case SAL_MSG_SYSPROCESSMENU: if ( SalImplHandleProcessMenu( pFrame, nMsg, nMP1, nMP2 ) ) { bDef = FALSE; nRet = (MRESULT)1; } break; #ifdef ENABLE_IME case WM_IMEREQUEST: if ( (ULONG)nMP1 == IMR_CONVRESULT ) { if ( pFrame->mbHandleIME ) { // Nur im Conversionmodus akzeptieren wir den IME-Input if ( pFrame->mbConversionMode ) { ImplSalYieldMutexAcquire(); if ( ImplHandleIMEConversion( pFrame, nMP2 ) ) { bDef = FALSE; nRet = (MRESULT)TRUE; } ImplSalYieldMutexRelease(); } } } else if ( (ULONG)nMP1 == IMR_CANDIDATE ) { if ( pFrame->mbHandleIME ) { ImplSalYieldMutexAcquire(); if ( (ULONG)nMP2 & IMR_CANDIDATE_SHOW ) ImplHandleIMEOpenCandidate( pFrame ); else if ( (ULONG)nMP2 & IMR_CANDIDATE_HIDE ) ImplHandleIMECloseCandidate( pFrame ); ImplSalYieldMutexRelease(); } } break; case WM_IMENOTIFY: if ( (ULONG)nMP1 == IMN_STARTCONVERSION ) { ImplSalYieldMutexAcquire(); if ( ImplHandleIMEStartConversion( pFrame ) ) { bDef = FALSE; nRet = (MRESULT)TRUE; } ImplSalYieldMutexRelease(); } else if ( (ULONG)nMP1 == IMN_ENDCONVERSION ) { if ( pFrame->mbHandleIME ) { ImplSalYieldMutexAcquire(); if ( ImplHandleIMEEndConversion( pFrame ) ) { bDef = FALSE; nRet = (MRESULT)TRUE; } ImplSalYieldMutexRelease(); } } break; #endif } if( bCheckTimers ) { SalData* pSalData = GetSalData(); if( pSalData->mnNextTimerTime ) { ULONG nCurTime; DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PVOID)&nCurTime, sizeof(ULONG)); if( pSalData->mnNextTimerTime < nCurTime ) { QMSG aMsg; if (!WinPeekMsg( pFrame->mhAB, &aMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE ) ) WinPostMsg( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, (MPARAM)nCurTime ); } } } if ( bDef ) nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); return nRet; } // ----------------------------------------------------------------------- void Os2SalFrame::ResetClipRegion() { } void Os2SalFrame::BeginSetClipRegion( ULONG ) { } void Os2SalFrame::UnionClipRegion( long, long, long, long ) { } void Os2SalFrame::EndSetClipRegion() { } // ----------------------------------------------------------------------- MRESULT EXPENTRY SalFrameSubClassWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 ) { MRESULT mReturn = 0L; // ticket#124 min size of 132 px is too much if (nMsg == WM_QUERYTRACKINFO) { PTRACKINFO pti; // first, let PM initialize TRACKINFO mReturn = aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 ); // now change default min size pti = (PTRACKINFO) nMP2; pti->ptlMinTrackSize.x = 64L; // now return to PM return mReturn; } return aSalShlData.mpFrameProc( hWnd, nMsg, nMP1, nMP2 ); } // -----------------------------------------------------------------------