1 package OS2::localMorphPM;
7 # print STDERR ">>>>>\n";
11 # print STDERR "<<<<<\n";
12 OS2::UnMorphPM(shift->[0])
22 our @ISA = qw(Exporter);
24 XSLoader::load('OS2::Process', $VERSION);
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.
144 # This AUTOLOAD is used to 'autoload' constants from the constant()
145 # XS function. If a constant is not found then control is passed
146 # to the AUTOLOAD in AutoLoader.
148 (my $constname = $AUTOLOAD) =~ s/.*:://;
149 my $val = constant($constname, @_ ? $_[0] : 0);
151 if ($! =~ /Invalid/ || $!{EINVAL}) {
152 die "Unsupported function $AUTOLOAD"
154 my ($pack,$file,$line) = caller;
155 die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
159 eval "sub $AUTOLOAD { $val }";
164 require OS2::Process::Const;
166 my ($err, $val) = OS2::Process::Const::constant($sym);
172 *{"$p\::$sym"} = sub () { $val };
173 (); # needed by import()
181 /^(HWND|WM|SC|SWP|WC|PROG|QW|EDI|WS|QWS|QWP|QWL|FF|FI|LS|FS|FCF|BS|MS|TBM|CF|CFI|FID)_/ ? const_import($_) : $_
183 goto &Exporter::import if @_ > 1 or $ini == 0;
186 # Preloaded methods go here.
188 sub Title () { (process_entry())[0] }
190 # *Title_set = \&sesmgr_title_set;
193 my ($title, @sw) = @_;
198 sub swTitle_set ($) {
199 my (@sw) = process_entry();
200 swTitle_set_sw(shift, @sw);
203 sub winTitle_set_sw {
204 my ($title, @sw) = @_;
205 my $h = OS2::localMorphPM->new(0);
206 WindowText_set $sw[1], $title;
209 sub winTitle_set ($) {
210 my (@sw) = process_entry();
211 winTitle_set_sw(shift, @sw);
215 my (@sw) = process_entry();
216 my $h = OS2::localMorphPM->new(0);
220 sub bothTitle_set ($) {
221 my (@sw) = process_entry();
223 winTitle_set_sw($t, @sw);
224 swTitle_set_sw($t, @sw);
229 return 1 if sesmgr_title_set($t);
230 return 0 unless $^E == 372;
231 my (@sw) = process_entry();
232 winTitle_set_sw($t, @sw);
233 swTitle_set_sw($t, @sw);
236 sub process_entry { swentry_expand(process_swentry(@_)) }
238 our @hentry_fields = qw( title owner_hwnd icon_hwnd
239 owner_phandle owner_pid owner_sid
240 visible nonswitchable jumpable ptype sw_entry );
242 sub swentry_hexpand ($) {
244 @h{@hentry_fields} = swentry_expand(shift);
248 sub process_hentry { swentry_hexpand(process_swentry(@_)) }
249 sub process_hwnd { process_hentry()->{owner_hwnd} }
251 my $swentry_size = swentry_size();
254 my $s = swentries_list();
255 my ($c, $s1) = unpack 'La*', $s;
256 die "Unconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s;
258 push @l, $e while $e = substr $s1, 0, $swentry_size, '';
262 sub process_entries () {
263 map [swentry_expand($_)], sw_entries;
266 sub process_hentries () {
267 map swentry_hexpand($_), sw_entries;
271 change_swentry(create_swentry(@_));
274 sub create_swentryh ($) {
276 create_swentry(@$h{@hentry_fields});
279 sub change_entryh ($) {
280 change_swentry(create_swentryh(shift));
283 # Massage entries into the same order as WindowPos_set:
285 my ($fl, $h, $w, $y, $x, $behind, $hwnd, @rest)
286 = unpack 'L l4 L4', WindowSWP(shift);
287 ($x, $y, $fl, $w, $h, $behind, @rest);
290 # Put them into a hash
293 @h{ qw(flags height width y x behind hwnd reserved1 reserved2) }
294 = unpack 'L l4 L4', WindowSWP(shift);
298 my @SWP_keys = ( [qw(width height)], # SWP_SIZE=1
299 [qw(x y)], # SWP_MOVE=2
300 [qw(behind)] ); # SWP_ZORDER=3
302 @SWP_def{ map @$_, @SWP_keys } = (0) x 20;
304 # Get them from a hash
305 sub hWindowPos_set ($$) {
307 my $hwnd = (@_ ? shift : $hash->{hwnd} );
309 if (exists $hash->{flags}) {
310 $flags = $hash->{flags};
311 } else { # Set flags according to existing keys in $hash
314 exists $hash->{$_} and $flags |= (1<<$bit) for @{$SWP_keys[$bit]};
317 for my $bit (0..2) { # Check for required keys
318 next unless $flags & (1<<$bit);
320 or die sprintf "key $_ required for flags=%#x", $flags
321 for @{$SWP_keys[$bit]};
323 my %h = (%SWP_def, flags => $flags, %$hash); # Avoid warnings
324 my ($x, $y, $fl, $w, $h, $behind) = @h{ qw(x y flags width height behind) };
325 WindowPos_set($hwnd, $x, $y, $fl, $w, $h, $behind);
328 sub ChildWindows (;$) {
329 my $hm = OS2::localMorphPM->new(0);
331 my $h = BeginEnumWindows(@_ ? shift : 1); # HWND_DESKTOP
333 push @kids, $w while $w = GetNextWindow $h;
338 # backward compatibility
339 *set_title = \&Title_set;
340 *get_title = \&Title;
342 # Autoload methods go after __END__, and are processed by the autosplit program.
349 OS2::Process - exports constants for system() call, and process control on OS2.
354 $pid = system(P_PM | P_BACKGROUND, "epm.exe");
358 =head2 Optional argument to system()
360 the builtin function system() under OS/2 allows an optional first
361 argument which denotes the mode of the process. Note that this argument is
362 recognized only if it is strictly numerical.
364 You can use either one of the process modes:
366 P_WAIT (0) = wait until child terminates (default)
367 P_NOWAIT = do not wait until child terminates
368 P_SESSION = new session
372 and optionally add PM and session option bits:
374 P_DEFAULT (0) = default
375 P_MINIMIZE = minimized
376 P_MAXIMIZE = maximized
377 P_FULLSCREEN = fullscreen (session only)
378 P_WINDOWED = windowed (session only)
380 P_FOREGROUND = foreground (if running in foreground)
381 P_BACKGROUND = background
383 P_NOCLOSE = don't close window on exit (session only)
385 P_QUOTE = quote all arguments
386 P_TILDE = MKS argument passing convention
387 P_UNRELATED = do not kill child when father terminates
389 =head2 Access to process properties
391 On OS/2 processes have the usual I<parent/child> semantic;
392 additionally, there is a hierarchy of sessions with their own
393 I<parent/child> tree. A session is either a FS session, or a windowed
394 pseudo-session created by PM. A session is a "unit of user
395 interaction", a change to in/out settings in one of them does not
396 affect other sessions.
402 returns the type of the current process (one of
403 "FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error.
405 =item C<file_type(file)>
407 returns the type of the executable file C<file>, or
408 dies on error. The bits 0-2 of the result contain one of the values
412 =item C<T_NOTSPEC> (0)
414 Application type is not specified in the executable header.
416 =item C<T_NOTWINDOWCOMPAT> (1)
418 Application type is not-window-compatible.
420 =item C<T_WINDOWCOMPAT> (2)
422 Application type is window-compatible.
424 =item C<T_WINDOWAPI> (3)
426 Application type is window-API.
430 The remaining bits should be masked with the following values to
431 determine the type of the executable:
437 Set to 1 if the executable file has been "bound" (by the BIND command)
438 as a Family API application. Bits 0, 1, and 2 still apply.
440 =item C<T_DLL> (0x10)
442 Set to 1 if the executable file is a dynamic link library (DLL)
443 module. Bits 0, 1, 2, 3, and 5 will be set to 0.
445 =item C<T_DOS> (0x20)
447 Set to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3,
448 and 4 will be set to 0.
450 =item C<T_PHYSDRV> (0x40)
452 Set to 1 if the executable file is a physical device driver.
454 =item C<T_VIRTDRV> (0x80)
456 Set to 1 if the executable file is a virtual device driver.
458 =item C<T_PROTDLL> (0x100)
460 Set to 1 if the executable file is a protected-memory dynamic link
463 =item C<T_32BIT> (0x4000)
465 Set to 1 for 32-bit executable files.
469 file_type() may croak with one of the strings C<"Invalid EXE
470 signature"> or C<"EXE marked invalid"> to indicate typical error
471 conditions. If given non-absolute path, will look on C<PATH>, will
472 add extention F<.exe> if no extension is present (add extension F<.>
475 =item C<@list = process_codepages()>
477 the first element is the currently active codepage, up to 2 additional
478 entries specify the system's "prepared codepages": the codepages the
479 user can switch to. The active codepage of a process is one of the
480 prepared codepages of the system (if present).
482 =item C<process_codepage_set($cp)>
484 sets the currently active codepage. [Affects printer output, in/out
485 codepages of sessions started by this process, and the default
486 codepage for drawing in PM; is inherited by kids. Does not affect the
487 out- and in-codepages of the session.]
491 returns the PID of the parent process.
493 =item C<ppidOf($pid = $$)>
495 returns the PID of the parent process of $pid. -1 on error.
497 =item C<sidOf($pid = $$)>
499 returns the session id of the process id $pid. -1 on error.
503 =head2 Control of VIO sessions
505 VIO applications are applications running in a text-mode session.
511 gets code page used for screen output (glyphs). -1 means that a user font
514 =item C<out_codepage_set($cp)>
516 sets code page used for screen output (glyphs). -1 switches to a preloaded
517 user font. -2 switches off the preloaded user font.
521 gets code page used for keyboard input. 0 means that a hardware codepage
524 =item C<in_codepage_set($cp)>
526 sets code page used for keyboard input.
528 =item C<($w, $h) = scrsize()>
530 width and height of the given console window in character cells.
532 =item C<scrsize_set([$w, ] $h)>
534 set height (and optionally width) of the given console window in
535 character cells. Use 0 size to keep the old size.
537 =item C<($s, $e, $w, $a) = cursor()>
539 gets start/end lines of the blinking cursor in the charcell, its width
540 (1 on text modes) and attribute (-1 for hidden, in text modes other
541 values mean visible, in graphic modes color).
543 =item C<cursor_set($s, $e, [$w [, $a]])>
545 sets start/end lines of the blinking cursor in the charcell. Negative
546 values mean percents of the character cell height.
550 gets a buffer with characters and attributes of the screen.
552 =item C<screen_set($buffer)>
554 restores the screen given the result of screen().
558 =head2 Control of the process list
560 With the exception of Title_set(), all these calls require that PM is
561 running, they would not work under alternative Session Managers.
565 =item process_entry()
567 returns a list of the following data:
573 Title of the process (in the C<Ctrl-Esc> list);
577 window handle of switch entry of the process (in the C<Ctrl-Esc> list);
581 window handle of the icon of the process;
585 process handle of the owner of the entry in C<Ctrl-Esc> list;
589 process id of the owner of the entry in C<Ctrl-Esc> list;
593 session id of the owner of the entry in C<Ctrl-Esc> list;
597 whether visible in C<Ctrl-Esc> list;
601 whether item cannot be switched to (note that it is not actually
602 grayed in the C<Ctrl-Esc> list));
606 whether participates in jump sequence;
610 program type. Possible values are:
619 Although there are several other program types for WIN-OS/2 programs,
620 these do not show up in this field. Instead, the PROG_VDM or
621 PROG_WINDOWEDVDM program types are used. For instance, for
622 PROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all
623 the WIN-OS/2 programs run in DOS sessions. For example, if a program
624 is a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM
625 session. Likewise, if it's a full-screen WIN-OS/2 program, it runs in
634 Optional arguments: the pid and the window-handle of the application running
635 in the OS/2 session to query.
637 =item process_hentry()
639 similar to process_entry(), but returns a hash reference, the keys being
641 title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid
642 visible nonswitchable jumpable ptype sw_entry
644 (a copy of the list of keys is in @hentry_fields).
646 =item process_entries()
648 similar to process_entry(), but returns a list of array reference for all
649 the elements in the switch list (one controlling C<Ctrl-Esc> window).
651 =item process_hentries()
653 similar to process_hentry(), but returns a list of hash reference for all
654 the elements in the switch list (one controlling C<Ctrl-Esc> window).
658 changes a process entry, arguments are the same as process_entry() returns.
660 =item change_entryh()
662 Similar to change_entry(), but takes a hash reference as an argument.
666 returns the C<owner_hwnd> of the process entry (for VIO windowed processes
667 this is the frame window of the session).
671 returns the text of the task switch menu entry of the current session.
672 (There is no way to get this info in non-standard Session Managers. This
673 implementation is a shortcut via process_entry().)
675 =item C<Title_set(newtitle)>
677 tries two different interfaces. The Session Manager one does not work
678 with some windows (if the title is set from the start).
679 This is a limitation of OS/2, in such a case $^E is set to 372 (type
683 for a funny - and wrong - explanation ;-). In such cases a
684 direct-manipulation of low-level entries is used (same as bothTitle_set()).
685 Keep in mind that some versions of OS/2 leak memory with such a manipulation.
689 returns text of the titlebar of the current process' window.
691 =item C<winTitle_set(newtitle)>
693 sets text of the titlebar of the current process' window. The change does not
694 affect the text of the switch entry of the current window.
696 =item C<swTitle_set(newtitle)>
698 sets text of the task switch menu entry of the current process' window. [There
699 is no API to query this title.] Does it via SwitchEntry interface,
700 not Session manager interface. The change does not affect the text of the
701 titlebar of the current window.
703 =item C<bothTitle_set(newtitle)>
705 sets text of the titlebar and task switch menu of the current process' window
706 via direct manipulation of the windows' texts.
708 =item C<SwitchToProgram($sw_entry)>
710 switch to session given by a switch list handle.
712 Use of this function causes another window (and its related windows)
713 of a PM session to appear on the front of the screen, or a switch to
714 another session in the case of a non-PM program. In either case,
715 the keyboard (and mouse for the non-PM case) input is directed to
720 =head2 Control of the PM windows
722 Some of these API's require sending a message to the specified window.
723 In such a case the process needs to be a PM process, or to be morphed
724 to a PM process via OS2::MorphPM().
726 For a temporary morphing to PM use L<OS2::localMorphPM class>.
728 Keep in mind that PM windows are engaged in 2 "orthogonal" window
729 trees, as well as in the z-order list.
731 One tree is given by the I<parent/child> relationship. This
732 relationship affects drawing (child is drawn relative to its parent
733 (lower-left corner), and the drawing is clipped by the parent's
734 boundary; parent may request that I<it's> drawing is clipped to be
735 confined to the outsize of the childs and/or siblings' windows);
736 hiding; minimizing/restoring; and destroying windows.
738 Another tree (not necessarily connected?) is given by I<ownership>
739 relationship. Ownership relationship assumes cooperation of the
740 engaged windows via passing messages on "important events"; e.g.,
741 scrollbars send information messages when the "bar" is moved, menus
742 send messages when an item is selected; frames
743 move/hide/unhide/minimize/restore/change-z-order-of owned frames when
744 the owner is moved/etc., and destroy the owned frames (even when these
745 frames are not descendants) when the owner is destroyed; etc. [An
746 important restriction on ownership is that owner should be created by
747 the same thread as the owned thread, so they engage in the same
750 Windows may be in many different state: Focused (take keyboard events) or not,
751 Activated (=Frame windows in the I<parent/child> tree between the root and
752 the window with the focus; usually indicate such "active state" by titlebar
753 highlights, and take mouse events) or not, Enabled/Disabled (this influences
754 the ability to update the graphic, and may change appearance, as for
755 enabled/disabled buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal
758 The APIs below all die() on error with the message being $^E.
762 =item C<WindowText($hwnd)>
764 gets "a text content" of a window. Requires (morphing to) PM.
766 =item C<WindowText_set($hwnd, $text)>
768 sets "a text content" of a window. Requires (morphing to) PM.
770 =item C<($x, $y, $flags, $width, $height, $behind, @rest) = WindowPos($hwnd)>
772 gets window position info as 8 integers (of C<SWP>), in the order suitable
773 for WindowPos_set(). @rest is marked as "reserved" in PM docs. $flags
774 is a combination of C<SWP_*> constants.
776 =item C<$hash = hWindowPos($hwnd)>
778 gets window position info as a hash reference; the keys are C<flags width
779 height x y behind hwnd reserved1 reserved2>.
783 exit unless $hash->{flags} & SWP_MAXIMIZE; # Maximized
785 =item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $width = 0, $height = 0, $behind = HWND_TOP)>
787 Set state of the window: position, size, zorder, show/hide, activation,
788 minimize/maximize/restore etc. Which of these operations to perform
789 is governed by $flags.
791 =item C<hWindowPos_set($hash, [$hwnd])>
793 Same as C<WindowPos_set>, but takes the position from keys C<fl width height
794 x y behind hwnd> of the hash referenced by $hash. If $hwnd is explicitly
795 specified, it overrides C<$hash->{hwnd}>. If $hash->{flags} is not specified,
796 it is calculated basing on the existing keys of $hash. Requires (morphing to) PM.
800 hWindowPos_set {flags => SWP_MAXIMIZE}, $hwnd; # Maximize
802 =item C<($pid, $tid) = WindowProcess($hwnd)>
804 gets I<PID> and I<TID> of the process associated to the window.
806 =item C<ClassName($hwnd)>
808 returns the class name of the window.
810 If this window is of any of the preregistered WC_* classes the class
811 name returned is in the form "#nnnnn", where "nnnnn" is a group
812 of up to five digits that corresponds to the value of the WC_* class name
817 returns the handle of the focus window. Optional argument for specifying
820 =item C<FocusWindow_set($hwnd)>
822 set the focus window by handle. Optional argument for specifying the desktop
823 to use. E.g, the first entry in program_entries() is the C<Ctrl-Esc> list.
824 To show an application, use either one of
826 WinShowWindow( $hwnd, 1 );
828 SwitchToProgram($switch_handle);
830 (Which work with alternative focus-to-front policies?) Requires (morphing to) PM.
832 =item C<ActiveWindow([$parentHwnd])>
834 gets the active subwindow's handle for $parentHwnd or desktop.
835 Returns FALSE if none.
837 =item C<ActiveWindow_set($hwnd, [$parentHwnd])>
839 sets the active subwindow's handle for $parentHwnd or desktop. Requires (morphing to) PM.
841 =item C<ShowWindow($hwnd [, $show])>
843 Set visible/hidden flag of the window. Default: $show is TRUE.
845 =item C<EnableWindowUpdate($hwnd [, $update])>
847 Set window visibility state flag for the window for subsequent drawing.
848 No actual drawing is done at this moment. Use C<ShowWindow($hwnd, $state)>
849 when redrawing is needed. While update is disabled, changes to the "window
850 state" do not change the appearence of the window. Default: $update is TRUE.
852 (What is manipulated is the bit C<WS_VISIBLE> of the window style.)
854 =item C<EnableWindow($hwnd [, $enable])>
856 Set the window enabled state. Default: $enable is TRUE.
858 Results in C<WM_ENABLED> message sent to the window. Typically, this
859 would change the appearence of the window. If at the moment of disabling
860 focus is in the window (or a descendant), focus is lost (no focus anywhere).
861 If focus is needed, it can be reassigned explicitly later.
863 =item IsWindowEnabled(), IsWindowVisible(), IsWindowShowing()
865 these functions take $hwnd as an argument. IsWindowEnabled() queries
866 the state changed by EnableWindow(), IsWindowVisible() the state changed
867 by ShowWindow(), IsWindowShowing() is true if there is a part of the window
868 visible on the screen.
870 =item C<PostMsg($hwnd, $msg, $mp1, $mp2)>
872 post message to a window. The meaning of $mp1, $mp2 is specific for each
873 message id $msg, they default to 0. E.g.,
875 use OS2::Process qw(:DEFAULT WM_SYSCOMMAND WM_CONTEXTMENU
876 WM_SAVEAPPLICATION WM_QUIT WM_CLOSE
877 SC_MAXIMIZE SC_RESTORE);
878 $hwnd = process_hentry()->{owner_hwnd};
879 # Emulate choosing `Restore' from the window menu:
880 PostMsg $hwnd, WM_SYSCOMMAND, MPFROMSHORT(SC_RESTORE); # Not immediate
882 # Emulate `Show-Contextmenu' (Double-Click-2), two ways:
883 PostMsg ActiveWindow, WM_CONTEXTMENU;
884 PostMsg FocusWindow, WM_CONTEXTMENU;
886 /* Emulate `Close' */
887 PostMsg ActiveWindow, WM_CLOSE;
889 /* Same but with some "warnings" to the application */
890 $hwnd = ActiveWindow;
891 PostMsg $hwnd, WM_SAVEAPPLICATION;
892 PostMsg $hwnd, WM_CLOSE;
893 PostMsg $hwnd, WM_QUIT;
895 In fact, MPFROMSHORT() may be omited above.
897 For messages to other processes, messages which take/return a pointer are
902 The functions MPFROMSHORT(), MPVOID(), MPFROMCHAR(), MPFROM2SHORT(),
903 MPFROMSH2CH(), MPFROMLONG() can be used the same way as from C. Use them
904 to construct parameters $m1, $m2 to PostMsg().
906 These functions are not exported by default.
908 =item C<$eh = BeginEnumWindows($hwnd)>
910 starts enumerating immediate child windows of $hwnd in z-order. The
911 enumeration reflects the state at the moment of BeginEnumWindows() calls;
912 use IsWindow() to be sure. All the functions in this group require (morphing to) PM.
914 =item C<$kid_hwnd = GetNextWindow($eh)>
916 gets the next kid in the list. Gets 0 on error or when the list ends.
918 =item C<EndEnumWindows($eh)>
920 End enumeration and release the list.
922 =item C<@list = ChildWindows([$hwnd])>
924 returns the list of child windows at the moment of the call. Same remark
925 as for enumeration interface applies. Defaults to HWND_DESKTOP.
930 printf ' ' x $o . "%#x\n", $h;
931 l($o+2,$_) for ChildWindows $h;
935 =item C<IsWindow($hwnd)>
937 true if the window handle is still valid.
939 =item C<QueryWindow($hwnd, $type)>
941 gets the handle of a related window. $type should be one of C<QW_*> constants.
943 =item C<IsChild($hwnd, $parent)>
945 return TRUE if $hwnd is a descendant of $parent.
947 =item C<WindowFromId($hwnd, $id)>
949 return a window handle of a child of $hwnd with the given $id.
951 hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU);
952 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
953 MPFROM2SHORT(SC_CLOSE, TRUE),
954 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
956 =item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])>
958 gets a handle of a child of $hwndParent at C<($x,$y)>. If $descedantsToo
959 (defaulting to 1) then children of children may be returned too. May return
960 $hwndParent (defaults to desktop) if no suitable children are found,
961 or 0 if the point is outside the parent.
963 $x and $y are relative to $hwndParent.
965 =item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])>
967 gets a dialog item window handle for an item of type $type of $dlgHwnd
968 relative to $relativeHwnd, which is descendant of $dlgHwnd.
969 $relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or
972 The return is always an immediate child of hwndDlg, even if hwnd is
973 not an immediate child window. $type may be
977 =item EDI_FIRSTGROUPITEM
979 First item in the same group.
981 =item EDI_FIRSTTABITEM
983 First item in dialog with style WS_TABSTOP. hwnd is ignored.
985 =item EDI_LASTGROUPITEM
987 Last item in the same group.
989 =item EDI_LASTTABITEM
991 Last item in dialog with style WS_TABSTOP. hwnd is ignored.
993 =item EDI_NEXTGROUPITEM
995 Next item in the same group. Wraps around to beginning of group when
996 the end of the group is reached.
998 =item EDI_NEXTTABITEM
1000 Next item with style WS_TABSTOP. Wraps around to beginning of dialog
1001 item list when end is reached.
1003 =item EDI_PREVGROUPITEM
1005 Previous item in the same group. Wraps around to end of group when the
1006 start of the group is reached. For information on the WS_GROUP style,
1009 =item EDI_PREVTABITEM
1011 Previous item with style WS_TABSTOP. Wraps around to end of dialog
1012 item list when beginning is reached.
1016 =item ResetWinError()
1018 Resets $^E. One may need to call it before the C<Win*>-class APIs which may
1019 return 0 during normal operation. In such a case one should check both
1020 for return value being zero and $^E being non-zero. The following APIs
1021 do ResetWinError() themselves, thus do not need an explicit one:
1030 This function is normally not needed. Not exported by default.
1034 =head1 OS2::localMorphPM class
1036 This class morphs the process to PM for the duration of the given scope.
1039 my $h = OS2::localMorphPM->new(0);
1043 The argument has the same meaning as one to OS2::MorphPM(). Calls can
1044 nest with internal ones being NOPs.
1076 Query/SetWindowULong/Short/Ptr, SetWindowBits.
1078 Implement InvalidateRect,
1079 CreateFrameControl. ClipbrdFmtInfo, ClipbrdData, OpenClipbrd, CloseClipbrd,
1080 ClipbrdData_set, EnumClipbrdFmt, EmptyClipbrd. SOMETHINGFROMMR.
1083 >But I wish to change the default button if the user enters some
1084 >text into an entryfield. I can detect the entry ok, but can't
1085 >seem to get the button to change to default.
1087 >No matter what message I send it, it's being ignored.
1089 You need to get the style of the buttons using WinQueryWindowULong/QWL_STYLE,
1090 set and reset the BS_DEFAULT bits as appropriate and then use
1091 WinSetWindowULong/QWL_STYLE to set the button style.
1092 Something like this:
1093 hwnd1 = WinWindowFromID (hwnd, id1);
1094 hwnd2 = WinWindowFromID (hwnd, id2);
1095 style1 = WinQueryWindowULong (hwnd1, QWL_STYLE);
1096 style2 = WinQueryWindowULong (hwnd2, QWL_STYLE);
1097 style1 |= style2 & BS_DEFAULT;
1098 style2 &= ~BS_DEFAULT;
1099 WinSetWindowULong (hwnd1, QWL_STYLE, style1);
1100 WinSetWindowULong (hwnd2, QWL_STYLE, style2);
1102 > How to do query and change a frame creation flags for existing window?
1104 Set the style bits that correspond to the FCF_* flag for the frame
1105 window and then send a WM_UPDATEFRAME message with the appropriate FCF_*
1109 ulFrameStyle = WinQueryWindowULong( WinQueryWindow(hwnd, QW_PARENT),
1111 ulFrameStyle = (ulFrameStyle & ~FS_SIZEBORDER) | FS_BORDER;
1112 WinSetWindowULong( WinQueryWindow(hwnd, QW_PARENT),
1115 WinSendMsg( WinQueryWindow(hwnd, QW_PARENT),
1117 MPFROMP(FCF_SIZEBORDER),
1120 If the FCF_* flags you want to change does not have a corresponding FS_*
1121 style (i.e. the FCF_* flag corresponds to the presence/lack of a frame
1122 control rather than a property of the frame itself) then you create or
1123 destroy the appropriate control window using the correct FID_* window
1124 identifier and then send the WM_UPDATEFRAME message with the appropriate
1127 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
1128 | SetFrameBorder() |
1129 | Changes a frame window's border to the requested type. |
1131 | Parameters on entry: |
1132 | hwndFrame -> Frame window whose border is to be changed. |
1133 | ulBorderStyle -> Type of border to change to. |
1136 | BOOL -> Success indicator. |
1138 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
1139 BOOL SetFrameBorder( HWND hwndFrame, ULONG ulBorderType ) {
1141 BOOL fSuccess = TRUE;
1143 ulFrameStyle = WinQueryWindowULong( hwndFrame, QWL_STYLE );
1145 switch ( ulBorderType ) {
1146 case FS_SIZEBORDER :
1147 ulFrameStyle = (ulFrameStyle & ~(FS_DLGBORDER | FS_BORDER))
1152 ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_BORDER))
1157 ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_DLGBORDER))
1167 fSuccess = WinSetWindowULong( hwndFrame, QWL_STYLE, ulFrameStyle );
1170 fSuccess = (BOOL)WinSendMsg( hwndFrame, WM_UPDATEFRAME, 0, 0 );
1172 fSuccess = WinInvalidateRect( hwndFrame, NULL, TRUE );
1176 return ( fSuccess );
1178 } // End SetFrameBorder()
1180 hwndMenu=WinLoadMenu(hwndParent,NULL,WND_IMAGE);
1181 WinSetWindowUShort(hwndMenu,QWS_ID,FID_MENU);
1182 ulStyle=WinQueryWindowULong(hwndMenu,QWL_STYLE);
1183 WinSetWindowULong(hwndMenu,QWL_STYLE,ulStyle|MS_ACTIONBAR);
1184 WinSendMsg(hwndParent,WM_UPDATEFRAME,MPFROMSHORT(FCF_MENU),0L);
1186 OS/2-windows have another "parent" called the *owner*,
1187 which must be set separately - to get a close relationship:
1189 WinSetOwner (hwndFrameChild, hwndFrameMain);
1191 Now your child should move with your main window!
1192 And always stays on top of it....
1194 To avoid this, for example for dialogwindows, you can
1195 also "disconnect" this relationship with:
1197 WinSetWindowBits (hwndFrameChild, QWL_STYLE
1198 , FS_NOMOVEWITHOWNER
1199 , FS_NOMOVEWITHOWNER);
1201 Adding a button icon later:
1203 /* switch the button style to BS_MINIICON */
1204 WinSetWindowBits(hwndBtn, QWL_STYLE, BS_MINIICON, BS_MINIICON) ;
1206 /* set up button control data */
1208 bcd.cb = sizeof(BTNCDATA);
1209 bcd.hImage = WinLoadPointer(HWND_DESKTOP, dllHandle, ID_ICON_BUTTON1) ;
1210 bcd.fsCheckState = bcd.fsHiliteState = 0 ;
1214 wp.fsStatus = WPM_CTLDATA;
1217 /* add the icon on the button */
1218 WinSendMsg(hwndBtn, WM_SETWINDOWPARAMS, (MPARAM)&wp, NULL);
1220 MO> Can anyone tell what OS/2 expects of an application to be properly
1221 MO> minimized to the desktop?
1222 case WM MINMAXFRAME :
1224 BOOL fShow = ! (((PSWP) mp1)->fl & SWP MINIMIZE);
1229 WinEnableWindowUpdate ( hwnd, FALSE );
1231 for (henum=WinBeginEnumWindows(hwnd);
1232 (hwndChild = WinGetNextWindow (henum)) != 0; )
1233 WinShowWindow ( hwndChild, fShow );
1235 WinEndEnumWindows ( henum );
1236 WinEnableWindowUpdate ( hwnd, TRUE );
1240 Why C<hWindowPos DesktopWindow> gives C<< behind => HWND_TOP >>?
1244 the majority of the APIs of this module set $^E on failure (no matter
1245 whether they die() on failure or not). By the semantic of PM API
1246 which returns something other than a boolean, it is impossible to
1247 distinguish failure from a "normal" 0-return. In such cases C<$^E ==
1248 0> indicates an absence of error.
1252 In addition to symbols described above, the following constants (available
1253 also via module C<OS2::Process::Const>) are exportable. Note that these
1254 symbols live in package C<OS2::Process::Const>, they are not available
1255 by full name through C<OS2::Process>!
1257 HWND_* Standard (abstract) window handles
1259 SC_* WM_SYSCOMMAND flavor
1260 SWP_* Size/move etc flag
1261 WC_* Standard window classes
1262 PROG_* Program category (PM, VIO etc)
1263 QW_* Query-Window flag
1264 EDI_* Enumerate-Dialog-Item code
1265 WS_* Window Style flag
1266 QWS_* Query-window-UShort offsets
1267 QWP_* Query-window-pointer offsets
1268 QWL_* Query-window-ULong offsets
1269 FF_* Frame-window state flags
1270 FI_* Frame-window information flags
1271 LS_* List box styles
1273 FCF_* Frame creation flags
1276 TBM_* Title bar messages?
1277 CF_* Clipboard formats
1278 CFI_* Clipboard storage type
1279 FID_* ids of subwindows of frames
1283 whether a given API dies or returns FALSE/empty-list on error may be
1284 confusing. This may change in the future.
1288 Andreas Kaiser <ak@ananke.s.bawue.de>,
1289 Ilya Zakharevich <ilya@math.ohio-state.edu>.
1293 C<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules.