Jump to content

[CR] TaskDialogIndirect (win-api comctl32.dll)


Recommended Posts

Hi,

 

I'm try to get a hint to make correct usage of the TaskDialogIndirect of comCtl32.dll It's Header will be

 

HRESULT TaskDialogIndirect(  _In_      const TASKDIALOGCONFIG *pTaskConfig,  _Out_opt_       int              *pnButton,  _Out_opt_       int              *pnRadioButton,  _Out_opt_       BOOL             *pfVerificationFlagChecked);

 

and the interesting part is the structure

 

typedef struct _TASKDIALOGCONFIG {  UINT                           cbSize;  HWND                           hwndParent;  HINSTANCE                      hInstance;  TASKDIALOG_FLAGS               dwFlags;  TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons;  PCWSTR                         pszWindowTitle;  union {    HICON  hMainIcon;    PCWSTR pszMainIcon;  };  PCWSTR                         pszMainInstruction;  PCWSTR                         pszContent;  UINT                           cButtons;  const TASKDIALOG_BUTTON        *pButtons;  int                            nDefaultButton;  UINT                           cRadioButtons;  const TASKDIALOG_BUTTON        *pRadioButtons;  int                            nDefaultRadioButton;  PCWSTR                         pszVerificationText;  PCWSTR                         pszExpandedInformation;  PCWSTR                         pszExpandedControlText;  PCWSTR                         pszCollapsedControlText;  union {    HICON  hFooterIcon;    PCWSTR pszFooterIcon;  };  PCWSTR                         pszFooter;  PFTASKDIALOGCALLBACK           pfCallback;  LONG_PTR                       lpCallbackData;  UINT                           cxWidth;} TASKDIALOGCONFIG;

I can call the function, get with no additional settings an empty dialog. BUt I'm not able to set any parameter in the structure, seems like it's content is messed up ... I use LV2012, 64bit on Win7, 64bit.

 

Thx for your help!

 

Peter

 

PS: I've also posted this question at ni.com, but have the impression, here are the smarter guys :shifty:

 

 

 

Link to comment

Hi,

 

I'm try to get a hint to make correct usage of the TaskDialogIndirect of comCtl32.dll It's Header will be

 

 

and the interesting part is the structure


I can call the function, get with no additional settings an empty dialog. BUt I'm not able to set any parameter in the structure, seems like it's content is messed up ... I use LV2012, 64bit on Win7, 64bit.

 

Thx for your help!

 

Peter

 

PS: I've also posted this question at ni.com, but have the impression, here are the smarter guys :shifty:

 

What are you trying to do? This is a pretty hairy structure to interface to from the LabVIEW diagram. I definitely think the only reasonable approach is to write a wrapper DLL that translates from proper LabVIEW datatypes to the according elements in this structure. A major work but the only maintainable solution! So is there anything you hope to achieve with this that you couldn't do with native LabVIEW elements?

Link to comment

Hi Rolf,

 

I'm a little bit unhappy with the built-in-LabVIEW MessageBoxes, so I wanted to get the windows-built-in boxes to use. (They are much more conforming to styleguide ..., I also like their possibilities to be conform to the actual windows display scheme. Have a look at http://http://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-2-_1320_-Task-Dialogs-in-Depth)

 

I'm able to use the "Messagebox" from user32.dll, but wanted the more flexibility in "TaskDialogIndirect", such as specifying an icon and own labeld buttons. As I already wrote, I can use (parts of) the structure to at least call the function (without a labVIEW crash), and see the "empty" dialog from this dll. Now I'm only looking for a small hint to get it's parameters to work. Of course, I can create my small wrapper, but would prefer a smaller solution, also to be able to distribute the application with less depencies.

 

Peter

Link to comment

Hi Rolf,

 

I'm a little bit unhappy with the built-in-LabVIEW MessageBoxes, so I wanted to get the windows-built-in boxes to use. (They are much more conforming to styleguide ..., I also like their possibilities to be conform to the actual windows display scheme. Have a look at http://http://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-2-_1320_-Task-Dialogs-in-Depth)

 

I'm able to use the "Messagebox" from user32.dll, but wanted the more flexibility in "TaskDialogIndirect", such as specifying an icon and own labeld buttons. As I already wrote, I can use (parts of) the structure to at least call the function (without a labVIEW crash), and see the "empty" dialog from this dll. Now I'm only looking for a small hint to get it's parameters to work. Of course, I can create my small wrapper, but would prefer a smaller solution, also to be able to distribute the application with less depencies.

 

Peter

 

Problem is that this structure is pretty wieldy, uses Unicode strings throughout and many bitness sensitive data elements. Basically, each LP<something> and H<something> in there is a pointer sized element, meaning a 32 bit integer on LabVIEW 32 bit and 64 bit integer on LabVIEW 64 bit. Same for the P<something> and <datatype> *<elementname> things. and yes they have to be treated as integer on LabVIEW diagram level since LabVIEW doesn't have other datatypes on its diagram level that directly correspond to these C pointers.

 

Not to talk about the unions!

 

So you end up with at least two totally different LabVIEW clusters to use for the two different platforms (and no don't tell me you are sure to only use this on one specific platform, you won't!  :D )

 

Trying to do this on LabVEW diagram niveau basically means that you not only have to figure out how to use all those different structure elements properly (a pretty demanding task already) but also play C compiler too, by translating between LabVIEW datatypes and their C counterparts properly. You just carved out for you a pretty in depth crash course in low level C compiler details.  :D

 

IMHO that doesn't weight up against a little unhappyiness that LabVIEW dialogs don't look exactly like some hyped defacto Microsoft user interface standard that keeps changing with every new Windows version, and that I personally find changing to the worse with almost every version.

Link to comment

Hi,

 

yes, It's correct, I have to create such a vi byteness-specific... And, yes, the structure is quite nasty. But I thought, because I can already open the dialog via function call, there is only small way to go to get the parameter correct. I hoped, I miss just one point in my implementation, which an expert can  easy find out...

 

Maybe there is a .net implementation (in the already included libraries of windows) to get this dialog?

 

And, I like it to create an application that fits more nicely in the windows enviroment, regarding the message boxes...

 

Peter

 

PS: Honestly, sometimes I like such challenges...

Link to comment

Hi,

 

yes, It's correct, I have to create such a vi byteness-specific... And, yes, the structure is quite nasty. But I thought, because I can already open the dialog via function call, there is only small way to go to get the parameter correct. I hoped, I miss just one point in my implementation, which an expert can  easy find out...

 

I would tag it übernasty. :D  Really, it's an API that I find even nasty to use from C directly.

 

 

 

Maybe there is a .net implementation (in the already included libraries of windows) to get this dialog?

 

Very likely there is. With all it's own complexeties such as correct .Net version that needs to be installed and instantiated by LabVIEW on startup. But the interfacing is made pretty easy since .Net provides a standard to describe the API sufficiently enough for LabVIEW to do the nasty interface conversion automatically.

Link to comment

As I told you, I like such code-digging ...

 

I saw in my wrapper dll the raw-data as transferred via the LabVIEW call. Seems like LabVIEW will special interpret the cluster data and I need to swap bytes, words and "64bit handles" in order to work. Now I have a working TaskDialogIndirect, need some more fine-tuning for buttons/labels/icons, but at least works.

 

post-53646-0-36907000-1434623056.png

Link to comment

As I told you, I like such code-digging ...

 

I saw in my wrapper dll the raw-data as transferred via the LabVIEW call. Seems like LabVIEW will special interpret the cluster data and I need to swap bytes, words and "64bit handles" in order to work. Now I have a working TaskDialogIndirect, need some more fine-tuning for buttons/labels/icons, but at least works.

 

You wouldn't need all that swapping if you had placed the natural sized element in that cluster, an int64 for 64 bit LabVIEW and an int32 for 32 bit LabVIEW. For the 0 elements in your cluster it doesn't matter anyhow.

 

Now you have a dialog with a title and a single string in it and it already looks complicated. Next step is to make it actually usefull by filling in the right data in all the other structure elements!  :D

Link to comment

I used on first hand the correct sized LabvIEW data types in the cluster, but I got some messed up data when I debug the data in a c-dll-wrapper. This is why I thought there is some data type miss-matching within LabVIEW.

 

Now, when I use a plain byte-array to transfer the data, it works just fine :) . All the other structure elements were quite easy, once I figured out, how I have to swap u64 (64bit handles) to be used in a C-dll.

Link to comment

I used on first hand the correct sized LabvIEW data types in the cluster, but I got some messed up data when I debug the data in a c-dll-wrapper. This is why I thought there is some data type miss-matching within LabVIEW.

 

Now, when I use a plain byte-array to transfer the data, it works just fine :) . All the other structure elements were quite easy, once I figured out, how I have to swap u64 (64bit handles) to be used in a C-dll.

 

The problem is certainly not endianess. LabVIEW uses internally whatever endianess is the prefered one for the platform. Endianess only comes into the picture when you flatten/unflatten (and typecast is a special case of flatten/unflatten) data into differently sized values. This is why you need to byte swap here.

 

Your issue about seemingly random data is most likely alignment. LabVIEW on x86 always packs data as tight as possible. Visual C uses a default alignment of 8 bytes. You can change that with pack() pragmas though.

Link to comment

I used on first hand the correct sized LabvIEW data types in the cluster, but I got some messed up data when I debug the data in a c-dll-wrapper. This is why I thought there is some data type miss-matching within LabVIEW.

 

Now, when I use a plain byte-array to transfer the data, it works just fine :) . All the other structure elements were quite easy, once I figured out, how I have to swap u64 (64bit handles) to be used in a C-dll.

 

One thing to be aware of is that the OS bitness and LabVIEW bitness are separate. That is. If you use LabVIEW 32 bit on a 64 bit platform you must use 32 bit addresses. Similarly, LabVIEW 32 bit can only load 32 bit binaries (DLLs) and LabVIEW 64 can only load 64 bit DLLs. You need to take that into account since LabVIEW 32 bit and LabVIEW 64 bit require different sized structures, are aligned differently and require different binaries.

 

Usually in the LabVIEW code we have a conditional disable structure with different allocations for each bitness if we are passing embedded pointers. Additionally, we have to supply two binaries if we are to support both LabVIEW 32 bit and LabVIEW 64 bit.

Edited by ShaunR
Link to comment

Hi,

I know this dialog "MessageBox" from windows, I now uses (after fighting with the dll call ...) the TaskDialogIndirect. This is a much more flexible function, allowing you to configure the button names, use custom icons and more.

 

For more details see http://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-2-_1320_-Task-Dialogs-in-Depth

 

WHen I finished the code (perhaps some bundling in a library), I can post my code here

Link to comment

Oh wow that is cool.  Please do post here when you get something working.  In the past I had a similar need.  Where I wanted a dialog box which looked similar to the system ones, but I could provide an image to be displayed below the text, above the buttons.  I had tons of code handling the window resize, resizing the image, and the text, and had code trying to increase the font size, and splitter positions.  It was a pain and wasn't very modular.  It also was system looking, it looked like my current system.

 

Having more low level control of system dialogs like that could be very useful.

Link to comment

Ok, here's the first rough version of the dll-calling VI as well as some SubVI's and controls.The code is currently 64bit only, and created by LabVIEW 2012. I will add 32bit support in next future...

 

Things to do/add:

- add conditional case to determine byteness, therefore create 32bit dll wrapper

- maybe also add case to detect OS prior MS Viste (no TaskDialogIndirect function available)

- create some "easy-to-use" sub-vi's for the most important functions

- create some nice icons for the vi's

- ...

 

TaskDialogIndirect Source.zip

Edited by peterp
Link to comment

Well thank you for your code...but your demo didn't really work for me.  In the Example the only button that did anything was the surprises.  I ran the Sample 1 Popup.vi and no error was returned but first call to TaskDialogIndirect returned a return type of -2147024809.

 

This was on a Windows 7 x64 machine, with LabVIEW 2013 SP1 32-bit.  Is this intended for 64 bit LabVIEW?

Link to comment

I've re-designed the code a litle bit, now some parts are also working with LabVIEW 32bit and 64 bit as well (except the icon handling, there I have to digg a little bit ...)

Maybe move this thread to the CR "uncertified" as it is an ongoing development?

 

What licencing are you planning to apply, just to clarify!

Edited by ShaunR
Link to comment

Hi,

 

ok, how do I move the thread to CR?

For licensing, I guess it will be BSD (or MIT/X-Windows-License); so feel free to edit (or correct) the code, use it in commercial or free applications, just keep the original mark in the VI's blockdiagram...

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.