1 /* AbiSource Application Framework
2  * Copyright (C) 1998 AbiSource, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301 USA.
18  */
19 
20 #include <stdio.h>
21 #include <windows.h>
22 
23 #include "ut_types.h"
24 #include "ut_assert.h"
25 #include "ut_Win32OS.h"
26 #include "gr_Win32Graphics.h"
27 #include "xap_Win32PreviewWidget.h"
28 
29 
30 //////////////////////////////////////////////////////////////////
31 //////////////////////////////////////////////////////////////////
32 
33 #define GWL(hwnd)		(XAP_Win32PreviewWidget *)GetWindowLongPtrW((hwnd), GWLP_USERDATA)
34 #define SWL(hwnd, f)	SetWindowLongPtrW((hwnd), GWLP_USERDATA,(LONG_PTR)(f))
35 
36 //////////////////////////////////////////////////////////////////
37 //////////////////////////////////////////////////////////////////
38 
39 ATOM		    XAP_Win32PreviewWidget::m_atomPreviewWidgetClass = 0;
40 UT_uint32	XAP_Win32PreviewWidget::m_iInstanceCount = 0;
41 wchar_t		XAP_Win32PreviewWidget::m_bufClassName[100];
42 
XAP_Win32PreviewWidget(XAP_Win32App * pWin32App,HWND hwndParent,UINT style)43 XAP_Win32PreviewWidget::XAP_Win32PreviewWidget(XAP_Win32App * pWin32App, HWND hwndParent, UINT style)
44 {
45 	m_hwndPreview = NULL;
46 	m_pWin32App = pWin32App;
47 	m_pGraphics = NULL;
48 	m_pPreview = NULL;
49 	m_pInsertSymbol = NULL;
50 
51 	if(!m_atomPreviewWidgetClass)
52 	{
53 		swprintf(m_bufClassName,L"PreviewWidget");
54 
55 		m_atomPreviewWidgetClass = UT_RegisterClassEx(CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | style,
56 													  _wndProc, m_pWin32App->getInstance(),
57 													  NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE+1), NULL,
58 													  NULL, m_bufClassName);
59 		UT_return_if_fail(m_atomPreviewWidgetClass);
60 	}
61 
62 	RECT rParent;
63 	GetClientRect(hwndParent,&rParent);
64 
65 	m_hwndPreview = UT_CreateWindowEx(0L, m_bufClassName, NULL,
66 								 WS_CHILD|WS_VISIBLE,
67 								 0,0,(rParent.right-rParent.left),(rParent.bottom-rParent.top),
68 								 hwndParent,NULL,m_pWin32App->getInstance(),NULL);
69 	UT_ASSERT(m_hwndPreview);
70 
71 	// bind window back to this object.  note that this will happen
72 	// after WM_Create (and many other messages) have gone thru, but
73 	// before anything we care about.
74 
75 	SWL(m_hwndPreview,this);
76 
77 	// create a GR_Graphics for this window and HDC
78 	GR_Win32AllocInfo ai(GetDC(m_hwndPreview),m_hwndPreview);
79 	m_pGraphics = (GR_Win32Graphics *)XAP_App::getApp()->newGraphics(ai);
80 	UT_ASSERT(m_pGraphics);
81 
82 	m_iInstanceCount++;
83 }
84 
~XAP_Win32PreviewWidget(void)85 XAP_Win32PreviewWidget::~XAP_Win32PreviewWidget(void)
86 {
87 	// destroy the child window we created now so that we can unregister
88 	// the window class.  (it is ok if this fails.)
89 	if (m_hwndPreview)
90 		DestroyWindow(m_hwndPreview);
91 
92 	m_iInstanceCount--;
93 	if(m_iInstanceCount == 0)
94 	{
95 		m_atomPreviewWidgetClass = 0;
96 		UT_DebugOnly<bool> bResult = (UnregisterClassW(m_bufClassName,m_pWin32App->getInstance()) == TRUE);
97 		UT_ASSERT_HARMLESS(bResult);
98 	}
99 
100 	DELETEP(m_pGraphics);
101 }
102 
getWindowSize(UT_uint32 * pWidth,UT_uint32 * pHeight) const103 void XAP_Win32PreviewWidget::getWindowSize(UT_uint32 * pWidth, UT_uint32 * pHeight) const
104 {
105 	RECT r;
106 	GetClientRect(m_hwndPreview,&r);
107 	if (pWidth)
108 		*pWidth = (r.right-r.left);
109 	if (pHeight)
110 		*pHeight = (r.bottom-r.top);
111 	return;
112 }
113 
114 //////////////////////////////////////////////////////////////////
115 //////////////////////////////////////////////////////////////////
116 
_wndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)117 LRESULT CALLBACK XAP_Win32PreviewWidget::_wndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
118 {
119 	// static callback
120 	XAP_Win32PreviewWidget * pThis = GWL(hwnd);
121 	if (!pThis)							// SWL() not yet called in constructor
122 		return UT_DefWindowProc(hwnd,iMsg,wParam,lParam);
123 
124 	// We handle all the windows messages here.  in the simplest type of
125 	// preview widget, all the platform & xp logic does is draw into it
126 	// (a view-only widget).  we send up paint events to help out with
127 	// this.  this is all supported in the base class.
128 	//
129 	// as we make more compilcated preview windows (with output and some
130 	// user input (such as clicking on the edges of a box to enable/disable
131 	// borders on a paragraph or cell), we may need to expand the set of
132 	// actions we propagate.  the intent here is that we will add virtual
133 	// stub functions in this base class (that do nothing) and let them
134 	// be overridden by the more advanced sub-classes.  having said this,
135 	// it sounds fairly obvious, but then most all comments just state
136 	// the obvious.... -- jeff
137 
138 	switch (iMsg)
139 	{
140 	case WM_PAINT:
141 		return pThis->onPaint(hwnd);
142 
143 	case WM_LBUTTONDOWN:
144 		return pThis->onLeftButtonDown(LOWORD(lParam), HIWORD(lParam));
145 
146 	case WM_LBUTTONDBLCLK:
147 		if( pThis->m_pInsertSymbol )
148 		{
149 			pThis->m_pInsertSymbol->doInsertSymbol();
150 			return 0;
151 		}
152 
153 	default:
154 		break;
155 	}
156 
157 	return UT_DefWindowProc(hwnd,iMsg,wParam,lParam);
158 }
159 
160 //////////////////////////////////////////////////////////////////
161 //////////////////////////////////////////////////////////////////
162 
onPaint(HWND hwnd)163 LRESULT XAP_Win32PreviewWidget::onPaint(HWND hwnd)
164 {
165 	UT_ASSERT(hwnd == m_hwndPreview);
166 
167 	PAINTSTRUCT ps;
168 	/*HDC hdc =*/ BeginPaint(hwnd, &ps);
169 
170 	if (m_pPreview)
171 		m_pPreview->draw();
172 
173 	EndPaint(hwnd, &ps);
174 	return 0;
175 }
176 
onLeftButtonDown(UT_sint32 x,UT_sint32 y)177 LRESULT	XAP_Win32PreviewWidget::onLeftButtonDown(UT_sint32 x, UT_sint32 y)
178 {
179 	if (m_pPreview)
180 		m_pPreview->onLeftButtonDown(x, y);
181 
182 	return 0;
183 }
184