Jump to content

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


Recommended Posts

Looks really COOL!! Couple notes/issues:

  • Not seeing any footers. Don't know what they should look like, but I don't think I'm seeing them based on the strings in the sample.
  • I don't quite get the "Expand more Details" sample. This may be related to the lack of the footer?
  • Not sure if the Window Title is working since they all say LabVIEW.exe.
  • Is there an option or ability to make the dialog modal?

I can certainly see a use for this, I like the idea of using the Windows dialogs.

 

This was tested/used with Win7 SP1 64bit and LabVIEW 2014 32bit

 

Side note: I would recommend using an event structure instead of building an array and using a case structure, this makes associating the button with the VI much easier.

 

Overall, I like it!

Link to comment

Ok,

 

I found some minor issues preventing the custom titlebar within 32bit LabVIEW; there seems also some issues with the "built-in" icons and the footer. I already correct the window title and built-in icons, now struggeling with the footer.

 

Regarding your side note: The sample was just quick'n'dirty, therefore I made it "the old way" ;)

 

BTW, I've also attached a sample, how the "footer" option will look like (sample is with the wrapper, used within 64bit LabVIEW)

TaskDialogIndirect Source.zip

post-53646-0-94359400-1435228056.png

Edited by peterp
  • Like 2
Link to comment

Wow keep up the good work.  Yeah I'd say the majority of LabVIEW developers still use 32 bit LabVIEW regardless of the bitness of the OS, but still the majority of the features are working in 32 bit LabVIEW.

 

I don't think this library is ready for a package yet, it is still very early.  When the time comes we can try to wrap these functions into simple to use functions, give it some pretty icons, and then package it up.  

 

I'm loving the progress, keep it up.  :worshippy:

Link to comment

Very neat.  Yeah I'd suggest making wrappers for each of the basic button examples you showed.  The goal in my mind is to have as few inputs as possible, and exclude using clusters if possible, as well as using enums when possible.  But I think some controls in your case will need to be rings, where maybe it has defined values, or a custom output.  And I'd suggest making default values for inputs valid, so that fewer required inputs are needed.

 

In my experience following these rules help make interfaces that other developers can use easily.  Cluttering up the interface with tons of options gets confusing to new developers, and giving them fewer options, with working default options helps them adopt it easier.

 

I don't have much time to work on these but here is an attempt at cleaning up some of the code.  Functionally it should be the same.  I moved some functions into the private code and exposed only important things as public, updated the example to use the event structure, and wrapped the first three functions into subVIs with icons, VI descriptions, and in the minimalist process I described earlier.  I don't have 2012 installed so I had to back save from 2013, I hope things didn't break in the process.

TaskDialogIndirect Source Hooovahh Edit.zip

Link to comment

I llike these improvements ... very nice!

 

Now I found also the reason why the Dialog is not "modal"; you have to specify the main application window handle; currently I just use the window handle of the internal core vi. Are there any ways to get this information without using a global, another input to the core vi? Because I can't use a fix name to get the window handle. And when I ask the application property "App.AllVIs" in memory and filter for execution state "Run top level", it's really slow.

 

BTW: I could open your edit version w/o any problem in LV2012...

Link to comment

I llike these improvements ... very nice!

 

Now I found also the reason why the Dialog is not "modal"; you have to specify the main application window handle; currently I just use the window handle of the internal core vi. Are there any ways to get this information without using a global, another input to the core vi? Because I can't use a fix name to get the window handle. And when I ask the application property "App.AllVIs" in memory and filter for execution state "Run top level", it's really slow.

 

BTW: I could open your edit version w/o any problem in LV2012...

 

One possibility is to use the Call Chain and reference the latest element in the resulting array. That is the top level VI of the current call chain, so might not be the top level of the entire application (when you use VI Server->Run VI or Call Asynchronous, but should be close enough).

 

Otherwise there should be an "App->Parent Window for Dialogs" property but last time I checked that always returned a 0 handle, which for most Windows APIs requiring a parent handle would mean that it is system modal as the 0 HWND is treated as a shortcut for the Desktop window, which is the parent of any other window on the desktop.

Link to comment

So what I usually do is get the calling VI reference using the call chain, and get the HWND from that.  I'd prefer this over getting the top most VI call because that could be a launching VI that has its window hidden.  This of course assumes that the VI calling this dialog is currently showing a VI.  Of course there is also the desire to sometimes have it be model for the whole system (HWND = 0).  This is what I've always used on my Windows Dialog, but again that needs its own dedicated subVI terminal input on every interface VI.

Link to comment

Regarding the window handle, I found some note here: http://www.delphi-treff.de/tipps-tricks/system/prozesse/fensterhandle-anhand-des-exe-namens-erhalten/

which basically uses the application executable name to get the approbiate window handle. Now I'm struggeling a little bit with this dll call und structure ...

 

That method requires passing a callback pointer to EnumWindow. You can't do that in native LabVIEW unless you use .NET callbacks or your own DLL.

Edited by ShaunR
Link to comment

I found this http://forums.codeguru.com/showthread.php?353149-How-to-Get-windows-Handle-using-Process-Id maybe it will work; I'm just implemementin git in LabVIEW...

 

OK, I got this code running (GetProcessIDsOfWindows)...

I also got the GetWindowHandleOfExecutable running, so I can get in the list of processes my application and will look with this ProcessID for the approbiate window handle... works nice. Just one question, before I will post all code: Is there a way to use "memset" in conjunction with DSNewPtr and MoveBlock, the LabVIEW build-in memory handling routines? I want to avoid re-creating memory pointer and free them each iteration to get an initialized memory block ...

GetProcessIDsOfWindows.zip

post-53646-0-68141900-1435753948.png

Edited by peterp
Link to comment

Oh, just saw your answer after editing my last post ... I use now GetTopWindow and GetNextWindow, and will search in ProcessList for the correct executableFile, obtain it's ProcessID and will check the open windows for this ProcessID. (see attachments in my previous post)

Edited by peterp
Link to comment

I've re-structured (again) the library, because it uses now quite some api-calls of windows. What do you think?

 

I'm now able to make the dialog modal as well, even when I don't understand, why the "Parent Window" of an LabVIEW executeable is not named like executable...

 

There is still something to do, because the window routines are currently x64 only...

WinAPI.zip

Link to comment

Restructure is good, but I'd suggest making the examples easier to find, maybe putting them at the top level.  I just know when I get a new toolkit my first thing I do is run the example and see how it works and I had to go three folders deep to find the Example.  Even if this is just a virtual folder in the library it might make finding examples easier.

 

Personally I don't think requiring x64 Windows is that big of a deal but others might.  I haven't used 32 bit Windows in several years.  The only reason I see 32 bit LabVIEW used is because some toolkits aren't compatible.

Link to comment

So I just did a test and the GetActiveWindow returns the same HWND as the Front Panel >> Native Window, and the deprecated function Front Panel >> OS Window.  Application >> Parent Window for Dialogs also returned 0 as mentioned earlier in this thread.

 

I also thought you might want to know an alternate way of getting PIDs and the application names, so the attached VI does that too.

 

EDIT:  Oh and the command line program wmic can get some other PID information.

Get HWND and PID.vi

Link to comment

So I just did a test and the GetActiveWindow returns the same HWND as the Front Panel >> Native Window, and the deprecated function Front Panel >> OS Window.  Application >> Parent Window for Dialogs also returned 0 as mentioned earlier in this thread.

 

I also thought you might want to know an alternate way of getting PIDs and the application names, so the attached VI does that too.

 

EDIT:  Oh and the command line program wmic can get some other PID information.

 

If you like wmic you'll love the wmi-delphi-code-creator  :wub:

Link to comment

So I just did a test and the GetActiveWindow returns the same HWND as the Front Panel >> Native Window, and the deprecated function Front Panel >> OS Window.

 

Not always. If your active window is the block diagram it returns its HWND :)

Just out of curiosity: Are there use cases for a modal dialog that doesn't belong to the active window?

Link to comment

Just out of curiosity: Are there use cases for a modal dialog that doesn't belong to the active window?

Well we can't control what window is active, the user can.  I mean we can temporarily change what the active window is, but there is no telling what the user does.  It could be a race condition between software and the user.

Link to comment

Wow, quite some traffic in this thread ...

 

As I mentioned, I can now use API-Calls to find "my" parent window. Just curios, which call will be, Dll-Calls to get Process list and than look for the window handle of the LabVIEW application or use the "Get HWND and PID" and obtain there the  "MaiWindowHandle".

 

BTW, I also added a progress bar example of the TaskDialogIndirect.

 

I also tried to implement a few "NamedPIpe" functions. Perhaps you guys can have a look? Especially the Named Pipes (I only found some old code, using a wrapper dll, which I did not want) will not work ... Even I thought I just translated the examples of msdn (https://msdn.microsoft.com/de-de/library/windows/desktop/aa365588%28v=vs.85%29.aspx https://msdn.microsoft.com/de-de/library/windows/desktop/aa365592%28v=vs.85%29.aspx) to LabVIEW code...

WinAPI.zip

  • Like 1
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.