1 /*
2  * Icontitle window class.
3  *
4  * Copyright 1997 Alex Korobka
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <user32.h>
22 
23 static BOOL bMultiLineTitle;
24 static HFONT hIconTitleFont;
25 
26 /*********************************************************************
27  * icon title class descriptor
28  */
29 const struct builtin_class_descr ICONTITLE_builtin_class =
30 {
31     WC_ICONTITLE,     /* name */
32     0,                /* style */
33     NULL,             /* procA (winproc is Unicode only) */
34     IconTitleWndProc, /* procW */
35     0,                /* extra */
36     IDC_ARROW,        /* cursor */
37     0                 /* brush */
38 };
39 
40 
41 
42 #ifndef __REACTOS__
43 /***********************************************************************
44  *           ICONTITLE_Create
45  */
ICONTITLE_Create(HWND owner)46 HWND ICONTITLE_Create( HWND owner )
47 {
48     HWND hWnd;
49     HINSTANCE instance = (HINSTANCE)GetWindowLongPtrA( owner, GWLP_HINSTANCE );
50     LONG style = WS_CLIPSIBLINGS;
51 
52     if (!IsWindowEnabled(owner)) style |= WS_DISABLED;
53     if( GetWindowLongPtrA( owner, GWL_STYLE ) & WS_CHILD )
54 	hWnd = CreateWindowExA( 0, (LPCSTR)ICONTITLE_CLASS_ATOM, NULL,
55                                 style | WS_CHILD, 0, 0, 1, 1,
56                                 GetParent(owner), 0, instance, NULL );
57     else
58 	hWnd = CreateWindowExA( 0, (LPCSTR)ICONTITLE_CLASS_ATOM, NULL,
59                                 style, 0, 0, 1, 1,
60                                 owner, 0, instance, NULL );
61     WIN_SetOwner( hWnd, owner );  /* MDI depends on this */
62     SetWindowLongPtrW( hWnd, GWL_STYLE,
63                        GetWindowLongPtrW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
64     return hWnd;
65 }
66 #endif
67 
68 /***********************************************************************
69  *           ICONTITLE_SetTitlePos
70  */
ICONTITLE_SetTitlePos(HWND hwnd,HWND owner)71 static BOOL ICONTITLE_SetTitlePos( HWND hwnd, HWND owner )
72 {
73     static const WCHAR emptyTitleText[] = {'<','.','.','.','>',0};
74     WCHAR str[80];
75     HDC hDC;
76     HFONT hPrevFont;
77     RECT rect;
78     INT cx, cy;
79     POINT pt;
80 
81     int length = GetWindowTextW( owner, str, sizeof(str)/sizeof(WCHAR) );
82 
83     while (length && str[length - 1] == ' ') /* remove trailing spaces */
84         str[--length] = 0;
85 
86     if( !length )
87     {
88         strcpyW( str, emptyTitleText );
89         length = strlenW( str );
90     }
91 
92     if (!(hDC = GetDC( hwnd ))) return FALSE;
93 
94     hPrevFont = SelectObject( hDC, hIconTitleFont );
95 
96     SetRect( &rect, 0, 0, GetSystemMetrics(SM_CXICONSPACING) -
97              GetSystemMetrics(SM_CXBORDER) * 2,
98              GetSystemMetrics(SM_CYBORDER) * 2 );
99 
100     DrawTextW( hDC, str, length, &rect, DT_CALCRECT | DT_CENTER | DT_NOPREFIX | DT_WORDBREAK |
101                (( bMultiLineTitle ) ? 0 : DT_SINGLELINE) );
102 
103     SelectObject( hDC, hPrevFont );
104     ReleaseDC( hwnd, hDC );
105 
106     cx = rect.right - rect.left +  4 * GetSystemMetrics(SM_CXBORDER);
107     cy = rect.bottom - rect.top;
108 
109     pt.x = (GetSystemMetrics(SM_CXICON) - cx) / 2;
110     pt.y = GetSystemMetrics(SM_CYICON);
111 
112     /* point is relative to owner, make it relative to parent */
113     MapWindowPoints( owner, GetParent(hwnd), &pt, 1 );
114 
115     SetWindowPos( hwnd, owner, pt.x, pt.y, cx, cy, SWP_NOACTIVATE );
116     return TRUE;
117 }
118 
119 /***********************************************************************
120  *           ICONTITLE_Paint
121  */
ICONTITLE_Paint(HWND hwnd,HWND owner,HDC hDC,BOOL bActive)122 static BOOL ICONTITLE_Paint( HWND hwnd, HWND owner, HDC hDC, BOOL bActive )
123 {
124     RECT rect;
125     HFONT hPrevFont;
126     HBRUSH hBrush;
127     COLORREF textColor = 0;
128 
129     if( bActive )
130     {
131 	hBrush = GetSysColorBrush(COLOR_ACTIVECAPTION);
132 	textColor = GetSysColor(COLOR_CAPTIONTEXT);
133     }
134     else
135     {
136         if( GetWindowLongPtrA( hwnd, GWL_STYLE ) & WS_CHILD )
137 	{
138 	    hBrush = (HBRUSH) GetClassLongPtrW(hwnd, GCLP_HBRBACKGROUND);
139 	    if( hBrush )
140 	    {
141 		INT level;
142 		LOGBRUSH logBrush;
143 		GetObjectA( hBrush, sizeof(logBrush), &logBrush );
144 		level = GetRValue(logBrush.lbColor) +
145 			   GetGValue(logBrush.lbColor) +
146 			      GetBValue(logBrush.lbColor);
147 		if( level < (0x7F * 3) )
148 		    textColor = RGB( 0xFF, 0xFF, 0xFF );
149 	    }
150 	    else
151 		hBrush = GetStockObject( WHITE_BRUSH );
152 	}
153 	else
154 	{
155 	    hBrush = GetStockObject( BLACK_BRUSH );
156 	    textColor = RGB( 0xFF, 0xFF, 0xFF );
157 	}
158     }
159 
160     GetClientRect( hwnd, &rect );
161     DPtoLP( hDC, (LPPOINT)&rect, 2 );
162     FillRect( hDC, &rect, hBrush );
163 
164     hPrevFont = SelectObject( hDC, hIconTitleFont );
165     if( hPrevFont )
166     {
167 	WCHAR buffer[80];
168 
169         INT length = GetWindowTextW( owner, buffer, sizeof(buffer)/sizeof(buffer[0]) );
170         SetTextColor( hDC, textColor );
171         SetBkMode( hDC, TRANSPARENT );
172 
173         DrawTextW( hDC, buffer, length, &rect, DT_CENTER | DT_NOPREFIX |
174                    DT_WORDBREAK | ((bMultiLineTitle) ? 0 : DT_SINGLELINE) );
175 
176 	SelectObject( hDC, hPrevFont );
177     }
178     return (hPrevFont != 0);
179 }
180 
181 /***********************************************************************
182  *           IconTitleWndProc
183  */
IconTitleWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)184 LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg,
185                                  WPARAM wParam, LPARAM lParam )
186 {
187     HWND owner = GetWindow( hWnd, GW_OWNER );
188 
189     if (!IsWindow(hWnd)) return 0;
190 
191     switch( msg )
192     {
193         case WM_CREATE:
194             if (!hIconTitleFont)
195             {
196                 LOGFONTA logFont;
197                 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
198                 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &bMultiLineTitle, 0 );
199                 hIconTitleFont = CreateFontIndirectA( &logFont );
200             }
201             return (hIconTitleFont ? 0 : -1);
202 	case WM_NCHITTEST:
203 	     return HTCAPTION;
204 	case WM_NCMOUSEMOVE:
205 	case WM_NCLBUTTONDBLCLK:
206 	     return SendMessageW( owner, msg, wParam, lParam );
207 	case WM_ACTIVATE:
208 	     if( wParam ) SetActiveWindow( owner );
209              return 0;
210 	case WM_CLOSE:
211 	     return 0;
212 	case WM_SHOWWINDOW:
213              if (wParam) ICONTITLE_SetTitlePos( hWnd, owner );
214 	     return 0;
215 	case WM_ERASEBKGND:
216             if( GetWindowLongPtrW( owner, GWL_STYLE ) & WS_CHILD )
217                 lParam = SendMessageW( owner, WM_ISACTIVEICON, 0, 0 );
218             else
219                 lParam = (owner == GetActiveWindow());
220             if( ICONTITLE_Paint( hWnd, owner, (HDC)wParam, (BOOL)lParam ) )
221                 ValidateRect( hWnd, NULL );
222             return 1;
223     }
224     return DefWindowProcW( hWnd, msg, wParam, lParam );
225 }
226