Posts: 36
Threads: 21
Joined: Mar 2022
Hello, I'm having some problems and don't know if this is the expected behavior.
1. When using some functions from DllImport like below, when the script ends it restores the original value, if this is the expected behavior, how I do not restore?.
[DllImport("ntdll.dll")]
static extern uint NtSetTimerResolution(uint DesiredResolution, bool SetResolution, out uint CurrentResolution);
2. I tried to place a canvas above all controls in wpfBuilder to show a dialog or message (like the example below) without success. Is it possible with wpfBuilder?
Posts: 12,028
Threads: 139
Joined: Dec 2002
11-02-2022, 07:34 AM
(This post was last modified: 11-02-2022, 10:33 AM by Gintaras.)
Probably OS restores when the process ends. Let the process run all the time. Consider role editorExtension.
Also, code like `wait.ms(10);` or `10.ms();`temporarily sets the timer resolution = 1 ms if timeMilliseconds < 100, and later restores. It uses timeBeginPeriod/timeEndPeriod.
Posts: 12,028
Threads: 139
Joined: Dec 2002
// script ""
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
var b = new wpfBuilder("Window").WinSize(500);
var dialog1 = new WpfDialogInWindow(b.Window);
b.R.Add("Text", out TextBox text1).Focus();
b.R.AddButton("Show dialog", _ => _ShowDialogInWindow()).Margin("70");
b.R.AddOkCancel();
b.End();
if (!b.ShowDialog()) return;
void _ShowDialogInWindow() {
if (dialog1.Content == null) { //show the same content created once. Or you can set new/different content each time.
var b = new wpfBuilder(panelType: WBPanelType.Canvas).Size(120, 120); //the Canvas
b.Add<Label>("Dialog");
b.AddButton("Cancel", _ => dialog1.Show(false)).XY(25, 80, 70, 20);
b.End();
dialog1.Content = b.Panel;
dialog1.ClickToHide = true;
//dialog1.Dialog.BorderBrush = Brushes.Orange;
//dialog1.Dialog.BorderThickness = new(2);
//dialog1.Dialog.Background = Brushes.LightYellow;
}
dialog1.Show(true);
}
/// <summary>
/// Shows a dialog-like content in the center of a WPF window.
/// </summary>
/// <example>
/// <code><![CDATA[
/// using System.Windows;
/// using System.Windows.Controls;
/// using System.Windows.Controls.Primitives;
/// using System.Windows.Input;
/// using System.Windows.Media;
///
/// var b = new wpfBuilder("Window").WinSize(500);
/// var dialog1 = new WpfDialogInWindow(b.Window);
/// b.R.Add("Text", out TextBox text1).Focus();
/// b.R.AddButton("Show dialog", _ => _ShowDialogInWindow()).Margin("70");
/// b.R.AddOkCancel();
/// b.End();
/// if (!b.ShowDialog()) return;
///
/// void _ShowDialogInWindow() {
/// if (dialog1.Content == null) { //show the same content created once. Or you can set new/different content each time.
/// var b = new wpfBuilder().Width(200);
/// b.R.Add<Label>("Dialog");
/// b.R.AddButton("Cancel", _ => dialog1.Show(false));
/// b.End();
/// dialog1.Content = b.Panel;
/// dialog1.ClickToHide = true;
/// }
/// dialog1.Show(true);
/// }
/// ]]></code>
/// </example>
class WpfDialogInWindow {
wpfBuilder _b;
Window _window;
Grid _grid;
FrameworkElement _winContent;
Border _border;
Border _dim;
/// <summary>
/// Initializes this object.
/// </summary>
/// <param name="w">A WPF window.</param>
/// <exception cref="InvalidOperationException">w.Content is not set.</exception>
/// <remarks>
/// Replaces <i>w</i> content with a panel where adds <i>w</i> content and a hidden <b>Border</b> control (<see cref="Dialog"/>) that will display user-defined content (<see cref="Content"/>) when <see cref="Show"/> called.
/// </remarks>
public WpfDialogInWindow(Window w) {
_window = w;
_winContent = w.Content as FrameworkElement ?? throw new InvalidOperationException("w.Content is not set");
w.Content = null;
_b = new(w);
_grid = _b.Panel as Grid;
_grid.Margin = default;
_b.Columns(-1, 0, -1);
_b.Row(-1).Add(_winContent).Span(3).SpanRows(3);
_dim = new() { Background = Brushes.Black, Opacity = .6, Visibility = Visibility.Hidden };
Grid.SetColumnSpan(_dim, 3); Grid.SetRowSpan(_dim, 3);
_grid.Children.Add(_dim);
_dim.MouseLeftButtonDown += (_, _) => { if(ClickToHide) Show(false); };
_b.R.Skip().Add(out _border).Span(1).Hidden().Border(padding: new(5), cornerRadius: 5).Brush(Brushes.White);
_b.Row(-1);
_b.End();
}
/// <summary>
/// Gets the dialog content container control. You can set its properties, eg background color.
/// </summary>
public Border Dialog => _border;
/// <summary>
/// Sets or gets dialog content.
/// </summary>
public FrameworkElement Content { get; set; }
/// <summary>
/// true if the dialog is visible.
/// </summary>
public bool IsVisible => _border.IsVisible;
/// <summary>
/// Hide the dialog when the user clicks the dimmed area.
/// </summary>
public bool ClickToHide { get; set; }
/// <summary>
/// Shows or hides the dialog.
/// </summary>
/// <param name="show"></param>
public void Show(bool show) {
if (show == IsVisible) return;
_border.Child = show ? Content : null;
_border.Visibility = show ? Visibility.Visible : Visibility.Hidden;
_dim.Visibility = show ? Visibility.Visible : Visibility.Hidden;
_winContent.IsEnabled = !show;
}
}
Posts: 36
Threads: 21
Joined: Mar 2022
As always, thank you, the dialog worked very well, and I will try to use the script as a editorExtension, it is strange that the OS restores original value, this occurs only in LA, in QM and other tools this don't occur.
Posts: 12,028
Threads: 139
Joined: Dec 2002
In my tests, OS restores the timer resolution when the process ends. Not only LA processes.
QM macros by default run in QM process. QM calls timeBeginPeriod(2) when starts, and restores when exits. A macro.exe does the same.
LA scripts run in separate processes, unless role editorExtension.