source: trunk/doc/swt002.html@ 23

Last change on this file since 23 was 9, checked in by lpino, 18 years ago
  • Initial commit
File size: 16.9 KB
Line 
1<?xml version='1.0' encoding='UTF-8'?>
2<?xml-stylesheet type="text/css"
3href="eclipseos2-xxe.css"
4?>
5<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
6"xhtml1-strict.dtd">
7<html>
8 <head>
9 <link type="text/css"
10 href="eclipseos2.css"
11 rel="stylesheet" />
12
13 <title>Eclipse for OS/2 Transitional Project Notes</title>
14 </head>
15
16 <body>
17 <h1>SWT Step 2. Basics of GUI, part 1</h1>
18
19 <h2>Objective</h2>
20
21 <p>Implement the basic SWT class hierarchy: from <code>o.e.swt.widgets.Widget</code>
22 to <code>o.e.swt.widgets.Shell</code> to be able to create windows in the
23 context of SWT. This will allow to do many other things just as they
24 should be done. The test example should create and show two SWT windows:
25 the top shell (filled with the default SWT background color, without any
26 content) and the secondary shell (also empty) which is always above the
27 top shell. Also it should handle the event queue in minimal, i.e. react to
28 the close action, clean up correctly and exit.</p>
29
30 <h2>Task notes</h2>
31
32 <h3>Device contexts</h3>
33
34 <p>In fact, that there are two different layers of output device
35 abstraction in OS/2: device contexts and presentation spaces, as opposed
36 to Windows where the device context plays the role of both -- and handle
37 to it is just allocated and returned by <code>Drawable.internal_new_GC()</code>
38 method which is overriden for different types of devices. In OS/2 we use
39 the presentation space handle as a return value of the <code>internal_new_GC()</code>.
40 The handle to the device context is stored in the <code>GCData.hdc</code>
41 field if non-null GCData object is passed to the <code>internal_new_GC()</code>.</p>
42
43 <p>For windows, the device context is not really opened by the
44 <code>internal_new_GC()</code>, the handle to it is just obtained via
45 <code>OS.GpiQueryDevice()</code> call with the presentation space handle
46 of the window passed as an argument. Correspondingly, it is not closed by
47 the <code>internal_dispose_GC()</code>.</p>
48
49 <p>For other devices, that require the real creation of the device context
50 (which, together with the creation of the presentation space and
51 associating the latter with the former, is made inside the <code>internal_new_GC()</code>),
52 the GCData object passed in should not be <code>null</code>, because the
53 handle of the device context will be necessary to correctly close this
54 context by the <code>internal_dispose_GC()</code>.</p>
55
56 <h4>Win32 API to OS/2 PM API mappings relative to device contexts</h4>
57
58 <p>Below is the approximate correspondence between Windows device context
59 functions and OS/2 ones:</p>
60
61 <table>
62 <tr>
63 <td><b>Windows GUI API</b></td>
64
65 <td><b>OS/2 PM API</b></td>
66
67 <td><b>Remarks</b></td>
68 </tr>
69
70 <tr>
71 <td>hDC = BeginPaint(hwnd...)</td>
72
73 <td>hps = WinBeginPaint(hwnd, NULL...) [Cached PS]</td>
74
75 <td>To draw during WM_PAINT message</td>
76 </tr>
77
78 <tr>
79 <td>EndPaint(hwnd...)</td>
80
81 <td>WinEndPaint(hps)</td>
82
83 <td></td>
84 </tr>
85
86 <tr>
87 <td>hDC = GetDC(hwnd) or hDC = GetWindowDC(hwnd)</td>
88
89 <td>hps = WinGetPS(hwnd), hps = WinGetScreenPS(hwndDesktop) [Cached
90 PS]</td>
91
92 <td>To draw during any message</td>
93 </tr>
94
95 <tr>
96 <td>ReleaseDC(hwnd, hDC)</td>
97
98 <td>WinReleasePS(hps)</td>
99
100 <td></td>
101 </tr>
102
103 <tr>
104 <td>hDC = CreateDC(...)</td>
105
106 <td>hdc = WinOpenWindowDC(hwnd) or DevOpenDC(...), hps =
107 GpiCreatePS(hab, hdc...) [Micro/Normal PS]</td>
108
109 <td>To dtaw on any device (usually display or printer)</td>
110 </tr>
111
112 <tr>
113 <td>DeleteDC(hDC)</td>
114
115 <td>GpiDestroyPS(hps), DevCloseDC(hdc)</td>
116
117 <td></td>
118 </tr>
119
120 <tr>
121 <td>CreateCompatibleDC(hDC)</td>
122
123 <td>hdcCompat = DevOpenDC(...hDC)</td>
124
125 <td>DC compatible with given</td>
126 </tr>
127 </table>
128
129 <h3><a name="ScreenCoordinates">Screen coordinates</a></h3>
130
131 <p>The coordinate space in OS/2 is flipped horizontally when compared to
132 its traditional orientation in the context of windows. That is, the origin
133 of the coordinate space is located in the lower left corner but not in the
134 upper left, as it considered to be in SWT or in Windows, in particular.
135 This should be always kept in mind. The formula to recalculate the
136 <kbd>y</kbd> coordinate of the rectangle from one system to another is
137 very simple: <code>y = parentHeight - (y + height)</code>, where
138 <code>parentHeight</code> is the height of the parent&#39;s space,
139 coordinates of the rectangle are relative to.</p>
140
141 <p>[<i><b>Note</b>: the following information is partially outdated, see
142 <a href="swt004.html#WidgetHeight">here</a></i>] The package method
143 <code>Control.getHeight()</code> can be used by classes within the
144 <code>o.e.swt.widgets</code> package to easily obtain the height of the
145 control itself and/or the height of its parent using <code>parent.getHeight()</code>
146 call (note, that if the parent is <code>null</code> or when the control is
147 a <code>Shell</code> instance, the <code>Display.getHeight()</code> must
148 be used to obtain the parent&#39;s height). Also, the <code>Control.getBounds(SWP)
149 </code>package method returns the height of the control&#39;s parent
150 (respecting the situation when the parent is <code>null</code> or the
151 control is a <code>Shell</code>) as the side effect of its invocation,
152 which is used, for example by the <code>setBounds()</code> method. But for
153 simple calculations the <code>getHeight()</code> method is more preferable
154 since it does less calculations.</p>
155
156 <p>The above applies to all <code>Win*</code> API calls relative to
157 sizing/positioning (such as <code>WinQueryWindowRect()</code>,
158 <code>WinSetWindowPos()</code> and so on). Hopefully, for <code>Gpi*</code>
159 calls we can setup the automatic horizontal flipping of the coordinate
160 space to be done by changing the default view transformation matrix of the
161 window&#39;s presentation space, so there&#39;s no need to do any
162 coordinate conversion when using <code>Gpi*</code> functions (see also
163 task notes in the <a href="swt003.html">SWT Step 003</a>).</p>
164
165 <h3>Windows</h3>
166
167 <p>In OS/2 every window has two types of relationship: parent-child and
168 ownership. In both SWT and Windows there is only the parentship. Although
169 the code for OS/2 related to these things will be a bit more complicated,
170 the situation is very simple: in most cases (window controls) the parent
171 and the owner is be the same. For shells the parent is the Desktop and the
172 owner is null (for top shells) or another shell (for secondary ones). Also
173 for some other windows (such as popup menus) the Desktop willbe the
174 parent. In SWT the term (and the field) <i>parent</i> references to the
175 real parent (the window which confines a child visually) except (not
176 embedded) shells, for which the <i>parent</i> is their owner (the window
177 which receives messages from them).</p>
178
179 <p>In OS/2 the frame window is the composite window of the special class
180 containing the decorative elements such as a titlebar, min/max buttons,
181 scroll bars (which are all windows themselves) as its children and ownees,
182 as opposed to Windows where this decoration is defined just by window
183 style flags in a call to the window creation function. So, the work with
184 frame windows (starting with the Decorations class in the widget
185 hierarchy) in OS/2 is slightly different -- in particular, the
186 <code>Decorations.createHandle()</code> (see below) does some additional
187 calls to create various frame controls (decorative elements) for the frame
188 window being created.</p>
189
190 <p>Dialog windows in OS/2 are just extensions of frame windows, they
191 subclass them and do some additional work (for example, handle the focus
192 traversal over dialog controls and maintain the result code of the dialog
193 window). Possibly, in SWT these windows will not be used at all and their
194 behavior will be just emulated on the basis of the ordinary <code>Shell</code>
195 widget.</p>
196
197 <h4>SWT window creation</h4>
198
199 <p>The common point of the native window creation is the <code>Control.createHandle()</code>
200 method, which is used almost by all subclasses. The logic of its work is
201 as follows:</p>
202
203 <ul>
204 <li>If the <code>Control</code>&#39;s parent is not <code>null</code>
205 the <code>hwndOwner</code> of the window being created is the
206 <code>parent.handle</code>, otherwise <code>null</code>.</li>
207
208 <li>If the <code>Control</code> supplies some nonzero handle value
209 before making a call to its <code>createHandle()</code>method (i.e. in
210 the constructor, before calling the <code>createWidget()</code>) it is
211 used as the window&#39;s <code>hwndParent</code>. Otherwise the
212 <code>parent.handle</code> is used as the <code>hwndParent</code> or
213 <code>HWND_DESKTOP</code> if the parent is <code>null</code>.</li>
214
215 <li>Window class and window style bits are obtained via the
216 <code>windowClass()</code>and <code>widgetStyle()</code>methods,
217 respectively. These methods are usually overrided by subclasses.</li>
218
219 <li>Window is then subclassed in the following way: the <code>Display.windowProc()</code>
220 becomes the new window procedure, which calls the <code>Control.windowProc()</code>,
221 which usually calls the old window procedure via the <code>Control.callWindowProc()</code>.</li>
222 </ul>
223
224 <h2>Step checklist</h2>
225
226 <table>
227 <col width="40%" />
228
229 <col />
230
231 <col width="50%" />
232
233 <thead>
234 <tr>
235 <th>Operation</th>
236
237 <th>Status</th>
238
239 <th>Remarks</th>
240 </tr>
241 </thead>
242
243 <tr>
244 <td>Partially implement the <code>Widget</code> class</td>
245
246 <td>Done [dmik]</td>
247
248 <td>Only the character translation is not implemented.</td>
249 </tr>
250
251 <tr>
252 <td>Partially Implement the <code>GC</code> class</td>
253
254 <td>Delayed</td>
255
256 <td>Almost completely commented. The major work will be done on the
257 step 3.</td>
258 </tr>
259
260 <tr>
261 <td>Add <code>EventTable</code>, <code>Listener</code>, <code>Event</code>,
262 <code>TypedListener</code> to compilation</td>
263
264 <td>Done [dmik]</td>
265
266 <td></td>
267 </tr>
268
269 <tr>
270 <td>Implement <code>Display.internal_new_GC()</code> and <code>Display.internal_dispose_GC()</code></td>
271
272 <td>Done [dmik]</td>
273
274 <td>See Task notes above.</td>
275 </tr>
276
277 <tr>
278 <td>Add <code>o.e.swt.events.*Listener</code>, <code>*Event</code> and
279 <code>*Adapter</code> classes to compilation</td>
280
281 <td>Done [dmik]</td>
282
283 <td></td>
284 </tr>
285
286 <tr>
287 <td>Add <code>o.e.swt.accessibility.*</code> (common and emulated) to
288 compilation</td>
289
290 <td>Done [dmik]</td>
291
292 <td></td>
293 </tr>
294
295 <tr>
296 <td>Add message time obtaining to <code>Widget.sendEvent()</code> and
297 <code>Widget.postEvent()</code></td>
298
299 <td>Done [dmik]</td>
300
301 <td></td>
302 </tr>
303
304 <tr>
305 <td>Implement <code>OS.WinSendMsg</code>, <code>OS.WinPostMsg()</code>,
306 <code>OS.WinQueryMsgTime()</code></td>
307
308 <td>Done [dmik]</td>
309
310 <td></td>
311 </tr>
312
313 <tr>
314 <td>Add standard <code>WM_*</code> constants</td>
315
316 <td>Done [dmik]</td>
317
318 <td>Most of them are commented and will be uncommented on demand</td>
319 </tr>
320
321 <tr>
322 <td>Add standard <code>WC_*</code> constants</td>
323
324 <td>Done [dmik]</td>
325
326 <td>Most of them are commented and will be uncommented on demand.
327 Since they actually are integer values (integer atoms) but natives
328 that use them require PSZ as a class name, a special static method
329 getAtom() is added to PSZ class that returns a string representation
330 of an atom.</td>
331 </tr>
332
333 <tr>
334 <td>Implement the <code>WidgetTable</code> class, <code>OS.Win[Set|Query]Window[ULong|UShort]()</code>
335 and add <code>QW[L|S]_*</code> constants</td>
336
337 <td>Done [dmik]</td>
338
339 <td></td>
340 </tr>
341
342 <tr>
343 <td>Implement the <code>OS.WinQueryClassInfo()</code> and add
344 <code>CLASSINFO</code> class</td>
345
346 <td>Done [dmik]</td>
347
348 <td></td>
349 </tr>
350
351 <tr>
352 <td>Implement <code>OS.WinQueryWindowRect()</code>, <code>OS.WinMapWindowPoints()</code>,
353 <code>RECTL</code> class</td>
354
355 <td>Done [dmik]</td>
356
357 <td></td>
358 </tr>
359
360 <tr>
361 <td>Implement <code>OS.WinIsWindowEnabled()</code>, <code>WinIsWindowVisible()</code>,
362 <code>WinQueryFocus()</code>, <code>WinQueryWindow()</code>,
363 <code>WinShowWindow()</code></td>
364
365 <td>Done [dmik]</td>
366
367 <td></td>
368 </tr>
369
370 <tr>
371 <td>Implement <code>OS.WinGetPS()</code>, <code>WinReleasePS()</code>,
372 <code>WinBeginPaint()</code>, <code>WinEndPaint()</code>,
373 <code>WinInvalidateRect()</code>, <code>WinUpdateWindow()</code></td>
374
375 <td>Done [dmik]</td>
376
377 <td></td>
378 </tr>
379
380 <tr>
381 <td>Implement the <code>OS.WinQuerySysValue()</code> and <code>SV_*</code>
382 constants</td>
383
384 <td>Done [dmik]</td>
385
386 <td></td>
387 </tr>
388
389 <tr>
390 <td>Add the static <code>Display.height</code> field</td>
391
392 <td>Done [dmik]</td>
393
394 <td>This field is used to flip the window coordinate space vertically</td>
395 </tr>
396
397 <tr>
398 <td>Add <code>o.e.swt.internal.pm.MRESULT</code> class</td>
399
400 <td>Done [dmik]</td>
401
402 <td>The reason it was added is that, as opposed to the simple int
403 type, <code>null</code> can be returned by individual message handlers
404 indicating that the message hasn&#39;t been processed and therefore
405 should be passed to the default window procedure.</td>
406 </tr>
407
408 <tr>
409 <td>Implement the helper function <code>OS.WinCallWindowProc()</code></td>
410
411 <td>Done [dmik]</td>
412
413 <td>To get the ability to call the window procedure given as the int
414 value (actually the C pointer to a function)</td>
415 </tr>
416
417 <tr>
418 <td>implement the <code>OS.WinSetWindowPos()</code> and <code>SWP_*</code>
419 constants</td>
420
421 <td>Done [dmik]</td>
422
423 <td></td>
424 </tr>
425
426 <tr>
427 <td>implement the <code>OS.WinCreateFrameControls()</code> and
428 <code>FCF_*</code>, <code>FS_*</code>, <code>FF_*</code> constants</td>
429
430 <td>Done [dmik]</td>
431
432 <td></td>
433 </tr>
434
435 <tr>
436 <td>Implement the <code>OS.WinGetScreenPC()</code> and <code>OS.GpiQueryDevice()</code></td>
437
438 <td>Done [dmik]</td>
439
440 <td></td>
441 </tr>
442
443 <tr>
444 <td>Implement <code>OS.WinQueryWindowTextLength()</code>,
445 <code>WinQueryWindowText()</code>, <code>WinSetWindowText()</code>,
446 add a new constructor to the <code>PSZ</code> class taking an integer
447 as the length of an empty string to create</td>
448
449 <td>Done [dmik]</td>
450
451 <td>Used to get/set shell titles</td>
452 </tr>
453
454 <tr>
455 <td>Implement the <code>OS.WinFillRect()</code> and <code>OS.objcpy()</code>
456 for the <code>RECTL</code> structure</td>
457
458 <td>Done [dmik]</td>
459
460 <td>Needed to handle <code>WM_ERASEBACKGROUND</code> message.</td>
461 </tr>
462
463 <tr>
464 <td>Partially implement the following classes to reach the step
465 objective: <code>o.e.swt.widgets.Control</code>, <code>Scrollable</code>,
466 <code>Composite</code>, <code>Canvas</code>, <code>Decorations</code>,
467 <code>Shell</code> and some others (<code>WidgetTable</code> etc) they
468 depend on</td>
469
470 <td>Done [dmik]</td>
471
472 <td>The majority of work has been done in the Control, Decorations and
473 Shell classes, others are almost fully commented.</td>
474 </tr>
475
476 <tr>
477 <td>Add the <code>SWT002</code> testcase</td>
478
479 <td>Done [dmik]</td>
480
481 <td>Note: <code>WinDestroyWindow()</code> is not called for secondary
482 shells explicitly. It&#39;s a planned behavior of SWT (see the
483 description of the <code>Widget.destroyWidget()</code>). It is
484 suitable for OS/2 when the window&#39;s owner is a <code>WC_FRAME</code>
485 window. See remarks inside the <code>Control.createHandle()</code>.</td>
486 </tr>
487 </table>
488 </body>
489</html>
Note: See TracBrowser for help on using the repository browser.