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
10*b557fc96SAndrew Rist *
11*b557fc96SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b557fc96SAndrew Rist *
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.
19*b557fc96SAndrew Rist *
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
CHelpPopupWindow(HINSTANCE hInstance,HWND hwndParent)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
~CHelpPopupWindow()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
setText(const rtl::OUString & aHelpText)128cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::setText( const rtl::OUString& aHelpText )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir m_HelpText = aHelpText;
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
133cdf0e10cSrcweir //---------------------------------------------------
134cdf0e10cSrcweir //
135cdf0e10cSrcweir //---------------------------------------------------
136cdf0e10cSrcweir
show(sal_Int32 x,sal_Int32 y)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
setParent(HWND hwndNewParent)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
calcWindowRect(LPRECT lprect)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
adjustWindowSize(sal_Int32 * cx_new,sal_Int32 * cy_new)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
adjustWindowPos(sal_Int32 x,sal_Int32 y,sal_Int32 cx,sal_Int32 cy)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
onPaint(HWND hWnd,HDC hdc)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
onNcDestroy()432cdf0e10cSrcweir void SAL_CALL CHelpPopupWindow::onNcDestroy()
433cdf0e10cSrcweir {
434cdf0e10cSrcweir m_hwnd = NULL;
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir //---------------------------------------------------
438cdf0e10cSrcweir //
439cdf0e10cSrcweir //---------------------------------------------------
440cdf0e10cSrcweir
onCreate(HWND hwnd)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
WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)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
RegisterWindowClass()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
UnregisterWindowClass()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