FOR EACH loControl IN laSelected >> amouseobj( laM, 1 ) >> loControl.Left = laM[3] && m.loControl.Left + m.lnHOffset >> loControl.Top = laM[4] &&m.loControl.Top + m.lnVOffset >>ENDFOR>>
LPARAMETERS tlCopyHorizontally AS Boolean, tnSpacing AS Number >>>#IF .F. >>>PARAMETERS: >>> tlCopyHorizontally (O) - Indicates whether the new controls should be >>> copied and aligned to the right of the selected >>> controls. If omitted, defaults to .F., the >>> controls will be copied below the selected >>> controls. >>> tnSpacing (O) - Indicates how many pixels to leave between the >>> selected group of controls, and the new controls. >>> IF omitted, defaults to 5. >>> >>>USAGE: >>> ON KEY LABEL CTRL+K DO oxCopyCtrl WITH .F., 10 >>> >>>NOTES: >>> We experience a refresh problem with this routine. Although the >>> controls were being copied and repositioned correctly, they often >>> appeared to be cut off (so that only the top or left edge of the group >>> of controls could be seen). Clicking in the form seemed to correct this, >>> but it would be better if the display could be corrected programmatically. >>>#ENDIF >>> >>>*-- When controls are copied and pasted without using the mouse, >>>*-- the default position for the new controls is 8 pixels below >>>*-- and 8 pixels to the right of the position of the selected >>>*-- controls. >>>#DEFINE DEFAULT_LEFT_OFFSET 8 >>>#DEFINE DEFAULT_TOP_OFFSET 8 >>> >>>LOCAL laSelected[1], ; >>> loControl AS Container, ; >>> lnLeft, ; >>> lnRight, ; >>> lnTop, ; >>> lnBottom, ; >>> lnHOffset, ; >>> lnVOffset >>> >>>*-- Check if the user wants to copy the controls horizontally, rather >>>*-- than vertically. >>>tlCopyHorizontally = ( VARTYPE( m.tlCopyHorizontally ) = "L" ; >>> AND m.tlCopyHorizontally ) >>> >>>*-- If a numeric value for spacing was passed, use it, otherwise we'll >>>*-- default to 5 pixels. >>>tnSpacing = IIF( VARTYPE( m.tnSpacing ) = "N", INT( m.tnSpacing ), 5 ) >>> >>>*-- Initialize the position variables so that the first control that's >>>*-- processed will update these variables with it's values. >>>lnLeft = 1000000 >>>lnRight = -1000000 >>>lnTop = 1000000 >>>lnBottom = -1000000 >>> >>>*-- Populate an array with object references for all selected controls. >>>IF ASELOBJ( laSelected ) = 0 >>> *-- Nothing was selected, so there's nothing to do. >>> RETURN >>>ENDIF >>> >>>*-- Determine the outer boundaries for the group of controls. >>>FOR EACH loControl IN laSelected >>> lnLeft = MIN( m.lnLeft, m.loControl.Left ) >>> lnRight = MAX( m.lnRight, m.loControl.Left + m.loControl.Width ) >>> lnTop = MIN( m.lnTop, m.loControl.Top ) >>> lnBottom = MAX( m.lnBottom, m.loControl.Top + m.loControl.Height ) >>>ENDFOR >>> >>>*-- Clear this variable, just to make sure we don't leave behind any >>>*-- dangling object references. >>>loControl = .NULL. >>> >>>IF m.tlCopyHorizontally >>> *-- The controls are to copied horizontally (to the right), so the >>> *-- new controls need to be moved to the right by the total width of >>> *-- the selected *group* of controls, minus the distance to the right >>> *-- that the new controls will have already moved, plus the spacing >>> *-- that was specified. >>> lnHOffset = m.lnRight - m.lnLeft - DEFAULT_LEFT_OFFSET + m.tnSpacing >>> *-- Move the controls back up by the amount that they will have been >>> *-- moved down, so that they align vertically with the original >>> *-- controls. >>> lnVOffset = -1 * DEFAULT_TOP_OFFSET >>>ELSE >>> *-- Move the controls back to the left by the amount that they will >>> *-- have been moved to the right, so that they align horizontally with >>> *-- the original controls. >>> lnHOffset = -1 * DEFAULT_LEFT_OFFSET >>> *-- The controls are to copied vertically (down), so the new controls >>> *-- need to be moved down by the total height of the selected *group* >>> *-- of controls, minus the distance down that the new controls will >>> *-- have already moved, plus the spacing that was specified. >>> lnVOffset = m.lnBottom - m.lnTop - DEFAULT_TOP_OFFSET + m.tnSpacing >>>ENDIF >>> >>> >>> >>>*-- Flush the keyboard buffer, and copy the selected controls. >>>KEYBOARD '{MOUSE}' PLAIN CLEAR >>>SYS( 1500, "_MED_COPY", "_MEDIT" ) >>> >>>*-- We seem to need a pause here while the clipboard is being populated. >>>*-- A half-second worked well for me, but your results may vary. >>>WAIT WINDOW "" NOCLEAR TIMEOUT .5 >>> >>>*-- Flush the keyboard buffer again, and paste the copied controls. >>>KEYBOARD '{MOUSE}' PLAIN CLEAR >>>SYS( 1500, "_MED_PASTE", "_MEDIT" ) >>> >>>*-- A pause after the paste also seems to be needed. >>>WAIT WINDOW "" NOCLEAR TIMEOUT .5 >>> >>>*-- The controls that were just pasted will now be the selected controls. >>>*-- Get the object references for them into an array so that we can scan >>>*-- through and adjust the positions of the controls. >>>ASELOBJ( laSelected ) >>>FOR EACH loControl IN laSelected >>> loControl.Left = m.loControl.Left + m.lnHOffset >>> loControl.Top = m.loControl.Top + m.lnVOffset >>>ENDFOR >>> >>>*-- Mike Yearwood - Feb 21, 2006 >>>*-- Setting focus to anything on the form/class designer >>>*-- seems to remove the refreshing problems. >>>*!* m.loControl.Parent.SetFocus() >>> >>>*-- Mike Yearwood - March 12, 2006 >>>*-- Better yet, how about setting focus to the first >>>*-- control in the new set. >>>FOR EACH m.loControl IN laSelected >>> IF PEMSTATUS(m.loControl,"SETFOCUS",5) >>> m.loControl.SetFocus() >>> EXIT >>> ENDIF >>>ENDFOR EACH m.loControl >>> >>>*-- Clear this variable, just to make sure we don't leave behind any >>>*-- dangling object references. >>>loControl = .NULL.