Commit | Line | Data |
---|---|---|
35bc1fdc IZ |
1 | package OS2::localMorphPM; |
2 | ||
3 | sub new { my ($c,$f) = @_; OS2::MorphPM($f); bless [shift], $c } | |
4 | sub DESTROY { OS2::UnMorphPM(shift->[0]) } | |
5 | ||
760ac839 LW |
6 | package OS2::Process; |
7 | ||
35bc1fdc IZ |
8 | BEGIN { |
9 | require Exporter; | |
10 | require DynaLoader; | |
11 | #require AutoLoader; | |
7f61b687 | 12 | |
35bc1fdc IZ |
13 | @ISA = qw(Exporter DynaLoader); |
14 | $VERSION = "1.0"; | |
15 | bootstrap OS2::Process; | |
16 | } | |
760ac839 | 17 | |
760ac839 LW |
18 | # Items to export into callers namespace by default. Note: do not export |
19 | # names by default without a very good reason. Use EXPORT_OK instead. | |
20 | # Do not simply export all your public functions/methods/constants. | |
21 | @EXPORT = qw( | |
22 | P_BACKGROUND | |
23 | P_DEBUG | |
24 | P_DEFAULT | |
25 | P_DETACH | |
26 | P_FOREGROUND | |
27 | P_FULLSCREEN | |
28 | P_MAXIMIZE | |
29 | P_MINIMIZE | |
30 | P_NOCLOSE | |
31 | P_NOSESSION | |
32 | P_NOWAIT | |
33 | P_OVERLAY | |
34 | P_PM | |
35 | P_QUOTE | |
36 | P_SESSION | |
37 | P_TILDE | |
38 | P_UNRELATED | |
39 | P_WAIT | |
40 | P_WINDOWED | |
7f61b687 IZ |
41 | my_type |
42 | file_type | |
43 | T_NOTSPEC | |
44 | T_NOTWINDOWCOMPAT | |
45 | T_WINDOWCOMPAT | |
46 | T_WINDOWAPI | |
47 | T_BOUND | |
48 | T_DLL | |
49 | T_DOS | |
50 | T_PHYSDRV | |
51 | T_VIRTDRV | |
52 | T_PROTDLL | |
53 | T_32BIT | |
35bc1fdc IZ |
54 | ppid |
55 | ppidOf | |
56 | sidOf | |
57 | scrsize | |
58 | scrsize_set | |
7f61b687 | 59 | process_entry |
35bc1fdc IZ |
60 | process_entries |
61 | process_hentry | |
62 | process_hentries | |
63 | change_entry | |
64 | change_entryh | |
65 | Title_set | |
66 | Title | |
67 | WindowText | |
68 | WindowText_set | |
69 | WindowPos | |
70 | WindowPos_set | |
71 | WindowProcess | |
72 | SwitchToProgram | |
73 | ActiveWindow | |
74 | ClassName | |
75 | FocusWindow | |
76 | FocusWindow_set | |
77 | ShowWindow | |
78 | PostMsg | |
79 | BeginEnumWindows | |
80 | EndEnumWindows | |
81 | GetNextWindow | |
82 | IsWindow | |
83 | ChildWindows | |
84 | out_codepage | |
85 | out_codepage_set | |
86 | in_codepage | |
87 | in_codepage_set | |
88 | cursor | |
89 | cursor_set | |
90 | screen | |
91 | screen_set | |
92 | process_codepages | |
93 | QueryWindow | |
94 | WindowFromId | |
95 | WindowFromPoint | |
96 | EnumDlgItem | |
760ac839 | 97 | ); |
35bc1fdc | 98 | |
760ac839 LW |
99 | sub AUTOLOAD { |
100 | # This AUTOLOAD is used to 'autoload' constants from the constant() | |
101 | # XS function. If a constant is not found then control is passed | |
102 | # to the AUTOLOAD in AutoLoader. | |
103 | ||
104 | local($constname); | |
105 | ($constname = $AUTOLOAD) =~ s/.*:://; | |
106 | $val = constant($constname, @_ ? $_[0] : 0); | |
107 | if ($! != 0) { | |
9c024a02 | 108 | if ($! =~ /Invalid/ || $!{EINVAL}) { |
760ac839 LW |
109 | $AutoLoader::AUTOLOAD = $AUTOLOAD; |
110 | goto &AutoLoader::AUTOLOAD; | |
111 | } | |
112 | else { | |
113 | ($pack,$file,$line) = caller; | |
114 | die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line. | |
115 | "; | |
116 | } | |
117 | } | |
118 | eval "sub $AUTOLOAD { $val }"; | |
119 | goto &$AUTOLOAD; | |
120 | } | |
121 | ||
760ac839 LW |
122 | # Preloaded methods go here. |
123 | ||
35bc1fdc IZ |
124 | sub Title () { (process_entry())[0] } |
125 | ||
126 | # *Title_set = \&sesmgr_title_set; | |
127 | ||
128 | sub swTitle_set_sw { | |
129 | my ($title, @sw) = @_; | |
130 | $sw[0] = $title; | |
131 | change_entry(@sw); | |
132 | } | |
133 | ||
134 | sub swTitle_set { | |
135 | my (@sw) = process_entry(); | |
136 | swTitle_set_sw(shift, @sw); | |
137 | } | |
138 | ||
139 | sub winTitle_set_sw { | |
140 | my ($title, @sw) = @_; | |
141 | my $h = OS2::localMorphPM->new(0); | |
142 | WindowText_set $sw[1], $title; | |
143 | } | |
144 | ||
145 | sub winTitle_set { | |
146 | my (@sw) = process_entry(); | |
147 | winTitle_set_sw(shift, @sw); | |
148 | } | |
149 | ||
150 | sub bothTitle_set { | |
151 | my (@sw) = process_entry(); | |
152 | my $t = shift; | |
153 | winTitle_set_sw($t, @sw); | |
154 | swTitle_set_sw($t, @sw); | |
155 | } | |
156 | ||
157 | sub Title_set { | |
158 | my $t = shift; | |
159 | return 1 if sesmgr_title_set($t); | |
160 | return 0 unless $^E == 372; | |
161 | my (@sw) = process_entry(); | |
162 | winTitle_set_sw($t, @sw); | |
163 | swTitle_set_sw($t, @sw); | |
164 | } | |
165 | ||
166 | sub process_entry { swentry_expand(process_swentry(@_)) } | |
167 | ||
168 | our @hentry_fields = qw( title owner_hwnd icon_hwnd | |
169 | owner_phandle owner_pid owner_sid | |
170 | visible nonswitchable jumpable ptype sw_entry ); | |
171 | ||
172 | sub swentry_hexpand ($) { | |
173 | my %h; | |
174 | @h{@hentry_fields} = swentry_expand(shift); | |
175 | \%h; | |
176 | } | |
177 | ||
178 | sub process_hentry { swentry_hexpand(process_swentry(@_)) } | |
179 | ||
180 | my $swentry_size = swentry_size(); | |
181 | ||
182 | sub sw_entries () { | |
183 | my $s = swentries_list(); | |
184 | my ($c, $s1) = unpack 'La*', $s; | |
185 | die "Unconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s; | |
186 | my (@l, $e); | |
187 | push @l, $e while $e = substr $s1, 0, $swentry_size, ''; | |
188 | @l; | |
189 | } | |
190 | ||
191 | sub process_entries () { | |
192 | map [swentry_expand($_)], sw_entries; | |
193 | } | |
194 | ||
195 | sub process_hentries () { | |
196 | map swentry_hexpand($_), sw_entries; | |
197 | } | |
198 | ||
199 | sub change_entry { | |
200 | change_swentry(create_swentry(@_)); | |
201 | } | |
202 | ||
203 | sub create_swentryh ($) { | |
204 | my $h = shift; | |
205 | create_swentry(@$h{@hentry_fields}); | |
206 | } | |
207 | ||
208 | sub change_entryh ($) { | |
209 | change_swentry(create_swentryh(shift)); | |
210 | } | |
211 | ||
212 | # Massage entries into the same order as WindowPos_set: | |
213 | sub WindowPos ($) { | |
214 | my ($fl, $w, $h, $x, $y, $behind, $hwnd, @rest) | |
215 | = unpack 'L l4 L4', WindowSWP(shift); | |
216 | ($x, $y, $fl, $w, $h, $behind, @rest); | |
217 | } | |
218 | ||
219 | sub ChildWindows ($) { | |
220 | my @kids; | |
221 | my $h = BeginEnumWindows shift; | |
222 | my $w; | |
223 | push @kids, $w while $w = GetNextWindow $h; | |
224 | EndEnumWindows $h; | |
225 | @kids; | |
226 | } | |
7f61b687 | 227 | |
760ac839 LW |
228 | # Autoload methods go after __END__, and are processed by the autosplit program. |
229 | ||
230 | 1; | |
231 | __END__ | |
232 | ||
233 | =head1 NAME | |
234 | ||
35bc1fdc | 235 | OS2::Process - exports constants for system() call, and process control on OS2. |
760ac839 LW |
236 | |
237 | =head1 SYNOPSIS | |
238 | ||
239 | use OS2::Process; | |
35bc1fdc | 240 | $pid = system(P_PM | P_BACKGROUND, "epm.exe"); |
760ac839 LW |
241 | |
242 | =head1 DESCRIPTION | |
243 | ||
35bc1fdc IZ |
244 | =head2 Optional argument to system() |
245 | ||
760ac839 LW |
246 | the builtin function system() under OS/2 allows an optional first |
247 | argument which denotes the mode of the process. Note that this argument is | |
248 | recognized only if it is strictly numerical. | |
249 | ||
250 | You can use either one of the process modes: | |
251 | ||
252 | P_WAIT (0) = wait until child terminates (default) | |
253 | P_NOWAIT = do not wait until child terminates | |
254 | P_SESSION = new session | |
255 | P_DETACH = detached | |
256 | P_PM = PM program | |
257 | ||
258 | and optionally add PM and session option bits: | |
259 | ||
260 | P_DEFAULT (0) = default | |
261 | P_MINIMIZE = minimized | |
262 | P_MAXIMIZE = maximized | |
263 | P_FULLSCREEN = fullscreen (session only) | |
264 | P_WINDOWED = windowed (session only) | |
265 | ||
266 | P_FOREGROUND = foreground (if running in foreground) | |
267 | P_BACKGROUND = background | |
268 | ||
269 | P_NOCLOSE = don't close window on exit (session only) | |
270 | ||
271 | P_QUOTE = quote all arguments | |
272 | P_TILDE = MKS argument passing convention | |
273 | P_UNRELATED = do not kill child when father terminates | |
274 | ||
7f61b687 IZ |
275 | =head2 Access to process properties |
276 | ||
35bc1fdc IZ |
277 | On OS/2 processes have the usual I<parent/child> semantic; |
278 | additionally, there is a hierarchy of sessions with their own | |
279 | I<parent/child> tree. A session is either a FS session, or a windowed | |
280 | pseudo-session created by PM. A session is a "unit of user | |
281 | interaction", a change to in/out settings in one of them does not | |
282 | affect other sessions. | |
7f61b687 | 283 | |
88c28ceb | 284 | =over |
7f61b687 | 285 | |
35bc1fdc IZ |
286 | =item my_type() |
287 | ||
288 | returns the type of the current process (one of | |
289 | "FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error. | |
290 | ||
291 | =item C<file_type(file)> | |
7f61b687 IZ |
292 | |
293 | returns the type of the executable file C<file>, or | |
294 | dies on error. The bits 0-2 of the result contain one of the values | |
295 | ||
88c28ceb | 296 | =over |
7f61b687 IZ |
297 | |
298 | =item C<T_NOTSPEC> (0) | |
299 | ||
35bc1fdc | 300 | Application type is not specified in the executable header. |
7f61b687 IZ |
301 | |
302 | =item C<T_NOTWINDOWCOMPAT> (1) | |
303 | ||
35bc1fdc | 304 | Application type is not-window-compatible. |
7f61b687 IZ |
305 | |
306 | =item C<T_WINDOWCOMPAT> (2) | |
307 | ||
35bc1fdc | 308 | Application type is window-compatible. |
7f61b687 IZ |
309 | |
310 | =item C<T_WINDOWAPI> (3) | |
311 | ||
312 | Application type is window-API. | |
313 | ||
314 | =back | |
315 | ||
316 | The remaining bits should be masked with the following values to | |
317 | determine the type of the executable: | |
318 | ||
88c28ceb | 319 | =over |
7f61b687 IZ |
320 | |
321 | =item C<T_BOUND> (8) | |
322 | ||
323 | Set to 1 if the executable file has been "bound" (by the BIND command) | |
324 | as a Family API application. Bits 0, 1, and 2 still apply. | |
325 | ||
326 | =item C<T_DLL> (0x10) | |
327 | ||
328 | Set to 1 if the executable file is a dynamic link library (DLL) | |
329 | module. Bits 0, 1, 2, 3, and 5 will be set to 0. | |
330 | ||
331 | =item C<T_DOS> (0x20) | |
332 | ||
333 | Set to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3, | |
334 | and 4 will be set to 0. | |
335 | ||
336 | =item C<T_PHYSDRV> (0x40) | |
337 | ||
35bc1fdc | 338 | Set to 1 if the executable file is a physical device driver. |
7f61b687 IZ |
339 | |
340 | =item C<T_VIRTDRV> (0x80) | |
341 | ||
35bc1fdc | 342 | Set to 1 if the executable file is a virtual device driver. |
7f61b687 IZ |
343 | |
344 | =item C<T_PROTDLL> (0x100) | |
345 | ||
346 | Set to 1 if the executable file is a protected-memory dynamic link | |
347 | library module. | |
348 | ||
349 | =item C<T_32BIT> (0x4000) | |
350 | ||
35bc1fdc | 351 | Set to 1 for 32-bit executable files. |
7f61b687 IZ |
352 | |
353 | =back | |
354 | ||
355 | file_type() may croak with one of the strings C<"Invalid EXE | |
356 | signature"> or C<"EXE marked invalid"> to indicate typical error | |
357 | conditions. If given non-absolute path, will look on C<PATH>, will | |
358 | add extention F<.exe> if no extension is present (add extension F<.> | |
359 | to suppress). | |
360 | ||
35bc1fdc IZ |
361 | =item C<@list = process_codepages()> |
362 | ||
363 | the first element is the currently active codepage, up to 2 additional | |
364 | entries specify the system's "prepared codepages": the codepages the | |
365 | user can switch to. The active codepage of a process is one of the | |
366 | prepared codepages of the system (if present). | |
367 | ||
368 | =item C<process_codepage_set($cp)> | |
369 | ||
370 | sets the currently active codepage. [Affects printer output, in/out | |
371 | codepages of sessions started by this process, and the default | |
372 | codepage for drawing in PM; is inherited by kids. Does not affect the | |
373 | out- and in-codepages of the session.] | |
374 | ||
375 | =item ppid() | |
376 | ||
377 | returns the PID of the parent process. | |
378 | ||
379 | =item C<ppidOf($pid = $$)> | |
380 | ||
381 | returns the PID of the parent process of $pid. -1 on error. | |
382 | ||
383 | =item C<sidOf($pid = $$)> | |
384 | ||
385 | returns the session id of the process id $pid. -1 on error. | |
386 | ||
387 | =back | |
388 | ||
389 | =head2 Control of VIO sessions | |
390 | ||
391 | VIO applications are applications running in a text-mode session. | |
392 | ||
393 | =over | |
394 | ||
395 | =item out_codepage() | |
396 | ||
397 | gets code page used for screen output (glyphs). -1 means that a user font | |
398 | was loaded. | |
399 | ||
400 | =item C<out_codepage_set($cp)> | |
401 | ||
402 | sets code page used for screen output (glyphs). -1 switches to a preloaded | |
403 | user font. -2 switches off the preloaded user font. | |
404 | ||
405 | =item in_codepage() | |
406 | ||
407 | gets code page used for keyboard input. 0 means that a hardware codepage | |
408 | is used. | |
409 | ||
410 | =item C<in_codepage_set($cp)> | |
411 | ||
412 | sets code page used for keyboard input. | |
413 | ||
414 | =item C<($w, $h) = scrsize()> | |
415 | ||
416 | width and height of the given console window in character cells. | |
417 | ||
418 | =item C<scrsize_set([$w, ] $h)> | |
419 | ||
420 | set height (and optionally width) of the given console window in | |
421 | character cells. Use 0 size to keep the old size. | |
422 | ||
423 | =item C<($s, $e, $w, $a) = cursor()> | |
424 | ||
425 | gets start/end lines of the blinking cursor in the charcell, its width | |
426 | (1 on text modes) and attribute (-1 for hidden, in text modes other | |
427 | values mean visible, in graphic modes color). | |
428 | ||
429 | =item C<cursor_set($s, $e, [$w [, $a]])> | |
430 | ||
431 | sets start/end lines of the blinking cursor in the charcell. Negative | |
432 | values mean percents of the character cell height. | |
433 | ||
434 | =item screen() | |
435 | ||
436 | gets a buffer with characters and attributes of the screen. | |
437 | ||
438 | =item C<screen_set($buffer)> | |
439 | ||
440 | restores the screen given the result of screen(). | |
441 | ||
442 | =back | |
443 | ||
444 | =head2 Control of the process list | |
445 | ||
446 | With the exception of Title_set(), all these calls require that PM is | |
447 | running, they would not work under alternative Session Managers. | |
448 | ||
449 | =over | |
450 | ||
7f61b687 IZ |
451 | =item process_entry() |
452 | ||
453 | returns a list of the following data: | |
454 | ||
88c28ceb | 455 | =over |
7f61b687 | 456 | |
35bc1fdc | 457 | =item |
7f61b687 IZ |
458 | |
459 | Title of the process (in the C<Ctrl-Esc> list); | |
460 | ||
35bc1fdc | 461 | =item |
7f61b687 IZ |
462 | |
463 | window handle of switch entry of the process (in the C<Ctrl-Esc> list); | |
464 | ||
35bc1fdc | 465 | =item |
7f61b687 IZ |
466 | |
467 | window handle of the icon of the process; | |
468 | ||
35bc1fdc | 469 | =item |
7f61b687 IZ |
470 | |
471 | process handle of the owner of the entry in C<Ctrl-Esc> list; | |
472 | ||
35bc1fdc | 473 | =item |
7f61b687 IZ |
474 | |
475 | process id of the owner of the entry in C<Ctrl-Esc> list; | |
476 | ||
35bc1fdc | 477 | =item |
7f61b687 IZ |
478 | |
479 | session id of the owner of the entry in C<Ctrl-Esc> list; | |
480 | ||
35bc1fdc | 481 | =item |
7f61b687 IZ |
482 | |
483 | whether visible in C<Ctrl-Esc> list; | |
484 | ||
88c28ceb | 485 | =item |
7f61b687 IZ |
486 | |
487 | whether item cannot be switched to (note that it is not actually | |
488 | grayed in the C<Ctrl-Esc> list)); | |
489 | ||
35bc1fdc | 490 | =item |
7f61b687 IZ |
491 | |
492 | whether participates in jump sequence; | |
493 | ||
35bc1fdc | 494 | =item |
7f61b687 | 495 | |
35bc1fdc | 496 | program type. Possible values are: |
7f61b687 | 497 | |
35bc1fdc IZ |
498 | PROG_DEFAULT 0 |
499 | PROG_FULLSCREEN 1 | |
500 | PROG_WINDOWABLEVIO 2 | |
501 | PROG_PM 3 | |
502 | PROG_VDM 4 | |
503 | PROG_WINDOWEDVDM 7 | |
7f61b687 IZ |
504 | |
505 | Although there are several other program types for WIN-OS/2 programs, | |
506 | these do not show up in this field. Instead, the PROG_VDM or | |
507 | PROG_WINDOWEDVDM program types are used. For instance, for | |
508 | PROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all | |
509 | the WIN-OS/2 programs run in DOS sessions. For example, if a program | |
510 | is a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM | |
511 | session. Likewise, if it's a full-screen WIN-OS/2 program, it runs in | |
512 | a PROG_VDM session. | |
513 | ||
35bc1fdc IZ |
514 | =item |
515 | ||
516 | switch-entry handle. | |
88c28ceb | 517 | |
7f61b687 IZ |
518 | =back |
519 | ||
35bc1fdc IZ |
520 | Optional arguments: the pid and the window-handle of the application running |
521 | in the OS/2 session to query. | |
522 | ||
523 | =item process_hentry() | |
524 | ||
525 | similar to process_entry(), but returns a hash reference, the keys being | |
526 | ||
527 | title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid | |
528 | visible nonswitchable jumpable ptype sw_entry | |
529 | ||
530 | (a copy of the list of keys is in @hentry_fields). | |
531 | ||
532 | =item process_entries() | |
7f61b687 | 533 | |
35bc1fdc IZ |
534 | similar to process_entry(), but returns a list of array reference for all |
535 | the elements in the switch list (one controlling C<Ctrl-Esc> window). | |
536 | ||
537 | =item process_hentries() | |
538 | ||
539 | similar to process_hentry(), but returns a list of hash reference for all | |
540 | the elements in the switch list (one controlling C<Ctrl-Esc> window). | |
541 | ||
542 | =item change_entry() | |
543 | ||
544 | changes a process entry, arguments are the same as process_entry() returns. | |
545 | ||
546 | =item change_entryh() | |
547 | ||
548 | Similar to change_entry(), but takes a hash reference as an argument. | |
549 | ||
550 | =item Title() | |
551 | ||
552 | returns a title of the current session. (There is no way to get this | |
553 | info in non-standard Session Managers, this implementation is a | |
554 | shortcut via process_entry().) | |
555 | ||
556 | =item C<Title_set(newtitle)> | |
557 | ||
558 | tries two different interfaces. The Session Manager one does not work | |
559 | with some windows (if the title is set from the start). | |
7f61b687 IZ |
560 | This is a limitation of OS/2, in such a case $^E is set to 372 (type |
561 | ||
562 | help 372 | |
563 | ||
35bc1fdc IZ |
564 | for a funny - and wrong - explanation ;-). In such cases a |
565 | direct-manipulation of low-level entries is used. Keep in mind that | |
566 | some versions of OS/2 leak memory with such a manipulation. | |
567 | ||
568 | =item C<SwitchToProgram($sw_entry)> | |
569 | ||
570 | switch to session given by a switch list handle. | |
571 | ||
572 | Use of this function causes another window (and its related windows) | |
573 | of a PM session to appear on the front of the screen, or a switch to | |
574 | another session in the case of a non-PM program. In either case, | |
575 | the keyboard (and mouse for the non-PM case) input is directed to | |
576 | the new program. | |
577 | ||
578 | =back | |
579 | ||
580 | =head2 Control of the PM windows | |
581 | ||
582 | Some of these API's require sending a message to the specified window. | |
583 | In such a case the process needs to be a PM process, or to be morphed | |
584 | to a PM process via OS2::MorphPM(). | |
585 | ||
586 | For a temporary morphing to PM use L<OS2::localMorphPM class>. | |
587 | ||
588 | Keep in mind that PM windows are engaged in 2 "orthogonal" window | |
589 | trees, as well as in the z-order list. | |
590 | ||
591 | One tree is given by the I<parent/child> relationship. This | |
592 | relationship affects drawing (child is drawn relative to its parent | |
593 | (lower-left corner), and the drawing is clipped by the parent's | |
594 | boundary; parent may request that I<it's> drawing is clipped to be | |
595 | confined to the outsize of the childs and/or siblings' windows); | |
596 | hiding; minimizing/restoring; and destroying windows. | |
597 | ||
598 | Another tree (not necessarily connected?) is given by I<ownership> | |
599 | relationship. Ownership relationship assumes cooperation of the | |
600 | engaged windows via passing messages on "important events"; e.g., | |
601 | scrollbars send information messages when the "bar" is moved, menus | |
602 | send messages when an item is selected; frames | |
603 | move/hide/unhide/minimize/restore/change-z-order-of owned frames when | |
604 | the owner is moved/etc., and destroy the owned frames (even when these | |
605 | frames are not descendants) when the owner is destroyed; etc. [An | |
606 | important restriction on ownership is that owner should be created by | |
607 | the same thread as the owned thread, so they engage in the same | |
608 | message queue.] | |
609 | ||
610 | Windows may be in many different state: Focused, Activated (=Windows | |
611 | in the I<parent/child> tree between the root and the window with | |
612 | focus; usually indicate such "active state" by titlebar highlights), | |
613 | Enabled/Disabled (this influences *an ability* to receive user input | |
614 | (be focused?), and may change appearance, as for enabled/disabled | |
615 | buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal, etc. | |
616 | ||
617 | =over | |
618 | ||
619 | =item C<WindowText($hwnd)> | |
620 | ||
621 | gets "a text content" of a window. | |
622 | ||
623 | =item C<WindowText_set($hwnd, $text)> | |
624 | ||
625 | sets "a text content" of a window. | |
626 | ||
627 | =item C<WindowPos($hwnd)> | |
628 | ||
629 | gets window position info as 8 integers (of C<SWP>), in the order suitable | |
630 | for WindowPos_set(): $x, $y, $fl, $w, $h, $behind, @rest. | |
631 | ||
632 | =item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $wid = 0, $h = 0, $behind = HWND_TOP)> | |
633 | ||
634 | Set state of the window: position, size, zorder, show/hide, activation, | |
635 | minimize/maximize/restore etc. Which of these operations to perform | |
636 | is governed by $flags. | |
637 | ||
638 | =item C<WindowProcess($hwnd)> | |
639 | ||
640 | gets I<PID> and I<TID> of the process associated to the window. | |
641 | ||
642 | =item ActiveWindow([$parentHwnd]) | |
643 | ||
644 | gets the active subwindow's handle for $parentHwnd or desktop. | |
645 | Returns FALSE if none. | |
646 | ||
647 | =item C<ClassName($hwnd)> | |
648 | ||
649 | returns the class name of the window. | |
650 | ||
651 | If this window is of any of the preregistered WC_* classes the class | |
652 | name returned is in the form "#nnnnn", where "nnnnn" is a group | |
653 | of up to five digits that corresponds to the value of the WC_* class name | |
654 | constant. | |
655 | ||
656 | =item FocusWindow() | |
657 | ||
658 | returns the handle of the focus window. Optional argument for specifying the desktop | |
659 | to use. | |
660 | ||
661 | =item C<FocusWindow_set($hwnd)> | |
662 | ||
663 | set the focus window by handle. Optional argument for specifying the desktop | |
664 | to use. E.g, the first entry in program_entries() is the C<Ctrl-Esc> list. | |
665 | To show it | |
666 | ||
667 | WinShowWindow( wlhwnd, TRUE ); | |
668 | WinSetFocus( HWND_DESKTOP, wlhwnd ); | |
669 | WinSwitchToProgram(wlhswitch); | |
670 | ||
671 | ||
672 | =item C<ShowWindow($hwnd [, $show])> | |
673 | ||
674 | Set visible/hidden flag of the window. Default: $show is TRUE. | |
675 | ||
676 | =item C<PostMsg($hwnd, $msg, $mp1, $mp2)> | |
677 | ||
678 | post message to a window. The meaning of $mp1, $mp2 is specific for each | |
679 | message id $msg, they default to 0. E.g., in C it is done similar to | |
680 | ||
681 | /* Emulate `Restore' */ | |
682 | WinPostMsg(SwitchBlock.tswe[i].swctl.hwnd, WM_SYSCOMMAND, | |
683 | MPFROMSHORT(SC_RESTORE), 0); | |
684 | ||
685 | /* Emulate `Show-Contextmenu' (Double-Click-2) */ | |
686 | hwndParent = WinQueryFocus(HWND_DESKTOP); | |
687 | hwndActive = WinQueryActiveWindow(hwndParent); | |
688 | WinPostMsg(hwndActive, WM_CONTEXTMENU, MPFROM2SHORT(0,0), MPFROMLONG(0)); | |
689 | ||
690 | /* Emulate `Close' */ | |
691 | WinPostMsg(pSWB->aswentry[i].swctl.hwnd, WM_CLOSE, 0, 0); | |
692 | ||
693 | /* Same but softer: */ | |
694 | WinPostMsg(hwndactive, WM_SAVEAPPLICATION, 0L, 0L); | |
695 | WinPostMsg(hwndactive, WM_CLOSE, 0L, 0L)); | |
696 | WinPostMsg(hwndactive, WM_QUIT, 0L, 0L)); | |
697 | ||
698 | =item C<$eh = BeginEnumWindows($hwnd)> | |
699 | ||
700 | starts enumerating immediate child windows of $hwnd in z-order. The | |
701 | enumeration reflects the state at the moment of BeginEnumWindows() calls; | |
702 | use IsWindow() to be sure. | |
703 | ||
704 | =item C<$kid_hwnd = GetNextWindow($eh)> | |
705 | ||
706 | gets the next kid in the list. Gets 0 on error or when the list ends. | |
7f61b687 | 707 | |
35bc1fdc | 708 | =item C<EndEnumWindows($eh)> |
7f61b687 | 709 | |
35bc1fdc IZ |
710 | End enumeration and release the list. |
711 | ||
712 | =item C<@list = ChildWindows($hwnd)> | |
713 | ||
714 | returns the list of child windows at the moment of the call. Same remark | |
715 | as for enumeration interface applies. Example of usage: | |
716 | ||
717 | sub l { | |
718 | my ($o,$h) = @_; | |
719 | printf ' ' x $o . "%#x\n", $h; | |
720 | l($o+2,$_) for ChildWindows $h; | |
721 | } | |
722 | l 0, $HWND_DESKTOP | |
723 | ||
724 | =item C<IsWindow($hwnd)> | |
725 | ||
726 | true if the window handle is still valid. | |
727 | ||
728 | =item C<QueryWindow($hwnd, $type)> | |
729 | ||
730 | gets the handle of a related window. $type should be one of C<QW_*> constants. | |
731 | ||
732 | =item C<IsChild($hwnd, $parent)> | |
733 | ||
734 | return TRUE if $hwnd is a descendant of $parent. | |
735 | ||
736 | =item C<WindowFromId($hwnd, $id)> | |
737 | ||
738 | return a window handle of a child of $hwnd with the given $id. | |
739 | ||
740 | hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU); | |
741 | WinSendMsg(hwndSysMenu, MM_SETITEMATTR, | |
742 | MPFROM2SHORT(SC_CLOSE, TRUE), | |
743 | MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)); | |
744 | ||
745 | =item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])> | |
746 | ||
747 | gets a handle of a child of $hwndParent at C<($x,$y)>. If $descedantsToo | |
748 | (defaulting to 0) then children of children may be returned too. May return | |
749 | $hwndParent (defaults to desktop) if no suitable children are found, | |
750 | or 0 if the point is outside the parent. | |
751 | ||
752 | $x and $y are relative to $hwndParent. | |
753 | ||
754 | =item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])> | |
755 | ||
756 | gets a dialog item window handle for an item of type $type of $dlgHwnd | |
757 | relative to $relativeHwnd, which is descendant of $dlgHwnd. | |
758 | $relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or | |
759 | EDI_LASTTABITEM. | |
760 | ||
761 | The return is always an immediate child of hwndDlg, even if hwnd is | |
762 | not an immediate child window. $type may be | |
763 | ||
764 | =over | |
765 | ||
766 | =item EDI_FIRSTGROUPITEM | |
767 | ||
768 | First item in the same group. | |
769 | ||
770 | =item EDI_FIRSTTABITEM | |
771 | ||
772 | First item in dialog with style WS_TABSTOP. hwnd is ignored. | |
773 | ||
774 | =item EDI_LASTGROUPITEM | |
775 | ||
776 | Last item in the same group. | |
777 | ||
778 | =item EDI_LASTTABITEM | |
779 | ||
780 | Last item in dialog with style WS_TABSTOP. hwnd is ignored. | |
781 | ||
782 | =item EDI_NEXTGROUPITEM | |
783 | ||
784 | Next item in the same group. Wraps around to beginning of group when | |
785 | the end of the group is reached. | |
786 | ||
787 | =item EDI_NEXTTABITEM | |
788 | ||
789 | Next item with style WS_TABSTOP. Wraps around to beginning of dialog | |
790 | item list when end is reached. | |
791 | ||
792 | =item EDI_PREVGROUPITEM | |
793 | ||
794 | Previous item in the same group. Wraps around to end of group when the | |
795 | start of the group is reached. For information on the WS_GROUP style, | |
796 | see Window Styles. | |
797 | ||
798 | =item EDI_PREVTABITEM | |
799 | ||
800 | Previous item with style WS_TABSTOP. Wraps around to end of dialog | |
801 | item list when beginning is reached. | |
7f61b687 IZ |
802 | |
803 | =back | |
804 | ||
35bc1fdc IZ |
805 | =back |
806 | ||
807 | =head1 OS2::localMorphPM class | |
808 | ||
809 | This class morphs the process to PM for the duration of the given context. | |
810 | ||
811 | { | |
812 | my $h = OS2::localMorphPM->new(0); | |
813 | # Do something | |
814 | } | |
815 | ||
816 | The argument has the same meaning as one to OS2::MorphPM(). Calls can | |
817 | nest with internal ones being NOPs. | |
818 | ||
819 | =head1 TODO | |
820 | ||
821 | Constants (currently one needs to get them looking in a header file): | |
822 | ||
823 | HWND_* | |
824 | WM_* /* Separate module? */ | |
825 | SC_* | |
826 | SWP_* | |
827 | WC_* | |
828 | PROG_* | |
829 | QW_* | |
830 | EDI_* | |
831 | WS_* | |
832 | ||
833 | Show/Hide, Enable/Disable (WinShowWindow(), WinIsWindowVisible(), | |
834 | WinEnableWindow(), WinIsWindowEnabled()). | |
835 | ||
836 | Maximize/minimize/restore via WindowPos_set(), check via checking | |
837 | WS_MAXIMIZED/WS_MINIMIZED flags (how to get them?). | |
838 | ||
839 | =head1 $^E | |
840 | ||
841 | the majority of the APIs of this module set $^E on failure (no matter | |
842 | whether they die() on failure or not). By the semantic of PM API | |
843 | which returns something other than a boolean, it is impossible to | |
844 | distinguish failure from a "normal" 0-return. In such cases C<$^E == | |
845 | 0> indicates an absence of error. | |
846 | ||
847 | =head1 BUGS | |
848 | ||
849 | whether a given API dies or returns FALSE/empty-list on error may be | |
850 | confusing. This may change in the future. | |
851 | ||
760ac839 LW |
852 | =head1 AUTHOR |
853 | ||
35bc1fdc | 854 | Andreas Kaiser <ak@ananke.s.bawue.de>, |
7f61b687 | 855 | Ilya Zakharevich <ilya@math.ohio-state.edu>. |
760ac839 LW |
856 | |
857 | =head1 SEE ALSO | |
858 | ||
35bc1fdc | 859 | C<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules. |
760ac839 LW |
860 | |
861 | =cut |