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