Sign in to follow this  
VirtualProgrammer

Displaying Windows from the Taskbar

Recommended Posts

Well recently, for testing purposes I created a program that displays the programs that are in the task bar. Or so I tried. What I attempted to do was to use EnumWindows() to go through all the windows and list them in my list box. But I ended up with EVERY window (not child windows), for example invisible windows which are not displayed on the Taskbar. I then tried to filter the results by using IsWindowVisible() but I still ended up with windows that weren't on the Taskbar. So my question is, "How do I only list windows that are on the Taskbar in my list box? and not child, invisible or any other sort of window?". Thank you. EDIT - Please go down as the subject of the thread has been changed from "Displaying Windows from the Taskbar" to "Using 'Modern style' Controls", thank you :D. [Edited by - VirtualProgrammer on May 9, 2009 7:38:14 AM]

Share this post


Link to post
Share on other sites
Hmm, the example searches for the Task Bar and then sees the programs that are on it. That does partly answer my question, but what I need is the algorithm used by the Task Bar to find the correct windows to list. So basically, how is it that the Task Bar can tell what programs it needs to display? what method is used?

Thank you :).

Share this post


Link to post
Share on other sites
theTroll: Thanks but I'm not sure looking for that style will work :).
adeyblue: Hmm thanks :D Your method sure seems to work nicely! But since I didn't understand some of the functions that you used I decided to do 'it' using another method. And the following seems to work great!:

if(IsWindowVisible(DesktopName) == TRUE && GetParent(DesktopName) == NULL && GetWindowLongPtr(DesktopName, GWL_STYLE) & WS_CAPTION)
{

GetWindowText(DesktopName, WNDTitle, 100);

SendMessage(DesktopsListLB, LB_ADDSTRING, NULL, (LPARAM)WNDTitle);

}


Is there anything wrong with using this method? for example, certain windows that should be detected that won't be.

Thank you.

Share this post


Link to post
Share on other sites
I'm guessing DesktopName is the window handle you're testing? That's a really bad name for that variable if that's the case (it's not a "name" and it's not the "desktop" either, hwnd is a pretty standard variable name for miscellaneous window handles).

Anyway, you've also got to test for the WS_EX_APPWINDOW and WS_EX_TOOLWINDOW extended window styles. Basically, WS_EX_APPWINDOW windows will always appear in the taskbar, even if they have an owner, and WS_EX_TOOLWINDOW windows will not appear in the taskbar even if they don't have an owner.

See MSDN for more details.

Share this post


Link to post
Share on other sites
Oh haha, that variable naming thing you're talking about was kind of an accident. Basically I already had another one of my tests up and running (it was to do with desktops :)) so I just quickly changed it around to see how window enumerating works.

Oh so that's why I need to look for them. Alright let me just implement that and give you the resulting code. Just to see if it is a good algorithm to use :).

Share this post


Link to post
Share on other sites
Well now I am using the following algorith to find the correct windows:

 if((IsWindowVisible(DesktopName) == TRUE && GetParent(DesktopName) == NULL && GetWindowLongPtr(DesktopName, GWL_STYLE) & WS_CAPTION) 
||
((GetWindowLongPtr(DesktopName, GWL_EXSTYLE) & WS_EX_APPWINDOW) && (GetWindowLongPtr(DesktopName, GWL_EXSTYLE) & !WS_EX_TOOLWINDOW)))
{

GetWindowText(DesktopName, WNDTitle, 100);

SendMessage(DesktopsListLB, LB_ADDSTRING, NULL, (LPARAM)WNDTitle);

}



What do you guys think? Anything missing from it?

Thanks :).

Share this post


Link to post
Share on other sites
Hmm, that's a pretty confusing condition there... I'd probably split it out into a separate function just to make it clearer. Like so:

bool IsShowInTaskbar(HWND hwnd)
{
if (!IsWindowVisible(hwnd)) {
return false;
}

LONG exstyle = GetWindowLong(hwnd, GWL_EX_EXSTYLE);
if ((exstyle & WS_EX_APPWINDOW) != 0) {
// WS_EX_APPWINDOW windows are always in the taskbar
return true;
}
if ((exstyle & WS_EX_TOOLWINDOW) != 0) {
// WS_EX_TOOLWINDOW windows are never in the taskbar
return false;
}

// if it's not WS_EX_APPWINDOW or WS_EX_TOOLWINDOW, then it's in the
// taskbar if it's a top-level window
return (GetParent(hwnd) == NULL);
}

Also, I don't believe you need to check the WS_CAPTION style. I don't think that has an effect.

Share this post


Link to post
Share on other sites
Hehe, I just read to the bottom of the article I linked before, I gotta highlight the section on "Choosing window titles" because, even though it's not related to this topic, it's too awesome to pass up:



It seems even Microsoft software isn't above being named and shamed there! Too funny :-)

Share this post


Link to post
Share on other sites
Alright then I'll remove the checking for the style "WS_CAPTION" :) I thought there was something wrong with it but couldn't be sure, it makes sense to remove it though; as some programs have a custom caption.

LOL! Yeah I noticed that before and laughed at it too :), "Windows Live Mess" haha. To be honest I'm quite suprised they used their own program as an example :P.

Well I believe this thread is pretty much RESOLVED. Thanks for all your help guys its been a pleasure ;).

Share this post


Link to post
Share on other sites
Well actually there is one more problem, kind of. But it isn't acutally related to the thread and it doesn't deserve its own one so I'll just post here. Why is it that every control I create looks like the old versions from Windows 98 or something? I'm using Windows Vista currently. If you require a screenshot please let me know.

Thank you :).

Share this post


Link to post
Share on other sites
You need to include a manifest with your executable so that it loads version 6 of the common control library. This page from MSDN describes the process of including one. It's a bit brief on the details, so if you need something more step-by-step, I'm sure you can google for one :-)

Share this post


Link to post
Share on other sites
Oh my god! I can't believe they had to make it so complicated. I mean I thought I would only have to use a single function :P. Seriously though I'm kinda anoyyed... I've never even heard about using manifest files and am stil not sure what they are. Well thanks for the link my friend, it did give me somewhere to start :).

EDIT - Also, how would I add the manifest file to my project in Visual Studio? Or do I just put the manifest file in the same folder as my executable before compiling?

[Edited by - VirtualProgrammer on May 8, 2009 4:27:19 AM]

Share this post


Link to post
Share on other sites
YES! I finally got the split button to show up :D, so I have to use manifest files for any new control that is past Windows 95? Also do I have to create a manifest file for every executable in my application (not that I have multiplae but I need to know)?

Share this post


Link to post
Share on other sites
I'm really sorry guys but could someone please explain this all to me :(... I never even knew about manifest files before Codeka told me. Its just killing me inside now... because I would really like some information on the subject, information such as what are the uses for manifest files, how they work, and what is this "XML" format which they use (which looks suspiciously like HTML).

What's really annoying me is that I don't even know what to search in google, I tried "Visual styles" but it just results in forums telling you how to crack your "uxtheme.dll" file to use unsighned themes and what not... so could someone please tell me what to search?

Thanks! :).

Share this post


Link to post
Share on other sites
This is the start page for the whole SxS technology. The reference link at the bottom leads to more goodies including documentation of the file format. They're basically MS's current favourite way of combatting DLL Hell with additional bits of metadata for UAC etc.

Share this post


Link to post
Share on other sites
Thanks for the links :P. Honestly though the whole talk of side by side assemblies confuses me a lot... so does binding and all these other terms I don't understand. Are there any simpler tutorials online that explain the whole thing in a better way?

Thanks :).

Share this post


Link to post
Share on other sites
The basic idea is this:

Many DLLs, such as comctl32.dll are used by a large number of programs. Since backwards compatibility must be maintained making changes to the controls in comctl32 is dangerous due to the high potential of breaking applications that have already been written and deployed. In XP, however, a large change to comctl32 was necessary in order to create the new theme API - this change broke a whole lot of apps. If you can only have one version of comctl32 on the system then you have two options 1) break a whole lot of apps and ensure that your customers never upgrade to XP or 2) ditch the new theme API and ensure that XP looks the same as 2000 making most people not want to upgrade to XP (since it is the same on the surface). Both situations mean XP wont sell.

Solution? Find a way to run multiple versions of comctl32 at the same time! The default must be the pre-XP comctl32 (version 5.2) since old apps dont know how to request it which means that new programs will need to request the new version in order to use it. This is where manifests come in. Manifests are the way to go since you need to know which version of comctl32 to load before the program starts running (switching versions at runtime would be mind-numbingly dangerous) and so you need a way of embedding the data within the binary that is not in the code.

Share this post


Link to post
Share on other sites
Oh that makes it much easier :D. Thanks man I do appreciate it. Just asking but have you memorised what you need to include in your manifest or do you just copy and paste the file?

Here's what I got from Microsoft (it has been a little changed as I way experimenting):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity

version="1.0.0.1"

processorArchitecture="X86"

name="ThoseGuys.Window Enumerator.Example"

type="win32"

/>

<description>This program enumerates windows.</description>

<dependency>

<dependentAssembly>

<assemblyIdentity

type="win32"

name="Microsoft.Windows.Common-Controls"

version="6.0.0.0"

processorArchitecture="X86"

publicKeyToken="6595b64144ccf1df"

language="*"

/>

</dependentAssembly>

</dependency>

</assembly>




What do all these XML tags mean? I mean I assumed that the text inbetween the description tags is the test you see when you highlight the main file, for example "Created by [insert company here]", but that didn't happen in my case so I don't know what all these tags and attributes point to.

Why is it that no one asks about this? I've barely found another thread like this, infact just one... is this supposed to be common knowledge or something; because I really don't know why people aren't asking questions or why there isn't mcuh information on manifests. I'd atleast expect some tutorial sites mentioning at the bottom that you need to create a manifest file in order to get "modern" looking controls...

Sorry if I'm asking to many questions... but I don't have much to turn to, not even a book (you'd expect one book to have information on this... c'mon).

EDIT - I have no idea why but when I try to set the note on my command link control it comes out in CHINESE! What the hell are the chances... anyways here's the code:

   Control = CreateWindowEx(NULL, "BUTTON", "Command Link", WS_CHILD | WS_VISIBLE | BS_COMMANDLINK, 10, 10, 200, 60, MainWindow, NULL, hInstance, NULL);

SendMessage(Control, BCM_SETNOTE, NULL, (LPARAM)"This control is called a \"Command Link\" and looks quite pretty doesn't it :D.");


As you can see there is no chinese yet the command link results having a chinese translation of the text above. Would this have to do with the manifest? because I don't see a reason for chinese text to result from that.

Thanks a lot! :).

[Edited by - VirtualProgrammer on May 9, 2009 7:29:48 PM]

Share this post


Link to post
Share on other sites
I do not know where the formal documentation for the XML schema is although most of it is easy enough to guess. assemblyIdentity, for example, describes a single binary. The first one in the file describes your executable, what version it is, what architecture it runs on, etc. The dependentAssembly area describes a binary that your binary depends on. In that manifest it is describing comctl32 version 6.0.0.0 (the one that came with XP).

As for making data appear in the properties dialog of your application you will need a version resource.

Finally, the reason you are getting Chinese is probably because the control is expecting a Unicode string but you are giving it an ANSI string.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this