Insert progressbar into statusbar panel using powershell and windows forms - windows

I am currently working on a project that requires me to put a progressbar in one of the panels of a statusbar. Does anyone have any experience with this, or can anyone provide any input or direction on how it is done. I have been searching for 2 days now for a solution with no luck. There is still not an abundance of powershell help out there, especially when it comes to windows forms.

This is relatively simple to do with PowerShell data sources in WPK.
You can get WPK as part of the PowerShellPack.
Here's a pretty decent progress viewer written in WPK:
New-Grid -Columns 2 {
New-TextBlock -Margin 10 -TextWrapping Wrap -ZIndex 1 -HorizontalAlignment Left -FontWeight Bold -FontSize 12 -DataBinding #{
"Text" = "LastProgress.Activity"
}
New-TextBlock -Margin 10 -ZIndex 1 -TextWrapping Wrap -Column 1 -VerticalAlignment Bottom -HorizontalAlignment Right -FontStyle Italic -FontSize 12 -DataBinding #{
"Text" = "LastProgress.StatusDescription"
}
New-ProgressBar -ColumnSpan 2 -MinHeight 250 -Name ProgressPercent -DataBinding #{
"Value" = "LastProgress.PercentComplete"
}
} -DataContext {
Get-PowerShellDataSource -Script {
foreach ($n in 1..100) {
Write-Progress "MajorProgress" "MinorProgress" -PercentComplete $n
Start-Sleep -Milliseconds 250
}
}
} -AsJob
The PowerShellDataSource returns an object with a list of all of the outputs for a given stream and the last item outputted on the given stream (i.e. Progress and LastProgress). In order to display the progress bar, we need bind to the LastProgress property.
The first half of the code declares the progress bar. By using the -DataBinding parameter the TextBlocks and Progress bars will automatically sync to the data context. Data context can either be declared at this level (as is shown in the example) or can be in a parent control.
The DataContext in this example is a simple PowerShell script that uses Write-Progress to output a test message every quarter second, but you can use any script you'd like.
Hope this helps.

Related

Showing more than one line of the notification description in the notification tray using an extension

I am currently designing an extension to make the notifications in the notification section of the calendar expendable. The goal is to make the noficiation expand like the initial notification on the desktop does. I have changed the type of notification added to the noficiation tray to class NotificationBanner from class NotificationMessage. I am currently using a work-around to make this work, this is what my expand function looks like:
expand(animate) {
this.expanded = true;
this._actionBin.visible = this._actionBin.get_n_children() > 0;
if (this._bodyStack.get_n_children() < 2) {
this._expandedLabel = new MessageList.URLHighlighter(this._bodyText,
true, this._useBodyMarkup);
this.setExpandedBody(this._expandedLabel);
}
if (animate) {
if (!this.clickedByButton && !this.forceExpansion) {
// This is the usual way notifications are expanded, using the layout manager
this._bodyStack.ease_property('#layout.expansion', 1, {
progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: MessageTray.ANIMATION_TIME,
});
}
else if (this.forceExpansion || this.clickedByButton) {
// When auto expanding or clicked by button, change height of body
oldHeight = this.bodyLabel.get_height();
const lines = Math.ceil(this._bodyText.length / 54);
this.bodyLabel.set_height(lines * this.bodyLabel.get_height());
}
this._actionBin.scale_y = 0;
this._actionBin.ease({
scale_y: 1,
duration: MessageTray.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
} else {
this._bodyStack.layout_manager.expansion = 1;
this._actionBin.scale_y = 1;
}
this.emit('expanded');
}
As you can see, I have 2 options for this extension: Force expand all notifications or make the user use a button to expand. The current solution is not elegant, it simply changes the height of the notification label which manages the body. Furhermore, the notification body still shows the three dots, implying that the body is still not expanded. I believe this to be an issue with the layout manager, since the proper way to expand is to set message._bodyStack.layout_manager.expansion to 1. That does not work in the case of expanding a message in the notification tray. Is anyone familiar with the layout manager or can help me find a different solution? Here is an image of what my current solution looks like:
Image of an automatically expanded notification in the notification tray due to the extension (note the three dots at the end of the first line being still there)
Okay I have found a solution, it is not related to the layout manager. The value of the message message.bodyLabel.clutter_text.ellipsize is set to 3, which is the main cause of the dots appearing on the notification. Setting this value to 0 solves this problem. I would have still loved to find a more elegant approach to displaying the body, but this will do.

Powershell form flickers when background image is added to the tab control

I was trying to add a background image to the tab control
$tc_ASSTabControl.BackgroundImage = [System.Drawing.Image]::FromFile('C:\Users\me\test\image1.jpg')
Here is the code to define the tab control
# Creating Tab Control
$tc_ASSTabControl = New-Object System.Windows.Forms.TabControl
# Customizing the ASS Tab Control
$tc_ASSTabControl | ForEach-Object {
$_.DataBindings.DefaultDataSourceUpdateMode = 0
$_.Location = New-Object System.Drawing.Point(18, 65)
$_.Name = "tc_ASSTabControl"
$_.Width = 850
$_.Height = 580
$_.BackColor = [System.Drawing.Color]::Transparent
}
When the background image is added, the form flickers when the form is loaded initially and whenever the tab(SelectedIndex of tab control) is changed.
I tried the following option
Setting DoubleBuffered property to true
#This code doesn't work
$form.DoubleBuffered = $true
Here is a relevant thread on How to fix the flickering in User Controls.
The backcolor property of each control was set to "Transparent" by
BackColor = [System.Drawing.Color]::Transparent
Here is the screen capture of the issue. This happens when the form is loaded as well.
Here is an example of how I have defined the label at the top of the first tab, in case that helps to understand the reason for the flickering.
$lbl_BrowseSearchFolder = New-Object system.Windows.Forms.Label -Property #{
text = "Browse for the folder that is to be searched"
AutoSize = $true
width = 25
height = 10
location = New-Object System.Drawing.Point(29, (25 + $ySpacer))
Font = 'Arial,10'
BackColor = [System.Drawing.Color]::Transparent
}
As you may see from the image, it's the controls on "Search Criteria" tab that are loaded with a lag. Is there any property of those controls that can be set to prevent this lag in loading?
Could someone suggest a way to fix the flickering issue on PowerShell form
I would try to suspend the layout of the form during the operation using SuspendLayout and resume ResumeLayout
The SuspendLayout and ResumeLayout methods are used in tandem to suppress multiple Layout events while you adjust multiple attributes of the control. For example, you would typically call the SuspendLayout method, then set the Size, Location, Anchor, or Dock properties of the control, and then call the ResumeLayout method to enable the changes to take effect.

Placeholder still visible when adding edit control to a CToolbar?

Years ago, I added an edit control to the toolbar in my application following directions similar to these:
http://www.codeproject.com/Articles/1106/Adding-a-Combo-Box-to-a-Docking-Toolbar
Similar directions can be found in many articles, so I think the procedure is fairly common. Until a few years ago, this worked fine, and the result was as shown in the article. However, I believe the move to XP changed the appearance of buttons in the toolbar, and instead I now see this in my application:
It seems as though the original instructions worked only because controls prior to the change occupied the entire height of the toolbar, so the edit control obstructed the separator behind it.
Ideally, I think the underlying separator should be made invisible. However, this doesn't seem to be handled explicitly in any of the articles I've found, and I'm not quite sure myself how to prevent the separator from being drawn.
Any help would be greatly appreciated. Thanks!
If you follow that article on codeproject exactly, you have probably modified the place holder into a separator from a button. This is why the separator line shown thru when the height of the button image is bigger than the height of the combo box.
If you keep the place holder as an empty button, you will not have such problem. A series of several place holder buttons may be needed in cascaded formation for a really useful length for the combobox.
This technique is demonstrated as follows:
// standard creation of the toolbar in CMainFrame::OnCreate
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
// status bar creation .....
// .....
// the place holders are a series of 5 empty toolbar buttons ie: ID_COMBO_1 to ID_COMBO_5
// get index of first combobox place holder
INT nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(ID_COMBO_1);
// get size of first place holder rectangle
CRect rcRect;
m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rcRect);
INT nWidth = rcRect.Width();
// calculate width of combobox with sum of all place holder (5 in total)
nWidth = nWidth * 5;
rcRect.top = 5; // top of combo box
rcRect.bottom = rcRect.top + 250; // drop height
rcRect.right = rcRect.left + nWidth;
// create the combobox to sit above the place holders
if(!m_comboBox.Create(CBS_DROPDOWNLIST | CBS_SORT | WS_VISIBLE |
WS_TABSTOP | WS_VSCROLL, rcRect, &m_wndToolBar, ID_COMBO_1))
{
TRACE(_T("Failed to create combo-box\n"));
return FALSE;
}
m_comboBox.AddString("Toolbar Combobox item one");
m_comboBox.AddString("Toolbar Combobox item two");
m_comboBox.AddString("Toolbar Combobox item three");
I've used this technique from CodeGuru. It's old, but, I've been using it for many years and it still works.

IUP, menu, webbrowser, tree, tabs

I have such menu situation:
int menu_create(Ihandle *menu)
{
hamburger = IupItem("&Hamburger", "hamburger");
IupSetAttributes(hamburger, "AUTOTOGGLE=YES, RADIO=YES");
char* ce = "Ćev&apčići";
cevapcici = IupItem(utf8_to_cp1250(ce), "cevapcici");
IupSetAttributes(cevapcici, "AUTOTOGGLE=YES, RADIO=YES");
exit = IupItem("Exit\tAlt+F4", "exit");
img4 = IupLoadImage("icons\\delete_16x16.ico");
IupSetAttributeHandle(exit, "TITLEIMAGE", img4);
menu = IupMenu(
IupSubmenu("File",
IupMenu(
hamburger,
cevapcici,
IupSeparator(),
IupItem("Carro&t", "carrot"),
IupSeparator(),
exit,
NULL)),
NULL);
IupSetFunction("exit", (Icallback)mnu_exit);
... etc...
IupSetHandle("menu", menu);
return IUP_DEFAULT;
}
How to get "radio toggle group" functionality with items hamburger and cevapcici so first turns off a second checkmark and opposite. This is my try but it don't work.
2) I try webbrowser example from IUP suite on my windows 7. Problem is that bad black flickering appear's during resize (increase). Also, background of webbrowser flicker black during showing.
I try a same example on Ubuntu and there flickering appear's too but it is not so much visible since background is there white.
Is here any way to get rid of those flickering or if not to get white background of webbrowser window on windows?
3) Since webbrowser is ole object (on windows) is it possible to use say "print preview" or "zoom" function by reference from IUP handle or at any other way like we used to do from MS programming tools?
wbInstance.ExecWB(Exec.OLECMDID_OPTICAL_ZOOM, ExecOpt.OLECMDEXECOPT_DONTPROMPTUSER, 150, DBNull.Value)
4) How can I get key_up event fired from IupTree?
5) Interesting situation with IupTabs:
frame3 = IupHbox(mat, val, NULL);
vboxt1 = IupVbox(frame3, NULL);
vboxt2 = IupVbox(frame3, NULL);
IupSetAttribute(vboxt1, "TABTITLE", "First documents... ");
IupSetAttribute(vboxt2, "TABTITLE", "Second documents... ");
tabs = IupTabs(vboxt1, vboxt2, NULL);
hbox1 = IupHbox(tabs, IupVbox(frame, tree, frame2, NULL), NULL);
dlg = IupDialog(hbox1);
When I set frame3 which should be a same for both tabs my GUI frozes.
However, I have to got same "mat" (IupMatrix) in both tabs because by changing tabs other data load in matrix but similar enough to use same matrix and related functions.
What to do here?
1) The RADIO attribute belongs to the IupMenu, not to the IupItem. This also means that all the IupItems inside that menu will be part of the radio.
A workaround would be to manually unset the other toggle inside the action callback.
2) That flicker is not caused by IUP. Don't know why the native controls are doing it.
3) Yes, but you will have to program that using the OLE API. If you take a look at the IupOleControl and IupWebBrower source code and send me the code to do it, I will be happy to add it to IUP.
4) You don't. Use the K_ANY callbacks.
5) You can not reuse a control in different places in any dialog. So you must have two different frames, with two different matrices. What you can do is to encapsulate your matrix, so the same function will create a matrix with the same attributes and callbacks any time you want one.

How to implement tk scrollbar for multiple listboxes (TCL)?

I tried all sort of options but no success in implement simple scrollbar for two or more listboxes. Following is my code giving error while scrolling. I hope you guys are helping me...
scrollbar .scroll -orient v
pack .scroll -side left -fill y
listbox .lis1
pack .lis1 -side left
listbox .lis2
pack .lis2 -side left
for {set x 0} {$x < 100} {incr x} {
.lis1 insert end $x
.lis2 insert end $x
}
.lis1 configure -yscrollcommand [list .scroll set]
.lis2 configure -yscrollcommand [list .scroll set]
.scroll configure -command ".lis1 yview .lis2 yview ";
thanking you.
There are a number of examples on the Tcler's wiki, but the core principle is to use a procedure to ensure that the scrolling protocol is synchronized between the widgets. Here's an example based off that wiki page:
# Some data to scroll through
set ::items [lrepeat 10 {*}"The quick brown fox jumps over the lazy dog."]
# Some widgets that will scroll together
listbox .list1 -listvar ::items -yscrollcommand {setScroll .scroll}
listbox .list2 -listvar ::items -yscrollcommand {setScroll .scroll}
scrollbar .scroll -orient vertical -command {synchScroll {.list1 .list2} yview}
# The connectors
proc setScroll {s args} {
$s set {*}$args
{*}[$s cget -command] moveto [lindex [$s get] 0]
}
proc synchScroll {widgets args} {
foreach w $widgets {$w {*}$args}
}
# Put the GUI together
pack .list1 .scroll .list2 -side left -fill y
It's worth noting that you can also plug any other scrollable widget into this scheme; everything in Tk scrolls the same way (except with -xscrollcommand and xview for horizontal scrolling, together with a change of scrollbar orientation). Furthermore, the connectors here, unlike the ones on the wiki page, can be used with multiple groups of scrolled widgets at once; the knowledge of what is scrolled together is stored in the -command option of the scrollbar (first argument to synchScroll callback).
[EDIT]: For 8.4 and before, you need slightly different connector procedures:
# The connectors
proc setScroll {s args} {
eval [list $s set] $args
eval [$s cget -command] [list moveto [lindex [$s get] 0]]
}
proc synchScroll {widgets args} {
foreach w $widgets {eval [list $w] $args}
}
Everything else will be the same.
I know that this post is really old but I recently discovered what I think is a fairly simple solution. Instead of using the vertical scrollbar I found that I can use the slider widget. With the slider you can get the position of the slider and use that to set the yview of the listbox(es). Multiple listboxes can be scrolled simultaneously. I use vtcl to build the GUI so the code I can provide may not beimmediately obvious for those using tk wm comands. But here is the code I use. It is bound to slider motion.
set listIndex [$widget(Scale1) get]
$widget(Listbox1) yview $listIndex
$widget(Listbox2) yview $listIndex
Hope that is helpful to somebody.
If you plan to do much work in the the callback command - make a procedure to do it as that is both faster (the procedure gets byte compiled) and less likely to introduce tcl syntax problems. In this case you are trying to perform two tcl commands in the scrollbar function so you need to separate the statements using newline or a semicolon.
Calling the scrollbar set function from both listboxes will just have the second one override the first. You either need a function to merge those two or if the lists have the same lengths, just call it from one of them to set the scrollbar size and position and then update all listboxes with the scrollbar callback.
There is a multilistbox package somewhere - try the Tcl wiki to locate examples.

Resources