Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Copy form controls H/V by X pixels
Message
De
30/04/2015 16:34:26
Mike Yearwood
Toronto, Ontario, Canada
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Gestionnaire d'écran & Écrans
Titre:
Copy form controls H/V by X pixels
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows Server 2012
Network:
Windows 2008 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01619303
Message ID:
01619303
Vues:
78
Ever notice how with form controls, Ctrl+C, Ctrl+V positions the new control down and to the right. Has that ever once been where you wanted the new control? I've done a lot of screens and I've either always wanted new controls below the old control, or to the right.

I came up with this code many years ago, and Mike Potjer tweaked it quite a bit. We never got it exactly perfect, but it works mostly. Any improvement is welcome. One would be to have it work on the report designer, and not just the screen designer. It defaults to 5 pixels.

To use it, set up an ON KEY LABEL like this:

ON KEY LABEL CTRL+K DO oxCopyCtrl WITH .F., 10

That means the new control will be placed 10 pixels vertically below the currently selected control. Re-issue the ON KEY LABEL and change the first parameter to .T. switches it to copying horizontally.

Mike Potjer and I agreed recently to donate this to the community. Specifically, we're hoping Thor can include it. The one thing it does which is annoying is removes the original control, or perhaps, moves the original control, or maybe it's a display problem.
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.
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform