This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / os2 / OS2 / Process / Process.pm
CommitLineData
35bc1fdc 1package OS2::localMorphPM;
30500b05 2# use strict;
35bc1fdc 3
30500b05
IZ
4sub new {
5 my ($c,$f) = @_;
6 OS2::MorphPM($f);
7 # print STDERR ">>>>>\n";
8 bless [$f], $c
9}
10sub DESTROY {
11 # print STDERR "<<<<<\n";
12 OS2::UnMorphPM(shift->[0])
13}
35bc1fdc 14
760ac839
LW
15package OS2::Process;
16
35bc1fdc
IZ
17BEGIN {
18 require Exporter;
30500b05 19 require XSLoader;
35bc1fdc 20 #require AutoLoader;
7f61b687 21
30500b05
IZ
22 our @ISA = qw(Exporter);
23 our $VERSION = "1.0";
24 XSLoader::load('OS2::Process', $VERSION);
35bc1fdc 25}
760ac839 26
760ac839
LW
27# Items to export into callers namespace by default. Note: do not export
28# names by default without a very good reason. Use EXPORT_OK instead.
29# Do not simply export all your public functions/methods/constants.
30500b05 30our @EXPORT = qw(
760ac839
LW
31 P_BACKGROUND
32 P_DEBUG
33 P_DEFAULT
34 P_DETACH
35 P_FOREGROUND
36 P_FULLSCREEN
37 P_MAXIMIZE
38 P_MINIMIZE
39 P_NOCLOSE
40 P_NOSESSION
41 P_NOWAIT
42 P_OVERLAY
43 P_PM
44 P_QUOTE
45 P_SESSION
46 P_TILDE
47 P_UNRELATED
48 P_WAIT
49 P_WINDOWED
7f61b687
IZ
50 my_type
51 file_type
52 T_NOTSPEC
53 T_NOTWINDOWCOMPAT
54 T_WINDOWCOMPAT
55 T_WINDOWAPI
56 T_BOUND
57 T_DLL
58 T_DOS
59 T_PHYSDRV
60 T_VIRTDRV
61 T_PROTDLL
62 T_32BIT
35bc1fdc
IZ
63 ppid
64 ppidOf
65 sidOf
66 scrsize
67 scrsize_set
7f61b687 68 process_entry
35bc1fdc
IZ
69 process_entries
70 process_hentry
71 process_hentries
72 change_entry
73 change_entryh
30500b05 74 process_hwnd
35bc1fdc
IZ
75 Title_set
76 Title
30500b05
IZ
77 winTitle_set
78 winTitle
79 swTitle_set
80 bothTitle_set
35bc1fdc
IZ
81 WindowText
82 WindowText_set
83 WindowPos
84 WindowPos_set
30500b05
IZ
85 hWindowPos
86 hWindowPos_set
35bc1fdc
IZ
87 WindowProcess
88 SwitchToProgram
30500b05 89 DesktopWindow
35bc1fdc 90 ActiveWindow
30500b05 91 ActiveWindow_set
35bc1fdc
IZ
92 ClassName
93 FocusWindow
94 FocusWindow_set
95 ShowWindow
96 PostMsg
97 BeginEnumWindows
98 EndEnumWindows
99 GetNextWindow
100 IsWindow
101 ChildWindows
102 out_codepage
103 out_codepage_set
18729d3e 104 process_codepage_set
35bc1fdc
IZ
105 in_codepage
106 in_codepage_set
107 cursor
108 cursor_set
109 screen
110 screen_set
111 process_codepages
112 QueryWindow
113 WindowFromId
114 WindowFromPoint
115 EnumDlgItem
30500b05
IZ
116 EnableWindow
117 EnableWindowUpdate
118 IsWindowEnabled
119 IsWindowVisible
120 IsWindowShowing
121 WindowPtr
122 WindowULong
123 WindowUShort
124 SetWindowBits
125 SetWindowPtr
126 SetWindowULong
127 SetWindowUShort
18729d3e
JH
128 TopLevel
129 FocusWindow_set_keep_Zorder
130
131 ActiveDesktopPathname
132 InvalidateRect
133 CreateFrameControl
134 ClipbrdFmtInfo
135 ClipbrdOwner
136 ClipbrdViewer
137 ClipbrdData
138 OpenClipbrd
139 CloseClipbrd
140 ClipbrdData_set
141 ClipbrdOwner_set
142 ClipbrdViewer_set
143 EnumClipbrdFmts
144 EmptyClipbrd
145 AddAtom
146 FindAtom
147 DeleteAtom
148 AtomUsage
149 AtomName
150 AtomLength
151 SystemAtomTable
152 CreateAtomTable
153 DestroyAtomTable
154
155 _ClipbrdData_set
156 ClipbrdText
157 ClipbrdText_set
158
159 _MessageBox
160 MessageBox
161 _MessageBox2
162 MessageBox2
163 LoadPointer
164 SysPointer
165 Alarm
166 FlashWindow
bd60b2b9
IZ
167
168 get_title
169 set_title
760ac839 170);
30500b05
IZ
171our @EXPORT_OK = qw(
172 ResetWinError
173 MPFROMSHORT
174 MPVOID
175 MPFROMCHAR
176 MPFROM2SHORT
177 MPFROMSH2CH
178 MPFROMLONG
179);
180
181our $AUTOLOAD;
35bc1fdc 182
760ac839
LW
183sub AUTOLOAD {
184 # This AUTOLOAD is used to 'autoload' constants from the constant()
185 # XS function. If a constant is not found then control is passed
186 # to the AUTOLOAD in AutoLoader.
187
30500b05
IZ
188 (my $constname = $AUTOLOAD) =~ s/.*:://;
189 my $val = constant($constname, @_ ? $_[0] : 0);
760ac839 190 if ($! != 0) {
9c024a02 191 if ($! =~ /Invalid/ || $!{EINVAL}) {
30500b05
IZ
192 die "Unsupported function $AUTOLOAD"
193 } else {
194 my ($pack,$file,$line) = caller;
760ac839
LW
195 die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
196";
197 }
198 }
199 eval "sub $AUTOLOAD { $val }";
200 goto &$AUTOLOAD;
201}
202
30500b05
IZ
203sub const_import {
204 require OS2::Process::Const;
205 my $sym = shift;
206 my ($err, $val) = OS2::Process::Const::constant($sym);
207 die $err if $err;
208 my $p = caller(1);
209
210 # no strict;
211
212 *{"$p\::$sym"} = sub () { $val };
213 (); # needed by import()
214}
215
216sub import {
217 my $class = shift;
218 my $ini = @_;
219 @_ = ($class,
220 map {
18729d3e 221 /^(HWND|WM|SC|SWP|WC|PROG|QW|EDI|WS|QWS|QWP|QWL|FF|FI|LS|FS|FCF|BS|MS|TBM|CF|CFI|FID|MB|MBID|CF|CFI|SPTR)_/ ? const_import($_) : $_
30500b05
IZ
222 } @_);
223 goto &Exporter::import if @_ > 1 or $ini == 0;
224}
225
760ac839
LW
226# Preloaded methods go here.
227
35bc1fdc
IZ
228sub Title () { (process_entry())[0] }
229
230# *Title_set = \&sesmgr_title_set;
231
232sub swTitle_set_sw {
233 my ($title, @sw) = @_;
234 $sw[0] = $title;
235 change_entry(@sw);
236}
237
30500b05 238sub swTitle_set ($) {
35bc1fdc
IZ
239 my (@sw) = process_entry();
240 swTitle_set_sw(shift, @sw);
241}
242
243sub winTitle_set_sw {
244 my ($title, @sw) = @_;
245 my $h = OS2::localMorphPM->new(0);
246 WindowText_set $sw[1], $title;
247}
248
30500b05 249sub winTitle_set ($) {
35bc1fdc
IZ
250 my (@sw) = process_entry();
251 winTitle_set_sw(shift, @sw);
252}
253
30500b05
IZ
254sub winTitle () {
255 my (@sw) = process_entry();
256 my $h = OS2::localMorphPM->new(0);
257 WindowText $sw[1];
258}
259
260sub bothTitle_set ($) {
35bc1fdc
IZ
261 my (@sw) = process_entry();
262 my $t = shift;
263 winTitle_set_sw($t, @sw);
264 swTitle_set_sw($t, @sw);
265}
266
30500b05 267sub Title_set ($) {
35bc1fdc
IZ
268 my $t = shift;
269 return 1 if sesmgr_title_set($t);
270 return 0 unless $^E == 372;
271 my (@sw) = process_entry();
272 winTitle_set_sw($t, @sw);
273 swTitle_set_sw($t, @sw);
274}
275
276sub process_entry { swentry_expand(process_swentry(@_)) }
277
278our @hentry_fields = qw( title owner_hwnd icon_hwnd
279 owner_phandle owner_pid owner_sid
280 visible nonswitchable jumpable ptype sw_entry );
281
282sub swentry_hexpand ($) {
283 my %h;
284 @h{@hentry_fields} = swentry_expand(shift);
285 \%h;
286}
287
288sub process_hentry { swentry_hexpand(process_swentry(@_)) }
30500b05 289sub process_hwnd { process_hentry()->{owner_hwnd} }
35bc1fdc
IZ
290
291my $swentry_size = swentry_size();
292
293sub sw_entries () {
294 my $s = swentries_list();
295 my ($c, $s1) = unpack 'La*', $s;
296 die "Unconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s;
297 my (@l, $e);
298 push @l, $e while $e = substr $s1, 0, $swentry_size, '';
299 @l;
300}
301
302sub process_entries () {
303 map [swentry_expand($_)], sw_entries;
304}
305
306sub process_hentries () {
307 map swentry_hexpand($_), sw_entries;
308}
309
310sub change_entry {
311 change_swentry(create_swentry(@_));
312}
313
314sub create_swentryh ($) {
315 my $h = shift;
316 create_swentry(@$h{@hentry_fields});
317}
318
319sub change_entryh ($) {
320 change_swentry(create_swentryh(shift));
321}
322
323# Massage entries into the same order as WindowPos_set:
324sub WindowPos ($) {
30500b05 325 my ($fl, $h, $w, $y, $x, $behind, $hwnd, @rest)
35bc1fdc
IZ
326 = unpack 'L l4 L4', WindowSWP(shift);
327 ($x, $y, $fl, $w, $h, $behind, @rest);
328}
329
30500b05
IZ
330# Put them into a hash
331sub hWindowPos ($) {
332 my %h;
333 @h{ qw(flags height width y x behind hwnd reserved1 reserved2) }
334 = unpack 'L l4 L4', WindowSWP(shift);
335 \%h;
336}
337
338my @SWP_keys = ( [qw(width height)], # SWP_SIZE=1
339 [qw(x y)], # SWP_MOVE=2
340 [qw(behind)] ); # SWP_ZORDER=3
341my %SWP_def;
342@SWP_def{ map @$_, @SWP_keys } = (0) x 20;
343
344# Get them from a hash
345sub hWindowPos_set ($$) {
346 my $hash = shift;
347 my $hwnd = (@_ ? shift : $hash->{hwnd} );
348 my $flags;
349 if (exists $hash->{flags}) {
350 $flags = $hash->{flags};
351 } else { # Set flags according to existing keys in $hash
352 $flags = 0;
353 for my $bit (0..2) {
354 exists $hash->{$_} and $flags |= (1<<$bit) for @{$SWP_keys[$bit]};
355 }
356 }
357 for my $bit (0..2) { # Check for required keys
358 next unless $flags & (1<<$bit);
359 exists $hash->{$_}
360 or die sprintf "key $_ required for flags=%#x", $flags
361 for @{$SWP_keys[$bit]};
362 }
363 my %h = (%SWP_def, flags => $flags, %$hash); # Avoid warnings
364 my ($x, $y, $fl, $w, $h, $behind) = @h{ qw(x y flags width height behind) };
365 WindowPos_set($hwnd, $x, $y, $fl, $w, $h, $behind);
366}
367
368sub ChildWindows (;$) {
369 my $hm = OS2::localMorphPM->new(0);
35bc1fdc 370 my @kids;
30500b05 371 my $h = BeginEnumWindows(@_ ? shift : 1); # HWND_DESKTOP
35bc1fdc
IZ
372 my $w;
373 push @kids, $w while $w = GetNextWindow $h;
374 EndEnumWindows $h;
375 @kids;
376}
7f61b687 377
18729d3e
JH
378sub TopLevel ($) {
379 my $d = DesktopWindow;
380 my $w = shift;
381 while (1) {
382 my $p = QueryWindow $w, 5; # QW_PARENT;
383 return $w if not $p or $p == $d;
384 $w = $p;
385 }
386}
387
388sub FocusWindow_set_keep_Zorder ($) {
389 my $w = shift;
390 my $t = TopLevel $w;
391 my $b = hWindowPos($t)->{behind}; # we are behind this
392 EnableWindowUpdate($t, 0);
393 FocusWindow_set($w);
394# sleep 1; # Make flicker stronger when present
395 hWindowPos_set {behind => $b}, $t;
396 EnableWindowUpdate($t, 1);
397}
398
399sub ClipbrdText (@) {
400 my $morph = OS2::localMorphPM->new(0);
401 OpenClipbrd();
402 my $txt = unpack 'p', pack 'L', ClipbrdData @_;
403 CloseClipbrd();
404 $txt;
405}
406
407sub ClipbrdText_set ($;$) {
408 my $morph = OS2::localMorphPM->new(0);
409 OpenClipbrd();
410 EmptyClipbrd(); # It may contain other types
411 my ($txt, $no_convert_nl) = (shift, shift);
412 ClipbrdData_set($txt, !$no_convert_nl, @_);
413 CloseClipbrd();
414}
415
416sub MessageBox ($;$$$$$) {
417 my $morph = OS2::localMorphPM->new(0);
418 die "MessageBox needs text" unless @_;
419 push @_ , ($0 eq '-e' ? "Perl one-liner's message" : "$0 message") if @_ == 1;
420 &_MessageBox;
421}
422
423my %pointers;
424
425sub get_pointer ($;$$) {
426 my $id = $_[0];
427 return $pointers{$id} if exists $pointers{$id};
428 $pointers{$id} = &SysPointer;
429}
430
431# $button needs to be of the form 'String', ['String'] or ['String', flag].
432# If ['String'], it is assumed the default button; same for 'String' if $only
433# is set.
434sub process_MB2 ($$;$) {
435 die "process_MB2() needs 2 arguments, got '@_'" unless @_ == 2 or @_ == 3;
436 my ($button, $ret, $only) = @_;
437 # default is BS_PUSHBUTTON, add BS_DEFAULT if $only is set
438 $button = [$button, $only ? 0x400 : 0] unless ref $button eq 'ARRAY';
439 push @$button, 0x400 if @$button == 1; # BS_PUSHBUTTON|BS_DEFAULT
440 die "Button needs to be of the form 'String', ['String'] or ['String', flag]"
441 unless @$button == 2;
442 pack "Z71 x L l", $button->[0], $ret, $button->[1]; # name, retval, flag
443}
444
445# If one button, make it the default one even if it is of 'String' => val form.
446# If icon is of the form 'SP#<number>', load this via SysPointer.
447sub process_MB2_INFO ($;$$$) {
448 my $l = 0;
449 my $out;
450 die "process_MB2_INFO() needs 1..4 arguments" unless @_ and @_ < 5;
451 my $buttons = shift;
452 die "Buttons array should consist of pairs" if @$buttons % 2;
453
454 push @_, 0 unless @_; # Icon id (pointer)
455 # Box flags (MB_MOVABLE and MB_INFORMATION or MB_CUSTOMICON)
456 push @_, ($_[0] ? 0x4080 : 0x4030) unless @_ > 1;
457 push @_, 0 unless @_ > 2; # Notify window
458
459 my ($icon, $style, $notify) = (shift, shift, shift);
460 $icon = get_pointer $1 if $icon =~ /^SP#(\d+)\z/;
461 $out = pack "L L L L", # icon, #buttons, style, notify, buttons
462 $icon, @$buttons/2, $style, $notify;
463 $out .= join '',
464 map process_MB2($buttons->[2*$_], $buttons->[2*$_+1], @$buttons == 2),
465 0..@$buttons/2-1;
466 pack('L', length(pack 'L', 0) + length $out) . $out;
467}
468
469# MessageBox2 'Try this', OS2::Process::process_MB2_INFO([['Dismiss', 0] => 0x1000], OS2::Process::get_pointer(22),0x4080,0), 'me', 1, 0, 0
470# or the shortcut
471# MessageBox2 'Try this', [[['Dismiss', 0] => 0x1000], 'SP#22'], 'me'
472# 0x80 means MB_CUSTOMICON (does not focus?!). This focuses:
473# MessageBox2 'Try this', [[['Dismiss',0x400] => 0x1000], 0, 0x4030,0]
474# 0x400 means BS_DEFAULT. This is the same as the shortcut
475# MessageBox2 'Try this', [[Dismiss => 0x1000]]
476sub MessageBox2 ($;$$$$$) {
477 my $morph = OS2::localMorphPM->new(0);
478 die "MessageBox needs text" unless @_;
479 push @_ , [[Dismiss => 0x1000], # Name, retval (BS_PUSHBUTTON|BS_DEFAULT)
480 #0, # get_pointer(11), # SPTR_ICONINFORMATION
481 #0x4030, # MB_MOVEABLE | MB_INFORMATION
482 #0, # Notify window; was 1==HWND_DESKTOP
483 ] if @_ == 1;
484 push @_ , ($0 eq '-e' ? "Perl one-liner's message" : "$0's message") if @_ == 2;
485 $_[1] = &process_MB2_INFO(@{$_[1]}) if ref($_[1]) eq 'ARRAY';
486 &_MessageBox2;
487}
488
bd60b2b9
IZ
489# backward compatibility
490*set_title = \&Title_set;
491*get_title = \&Title;
492
760ac839
LW
493# Autoload methods go after __END__, and are processed by the autosplit program.
494
4951;
496__END__
497
498=head1 NAME
499
35bc1fdc 500OS2::Process - exports constants for system() call, and process control on OS2.
760ac839
LW
501
502=head1 SYNOPSIS
503
504 use OS2::Process;
35bc1fdc 505 $pid = system(P_PM | P_BACKGROUND, "epm.exe");
760ac839
LW
506
507=head1 DESCRIPTION
508
35bc1fdc
IZ
509=head2 Optional argument to system()
510
760ac839
LW
511the builtin function system() under OS/2 allows an optional first
512argument which denotes the mode of the process. Note that this argument is
513recognized only if it is strictly numerical.
514
515You can use either one of the process modes:
516
517 P_WAIT (0) = wait until child terminates (default)
518 P_NOWAIT = do not wait until child terminates
519 P_SESSION = new session
520 P_DETACH = detached
521 P_PM = PM program
522
523and optionally add PM and session option bits:
524
525 P_DEFAULT (0) = default
526 P_MINIMIZE = minimized
527 P_MAXIMIZE = maximized
528 P_FULLSCREEN = fullscreen (session only)
529 P_WINDOWED = windowed (session only)
530
531 P_FOREGROUND = foreground (if running in foreground)
532 P_BACKGROUND = background
533
534 P_NOCLOSE = don't close window on exit (session only)
535
536 P_QUOTE = quote all arguments
537 P_TILDE = MKS argument passing convention
538 P_UNRELATED = do not kill child when father terminates
539
7f61b687
IZ
540=head2 Access to process properties
541
35bc1fdc
IZ
542On OS/2 processes have the usual I<parent/child> semantic;
543additionally, there is a hierarchy of sessions with their own
544I<parent/child> tree. A session is either a FS session, or a windowed
545pseudo-session created by PM. A session is a "unit of user
546interaction", a change to in/out settings in one of them does not
547affect other sessions.
7f61b687 548
88c28ceb 549=over
7f61b687 550
35bc1fdc
IZ
551=item my_type()
552
553returns the type of the current process (one of
554"FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error.
555
556=item C<file_type(file)>
7f61b687
IZ
557
558returns the type of the executable file C<file>, or
559dies on error. The bits 0-2 of the result contain one of the values
560
88c28ceb 561=over
7f61b687
IZ
562
563=item C<T_NOTSPEC> (0)
564
35bc1fdc 565Application type is not specified in the executable header.
7f61b687
IZ
566
567=item C<T_NOTWINDOWCOMPAT> (1)
568
35bc1fdc 569Application type is not-window-compatible.
7f61b687
IZ
570
571=item C<T_WINDOWCOMPAT> (2)
572
35bc1fdc 573Application type is window-compatible.
7f61b687
IZ
574
575=item C<T_WINDOWAPI> (3)
576
577Application type is window-API.
578
579=back
580
581The remaining bits should be masked with the following values to
582determine the type of the executable:
583
88c28ceb 584=over
7f61b687
IZ
585
586=item C<T_BOUND> (8)
587
588Set to 1 if the executable file has been "bound" (by the BIND command)
589as a Family API application. Bits 0, 1, and 2 still apply.
590
591=item C<T_DLL> (0x10)
592
593Set to 1 if the executable file is a dynamic link library (DLL)
594module. Bits 0, 1, 2, 3, and 5 will be set to 0.
595
596=item C<T_DOS> (0x20)
597
598Set to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3,
599and 4 will be set to 0.
600
601=item C<T_PHYSDRV> (0x40)
602
35bc1fdc 603Set to 1 if the executable file is a physical device driver.
7f61b687
IZ
604
605=item C<T_VIRTDRV> (0x80)
606
35bc1fdc 607Set to 1 if the executable file is a virtual device driver.
7f61b687
IZ
608
609=item C<T_PROTDLL> (0x100)
610
611Set to 1 if the executable file is a protected-memory dynamic link
612library module.
613
614=item C<T_32BIT> (0x4000)
615
35bc1fdc 616Set to 1 for 32-bit executable files.
7f61b687
IZ
617
618=back
619
620file_type() may croak with one of the strings C<"Invalid EXE
621signature"> or C<"EXE marked invalid"> to indicate typical error
622conditions. If given non-absolute path, will look on C<PATH>, will
623add extention F<.exe> if no extension is present (add extension F<.>
624to suppress).
625
35bc1fdc
IZ
626=item C<@list = process_codepages()>
627
628the first element is the currently active codepage, up to 2 additional
629entries specify the system's "prepared codepages": the codepages the
630user can switch to. The active codepage of a process is one of the
631prepared codepages of the system (if present).
632
633=item C<process_codepage_set($cp)>
634
635sets the currently active codepage. [Affects printer output, in/out
636codepages of sessions started by this process, and the default
637codepage for drawing in PM; is inherited by kids. Does not affect the
638out- and in-codepages of the session.]
639
640=item ppid()
641
642returns the PID of the parent process.
643
644=item C<ppidOf($pid = $$)>
645
646returns the PID of the parent process of $pid. -1 on error.
647
648=item C<sidOf($pid = $$)>
649
650returns the session id of the process id $pid. -1 on error.
651
652=back
653
654=head2 Control of VIO sessions
655
656VIO applications are applications running in a text-mode session.
657
658=over
659
660=item out_codepage()
661
662gets code page used for screen output (glyphs). -1 means that a user font
663was loaded.
664
665=item C<out_codepage_set($cp)>
666
667sets code page used for screen output (glyphs). -1 switches to a preloaded
668user font. -2 switches off the preloaded user font.
669
670=item in_codepage()
671
672gets code page used for keyboard input. 0 means that a hardware codepage
673is used.
674
675=item C<in_codepage_set($cp)>
676
677sets code page used for keyboard input.
678
679=item C<($w, $h) = scrsize()>
680
681width and height of the given console window in character cells.
682
683=item C<scrsize_set([$w, ] $h)>
684
685set height (and optionally width) of the given console window in
686character cells. Use 0 size to keep the old size.
687
688=item C<($s, $e, $w, $a) = cursor()>
689
690gets start/end lines of the blinking cursor in the charcell, its width
691(1 on text modes) and attribute (-1 for hidden, in text modes other
692values mean visible, in graphic modes color).
693
694=item C<cursor_set($s, $e, [$w [, $a]])>
695
696sets start/end lines of the blinking cursor in the charcell. Negative
697values mean percents of the character cell height.
698
699=item screen()
700
701gets a buffer with characters and attributes of the screen.
702
703=item C<screen_set($buffer)>
704
18729d3e
JH
705restores the screen given the result of screen(). E.g., if the file
706C<$file> contains the sceen contents, then
707
708 open IN, $file or die;
709 binmode IN;
710 read IN, $in, -s IN;
711 $s = screen;
712 $in .= qq(\0) x (length($s) - length $in);
713 substr($in, length $s) = '';
714 screen_set $in;
715
716will restore the screen content even if the height of the window
717changed (if the width changed, more manipulation is needed).
35bc1fdc
IZ
718
719=back
720
721=head2 Control of the process list
722
723With the exception of Title_set(), all these calls require that PM is
724running, they would not work under alternative Session Managers.
725
726=over
727
7f61b687
IZ
728=item process_entry()
729
730returns a list of the following data:
731
88c28ceb 732=over
7f61b687 733
35bc1fdc 734=item
7f61b687
IZ
735
736Title of the process (in the C<Ctrl-Esc> list);
737
35bc1fdc 738=item
7f61b687
IZ
739
740window handle of switch entry of the process (in the C<Ctrl-Esc> list);
741
35bc1fdc 742=item
7f61b687
IZ
743
744window handle of the icon of the process;
745
35bc1fdc 746=item
7f61b687
IZ
747
748process handle of the owner of the entry in C<Ctrl-Esc> list;
749
35bc1fdc 750=item
7f61b687
IZ
751
752process id of the owner of the entry in C<Ctrl-Esc> list;
753
35bc1fdc 754=item
7f61b687
IZ
755
756session id of the owner of the entry in C<Ctrl-Esc> list;
757
35bc1fdc 758=item
7f61b687
IZ
759
760whether visible in C<Ctrl-Esc> list;
761
88c28ceb 762=item
7f61b687
IZ
763
764whether item cannot be switched to (note that it is not actually
765grayed in the C<Ctrl-Esc> list));
766
35bc1fdc 767=item
7f61b687
IZ
768
769whether participates in jump sequence;
770
35bc1fdc 771=item
7f61b687 772
35bc1fdc 773program type. Possible values are:
7f61b687 774
35bc1fdc
IZ
775 PROG_DEFAULT 0
776 PROG_FULLSCREEN 1
777 PROG_WINDOWABLEVIO 2
778 PROG_PM 3
779 PROG_VDM 4
780 PROG_WINDOWEDVDM 7
7f61b687
IZ
781
782Although there are several other program types for WIN-OS/2 programs,
783these do not show up in this field. Instead, the PROG_VDM or
784PROG_WINDOWEDVDM program types are used. For instance, for
785PROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all
786the WIN-OS/2 programs run in DOS sessions. For example, if a program
787is a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM
788session. Likewise, if it's a full-screen WIN-OS/2 program, it runs in
789a PROG_VDM session.
790
35bc1fdc
IZ
791=item
792
793switch-entry handle.
88c28ceb 794
7f61b687
IZ
795=back
796
35bc1fdc
IZ
797Optional arguments: the pid and the window-handle of the application running
798in the OS/2 session to query.
799
800=item process_hentry()
801
802similar to process_entry(), but returns a hash reference, the keys being
803
804 title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid
805 visible nonswitchable jumpable ptype sw_entry
806
807(a copy of the list of keys is in @hentry_fields).
808
809=item process_entries()
7f61b687 810
35bc1fdc
IZ
811similar to process_entry(), but returns a list of array reference for all
812the elements in the switch list (one controlling C<Ctrl-Esc> window).
813
814=item process_hentries()
815
816similar to process_hentry(), but returns a list of hash reference for all
817the elements in the switch list (one controlling C<Ctrl-Esc> window).
818
819=item change_entry()
820
821changes a process entry, arguments are the same as process_entry() returns.
822
823=item change_entryh()
824
825Similar to change_entry(), but takes a hash reference as an argument.
826
30500b05
IZ
827=item process_hwnd()
828
829returns the C<owner_hwnd> of the process entry (for VIO windowed processes
830this is the frame window of the session).
831
35bc1fdc
IZ
832=item Title()
833
30500b05
IZ
834returns the text of the task switch menu entry of the current session.
835(There is no way to get this info in non-standard Session Managers. This
836implementation is a shortcut via process_entry().)
35bc1fdc
IZ
837
838=item C<Title_set(newtitle)>
839
840tries two different interfaces. The Session Manager one does not work
841with some windows (if the title is set from the start).
7f61b687
IZ
842This is a limitation of OS/2, in such a case $^E is set to 372 (type
843
844 help 372
845
35bc1fdc 846for a funny - and wrong - explanation ;-). In such cases a
30500b05
IZ
847direct-manipulation of low-level entries is used (same as bothTitle_set()).
848Keep in mind that some versions of OS/2 leak memory with such a manipulation.
849
850=item winTitle()
851
852returns text of the titlebar of the current process' window.
853
854=item C<winTitle_set(newtitle)>
855
856sets text of the titlebar of the current process' window. The change does not
857affect the text of the switch entry of the current window.
858
859=item C<swTitle_set(newtitle)>
860
861sets text of the task switch menu entry of the current process' window. [There
862is no API to query this title.] Does it via SwitchEntry interface,
863not Session manager interface. The change does not affect the text of the
864titlebar of the current window.
865
866=item C<bothTitle_set(newtitle)>
867
868sets text of the titlebar and task switch menu of the current process' window
869via direct manipulation of the windows' texts.
35bc1fdc 870
18729d3e 871=item C<SwitchToProgram([$sw_entry])>
35bc1fdc 872
18729d3e 873switch to session given by a switch list handle (defaults to the entry of our process).
35bc1fdc
IZ
874
875Use of this function causes another window (and its related windows)
876of a PM session to appear on the front of the screen, or a switch to
877another session in the case of a non-PM program. In either case,
878the keyboard (and mouse for the non-PM case) input is directed to
879the new program.
880
881=back
882
883=head2 Control of the PM windows
884
885Some of these API's require sending a message to the specified window.
886In such a case the process needs to be a PM process, or to be morphed
887to a PM process via OS2::MorphPM().
888
889For a temporary morphing to PM use L<OS2::localMorphPM class>.
890
891Keep in mind that PM windows are engaged in 2 "orthogonal" window
892trees, as well as in the z-order list.
893
894One tree is given by the I<parent/child> relationship. This
895relationship affects drawing (child is drawn relative to its parent
896(lower-left corner), and the drawing is clipped by the parent's
897boundary; parent may request that I<it's> drawing is clipped to be
898confined to the outsize of the childs and/or siblings' windows);
899hiding; minimizing/restoring; and destroying windows.
900
901Another tree (not necessarily connected?) is given by I<ownership>
902relationship. Ownership relationship assumes cooperation of the
903engaged windows via passing messages on "important events"; e.g.,
904scrollbars send information messages when the "bar" is moved, menus
905send messages when an item is selected; frames
906move/hide/unhide/minimize/restore/change-z-order-of owned frames when
907the owner is moved/etc., and destroy the owned frames (even when these
908frames are not descendants) when the owner is destroyed; etc. [An
909important restriction on ownership is that owner should be created by
910the same thread as the owned thread, so they engage in the same
911message queue.]
912
30500b05
IZ
913Windows may be in many different state: Focused (take keyboard events) or not,
914Activated (=Frame windows in the I<parent/child> tree between the root and
915the window with the focus; usually indicate such "active state" by titlebar
916highlights, and take mouse events) or not, Enabled/Disabled (this influences
917the ability to update the graphic, and may change appearance, as for
918enabled/disabled buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal
919or not, etc.
920
921The APIs below all die() on error with the message being $^E.
35bc1fdc
IZ
922
923=over
924
925=item C<WindowText($hwnd)>
926
30500b05 927gets "a text content" of a window. Requires (morphing to) PM.
35bc1fdc
IZ
928
929=item C<WindowText_set($hwnd, $text)>
930
30500b05 931sets "a text content" of a window. Requires (morphing to) PM.
35bc1fdc 932
30500b05 933=item C<($x, $y, $flags, $width, $height, $behind, @rest) = WindowPos($hwnd)>
35bc1fdc
IZ
934
935gets window position info as 8 integers (of C<SWP>), in the order suitable
30500b05
IZ
936for WindowPos_set(). @rest is marked as "reserved" in PM docs. $flags
937is a combination of C<SWP_*> constants.
938
939=item C<$hash = hWindowPos($hwnd)>
940
941gets window position info as a hash reference; the keys are C<flags width
942height x y behind hwnd reserved1 reserved2>.
35bc1fdc 943
30500b05
IZ
944Example:
945
946 exit unless $hash->{flags} & SWP_MAXIMIZE; # Maximized
947
948=item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $width = 0, $height = 0, $behind = HWND_TOP)>
35bc1fdc
IZ
949
950Set state of the window: position, size, zorder, show/hide, activation,
951minimize/maximize/restore etc. Which of these operations to perform
952is governed by $flags.
953
30500b05 954=item C<hWindowPos_set($hash, [$hwnd])>
35bc1fdc 955
30500b05
IZ
956Same as C<WindowPos_set>, but takes the position from keys C<fl width height
957x y behind hwnd> of the hash referenced by $hash. If $hwnd is explicitly
958specified, it overrides C<$hash->{hwnd}>. If $hash->{flags} is not specified,
959it is calculated basing on the existing keys of $hash. Requires (morphing to) PM.
35bc1fdc 960
30500b05 961Example:
35bc1fdc 962
30500b05
IZ
963 hWindowPos_set {flags => SWP_MAXIMIZE}, $hwnd; # Maximize
964
965=item C<($pid, $tid) = WindowProcess($hwnd)>
966
967gets I<PID> and I<TID> of the process associated to the window.
35bc1fdc
IZ
968
969=item C<ClassName($hwnd)>
970
971returns the class name of the window.
972
973If this window is of any of the preregistered WC_* classes the class
974name returned is in the form "#nnnnn", where "nnnnn" is a group
975of up to five digits that corresponds to the value of the WC_* class name
976constant.
977
978=item FocusWindow()
979
30500b05
IZ
980returns the handle of the focus window. Optional argument for specifying
981the desktop to use.
35bc1fdc
IZ
982
983=item C<FocusWindow_set($hwnd)>
984
985set the focus window by handle. Optional argument for specifying the desktop
986to use. E.g, the first entry in program_entries() is the C<Ctrl-Esc> list.
30500b05 987To show an application, use either one of
35bc1fdc 988
30500b05 989 WinShowWindow( $hwnd, 1 );
18729d3e 990 FocusWindow_set( $hwnd );
30500b05 991 SwitchToProgram($switch_handle);
35bc1fdc 992
18729d3e
JH
993(Which work with alternative focus-to-front policies?) Requires
994(morphing to) PM.
995
996Switching focus to currently-unfocused window moves the window to the
997front in Z-order; use FocusWindow_set_keep_Zorder() to avoid this.
998
999=item C<FocusWindow_set_keep_Zorder($hwnd)>
1000
1001same as FocusWindow_set(), but preserves the Z-order of windows.
30500b05
IZ
1002
1003=item C<ActiveWindow([$parentHwnd])>
1004
1005gets the active subwindow's handle for $parentHwnd or desktop.
1006Returns FALSE if none.
1007
1008=item C<ActiveWindow_set($hwnd, [$parentHwnd])>
1009
1010sets the active subwindow's handle for $parentHwnd or desktop. Requires (morphing to) PM.
35bc1fdc
IZ
1011
1012=item C<ShowWindow($hwnd [, $show])>
1013
1014Set visible/hidden flag of the window. Default: $show is TRUE.
1015
30500b05
IZ
1016=item C<EnableWindowUpdate($hwnd [, $update])>
1017
1018Set window visibility state flag for the window for subsequent drawing.
1019No actual drawing is done at this moment. Use C<ShowWindow($hwnd, $state)>
1020when redrawing is needed. While update is disabled, changes to the "window
1021state" do not change the appearence of the window. Default: $update is TRUE.
1022
1023(What is manipulated is the bit C<WS_VISIBLE> of the window style.)
1024
1025=item C<EnableWindow($hwnd [, $enable])>
1026
1027Set the window enabled state. Default: $enable is TRUE.
1028
1029Results in C<WM_ENABLED> message sent to the window. Typically, this
1030would change the appearence of the window. If at the moment of disabling
1031focus is in the window (or a descendant), focus is lost (no focus anywhere).
1032If focus is needed, it can be reassigned explicitly later.
1033
1034=item IsWindowEnabled(), IsWindowVisible(), IsWindowShowing()
1035
1036these functions take $hwnd as an argument. IsWindowEnabled() queries
1037the state changed by EnableWindow(), IsWindowVisible() the state changed
1038by ShowWindow(), IsWindowShowing() is true if there is a part of the window
1039visible on the screen.
1040
35bc1fdc
IZ
1041=item C<PostMsg($hwnd, $msg, $mp1, $mp2)>
1042
1043post message to a window. The meaning of $mp1, $mp2 is specific for each
30500b05
IZ
1044message id $msg, they default to 0. E.g.,
1045
1046 use OS2::Process qw(:DEFAULT WM_SYSCOMMAND WM_CONTEXTMENU
1047 WM_SAVEAPPLICATION WM_QUIT WM_CLOSE
1048 SC_MAXIMIZE SC_RESTORE);
1049 $hwnd = process_hentry()->{owner_hwnd};
1050 # Emulate choosing `Restore' from the window menu:
1051 PostMsg $hwnd, WM_SYSCOMMAND, MPFROMSHORT(SC_RESTORE); # Not immediate
1052
1053 # Emulate `Show-Contextmenu' (Double-Click-2), two ways:
1054 PostMsg ActiveWindow, WM_CONTEXTMENU;
1055 PostMsg FocusWindow, WM_CONTEXTMENU;
1056
1057 /* Emulate `Close' */
1058 PostMsg ActiveWindow, WM_CLOSE;
1059
1060 /* Same but with some "warnings" to the application */
1061 $hwnd = ActiveWindow;
1062 PostMsg $hwnd, WM_SAVEAPPLICATION;
1063 PostMsg $hwnd, WM_CLOSE;
1064 PostMsg $hwnd, WM_QUIT;
35bc1fdc 1065
30500b05 1066In fact, MPFROMSHORT() may be omited above.
35bc1fdc 1067
30500b05
IZ
1068For messages to other processes, messages which take/return a pointer are
1069not supported.
35bc1fdc 1070
30500b05 1071=item C<MP*()>
35bc1fdc 1072
30500b05
IZ
1073The functions MPFROMSHORT(), MPVOID(), MPFROMCHAR(), MPFROM2SHORT(),
1074MPFROMSH2CH(), MPFROMLONG() can be used the same way as from C. Use them
1075to construct parameters $m1, $m2 to PostMsg().
1076
1077These functions are not exported by default.
35bc1fdc
IZ
1078
1079=item C<$eh = BeginEnumWindows($hwnd)>
1080
1081starts enumerating immediate child windows of $hwnd in z-order. The
1082enumeration reflects the state at the moment of BeginEnumWindows() calls;
30500b05 1083use IsWindow() to be sure. All the functions in this group require (morphing to) PM.
35bc1fdc
IZ
1084
1085=item C<$kid_hwnd = GetNextWindow($eh)>
1086
1087gets the next kid in the list. Gets 0 on error or when the list ends.
7f61b687 1088
35bc1fdc 1089=item C<EndEnumWindows($eh)>
7f61b687 1090
35bc1fdc
IZ
1091End enumeration and release the list.
1092
30500b05 1093=item C<@list = ChildWindows([$hwnd])>
35bc1fdc
IZ
1094
1095returns the list of child windows at the moment of the call. Same remark
30500b05
IZ
1096as for enumeration interface applies. Defaults to HWND_DESKTOP.
1097Example of usage:
35bc1fdc
IZ
1098
1099 sub l {
1100 my ($o,$h) = @_;
1101 printf ' ' x $o . "%#x\n", $h;
1102 l($o+2,$_) for ChildWindows $h;
1103 }
1104 l 0, $HWND_DESKTOP
1105
1106=item C<IsWindow($hwnd)>
1107
1108true if the window handle is still valid.
1109
1110=item C<QueryWindow($hwnd, $type)>
1111
1112gets the handle of a related window. $type should be one of C<QW_*> constants.
1113
1114=item C<IsChild($hwnd, $parent)>
1115
1116return TRUE if $hwnd is a descendant of $parent.
1117
1118=item C<WindowFromId($hwnd, $id)>
1119
1120return a window handle of a child of $hwnd with the given $id.
1121
1122 hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU);
1123 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
1124 MPFROM2SHORT(SC_CLOSE, TRUE),
1125 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
1126
1127=item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])>
1128
1129gets a handle of a child of $hwndParent at C<($x,$y)>. If $descedantsToo
30500b05 1130(defaulting to 1) then children of children may be returned too. May return
35bc1fdc
IZ
1131$hwndParent (defaults to desktop) if no suitable children are found,
1132or 0 if the point is outside the parent.
1133
1134$x and $y are relative to $hwndParent.
1135
1136=item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])>
1137
1138gets a dialog item window handle for an item of type $type of $dlgHwnd
1139relative to $relativeHwnd, which is descendant of $dlgHwnd.
1140$relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or
1141EDI_LASTTABITEM.
1142
1143The return is always an immediate child of hwndDlg, even if hwnd is
1144not an immediate child window. $type may be
1145
1146=over
1147
1148=item EDI_FIRSTGROUPITEM
1149
1150First item in the same group.
1151
1152=item EDI_FIRSTTABITEM
1153
1154First item in dialog with style WS_TABSTOP. hwnd is ignored.
1155
1156=item EDI_LASTGROUPITEM
1157
1158Last item in the same group.
1159
1160=item EDI_LASTTABITEM
1161
1162Last item in dialog with style WS_TABSTOP. hwnd is ignored.
1163
1164=item EDI_NEXTGROUPITEM
1165
1166Next item in the same group. Wraps around to beginning of group when
1167the end of the group is reached.
1168
1169=item EDI_NEXTTABITEM
1170
1171Next item with style WS_TABSTOP. Wraps around to beginning of dialog
1172item list when end is reached.
1173
1174=item EDI_PREVGROUPITEM
1175
1176Previous item in the same group. Wraps around to end of group when the
1177start of the group is reached. For information on the WS_GROUP style,
1178see Window Styles.
1179
1180=item EDI_PREVTABITEM
1181
1182Previous item with style WS_TABSTOP. Wraps around to end of dialog
1183item list when beginning is reached.
7f61b687
IZ
1184
1185=back
1186
18729d3e
JH
1187=item DesktopWindow()
1188
1189gets the actual window handle of the PM desktop; most APIs accept the
1190pseudo-handle C<HWND_DESKTOP> instead. Keep in mind that the WPS
1191desktop (one with WindowText() being C<"Desktop">) is a different beast?!
1192
1193=item TopLevel($hwnd)
1194
1195gets the toplevel window of $hwnd.
1196
30500b05
IZ
1197=item ResetWinError()
1198
1199Resets $^E. One may need to call it before the C<Win*>-class APIs which may
1200return 0 during normal operation. In such a case one should check both
1201for return value being zero and $^E being non-zero. The following APIs
1202do ResetWinError() themselves, thus do not need an explicit one:
1203
1204 WindowPtr
1205 WindowULong
1206 WindowUShort
1207 WindowTextLength
1208 ActiveWindow
1209 PostMsg
1210
1211This function is normally not needed. Not exported by default.
1212
35bc1fdc
IZ
1213=back
1214
18729d3e
JH
1215=head2 Control of the PM data
1216
1217=over
1218
1219=item ActiveDesktopPathname()
1220
1221gets the path of the directory which corresponds to Desktop.
1222
1223=item ClipbrdText()
1224
1225gets the content of the clipboard. An optional argument is the format
1226of the data in the clipboard (defaults to C<CF_TEXT>).
1227
1228Note that the usual convention is to have clipboard data with
1229C<"\r\n"> as line separators.
1230
1231=item ClipbrdText_set($txt)
1232
1233sets the text content of the clipboard. Unless the optional argument
1234is TRUE, will convert newlines to C<"\r\n">. Another optional
1235argument is the format of the data in the clipboard (defaults to
1236C<CF_TEXT>).
1237
1238=item InvalidateRect
1239
1240=item CreateFrameControl
1241
1242=item ClipbrdFmtInfo
1243
1244=item ClipbrdOwner
1245
1246=item ClipbrdViewer
1247
1248=item ClipbrdData
1249
1250=item OpenClipbrd
1251
1252=item CloseClipbrd
1253
1254=item ClipbrdData_set
1255
1256=item ClipbrdOwner_set
1257
1258=item ClipbrdViewer_set
1259
1260=item EnumClipbrdFmts
1261
1262=item EmptyClipbrd
1263
1264=item AddAtom
1265
1266=item FindAtom
1267
1268=item DeleteAtom
1269
1270=item AtomUsage
1271
1272=item AtomName
1273
1274=item AtomLength
1275
1276=item SystemAtomTable
1277
1278=item CreateAtomTable
1279
1280=item DestroyAtomTable
1281
1282Low-level methods to access clipboard and the atom table(s).
1283
1284=back
1285
35bc1fdc
IZ
1286=head1 OS2::localMorphPM class
1287
30500b05 1288This class morphs the process to PM for the duration of the given scope.
35bc1fdc
IZ
1289
1290 {
1291 my $h = OS2::localMorphPM->new(0);
1292 # Do something
1293 }
1294
1295The argument has the same meaning as one to OS2::MorphPM(). Calls can
1296nest with internal ones being NOPs.
1297
1298=head1 TODO
1299
30500b05 1300Add tests for:
35bc1fdc 1301
30500b05
IZ
1302 SwitchToProgram
1303 ClassName
1304 out_codepage
1305 out_codepage_set
1306 in_codepage
1307 in_codepage_set
1308 cursor
1309 cursor_set
1310 screen
1311 screen_set
1312 process_codepages
1313 QueryWindow
1314 EnumDlgItem
1315 WindowPtr
1316 WindowULong
1317 WindowUShort
1318 SetWindowBits
1319 SetWindowPtr
1320 SetWindowULong
1321 SetWindowUShort
1322 my_type
1323 file_type
1324 scrsize
1325 scrsize_set
1326
18729d3e
JH
1327Document and test: Query/SetWindowULong/Short/Ptr, SetWindowBits.
1328InvalidateRect, CreateFrameControl, ClipbrdFmtInfo ClipbrdOwner
1329ClipbrdViewer ClipbrdData OpenClipbrd CloseClipbrd ClipbrdData_set
1330ClipbrdOwner_set ClipbrdViewer_set EnumClipbrdFmts EmptyClipbrd
1331AddAtom FindAtom DeleteAtom AtomUsage AtomName AtomLength
1332SystemAtomTable CreateAtomTable DestroyAtomTable
30500b05 1333
18729d3e 1334Implement SOMETHINGFROMMR.
30500b05
IZ
1335
1336
1337 >But I wish to change the default button if the user enters some
1338 >text into an entryfield. I can detect the entry ok, but can't
1339 >seem to get the button to change to default.
1340 >
1341 >No matter what message I send it, it's being ignored.
1342
1343 You need to get the style of the buttons using WinQueryWindowULong/QWL_STYLE,
1344 set and reset the BS_DEFAULT bits as appropriate and then use
1345 WinSetWindowULong/QWL_STYLE to set the button style.
1346 Something like this:
1347 hwnd1 = WinWindowFromID (hwnd, id1);
1348 hwnd2 = WinWindowFromID (hwnd, id2);
1349 style1 = WinQueryWindowULong (hwnd1, QWL_STYLE);
1350 style2 = WinQueryWindowULong (hwnd2, QWL_STYLE);
1351 style1 |= style2 & BS_DEFAULT;
1352 style2 &= ~BS_DEFAULT;
1353 WinSetWindowULong (hwnd1, QWL_STYLE, style1);
1354 WinSetWindowULong (hwnd2, QWL_STYLE, style2);
1355
1356 > How to do query and change a frame creation flags for existing window?
1357
1358 Set the style bits that correspond to the FCF_* flag for the frame
1359 window and then send a WM_UPDATEFRAME message with the appropriate FCF_*
1360 flag in mp1.
1361
1362 ULONG ulFrameStyle;
1363 ulFrameStyle = WinQueryWindowULong( WinQueryWindow(hwnd, QW_PARENT),
1364 QWL_STYLE );
1365 ulFrameStyle = (ulFrameStyle & ~FS_SIZEBORDER) | FS_BORDER;
1366 WinSetWindowULong( WinQueryWindow(hwnd, QW_PARENT),
1367 QWL_STYLE,
1368 ulFrameStyle );
1369 WinSendMsg( WinQueryWindow(hwnd, QW_PARENT),
1370 WM_UPDATEFRAME,
1371 MPFROMP(FCF_SIZEBORDER),
1372 MPVOID );
1373
1374 If the FCF_* flags you want to change does not have a corresponding FS_*
1375 style (i.e. the FCF_* flag corresponds to the presence/lack of a frame
1376 control rather than a property of the frame itself) then you create or
1377 destroy the appropriate control window using the correct FID_* window
1378 identifier and then send the WM_UPDATEFRAME message with the appropriate
1379 FCF_* flag in mp1.
1380
1381 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
1382 | SetFrameBorder() |
1383 | Changes a frame window's border to the requested type. |
1384 | |
1385 | Parameters on entry: |
1386 | hwndFrame -> Frame window whose border is to be changed. |
1387 | ulBorderStyle -> Type of border to change to. |
1388 | |
1389 | Returns: |
1390 | BOOL -> Success indicator. |
1391 | |
1392 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
1393 BOOL SetFrameBorder( HWND hwndFrame, ULONG ulBorderType ) {
1394 ULONG ulFrameStyle;
1395 BOOL fSuccess = TRUE;
1396
1397 ulFrameStyle = WinQueryWindowULong( hwndFrame, QWL_STYLE );
1398
1399 switch ( ulBorderType ) {
1400 case FS_SIZEBORDER :
1401 ulFrameStyle = (ulFrameStyle & ~(FS_DLGBORDER | FS_BORDER))
1402 | FS_SIZEBORDER;
1403 break;
1404
1405 case FS_DLGBORDER :
1406 ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_BORDER))
1407 | FS_DLGBORDER;
1408 break;
1409
1410 case FS_BORDER :
1411 ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_DLGBORDER))
1412 | FS_BORDER;
1413 break;
1414
1415 default :
1416 fSuccess = FALSE;
1417 break;
1418 } // end switch
1419
1420 if ( fSuccess ) {
1421 fSuccess = WinSetWindowULong( hwndFrame, QWL_STYLE, ulFrameStyle );
1422
1423 if ( fSuccess ) {
1424 fSuccess = (BOOL)WinSendMsg( hwndFrame, WM_UPDATEFRAME, 0, 0 );
1425 if ( fSuccess )
1426 fSuccess = WinInvalidateRect( hwndFrame, NULL, TRUE );
1427 }
1428 }
1429
1430 return ( fSuccess );
1431
1432 } // End SetFrameBorder()
1433
1434 hwndMenu=WinLoadMenu(hwndParent,NULL,WND_IMAGE);
1435 WinSetWindowUShort(hwndMenu,QWS_ID,FID_MENU);
1436 ulStyle=WinQueryWindowULong(hwndMenu,QWL_STYLE);
1437 WinSetWindowULong(hwndMenu,QWL_STYLE,ulStyle|MS_ACTIONBAR);
1438 WinSendMsg(hwndParent,WM_UPDATEFRAME,MPFROMSHORT(FCF_MENU),0L);
1439
1440 OS/2-windows have another "parent" called the *owner*,
1441 which must be set separately - to get a close relationship:
1442
1443 WinSetOwner (hwndFrameChild, hwndFrameMain);
1444
1445 Now your child should move with your main window!
1446 And always stays on top of it....
1447
1448 To avoid this, for example for dialogwindows, you can
1449 also "disconnect" this relationship with:
1450
1451 WinSetWindowBits (hwndFrameChild, QWL_STYLE
1452 , FS_NOMOVEWITHOWNER
1453 , FS_NOMOVEWITHOWNER);
1454
1455 Adding a button icon later:
1456
1457 /* switch the button style to BS_MINIICON */
1458 WinSetWindowBits(hwndBtn, QWL_STYLE, BS_MINIICON, BS_MINIICON) ;
1459
1460 /* set up button control data */
1461 BTNCDATA bcd;
1462 bcd.cb = sizeof(BTNCDATA);
1463 bcd.hImage = WinLoadPointer(HWND_DESKTOP, dllHandle, ID_ICON_BUTTON1) ;
1464 bcd.fsCheckState = bcd.fsHiliteState = 0 ;
1465
1466
1467 WNDPARAMS wp;
1468 wp.fsStatus = WPM_CTLDATA;
1469 wp.pCtlData = &bcd;
1470
1471 /* add the icon on the button */
1472 WinSendMsg(hwndBtn, WM_SETWINDOWPARAMS, (MPARAM)&wp, NULL);
35bc1fdc 1473
30500b05
IZ
1474 MO> Can anyone tell what OS/2 expects of an application to be properly
1475 MO> minimized to the desktop?
1476 case WM MINMAXFRAME :
1477 {
1478 BOOL fShow = ! (((PSWP) mp1)->fl & SWP MINIMIZE);
1479 HENUM henum;
35bc1fdc 1480
30500b05
IZ
1481 HWND hwndChild;
1482
1483 WinEnableWindowUpdate ( hwnd, FALSE );
1484
1485 for (henum=WinBeginEnumWindows(hwnd);
1486 (hwndChild = WinGetNextWindow (henum)) != 0; )
1487 WinShowWindow ( hwndChild, fShow );
1488
1489 WinEndEnumWindows ( henum );
1490 WinEnableWindowUpdate ( hwnd, TRUE );
1491 }
1492 break;
1493
1494Why C<hWindowPos DesktopWindow> gives C<< behind => HWND_TOP >>?
35bc1fdc
IZ
1495
1496=head1 $^E
1497
1498the majority of the APIs of this module set $^E on failure (no matter
1499whether they die() on failure or not). By the semantic of PM API
1500which returns something other than a boolean, it is impossible to
1501distinguish failure from a "normal" 0-return. In such cases C<$^E ==
15020> indicates an absence of error.
1503
30500b05
IZ
1504=head1 EXPORTS
1505
1506In addition to symbols described above, the following constants (available
1507also via module C<OS2::Process::Const>) are exportable. Note that these
1508symbols live in package C<OS2::Process::Const>, they are not available
1509by full name through C<OS2::Process>!
1510
1511 HWND_* Standard (abstract) window handles
1512 WM_* Message ids
1513 SC_* WM_SYSCOMMAND flavor
1514 SWP_* Size/move etc flag
1515 WC_* Standard window classes
1516 PROG_* Program category (PM, VIO etc)
1517 QW_* Query-Window flag
1518 EDI_* Enumerate-Dialog-Item code
1519 WS_* Window Style flag
1520 QWS_* Query-window-UShort offsets
1521 QWP_* Query-window-pointer offsets
1522 QWL_* Query-window-ULong offsets
1523 FF_* Frame-window state flags
1524 FI_* Frame-window information flags
1525 LS_* List box styles
1526 FS_* Frame style
1527 FCF_* Frame creation flags
1528 BS_* Button style
1529 MS_* Menu style
1530 TBM_* Title bar messages?
1531 CF_* Clipboard formats
1532 CFI_* Clipboard storage type
1533 FID_* ids of subwindows of frames
1534
35bc1fdc
IZ
1535=head1 BUGS
1536
1537whether a given API dies or returns FALSE/empty-list on error may be
1538confusing. This may change in the future.
1539
760ac839
LW
1540=head1 AUTHOR
1541
35bc1fdc 1542Andreas Kaiser <ak@ananke.s.bawue.de>,
7f61b687 1543Ilya Zakharevich <ilya@math.ohio-state.edu>.
760ac839
LW
1544
1545=head1 SEE ALSO
1546
35bc1fdc 1547C<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules.
760ac839
LW
1548
1549=cut