I saw on another application this
the button open a menu popup and on the menu there are two slider controls , Can make it on Fwh ?
How make it?
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
How make it?
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Re: How make it?
Silvio,
You can connect a dialog to the button on action.
Dialog-top = button-bottom, dialog-left = button-left.
There You can include what ever You want.
If needed You can paint a colored border around the dialog.
The logic can be used on any other object.
In xBrowse it is connected to a cell.
connecting the dialog to the button ( main function )
// --------------
...
...
DEFINE DIALOG oDlg1 FROM 0, 0 TO 180, 200 OF oDlg PIXEL TRUEPIXEL FONT oFont ;
STYLE WS_POPUP
...
@ 20, 30 BTNBMP oBtn1 2007 ;
SIZE 30, 30 OF oDlg NOBORDER ;
ACTION MYDLG( oDlg, oBtn1, oFont )
...
ACTIVATE DIALOG oDlg CENTERED
RETURN NIL
// --------------
FUNCTION MYDLG( oDlg, oBtn, oFont )
LOCAL oDlg1, oBtn2, oSlider1, nSlidPos1 := 1, oSlider2, nSlidPos2 := 2
LOCAL oRect1 := oDlg:GetRect()
LOCAL nTop1 := oRect1:nTop
LOCAL nLeft1 := oRect1:nLeft
LOCAL nTop2 := oBtn:nTop() + oBtn:nHeight() + 25 // 25 = dlg-title
LOCAL nLeft2 := oBtn:nLeft()
DEFINE DIALOG oDlg1 FROM 0, 0 TO 180, 200 OF oDlg PIXEL TRUEPIXEL FONT oFont ;
STYLE WS_POPUP
@ 20, 20 SLIDER oSlider1 VAR nSlidPos1 OF oDlg1 ;
HORIZONTAL ;
RANGE 0, 10 ;
COLORS CLR_RED, CLR_HGRAY, CLR_CYAN ;
MARKS 10 ;
SIZE 160, 35 PIXEL UPDATE
oSlider1:SetFont( oFont )
@ 80, 20 SLIDER oSlider2 VAR nSlidPos2 OF oDlg1 ;
HORIZONTAL ;
RANGE 0, 10 ;
COLORS CLR_RED, CLR_HGRAY, CLR_CYAN ;
MARKS 10 ;
SIZE 160, 35 PIXEL UPDATE
oSlider2:SetFont( oFont )
ACTIVATE DIALOG oDlg1 ;
ON INIT oDlg1:Move( nTop1 + nTop2, nLeft1 + nLeft2, , , .t. )
RETURN NIL
best regards
Uwe
You can connect a dialog to the button on action.
Dialog-top = button-bottom, dialog-left = button-left.
There You can include what ever You want.
If needed You can paint a colored border around the dialog.
The logic can be used on any other object.
In xBrowse it is connected to a cell.
connecting the dialog to the button ( main function )
// --------------
...
...
DEFINE DIALOG oDlg1 FROM 0, 0 TO 180, 200 OF oDlg PIXEL TRUEPIXEL FONT oFont ;
STYLE WS_POPUP
...
@ 20, 30 BTNBMP oBtn1 2007 ;
SIZE 30, 30 OF oDlg NOBORDER ;
ACTION MYDLG( oDlg, oBtn1, oFont )
...
ACTIVATE DIALOG oDlg CENTERED
RETURN NIL
// --------------
FUNCTION MYDLG( oDlg, oBtn, oFont )
LOCAL oDlg1, oBtn2, oSlider1, nSlidPos1 := 1, oSlider2, nSlidPos2 := 2
LOCAL oRect1 := oDlg:GetRect()
LOCAL nTop1 := oRect1:nTop
LOCAL nLeft1 := oRect1:nLeft
LOCAL nTop2 := oBtn:nTop() + oBtn:nHeight() + 25 // 25 = dlg-title
LOCAL nLeft2 := oBtn:nLeft()
DEFINE DIALOG oDlg1 FROM 0, 0 TO 180, 200 OF oDlg PIXEL TRUEPIXEL FONT oFont ;
STYLE WS_POPUP
@ 20, 20 SLIDER oSlider1 VAR nSlidPos1 OF oDlg1 ;
HORIZONTAL ;
RANGE 0, 10 ;
COLORS CLR_RED, CLR_HGRAY, CLR_CYAN ;
MARKS 10 ;
SIZE 160, 35 PIXEL UPDATE
oSlider1:SetFont( oFont )
@ 80, 20 SLIDER oSlider2 VAR nSlidPos2 OF oDlg1 ;
HORIZONTAL ;
RANGE 0, 10 ;
COLORS CLR_RED, CLR_HGRAY, CLR_CYAN ;
MARKS 10 ;
SIZE 160, 35 PIXEL UPDATE
oSlider2:SetFont( oFont )
ACTIVATE DIALOG oDlg1 ;
ON INIT oDlg1:Move( nTop1 + nTop2, nLeft1 + nLeft2, , , .t. )
RETURN NIL
best regards
Uwe
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
i work with FW.
If you have any questions about special functions, maybe i can help.
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
Re: How make it?
Uwe,
If I wanted a dialog I already knew how to do it
I think I asked for a particular thing
If you look closely you will see that the button opens a POPUP MENU control
and therefore not a dialog
other times you've already answered with other things that I don't even think about asking!!!!
If I wanted a dialog I already knew how to do it
I think I asked for a particular thing
If you look closely you will see that the button opens a POPUP MENU control
and therefore not a dialog
other times you've already answered with other things that I don't even think about asking!!!!
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Re: How make it?
Silvio,
that comes close to the needed result.
But never mind I can save my time.
regards
Uwe
in case something is not possible I'm looking for a alternative solutionthe button open a menu popup and on the menu there are two slider controls
that comes close to the needed result.
Trying to find a solution It is not a answer to something else.other times you've already answered with other things that I don't even think about asking!!!!
But never mind I can save my time.
regards
Uwe
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
i work with FW.
If you have any questions about special functions, maybe i can help.
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
Re: How make it?
please,
I'm searching if I can make a codeblock type bInit to run a function to insert the slider into menuitem of menupopup
I found some question on Internet
https://stackoverflow.com/questions/398 ... -3-xcode-8
https://www.codeproject.com/Articles/26 ... lider-Menu
I found a source someone can converte it to fwh (https://www.codeproject.com/Articles/26 ... lider-Menu)
Code: Select all
#include "Fivewin.ch"
#include "Slider.ch"
Function Test()
Local aget[10]
Local oDlgTest
Local oFont
Local oBtn1
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12 BOLD
DEFINE DIALOG oDlgTest FROM 0, 0 TO 180, 200 PIXEL TRUEPIXEL FONT oFont
@ 20, 30 BUTTON oBtn1 PROMPT "%" ;
SIZE 30, 30 PIXEL OF oDlgTest
oBtn1:bRClicked := {|nRow,nCol| MyPercentuale2(oBtn1,aget,oDlgTest,oFont,nRow,nCol) }
ACTIVATE DIALOG oDlgTest CENTERED
RETURN NIL
//-------------------------------------------------------------------------//
Function MyPercentuale2(oBtn,aget,oDlg,oFont,nRow,nCol)
Local oMyoMenu
Local aItem[4]
Local nSconto_Percentuale := 0.00
Local nSconto_Giorni:= 0
bAction1 :=Sliders(aItem[1])
bAction3 :=Sliders(aItem[3])
MENU oMyoMenu POPUP
MENUITEM aItem[1] PromPt "Slider 1" // BLOCK bAction1
MENUITEM aItem[2] PromPt "Sconto giorni :" + Ltrim(str(nSconto_Giorni))
MENUITEM aItem[3] PromPt "Slider 3" BLOCK bAction3
MENUITEM aItem[4] PromPt "Sconto percentuale :"+ Ltrim(str(nSconto_Percentuale))
ENDMENU
ACTIVATE POPUP oMyoMenu OF oDlg AT oBtn:nTop+nRow, oBtn:nLeft+nCol
RETURN (NIL)
Function Sliders(aItem)
Local oSlider1
Local nSlidPos1 := 1
@ 60, 20 SLIDER oSlider1 VAR nSlidPos1 OF aItem ;
HORIZONTAL ;
RANGE 0, 10 ;
COLORS CLR_RED, CLR_HGRAY, CLR_CYAN ;
MARKS 10 ;
SIZE 160, 35 PIXEL UPDATE
return nil
I'm searching if I can make a codeblock type bInit to run a function to insert the slider into menuitem of menupopup
I found some question on Internet
https://stackoverflow.com/questions/398 ... -3-xcode-8
https://www.codeproject.com/Articles/26 ... lider-Menu
I found a source someone can converte it to fwh (https://www.codeproject.com/Articles/26 ... lider-Menu)
Code: Select all
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
using System.IO;
using System.Reflection;
using System.Windows.Media;
using System.Diagnostics;
using System.Windows.Controls.Primitives;
namespace SliderMenu
{
public partial class SliderMenuItem : MenuItem
{
private const double ThumbHeight = 11.0d;
private Slider m_Slider;
private SortedDictionary<double, double> m_TickValueMap;
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Instance Constructor.
/// </summary>
public SliderMenuItem()
{
m_TickValueMap = new SortedDictionary<double, double>();
InitializeComponent();
}
#region Attached Property Steps
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Getting Steps property
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static int GetSteps(DependencyObject obj)
{
return (int)obj.GetValue(StepsProperty);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Setting Steps property
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetSteps(DependencyObject obj, int value)
{
obj.SetValue(StepsProperty, value);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// The number of steps, or tick placements between a menu item
/// and the previous one.
/// </summary>
public static readonly DependencyProperty StepsProperty =
DependencyProperty.RegisterAttached(
"Steps",
typeof(int),
typeof(SliderMenuItem),
new UIPropertyMetadata(1));
#endregion
#region Attached Property Value
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Gets or Sets the value for this slider.
/// </summary>
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Value property
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static double GetValue(DependencyObject obj)
{
return (double)obj.GetValue(ValueProperty);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Value property
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetValue(DependencyObject obj, double value)
{
obj.SetValue(ValueProperty, value);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// The real value for the slider.
/// </summary>
public static readonly DependencyProperty ValueProperty =
DependencyProperty.RegisterAttached(
"Value",
typeof(double),
typeof(SliderMenuItem),
new UIPropertyMetadata(1.0d, Value_ValueChanged));
#endregion
#region Attached Property Skip
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Skip property for sub menu items. Allows a menu item to
/// skip a tick mark. Especially useful for separators.
/// </summary>
public static readonly DependencyProperty SkipProperty =
DependencyProperty.RegisterAttached(
"Skip",
typeof(bool),
typeof(SliderMenuItem),
new UIPropertyMetadata(false));
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Skip property.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool GetSkip(DependencyObject obj)
{
return (bool)obj.GetValue(SkipProperty);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Xaml accessor function for Skip property.
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetSkip(DependencyObject obj, bool value)
{
obj.SetValue(SkipProperty, value);
}
#endregion
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Listen for change to Value property.
/// </summary>
/// <param name="obj"></param>
/// <param name="e"></param>
private static void Value_ValueChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
// find appropriate tick spot, and set slider value
SliderMenuItem item = obj as SliderMenuItem;
if (item != null)
{
SetTickToValue(item, (double)e.NewValue);
}
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Listen for change to slider value. Enables binding where
/// SliderMenuItem is the target, and a framework element is the source.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Slider_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
// find appropriate tick spot, and set slider value
SetValueToTick(this, (double)e.NewValue);
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Sets the slider thumb to the closest match after the value changes.
/// </summary>
/// <param name="item"></param>
/// <param name="newValue"></param>
private static void SetTickToValue(SliderMenuItem item, double newValue)
{
// find tick spot where
double[] ticks = new double[item.m_TickValueMap.Keys.Count];
item.m_TickValueMap.Keys.CopyTo(ticks, 0);
// Find exact match
if (item.m_TickValueMap.ContainsValue(newValue))
{
foreach (double tick in item.m_TickValueMap.Keys)
{
if (item.m_TickValueMap[tick] == newValue)
{
item.m_Slider.Value = tick;
return;
}
}
}
// Find closest match
for (int i = 1; i < item.m_TickValueMap.Count; i++)
{
double lowTick = ticks[i - 1];
double highTick = ticks[i];
double lowValue = item.m_TickValueMap[lowTick];
double highValue = item.m_TickValueMap[highTick];
//double newValue = (double)e.NewValue;
if (newValue > lowValue &&
newValue < highValue)
{
double valueScale = highValue - lowValue;
double tickScale = highTick - lowTick;
// set slider to closest tick match
double newTick = (newValue - lowValue) / (valueScale) * tickScale + lowTick;
item.m_Slider.Value = newTick;
}
}
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// After the slider value has changed, update the Value property to
/// hold the scaled value.
/// </summary>
private static void SetValueToTick(SliderMenuItem item, double tickValue)
{
if (item.m_TickValueMap.ContainsKey(tickValue))
{
item.Value = item.m_TickValueMap[tickValue];
return;
}
double[] keys = new double[item.m_TickValueMap.Keys.Count];
item.m_TickValueMap.Keys.CopyTo(keys, 0);
int index = Array.BinarySearch<double>(keys, tickValue);
Debug.Assert(index < 0, "What? How come I didn't find the key already?");
index = ~index;
Debug.Assert(index < item.Items.Count, "How did tick value go above 1000?");
Debug.Assert(index != 0, "Insert location was before element 0.");
double lowTick = keys[index - 1];
double highTick = keys[index];
double lowValue = item.m_TickValueMap[lowTick];
double highValue = item.m_TickValueMap[highTick];
double valueScale = highValue - lowValue;
double sourceScale = highTick - lowTick;
double newValue = (tickValue - lowTick) * valueScale / sourceScale + lowValue;
item.Value = newValue;
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// After template is applied, save reference to slider object.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.m_Slider = this.Template.FindName("PART_Slider", this) as Slider;
if (m_Slider == null)
throw new InvalidOperationException("Control template is missing part Slider_PART");
m_Slider.ValueChanged += Slider_ValueChanged;
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// Arrange pass. Call base method to figure out menu item placement,
/// then place tick marks at the centers of the menu items.
/// </summary>
/// <param name="arrangeBounds"></param>
/// <returns></returns>
protected override Size ArrangeOverride(Size arrangeBounds)
{
Size returnSize = base.ArrangeOverride(arrangeBounds);
FrameworkElement topElement = null;
FrameworkElement bottomElement = null;
for (int i = 0; i < Items.Count; i++)
{
FrameworkElement elem = Items[i] as FrameworkElement;
Debug.Assert(elem != null, "Added an object that wasn't a FrameworkElement??");
// Find the bottom element. It must have a value greater or equal to the
// top element
if (topElement != null)
{
if ((double)elem.GetValue(SliderMenuItem.ValueProperty) >=
(double)topElement.GetValue(SliderMenuItem.ValueProperty))
{
bottomElement = elem;
}
}
// Move along. Nothing to see here.
if ((bool)(elem.GetValue(SliderMenuItem.SkipProperty)))
continue;
// set the first element
if (topElement == null)
topElement = elem;
}
// Single element. Not much of a slider, but don't crash
if (bottomElement == null && topElement != null)
bottomElement = topElement;
// No elements. Nothing to do.
if (bottomElement == null && topElement == null)
return returnSize;
// Calculate top, bottom margins.
// This margin enables the thumb stop at 0 and 100 to line up with
// the center of the top and bottom menu items.
Rect bound = LayoutInformation.GetLayoutSlot(topElement);
double topMargin = bound.Top + ThumbHeight / 2;
double pointZero = bound.Top + bound.Height / 2.0;
bound = LayoutInformation.GetLayoutSlot(bottomElement);
double bottomMargin = returnSize.Height - bound.Bottom + ThumbHeight / 2.0d;
double pointOneHundred = bound.Top + bound.Height / 2.0d;
// Set the margin.
m_Slider.Margin = new Thickness(0, topMargin, 0, bottomMargin);
for (int i = 0; i < Items.Count; i++)
{
FrameworkElement elem = Items[i] as FrameworkElement;
if (elem is MenuItem)
((MenuItem)elem).Click += new RoutedEventHandler(SliderMenuItem_Click);
// Move along. Nothing to see here.
if ((bool)(elem.GetValue(SliderMenuItem.SkipProperty)))
continue;
// Grab the coordinates of the child menu item
bound = LayoutInformation.GetLayoutSlot(elem);
// Get the number of steps, or tick spots between this child menu item
// and the previous one.
int steps = (int)elem.GetValue(SliderMenuItem.StepsProperty);
// A value of 0 for Steps is like setting Skip = true
if (steps < 1)
continue;
// Calculate tick spot.
double thisTickSpot = 1000.0d * (bound.Top - pointZero + bound.Height / 2.0d)
/ (pointOneHundred - pointZero);
// Calculate continuous tick spots. Only allow continuous after the first element.
if (m_Slider.Ticks.Count > 0)
{
double lastTickSpot = m_Slider.Ticks[m_Slider.Ticks.Count - 1];
double division = (thisTickSpot - lastTickSpot) / steps;
for (int current_step = 1; current_step < steps; current_step++)
{
double intermediateTickSpot = lastTickSpot + current_step * division;
m_Slider.Ticks.Add(intermediateTickSpot);
}
}
m_Slider.Ticks.Add(thisTickSpot);
double sliderValue = (double)elem.GetValue(SliderMenuItem.ValueProperty);
m_TickValueMap[thisTickSpot] = sliderValue;
}
// At end of arrange pass, set the tick to the inital value
SetTickToValue(this, Value);
return returnSize;
}
/// §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
/// <summary>
/// A child menu item was clicked. Set the value automatically.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SliderMenuItem_Click(object sender, RoutedEventArgs e)
{
this.Value = (double)((DependencyObject)sender).GetValue(SliderMenuItem.ValueProperty);
}
}
}
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
Re: How make it?
for now I resolve in this mode:
the user can use the percentual on Total or make a descount on days
it is beautifull but not professonal work
the user can use the percentual on Total or make a descount on days
it is beautifull but not professonal work
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Re: How make it?
Dear Silvio
Currently it is not possible, but it is not impossible
For some time I was studying that possibility, but for lack of time I left it unfinished.
I hope to be able to return to the subject and get what you propose. It is not simple because although the item has hWnd it is not considered as a container of controls. We'll see
Currently it is not possible, but it is not impossible
For some time I was studying that possibility, but for lack of time I left it unfinished.
I hope to be able to return to the subject and get what you propose. It is not simple because although the item has hWnd it is not considered as a container of controls. We'll see
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.