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