Jump to content

Customizing Your Applications Taskbar Functionality


Recommended Posts

I was thinking it would be cool to write an API that would allow programmers to customize the thumbnail popups in windows 7, especially with the ability to add buttons (see http://dotnet.dzone....ndows-7-taskbar and attached image). From what I can tell, even after taking the knowledgebase steps on NIs site to make .NET 4.0 available in LabVIEW, the necessary namespaces are not available in LabVIEW. Even if they were, I'm not sure how I'd get this to work because it requires xaml files. I suppose I would have to write a .NET wrapper, but then I don't think this would be dynamic enough to make into a standard API for LabVIEW applications that need more or less buttons without modifying the wrapper text code. Unless, somehow you had all buttons fire a single event to be captured by LabVIEW in which the event data had the name of the button pressed, allowing you to determine what to do on that button press. Suggestions, or is this just not going to be possible?

post-15770-0-18593200-1339788695.png

Link to comment

I'm curious to what end you're seeking this. I have only ever written test and measurement applications, never software products, in LabVIEW; none of which would benefit from (or would it be functionally appropriate to have) taskbar controls.

On my list of interesting integration projects are a non-CVI interface for ShellNotify (tray icons) and awesome Windows Explorer integration to add a properties sheet and better launch-time functionality for LabVIEW files. This seems like it falls into that kind of category - pretty awesome but questionably useful.

Link to comment

I was thinking it would be cool to write an API that would allow programmers to customize the thumbnail popups in windows 7, especially with the ability to add buttons (see http://dotnet.dzone....ndows-7-taskbar and attached image). From what I can tell, even after taking the knowledgebase steps on NIs site to make .NET 4.0 available in LabVIEW, the necessary namespaces are not available in LabVIEW. Even if they were, I'm not sure how I'd get this to work because it requires xaml files. I suppose I would have to write a .NET wrapper, but then I don't think this would be dynamic enough to make into a standard API for LabVIEW applications that need more or less buttons without modifying the wrapper text code. Unless, somehow you had all buttons fire a single event to be captured by LabVIEW in which the event data had the name of the button pressed, allowing you to determine what to do on that button press. Suggestions, or is this just not going to be possible?

From what I read on MDSN it is fairly easy to do that from C/C++. You just want to use the ITaskBar3 interface in shobjidl.h. A single call to


// Create an instance of ITaskbarList3

ITaskBarList3 *ptbl;

HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl);

[/CODE]

And then you can call the relevant methods of the ITaskBarList3 COM object. This even works from pure C.

[CODE] if (SUCCEEDED(hr)) { // Declare the image list that contains the button images. hr = ptbl->ThumbBarSetImageList(hwnd, himl); if (SUCCEEDED(hr)) { // Attach the toolbar to the thumbnail hr = ptbl->ThumbBarAddButtons(hwnd, ARRAYSIZE(thbButtons), &thbButtons); } ptbl->Release(); } return hr; [/CODE]

However handling of events happens through Windows messages, so you have to hook the Windows message queue in LabVIEW and this is were things always get a bit hairy with Windows shell integration in LabVIEW. Same about ShellNotify and other such things.

On my list of interesting integration projects are a non-CVI interface for ShellNotify (tray icons) and awesome Windows Explorer integration to add a properties sheet and better launch-time functionality for LabVIEW files. This seems like it falls into that kind of category - pretty awesome but questionably useful.

Same here! A fun project to do but with very little real world benefit for the type of application we generally do in LabVIEW.

Link to comment
pretty awesome but questionably useful.

Agreed. Not very useful, I just thought it would be cool! There is a notify icon API someone wrote over at NI.com. It is set up very nicely, and uses dynamic and user events to register all the callbacks to be utilized in the event structure. If you can't find it let me know and I will dig it up and send you the zip or forward the link. It's always a bummer when I want to do something like a notify icon but realize someone has already done it, and done it well. Then I get torn between doing it for my own use, enjoyment and learning, but always have in the back of my mind that I'm just reinventing the wheel and as an engineer that pains me!

rolf, thanks for the suggestion. I may see what i can do, but as I said since this is for my own enjoyment and not a top priority, I have a feeling writing this wrapper will fall by the wayside!

edit: you said shell notify, i got mixed up! Either way, the notify icon is pretty cool so I'll leave my shpeal even though it is a bit unrelated!

Edited by for(imstuck)
Link to comment

edit: you said shell notify, i got mixed up! Either way, the notify icon is pretty cool so I'll leave my shpeal even though it is a bit unrelated!

There's a couple over on NI.com... One uses a CVI interface (blech), one uses a .NET assembly (which I forgot about), and there may be one more floating around. Maybe I haven't seen the one you're referring to, feel free to post it up.

I really enjoy interfacing with external code in LabVIEW (weird, I know), so I wanted to try an implementation which only used Win32 API calls, just for sport.

From what I read on MDSN it is fairly easy to do that from C/C++. You just want to use the ITaskBar3 interface in shobjidl.h. A single call to


// Create an instance of ITaskbarList3

ITaskBarList3 *ptbl;

HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl);

[/CODE]

The sad thing is the there's still a bit of work there, especially depending on what the IID_PPV_ARGS() macro does. Plus, any time I use API constants I like to make a ring or enum to make the implementation clean; usually I crack open Visual Studio to make that easier. I wonder how useful it would be to have a LabVIEW module which can parse C/C++ includes and let you lookup defines and constants by name. Obviously, you'd have to dance around datatypes, but still...

Link to comment

There's a couple over on NI.com... One uses a CVI interface (blech), one uses a .NET assembly (which I forgot about), and there may be one more floating around. Maybe I haven't seen the one you're referring to, feel free to post it up.

I really enjoy interfacing with external code in LabVIEW (weird, I know), so I wanted to try an implementation which only used Win32 API calls, just for sport.

Here ya go.

Not a fan of .NET. Nasty, bloaty rubbish that labview can't keep up with for versioning.

Link to comment

There's a couple over on NI.com... One uses a CVI interface (blech), one uses a .NET assembly (which I forgot about), and there may be one more floating around. Maybe I haven't seen the one you're referring to, feel free to post it up.

I really enjoy interfacing with external code in LabVIEW (weird, I know), so I wanted to try an implementation which only used Win32 API calls, just for sport.

The sad thing is the there's still a bit of work there, especially depending on what the IID_PPV_ARGS() macro does. Plus, any time I use API constants I like to make a ring or enum to make the implementation clean; usually I crack open Visual Studio to make that easier. I wonder how useful it would be to have a LabVIEW module which can parse C/C++ includes and let you lookup defines and constants by name. Obviously, you'd have to dance around datatypes, but still...

I didn't mean to indicate to call this function with the Call Library Node. While it would work for this one (and IID_PPV_ARGS() is just a casting macro to make sure the parameter passes to the function without compiling warning), the resulting ptbl is a pointer to a virtual table dispatch structure and that is a bit nasty to reference from a Call Library Node. However there is no way without invoking at least 3 or so methods from that virtual table to implement anything useful in terms of TaskBar App thumbs and friends.

My only acceptable solution to this would be to write a little C code that is compiled into a DLL and then called from LabVIEW. This is also mandated in my opinion by the fact that any feedback from the Taskbar to the application is done through the Windows message queue. Hooking that, while possible with the LabVIEW Windows message queue library floating around, is a painful process, and much more cleanly done in the same C code DLL.

As to creating your mentioned C header parser: Believe me you don't want to go there. I implemented such a beast for a project where I had to adapt to register definitions for a CAN device based on C type declarations in a database like structure. It "only" had to be able to identify the basic C types, structures and arrays and the typedefs made from them. And it already got a major task and one that, while it worked I didn't particularly feel confident about, to make some changes to it without breaking something else in it. Without an extensive unit test framework such a thing is already unmaintainable in any form. And while it theoretically also could parse function declarations that part never got tested at all, since it was not a requirement for the task at hand. And I'm sure there are still many C header nasties, that program can't parse properly. The C header parser used in the Import Library Wizard is most likely a bit further than the one I had written, but it also has it's limits and very specifically only maintains the information it requires to create the Call Library Node configuration for a particular function. This means that enum values are simply discarded, as the only information this library needs is the actual size of the enum, not its detailed definition.

Here ya go.

Not a fan of .NET. Nasty, bloaty rubbish that labview can't keep up with for versioning.

Same here. Add to this the fact that .Net is limiting yourself automatically to Windows only (no Mono is no solution as LabVIEW still lacks the .Net support on non-Windows platforms to even be theoretically able to call Mono. In practice it would almost surely fail even if it had such support.) This may seem like a moot point in this case with Windows shell integration, but I'm working regularly on other things where multi-platform support is not only an option but sometimes a requirement. And once you start to go down the C DLL path for such things you really don't feel like learning yet another programming environment like .Net, that is not only heavyweight and clunky but also limits yourself to a specific platform. I'm also sure that the frequent versioning of .Net is not just a coincidence but a strategy, to make following it getting a true challenge both for Mono as well as competing application development environments to MS Visual development offerings. By avoiding it whenever possible, I'm not limited by this strategy. :D

From the little exposure to .Net so far I have to say it is very amazing how much they copied Java. Many libraries use the exact same naming only adapted to the .Net naming convention of using function names that start with an uppercase letter instead of a lowercase letter as Java uses. Almost feels like someone took the Java interfaces and put them through a tool to convert type names and function names to a different naming convention just for the sake of not being blamed for taking them verbatim.

Link to comment

This discussion reminds me of an another Windows API I have yet to use but have wanted to. I saw that there is an API for controlling the progress of an application, through the taskbar (not sure if there is a name for it).

http://sine.ni.com/nips/cds/view/p/lang/en/nid/210184

Very neat stuff, but like I said I haven't found a good place to use it yet.

Link to comment

This discussion reminds me of an another Windows API I have yet to use but have wanted to. I saw that there is an API for controlling the progress of an application, through the taskbar (not sure if there is a name for it).

http://sine.ni.com/n...g/en/nid/210184

Very neat stuff, but like I said I haven't found a good place to use it yet.

The only reason I can think of to use that at the moment is if you want to make a VI that has a progress bar be more consistent with other Windows 7 dialogs (a minor usability feature).

Link to comment

Well, out of curiosity I did spend a few hours on this. But it seems Windows is effectively denying every cooperation in making this functionality work from within LabVIEW. I can create a small Windows executable that uses the functions to assign an imagelist and the thumbbar definitions for the tumbbar buttons just fine, and I can use most of the other TaskBarList methods from within LabVIEW easily such as the Progress Bar functionality but any attempt to set the imagelist for the buttons from within LabVIEW fails with a very useless E_FAIL error message. Not sure what that would be really.

Link to comment

I think this feature can be very useful:

At the moment all the open LV windows look exactly the same no matter if they are BD or FP or even if they were opened from different LV versions.

Once this option will be available we could have a list of open vis with the icon from the connector pane next to each vi with different background color for BD and for FP and a number with the LV version.

Besides that, we could have a preview of the vi and even an option to see its status (running/broken/clone/properties/type).

Link to comment

Well, out of curiosity I did spend a few hours on this. But it seems Windows is effectively denying every cooperation in making this functionality work from within LabVIEW. I can create a small Windows executable that uses the functions to assign an imagelist and the thumbbar definitions for the tumbbar buttons just fine, and I can use most of the other TaskBarList methods from within LabVIEW easily such as the Progress Bar functionality but any attempt to set the imagelist for the buttons from within LabVIEW fails with a very useless E_FAIL error message. Not sure what that would be really.

Disappointing that you were stone-walled. Any interest in making the code public domain for tinkering?

I think this feature can be very useful:

At the moment all the open LV windows look exactly the same no matter if they are BD or FP or even if they were opened from different LV versions.

Once this option will be available we could have a list of open vis with the icon from the connector pane next to each vi with different background color for BD and for FP and a number with the LV version.

Besides that, we could have a preview of the vi and even an option to see its status (running/broken/clone/properties/type).

What you're talking about is actually a feature for the LabVIEW IDE, not LabVIEW applications.

Link to comment

It should be an IDE feature yet there are cases we need this feature in our own deployed apps.

If your application uses a secondary window to show a graph or a ccd, for example, then you would like to make it easy for the user to find the right window.

It could have been awesome if NI implemented it in the IDE and gave us hooks into the system.

However, even though people asked for this feature repeatedly, they never implemented it for some bizaere reason, thus, it is up to us to implement it.

Link to comment

Disappointing that you were stone-walled. Any interest in making the code public domain for tinkering?

Believe me, you do not want to thinker with that. It's deep in the DCOM internas and after a few more hours debugging through disassembly even into the Windows interna I've figured it out. It was a combination of comctrl32 side-by-side assembly versioning and DCOM marshalling because of apartment threading limitations.caused by the fact that DCOM is still based on OLE and it's Windows 3.1 heritage. So I am now able to get some thumbbar buttons to draw and even return user events to LabVIEW. I'm going to do a little more cleanup and will then post the VI library.

It should be an IDE feature yet there are cases we need this feature in our own deployed apps.

If your application uses a secondary window to show a graph or a ccd, for example, then you would like to make it easy for the user to find the right window.

It could have been awesome if NI implemented it in the IDE and gave us hooks into the system.

However, even though people asked for this feature repeatedly, they never implemented it for some bizaere reason, thus, it is up to us to implement it.

I think saying that this should be an IDE feature is a waaaaay to strong statement. It's a funny Windows gadget much like toolbar ribbons, but it's implementation has a few limitations and it's API is quite awkward. You wouldn't want to deal with the Taskbar API as is from a LabVIEW application as there are simply to many things you can do wrong to mess up for good. I'm trying to hide some of that complexity in the LabVIEW library I'm currently working on, but I'm not sure it will be possible to make it idiot proof, and as we all know engineers are even worse :D.

Another point I have read on some blog about the Windows Taskbar excitement from many users applies here as well. You should NOT implement Windows taskbar functionality into your application, just because you can!! It's a decision that needs to be thought out seriously and implemented well, otherwise it is more annoying for the user than useful. The thumbbar specifically are only really useful for operations that do not require any activation of the application window in question. So what could this be used for in the LabVIEW project window? Starting a VI? Starting or stopping a compile build? Maybe the cancelation of a stop build but anything else needs more context such as which VI to start, or which of the potentially several target builds to start, etc, so it needs activation of the according window and context specific selection for the action and then the buttons make absolutely no sense. Clicking the thumbnail icon to activate the window and do whatever is needed to do is much more intuitive, than selecting a possibly obscure thumbbar button, that switches over to a dialog or the main VI in question to require the user to select in more detail what he wants to do.

Attached is a first version of the library. Documentation is a little scarce at this stage, but it should be possible to figure out the most important functionality by looking at the two examples.

And before anyone complains that the incuded DLL can't be loaded on his machine. This DLL was compiled using Visual C 2005 and requires therefore the MS C runtime library version 8.0.x. The attached vcruntime8.0.zip file contains both installers for the 32 bit and 64 bit versions of the MS C redistributable runtime libraries. Install whatever version your LabVIEW system has in order for the DLL to work. These installers are the most recent VC 8.0 runtime libraries officially available from Microsoft.

lvtaskbar.zip

vcruntime8.0.zip

Link to comment

Believe me, you do not want to thinker with that. It's deep in the DCOM internas and after a few more hours debugging through disassembly even into the Windows interna I've figured it out. It was a combination of comctrl32 side-by-side assembly versioning and DCOM marshalling because of apartment threading limitations.caused by the fact that DCOM is still based on OLE and it's Windows 3.1 heritage. So I am now able to get some thumbbar buttons to draw and even return user events to LabVIEW. I'm going to do a little more cleanup and will then post the VI library.

I'm sure I've said this before, but I am seriously jealous of your low-level knowledge, particularly of the Windows operating system. Bravo, I look forward to seeing the library. :)

I agree that the taskbar interface is so marginally useful that I would actually be disappointed if NI wasted any time on it. There are so many things that would be better served with developer time. If you want some examples, just scroll through the top kudos'd ideas on the Idea Exchange. However, if you really do think it's that valuable, you should add it and see if you can garner support for it.

  • Like 1
Link to comment
  • 5 weeks later...

Great work! It is always exciting to see LabVIEW getting access to a previously dark corner of the UI.

When I run the Taskbar Example it works the first time, but will not show the thumb buttons again on successive executions. If I close the VI (dump it out of memory), reopen it and run it, the buttons appear again. Is this another peculiarity of the API?

Thanks!

Link to comment

Great work! It is always exciting to see LabVIEW getting access to a previously dark corner of the UI.

When I run the Taskbar Example it works the first time, but will not show the thumb buttons again on successive executions. If I close the VI (dump it out of memory), reopen it and run it, the buttons appear again. Is this another peculiarity of the API?

Thanks!

Yes! You can not change the buttons for a window once they are assigned, only hide them with the other method. It should have nothing to do with dumping the VIs out of memory, but closing the window (and therefore removing its taskbutton from the taskbar) which has the buttons assigned.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.