1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_fpicker.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir //------------------------------------------------------------------------ 32*cdf0e10cSrcweir // includes 33*cdf0e10cSrcweir //------------------------------------------------------------------------ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <tchar.h> 36*cdf0e10cSrcweir #include "helppopupwindow.hxx" 37*cdf0e10cSrcweir #include <osl/diagnose.h> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir //------------------------------------------------------------------------ 40*cdf0e10cSrcweir // 41*cdf0e10cSrcweir //------------------------------------------------------------------------ 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir using rtl::OUString; 44*cdf0e10cSrcweir using osl::Mutex; 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir //------------------------------------------------------------------------ 47*cdf0e10cSrcweir // 48*cdf0e10cSrcweir //------------------------------------------------------------------------ 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir namespace /* private */ 51*cdf0e10cSrcweir { 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst"); 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir }; 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir //------------------------------------------------------------------------ 58*cdf0e10cSrcweir // defines 59*cdf0e10cSrcweir //------------------------------------------------------------------------ 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir #define HELPPOPUPWND_CLASS_NAME TEXT("hlppopupwnd###") 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir const sal_Int32 MAX_CHARS_PER_LINE = 55; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir const sal_Int32 SHADOW_WIDTH = 6; 66*cdf0e10cSrcweir const sal_Int32 SHADOW_HEIGHT = 6; 67*cdf0e10cSrcweir const sal_Int32 SHADOW_OFFSET = 6; 68*cdf0e10cSrcweir const sal_Int32 YOFFSET = 20; 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir const DWORD OUTER_FRAME_COLOR = 0; // black 71*cdf0e10cSrcweir const sal_Int32 OUTER_FRAME_WIDTH = 1; // pixel 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir // it's the standard windows color of an inactive window border 74*cdf0e10cSrcweir const DWORD INNER_FRAME_COLOR = 0xC8D0D4; 75*cdf0e10cSrcweir const sal_Int32 INNER_FRAME_WIDTH = 1; // pixel 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir //--------------------------------------------------- 78*cdf0e10cSrcweir // static member initialization 79*cdf0e10cSrcweir //--------------------------------------------------- 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir osl::Mutex CHelpPopupWindow::s_Mutex; 82*cdf0e10cSrcweir ATOM CHelpPopupWindow::s_ClassAtom = 0; 83*cdf0e10cSrcweir sal_Int32 CHelpPopupWindow::s_RegisterWndClassCount = 0; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir //--------------------------------------------------- 86*cdf0e10cSrcweir // 87*cdf0e10cSrcweir //--------------------------------------------------- 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir CHelpPopupWindow::CHelpPopupWindow( 90*cdf0e10cSrcweir HINSTANCE hInstance, 91*cdf0e10cSrcweir HWND hwndParent ) : 92*cdf0e10cSrcweir m_hMargins( 0 ), 93*cdf0e10cSrcweir m_vMargins( 0 ), 94*cdf0e10cSrcweir m_avCharWidth( 0 ), 95*cdf0e10cSrcweir m_avCharHeight( 0 ), 96*cdf0e10cSrcweir m_hwnd( NULL ), 97*cdf0e10cSrcweir m_hwndParent( hwndParent ), 98*cdf0e10cSrcweir m_hInstance( hInstance ), 99*cdf0e10cSrcweir m_hBitmapShadow( NULL ), 100*cdf0e10cSrcweir m_hBrushShadow( NULL ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir m_bWndClassRegistered = RegisterWindowClass( ) ? sal_True : sal_False; 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir // create a pattern brush for the window shadow 105*cdf0e10cSrcweir WORD aPattern[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir m_hBitmapShadow = CreateBitmap( 8, 8, 1, 1, aPattern ); 108*cdf0e10cSrcweir m_hBrushShadow = CreatePatternBrush( m_hBitmapShadow ); 109*cdf0e10cSrcweir } 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir //--------------------------------------------------- 112*cdf0e10cSrcweir // 113*cdf0e10cSrcweir //--------------------------------------------------- 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir CHelpPopupWindow::~CHelpPopupWindow( ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir // remember: we don't have to destroy the 118*cdf0e10cSrcweir // preview window because it will be destroyed 119*cdf0e10cSrcweir // by it's parent window (the FileOpen dialog) 120*cdf0e10cSrcweir // but we have to unregister the window class 121*cdf0e10cSrcweir if ( m_bWndClassRegistered ) 122*cdf0e10cSrcweir UnregisterWindowClass( ); 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir DeleteObject( m_hBitmapShadow ); 125*cdf0e10cSrcweir DeleteObject( m_hBrushShadow ); 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir //--------------------------------------------------- 129*cdf0e10cSrcweir // 130*cdf0e10cSrcweir //--------------------------------------------------- 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::setText( const rtl::OUString& aHelpText ) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir m_HelpText = aHelpText; 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir //--------------------------------------------------- 138*cdf0e10cSrcweir // 139*cdf0e10cSrcweir //--------------------------------------------------- 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::show( sal_Int32 x, sal_Int32 y ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir OSL_ENSURE( NULL == m_hwnd, "method should not be called twice in sequence" ); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir // we create a window with length and heigth of 0 146*cdf0e10cSrcweir // first in order to get a device context of this 147*cdf0e10cSrcweir // window, then we calculate the upper left corner 148*cdf0e10cSrcweir // and the dimensions and resize the window 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir m_hwnd = CreateWindowEx( 151*cdf0e10cSrcweir NULL, 152*cdf0e10cSrcweir HELPPOPUPWND_CLASS_NAME, 153*cdf0e10cSrcweir NULL, 154*cdf0e10cSrcweir WS_POPUP, 155*cdf0e10cSrcweir 0, 156*cdf0e10cSrcweir 0, 157*cdf0e10cSrcweir 0, 158*cdf0e10cSrcweir 0, 159*cdf0e10cSrcweir m_hwndParent, 160*cdf0e10cSrcweir NULL, 161*cdf0e10cSrcweir m_hInstance, 162*cdf0e10cSrcweir (LPVOID)this ); 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir OSL_ENSURE( m_hwnd, "creating help popup window failed" ); 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir sal_Int32 cx_new; 167*cdf0e10cSrcweir sal_Int32 cy_new; 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir adjustWindowSize( &cx_new, &cy_new ); 170*cdf0e10cSrcweir adjustWindowPos( x, y, cx_new, cy_new ); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir UpdateWindow( m_hwnd ); 173*cdf0e10cSrcweir ShowWindow( m_hwnd, SW_SHOW ); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir //--------------------------------------------------- 177*cdf0e10cSrcweir // 178*cdf0e10cSrcweir //--------------------------------------------------- 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir HWND SAL_CALL CHelpPopupWindow::setParent( HWND hwndNewParent ) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir HWND oldParent = m_hwndParent; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir m_hwndParent = hwndNewParent; 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir return oldParent; 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir //--------------------------------------------------- 190*cdf0e10cSrcweir // calculates the necessary dimensions of the popup 191*cdf0e10cSrcweir // window including the margins etc. 192*cdf0e10cSrcweir //--------------------------------------------------- 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::calcWindowRect( LPRECT lprect ) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir OSL_ASSERT( m_hwnd && lprect ); 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir SetRect( lprect, 0, 0, MAX_CHARS_PER_LINE * m_avCharWidth, 0 ); 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir HDC hdc = GetDC( m_hwnd ); 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir // set the font we are using later 203*cdf0e10cSrcweir HGDIOBJ oldFont = SelectObject( 204*cdf0e10cSrcweir hdc, GetStockObject( DEFAULT_GUI_FONT ) ); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir UINT nFormat = DT_WORDBREAK | DT_CALCRECT | DT_EXTERNALLEADING | DT_LEFT; 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir if ( m_HelpText.getLength( ) <= MAX_CHARS_PER_LINE ) 209*cdf0e10cSrcweir nFormat |= DT_SINGLELINE; 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir DrawText( 212*cdf0e10cSrcweir hdc, 213*cdf0e10cSrcweir reinterpret_cast<LPCTSTR>(m_HelpText.getStr( )), 214*cdf0e10cSrcweir m_HelpText.getLength( ), 215*cdf0e10cSrcweir lprect, 216*cdf0e10cSrcweir nFormat ); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir // add the necessary space for the frames 219*cdf0e10cSrcweir // and margins 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir lprect->bottom += 222*cdf0e10cSrcweir m_vMargins + 223*cdf0e10cSrcweir SHADOW_HEIGHT + 224*cdf0e10cSrcweir OUTER_FRAME_WIDTH * 2 + 225*cdf0e10cSrcweir INNER_FRAME_WIDTH * 2; 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir lprect->right += 228*cdf0e10cSrcweir SHADOW_WIDTH + 229*cdf0e10cSrcweir 2 * m_avCharWidth + 230*cdf0e10cSrcweir OUTER_FRAME_WIDTH * 2 + 231*cdf0e10cSrcweir INNER_FRAME_WIDTH * 2; 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir SelectObject( hdc, oldFont ); 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir ReleaseDC( m_hwnd, hdc ); 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir //--------------------------------------------------- 239*cdf0e10cSrcweir // 240*cdf0e10cSrcweir //--------------------------------------------------- 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::adjustWindowSize( sal_Int32* cx_new, sal_Int32* cy_new ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir OSL_ASSERT( cx_new && cy_new ); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir RECT rect; 247*cdf0e10cSrcweir calcWindowRect( &rect ); 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir // adjust the window size 250*cdf0e10cSrcweir SetWindowPos( 251*cdf0e10cSrcweir m_hwnd, 252*cdf0e10cSrcweir NULL, 253*cdf0e10cSrcweir 0, 254*cdf0e10cSrcweir 0, 255*cdf0e10cSrcweir rect.right, 256*cdf0e10cSrcweir rect.bottom, 257*cdf0e10cSrcweir SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir *cx_new = rect.right; 260*cdf0e10cSrcweir *cy_new = rect.bottom; 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir //--------------------------------------------------- 264*cdf0e10cSrcweir // 265*cdf0e10cSrcweir //--------------------------------------------------- 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::adjustWindowPos( 268*cdf0e10cSrcweir sal_Int32 x, sal_Int32 y, sal_Int32 cx, sal_Int32 cy ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir int popX; 271*cdf0e10cSrcweir int popY; 272*cdf0e10cSrcweir int popWidth; 273*cdf0e10cSrcweir int popHeight; 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir OSL_ASSERT( m_hwnd ); 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir HDC hdc = GetDC( m_hwnd ); 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir // assuming these are screen coordinates 280*cdf0e10cSrcweir popWidth = cx; 281*cdf0e10cSrcweir popHeight = cy; 282*cdf0e10cSrcweir popX = x - ( popWidth / 2 ); 283*cdf0e10cSrcweir popY = y - YOFFSET; 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir int xScreen = GetDeviceCaps( hdc, HORZRES ); 286*cdf0e10cSrcweir int yScreen = GetDeviceCaps( hdc, VERTRES ); 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir if (popX < 0) 289*cdf0e10cSrcweir popX = 0; 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if (popY < 0) 292*cdf0e10cSrcweir popY = 0; 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir if ((popX + popWidth) > xScreen) 295*cdf0e10cSrcweir popX = xScreen - popWidth; 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir if ((popY + popHeight) > yScreen) 298*cdf0e10cSrcweir popY = yScreen - popHeight; 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir SetWindowPos( 301*cdf0e10cSrcweir m_hwnd, 302*cdf0e10cSrcweir NULL, 303*cdf0e10cSrcweir popX, 304*cdf0e10cSrcweir popY, 305*cdf0e10cSrcweir 0, 306*cdf0e10cSrcweir 0, 307*cdf0e10cSrcweir SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ); 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir ReleaseDC( m_hwnd, hdc ); 310*cdf0e10cSrcweir } 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir //--------------------------------------------------- 313*cdf0e10cSrcweir // 314*cdf0e10cSrcweir //--------------------------------------------------- 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::onPaint( HWND hWnd, HDC hdc ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir RECT rc; 319*cdf0e10cSrcweir RECT rect; 320*cdf0e10cSrcweir HGDIOBJ hpen, hpenOld; 321*cdf0e10cSrcweir HGDIOBJ hbrOld; 322*cdf0e10cSrcweir COLORREF oldBkColor; 323*cdf0e10cSrcweir COLORREF oldTextColor; 324*cdf0e10cSrcweir HGDIOBJ oldFont; 325*cdf0e10cSrcweir HGDIOBJ oldBrush; 326*cdf0e10cSrcweir HGDIOBJ hBrush; 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir GetClientRect( hWnd, &rc ); 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir // draw the black border 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir hBrush = CreateSolidBrush( GetSysColor( COLOR_INFOBK ) ); 333*cdf0e10cSrcweir oldBrush = SelectObject( hdc, hBrush ); 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir hpen = CreatePen( PS_SOLID, 0, OUTER_FRAME_COLOR ); 336*cdf0e10cSrcweir hpenOld = SelectObject( hdc, hpen ); 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir Rectangle( hdc, 339*cdf0e10cSrcweir rc.left + OUTER_FRAME_WIDTH, 340*cdf0e10cSrcweir rc.top + OUTER_FRAME_WIDTH, 341*cdf0e10cSrcweir rc.right - SHADOW_WIDTH, 342*cdf0e10cSrcweir rc.bottom - SHADOW_HEIGHT); 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir SelectObject( hdc, oldBrush ); 345*cdf0e10cSrcweir SelectObject( hdc, hpenOld ); 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir DeleteObject( hBrush ); 348*cdf0e10cSrcweir DeleteObject( hpen ); 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir // draw a light gray border 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir hBrush = CreateSolidBrush( GetSysColor( COLOR_INFOBK ) ); 353*cdf0e10cSrcweir oldBrush = SelectObject( hdc, hBrush ); 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir hpen = CreatePen( PS_SOLID, 0, INNER_FRAME_COLOR ); 356*cdf0e10cSrcweir hpenOld = SelectObject( hdc, hpen ); 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir Rectangle( hdc, 359*cdf0e10cSrcweir rc.left + OUTER_FRAME_WIDTH + 1, 360*cdf0e10cSrcweir rc.top + OUTER_FRAME_WIDTH + 1, 361*cdf0e10cSrcweir rc.right - SHADOW_WIDTH - OUTER_FRAME_WIDTH, 362*cdf0e10cSrcweir rc.bottom - SHADOW_HEIGHT - OUTER_FRAME_WIDTH ); 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir SelectObject( hdc, oldBrush ); 365*cdf0e10cSrcweir SelectObject( hdc, hpenOld ); 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir DeleteObject( hBrush ); 368*cdf0e10cSrcweir DeleteObject( hpen ); 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir // Write some text to this window 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir rect.left = rc.left + OUTER_FRAME_WIDTH + INNER_FRAME_WIDTH + 1 + m_hMargins; 373*cdf0e10cSrcweir rect.top = rc.top + OUTER_FRAME_WIDTH + INNER_FRAME_WIDTH + 1 + m_vMargins / 2; 374*cdf0e10cSrcweir rect.right = rc.right - SHADOW_WIDTH - OUTER_FRAME_WIDTH - INNER_FRAME_WIDTH - m_hMargins; 375*cdf0e10cSrcweir rect.bottom = rc.bottom - SHADOW_HEIGHT - OUTER_FRAME_WIDTH - INNER_FRAME_WIDTH - m_vMargins / 2; 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir oldBkColor = SetBkColor( hdc, GetSysColor( COLOR_INFOBK ) ); 378*cdf0e10cSrcweir oldTextColor = SetTextColor( hdc, COLOR_INFOTEXT ); 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir oldFont = SelectObject( hdc, GetStockObject( DEFAULT_GUI_FONT ) ); 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir UINT nFormat = DT_WORDBREAK | DT_EXTERNALLEADING | DT_LEFT; 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if ( m_HelpText.getLength( ) <= MAX_CHARS_PER_LINE ) 385*cdf0e10cSrcweir nFormat |= DT_SINGLELINE; 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir DrawText( 388*cdf0e10cSrcweir hdc, 389*cdf0e10cSrcweir (LPWSTR)m_HelpText.getStr( ), 390*cdf0e10cSrcweir m_HelpText.getLength( ), 391*cdf0e10cSrcweir &rect, 392*cdf0e10cSrcweir nFormat ); 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir SelectObject( hdc, oldFont ); 395*cdf0e10cSrcweir SetTextColor( hdc, oldTextColor ); 396*cdf0e10cSrcweir SetBkColor( hdc, oldBkColor ); 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir // set text color and text background color 399*cdf0e10cSrcweir // see MSDN PatBlt 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir oldBkColor = SetBkColor( hdc, RGB( 0, 0, 0 ) ); 402*cdf0e10cSrcweir oldTextColor = SetTextColor( hdc, RGB( 255, 255, 255 ) ); 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir // Get our brush for the shadow 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir UnrealizeObject( m_hBrushShadow ); 407*cdf0e10cSrcweir hbrOld = SelectObject( hdc, m_hBrushShadow ); 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir // bottom shadow 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir PatBlt(hdc, 412*cdf0e10cSrcweir rc.left + SHADOW_OFFSET, 413*cdf0e10cSrcweir rc.bottom - SHADOW_HEIGHT, 414*cdf0e10cSrcweir rc.right - SHADOW_OFFSET - SHADOW_WIDTH, 415*cdf0e10cSrcweir SHADOW_HEIGHT, 416*cdf0e10cSrcweir 0xA000C9); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir // right-side shadow 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir PatBlt(hdc, 421*cdf0e10cSrcweir rc.right - SHADOW_WIDTH, 422*cdf0e10cSrcweir rc.top + SHADOW_OFFSET, 423*cdf0e10cSrcweir SHADOW_WIDTH, 424*cdf0e10cSrcweir rc.bottom - SHADOW_OFFSET, 425*cdf0e10cSrcweir 0xA000C9); 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir SelectObject(hdc, hbrOld); 428*cdf0e10cSrcweir SetTextColor( hdc, oldTextColor ); 429*cdf0e10cSrcweir SetBkColor( hdc, oldBkColor ); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir //--------------------------------------------------- 433*cdf0e10cSrcweir // 434*cdf0e10cSrcweir //--------------------------------------------------- 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::onNcDestroy() 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir m_hwnd = NULL; 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir //--------------------------------------------------- 442*cdf0e10cSrcweir // 443*cdf0e10cSrcweir //--------------------------------------------------- 444*cdf0e10cSrcweir 445*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::onCreate( HWND hwnd ) 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir m_hwnd = hwnd; 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir HDC hdc = GetDC( m_hwnd ); 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir HGDIOBJ oldFont = SelectObject( 452*cdf0e10cSrcweir hdc, GetStockObject( DEFAULT_GUI_FONT ) ); 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir TEXTMETRIC tm; 455*cdf0e10cSrcweir GetTextMetrics( hdc, &tm ); 456*cdf0e10cSrcweir 457*cdf0e10cSrcweir m_avCharWidth = tm.tmAveCharWidth; 458*cdf0e10cSrcweir m_avCharHeight = tm.tmHeight; 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir if ( 0 == m_hMargins ) 461*cdf0e10cSrcweir m_hMargins = m_avCharWidth; 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir if ( 0 == m_vMargins ) 464*cdf0e10cSrcweir m_vMargins = m_avCharHeight; 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir SelectObject( hdc, oldFont ); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir ReleaseDC( m_hwnd, hdc ); 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir //--------------------------------------------------- 472*cdf0e10cSrcweir // 473*cdf0e10cSrcweir //--------------------------------------------------- 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir LRESULT CALLBACK CHelpPopupWindow::WndProc( 476*cdf0e10cSrcweir HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir LRESULT lResult = 0; 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir switch ( uMsg ) 481*cdf0e10cSrcweir { 482*cdf0e10cSrcweir case WM_CREATE: 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir LPCREATESTRUCT lpcs = 485*cdf0e10cSrcweir reinterpret_cast< LPCREATESTRUCT >( lParam ); 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir OSL_ASSERT( lpcs->lpCreateParams ); 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( 490*cdf0e10cSrcweir lpcs->lpCreateParams ); 491*cdf0e10cSrcweir 492*cdf0e10cSrcweir // connect the instance handle to the window 493*cdf0e10cSrcweir SetProp( hWnd, CURRENT_INSTANCE, pImpl ); 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir pImpl->onCreate( hWnd ); 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir // capture mouse and keybord events 498*cdf0e10cSrcweir SetCapture( hWnd ); 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir break; 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir case WM_PAINT: 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( 505*cdf0e10cSrcweir GetProp( hWnd, CURRENT_INSTANCE ) ); 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir OSL_ASSERT( pImpl ); 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir PAINTSTRUCT ps; 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir BeginPaint(hWnd, &ps); 512*cdf0e10cSrcweir pImpl->onPaint( hWnd, ps.hdc ); 513*cdf0e10cSrcweir EndPaint(hWnd, &ps); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir break; 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir case WM_NCDESTROY: 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir // RemoveProp returns the saved value on success 520*cdf0e10cSrcweir CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( 521*cdf0e10cSrcweir RemoveProp( hWnd, CURRENT_INSTANCE ) ); 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir OSL_ASSERT( pImpl ); 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir pImpl->onNcDestroy(); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir break; 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir case WM_LBUTTONDOWN: 530*cdf0e10cSrcweir case WM_KEYDOWN: 531*cdf0e10cSrcweir case WM_SYSKEYDOWN: 532*cdf0e10cSrcweir case WM_MBUTTONDOWN: 533*cdf0e10cSrcweir case WM_RBUTTONDOWN: 534*cdf0e10cSrcweir ReleaseCapture(); 535*cdf0e10cSrcweir DestroyWindow(hWnd); 536*cdf0e10cSrcweir break; 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir default: 539*cdf0e10cSrcweir return DefWindowProc(hWnd, uMsg, wParam, lParam); 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir return lResult; 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir //--------------------------------------------------- 546*cdf0e10cSrcweir // 547*cdf0e10cSrcweir //--------------------------------------------------- 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir ATOM SAL_CALL CHelpPopupWindow::RegisterWindowClass( ) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir osl::MutexGuard aGuard( s_Mutex ); 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir if ( 0 == s_ClassAtom ) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir // register the window class 556*cdf0e10cSrcweir WNDCLASSEX wndClsEx; 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir ZeroMemory(&wndClsEx, sizeof(wndClsEx)); 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir wndClsEx.cbSize = sizeof(wndClsEx); 561*cdf0e10cSrcweir wndClsEx.lpfnWndProc = CHelpPopupWindow::WndProc; 562*cdf0e10cSrcweir wndClsEx.hInstance = m_hInstance; 563*cdf0e10cSrcweir wndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW); 564*cdf0e10cSrcweir wndClsEx.hbrBackground = (HBRUSH)GetStockObject( NULL_BRUSH ); 565*cdf0e10cSrcweir wndClsEx.lpszClassName = HELPPOPUPWND_CLASS_NAME; 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir // register the preview window class 568*cdf0e10cSrcweir // !!! Win95 - the window class will be unregistered automaticly 569*cdf0e10cSrcweir // if the dll is unloaded 570*cdf0e10cSrcweir // Win2000 - the window class must be unregistered manually 571*cdf0e10cSrcweir // if the dll is unloaded 572*cdf0e10cSrcweir s_ClassAtom = RegisterClassEx( &wndClsEx ); 573*cdf0e10cSrcweir OSL_ASSERT(s_ClassAtom); 574*cdf0e10cSrcweir } 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir // increment the register class counter 577*cdf0e10cSrcweir // so that we keep track of the number 578*cdf0e10cSrcweir // of class registrations 579*cdf0e10cSrcweir if (0 != s_ClassAtom) 580*cdf0e10cSrcweir s_RegisterWndClassCount++; 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir return s_ClassAtom; 583*cdf0e10cSrcweir } 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir //--------------------------------------------------- 586*cdf0e10cSrcweir // 587*cdf0e10cSrcweir //--------------------------------------------------- 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::UnregisterWindowClass( ) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir osl::MutexGuard aGuard( s_Mutex ); 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir OSL_ASSERT( ( (0 != s_ClassAtom) && (s_RegisterWndClassCount > 0)) || 594*cdf0e10cSrcweir ( (0 == s_ClassAtom) && (0 == s_RegisterWndClassCount) ) ); 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir // update the register class counter 597*cdf0e10cSrcweir // and unregister the window class if 598*cdf0e10cSrcweir // counter drops to zero 599*cdf0e10cSrcweir if ( 0 != s_ClassAtom ) 600*cdf0e10cSrcweir { 601*cdf0e10cSrcweir s_RegisterWndClassCount--; 602*cdf0e10cSrcweir OSL_ASSERT( s_RegisterWndClassCount >= 0 ); 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir if ( 0 == s_RegisterWndClassCount ) 606*cdf0e10cSrcweir { 607*cdf0e10cSrcweir if ( !UnregisterClass( 608*cdf0e10cSrcweir (LPCTSTR)MAKELONG( s_ClassAtom, 0 ), m_hInstance ) ) 609*cdf0e10cSrcweir { 610*cdf0e10cSrcweir OSL_ENSURE( false, "unregister window class failed" ); 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir s_ClassAtom = 0; 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir } 616