|
Introduction
This utility allows you to change the order of items on your taskbar, by
dragging them into position in a list.

The list shows all of your visible top-level windows. To move a window you
simply drag the window's title into the order you wish the windows to appear,
and click the Sort button.
To exit the utility, click on the Close button.
How it works
The application enumerates windows which are top-level (ie have no owner), and do not
explicitly prevent themselves appearing in the taskbar. It adds each of the windows' titles
to a drag list box (CDragListBox), along with the icon for the app. The user
can then re-order the windows. When the user clicks the Sort button, each window is hidden
using ShowWindow(SW_HIDE) and then re-shown (ShowWindow(SW_SHOW))
in the order of the list - top to bottom. This has the effect of the window being removed
from the taskbar and then being re-added at the right-hand side.
Known limitations
Unfortunately there doesn't appear to be any way of interrogating the taskbar to determine, firstly
which windows appear there, and secondly in what order they currently appear. This means that each time
the utility is run the user needs to re-order each window from scratch.
That's all there is to it - have fun!
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 29 (Total in Forum: 29) (Refresh) | FirstPrevNext |
|
 |
|
|
Hi,
How would one convert this to .Net code as I a not a C++ programmer. I think I actually might have a commercial use for this so please let me know if you are interested in working together.
Contact me on Plury@24.com as I can not update my profile on the code project, it gives an error.
Thanks
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
There is a utility "Taskbar Manager" at http://www.askarya.com/tm/tm.asp[^]which lets you drag and drop buttons on the taskbar. You can also save and load the order of taskbar buttons.
It works on Windows 2000 and XP. Works better on XP if taskbar button grouping is disabled.
TCM
Code till death
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
Best thanks for this very needfull Tool from Germany 
I would suggest, to save the Order that the user choses to a file. Mostly the first 5 to 10 Applications will be same Subject (also with choosen File etc.). So You could sort this ones and leave the rest as it is.
Would be much better 
Greetings, Jan
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I suggest that you save the order, always adding new applications to the sorted list and never removing applications. This way, whenever a user sorts taskbar items, they teach the Taskbar Sorter Utility their general preferences. To do this properly you might need to add some meta data for each application rather than simply a straight list, a simple xml structure would be sufficient. It the utility has a systray presence, a user could then right-click the systray icon and choose "AutoSort" and the taskbar items could be automatically sorted according to previously chosen preferences.
Great work! Kandarp
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, all:
First it is a good and very useful tool that will rescue to my "memory leak" especially when I have so many windows opened.
I have found the same need to save the order especially when I open new windows and would like to add them to the sorting list. If I close the sorter and reopen it, the new windows are added to the list but the order is changed based on the current z-ordering.
I have made a bit enhancement to the program to keep the original list (not to save it to a file anyway)intact but keep refreshing itself with newly added windows (appending them to the end of the list) when the "sort" button is clicked.
The code is working but I did not polish it. So it could cause some leak, etc.
The code is as follows.
In TaskbarSortDlg.cpp, function void CTaskbarSortDlg::OnOK()
======================= void CTaskbarSortDlg::OnOK() {
TRACE0("==== Fill list again\n");
int n;
// get each of the windows in the list, and hide, then re-show them // that should leave them in the correct order in the taskbar
// GetCount(): CListBox function
int nNumItems = m_listWindows.GetCount();
TRACE1("==== nNumItems = %d\n", nNumItems);
HWND *ha; char **la;
ha = new HWND[nNumItems]; la = new char*[nNumItems];
char *lpsz;
// copy list for (n = 0; n < nNumItems; n++) {
// save HWND ha[n] = (HWND)m_listWindows.GetItemData(n);
// save titles lpsz = new char[(m_listWindows.GetTextLen(n))]; m_listWindows.GetText(n, lpsz);
la[n] = lpsz;
TRACE1("==== lpsz = %s\n", lpsz);
}
// clean up for (n = 0; n < nNumItems; n++) { TRACE1("====== delete %d\n", n); int ret = m_listWindows.DeleteString(0); // the index will change after the delete; so always delete the first one //int ret = m_listWindows.DeleteString(n); TRACE1("====== ret = %d\n", ret); }
int nNumItems2 = m_listWindows.GetCount();
TRACE1("==== after clean up = %d\n", nNumItems2);
// refresh
FillList();
nNumItems2 = m_listWindows.GetCount();
TRACE1("==== after clean up = %d\n", nNumItems2);
// resort
int copy = 0;
for (n = 0; n < nNumItems; n++) { int m = m_listWindows.FindStringExact(-1, la[n]);
TRACE1("==== n = %d\n", n); TRACE1("==== m = %d\n", m); TRACE1("==== la[n] = %s\n", la[n]); TRACE1("==== ha[n] = %d\n", ha[n]);
// if find same one, delete it and add to the end // if not found then ignore it // this way the final list would be new items + existing old items
if(m != LB_ERR && (HWND)m_listWindows.GetItemData(m) == ha[n]) { int ret = m_listWindows.DeleteString(m); // delete from list TRACE1("==== ret = %d\n", ret);
int temp = m_listWindows.GetCount(); TRACE1("==== temp = %d\n", temp);
// add to end of list m_listWindows.AddString(la[n]);
temp = m_listWindows.GetCount();
TRACE1("==== temp = %d\n", temp); // should -1 because deleted first m_listWindows.SetItemData(temp-1,(DWORD)ha[n]);
lpsz = new char[(m_listWindows.GetTextLen(temp-1))]; m_listWindows.GetText(temp-1, lpsz);
TRACE1("==== copied lpsz = %s\n", lpsz); TRACE1("==== copied hwnd = %d\n", m_listWindows.GetItemData(temp-1)); //delete lpsz;
copy++; } else { TRACE0("=== New"); }
}
// move the new items to the end
int nNumItems1 = m_listWindows.GetCount();
TRACE1("==== nNumItems1 = %d\n", nNumItems1);
int diff = nNumItems1 - copy;
TRACE1("==== diff = %d\n", diff);
for (n = 0; n < diff; n++) {
lpsz = new char[(m_listWindows.GetTextLen(0))]; m_listWindows.GetText(0, lpsz);
TRACE1("==== new lpsz = %s\n", lpsz);
m_listWindows.AddString(lpsz);
DWORD nhwnd = m_listWindows.GetItemData(0);
TRACE1("==== new hwnd = %d\n", nhwnd);
int temp = m_listWindows.GetCount(); TRACE1("==== temp = %d\n", temp);
// need to remember to -1 from count m_listWindows.SetItemData(temp -1,(DWORD) nhwnd);
m_listWindows.DeleteString(0);
}
nNumItems = m_listWindows.GetCount();
TRACE1("==== nNumItems = %d\n", nNumItems);
for (n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); TRACE1("==== hwnd = %d\n", hwnd); ::ShowWindow(hwnd, SW_HIDE); ::ShowWindow(hwnd, SW_SHOW); } // now hide and show self ShowWindow(SW_HIDE); ShowWindow(SW_SHOW); SetForegroundWindow();
// don't close the dialog //CDialog::OnOK(); }
============================================== Thanks to Paul's good work and hope this helps, too.
David
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Some more update to take care of title changes in the same window.
=======
void CTaskbarSortDlg::OnOK() {
TRACE0("================================ Fill list again\n");
int n;
// get each of the windows in the list, and hide, then re-show them // that should leave them in the correct order in the taskbar
// GetCount(): CListBox function
int nNumItems = m_listWindows.GetCount();
TRACE1("==== nNumItems = %d\n", nNumItems);
HWND *ha; char **la;
ha = new HWND[nNumItems]; la = new char*[nNumItems];
char *lpsz;
// copy list for (n = 0; n < nNumItems; n++) {
// save HWND ha[n] = (HWND)m_listWindows.GetItemData(n);
// save titles lpsz = new char[(m_listWindows.GetTextLen(n))]; m_listWindows.GetText(n, lpsz);
la[n] = lpsz;
TRACE1("==== lpsz = [%s]\n", lpsz);
}
// clean up for (n = 0; n < nNumItems; n++) { TRACE1("====== delete %d\n", n); int ret = m_listWindows.DeleteString(0); // the index will change after the delete; so always delete the first one //int ret = m_listWindows.DeleteString(n); TRACE1("====== ret = %d\n", ret); }
int nNumItems2 = m_listWindows.GetCount();
TRACE1("==== after clean up = %d\n", nNumItems2);
// refresh
FillList();
nNumItems2 = m_listWindows.GetCount();
TRACE1("==== after refill = %d\n", nNumItems2);
/* // save new list HWND *ha1; char **la1;
ha1 = new HWND[nNumItems2]; la1 = new char*[nNumItems2];
//char *lpsz;
// copy list for (n = 0; n < nNumItems2; n++) {
// save HWND ha1[n] = (HWND)m_listWindows.GetItemData(n);
// save titles lpsz = new char[(m_listWindows.GetTextLen(n))]; m_listWindows.GetText(n, lpsz);
la1[n] = lpsz;
TRACE1("==== new list lpsz = [%s]\n", lpsz);
} */
// resort
int copy = 0;
for (n = 0; n < nNumItems; n++) { //int m = m_listWindows.FindStringExact(-1, la[n]);
TRACE1("==== n (org) = %d\n", n); //TRACE1("==== m (new) = %d\n", m); TRACE1("==== la[n] = %s\n", la[n]); TRACE1("==== ha[n] = %d\n", ha[n]);
// if find same one, delete it and add to the end // if not found then ignore it // this way the final list would be new items + existing old items /* if(m != LB_ERR && (HWND)m_listWindows.GetItemData(m) == ha[n]) { int ret = m_listWindows.DeleteString(m); // delete from list TRACE1("==== ret = %d\n", ret);
int temp = m_listWindows.GetCount(); TRACE1("==== temp = %d\n", temp);
// add to end of list m_listWindows.AddString(la[n]);
temp = m_listWindows.GetCount();
TRACE1("==== temp = %d\n", temp); // should -1 because deleted first m_listWindows.SetItemData(temp-1,(DWORD)ha[n]);
lpsz = new char[(m_listWindows.GetTextLen(temp-1))]; m_listWindows.GetText(temp-1, lpsz);
TRACE1("==== copied lpsz = %s\n", lpsz); TRACE1("==== copied hwnd = %d\n", m_listWindows.GetItemData(temp-1)); //delete lpsz;
copy++; } else */ // if title changes as in file explorer { //TRACE0("=== Title changed: check window id"); // compare array
for(int i = 0; i< m_listWindows.GetCount(); i++) { HWND ha1 = (HWND)m_listWindows.GetItemData(i);
// save titles lpsz = new char[(m_listWindows.GetTextLen(i))]; m_listWindows.GetText(i, lpsz);
if(ha1 == ha[n]) { // window found by id int ret = m_listWindows.DeleteString(i); // delete from list TRACE1("==== delete item: ret = %d\n", ret);
int temp = m_listWindows.GetCount(); TRACE1("==== current number = %d\n", temp);
// add to end of list but change title first m_listWindows.AddString(lpsz);
temp = m_listWindows.GetCount();
TRACE1("==== new number = %d\n", temp); // should -1 because deleted first m_listWindows.SetItemData(temp-1,(DWORD)ha[n]);
lpsz = new char[(m_listWindows.GetTextLen(temp-1))]; m_listWindows.GetText(temp-1, lpsz);
TRACE1("==== title: org lpsz = [%s]\n", la[n]); TRACE1("==== title: copied lpsz = [%s]\n", lpsz); TRACE1("==== title: copied hwnd = %d\n", m_listWindows.GetItemData(temp-1)); //delete lpsz;
copy++;
break; } } }
}
// move the new items to the end
int nNumItems1 = m_listWindows.GetCount();
TRACE1("==== nNumItems1 = %d\n", nNumItems1);
int diff = nNumItems1 - copy;
TRACE1("==== diff = %d\n", diff);
for (n = 0; n < diff; n++) {
lpsz = new char[(m_listWindows.GetTextLen(0))]; m_listWindows.GetText(0, lpsz);
TRACE1("==== move: new lpsz = [%s]\n", lpsz);
m_listWindows.AddString(lpsz);
DWORD nhwnd = m_listWindows.GetItemData(0);
TRACE1("==== move: new hwnd = %d\n", nhwnd);
int temp = m_listWindows.GetCount(); TRACE1("==== move: new number = %d\n", temp);
// need to remember to -1 from count m_listWindows.SetItemData(temp -1,(DWORD) nhwnd);
m_listWindows.DeleteString(0);
}
nNumItems = m_listWindows.GetCount();
TRACE1("==== nNumItems = %d\n", nNumItems);
for (n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); TRACE1("==== hwnd = %d\n", hwnd); ::ShowWindow(hwnd, SW_HIDE); ::ShowWindow(hwnd, SW_SHOW); } // now hide and show self ShowWindow(SW_HIDE); ShowWindow(SW_SHOW); SetForegroundWindow();
// don't close the dialog //CDialog::OnOK(); }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is a nice utility, it works pretty well. I can think of all kinds of interesting ways to extend it. 
In order to get it to work on Windows XP, though, I had to make a code change, because of XP's task grouping.
Change this code in CTaskbarSortDlg::OnOK():
int nNumItems = m_listWindows.GetCount(); for (int n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); ::ShowWindow(hwnd, SW_HIDE); ::ShowWindow(hwnd, SW_SHOW); }
to
int nNumItems = m_listWindows.GetCount(); for (int n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); ::ShowWindow(hwnd, SW_HIDE); }
for (n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); ::ShowWindow(hwnd, SW_SHOW); }
Also, in CDragIconListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) there is a line that has this:
CImageList* pImageList = new CImageList;
pImageList is never deleted, causing a leak. So at the end of this function I added
delete pImageList;
Thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I found (for me at least) that if you change the line
pImageList->Create(16, 16, ILC_COLOR | ILC_MASK, 1, 1);
,in the CDragIconListBox::DrawItem function, to use ILC_COLOR32 instead, the icons in the listbox look better (since they now use are 32-bit instead of the default 4-bit).
very useful program btw
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
James Johnson always closes and reopens apps so he gets them in the right order in his taskbar. This app will suit him nicely. I was actually planning to write one like this, but now that you have overtaken me, I won't need to.
Nish
Author of the romantic comedy
Summer Love and Some more Cricket [New Win]
Buy it, read it and admire me 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I used to do the same which is why I wrote it!
--- "The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Paul S. Vickery wrote: I used to do the same which is why I wrote it!
That's cool Paul. And don't be depressed about pcmag. At least you got some fun out of coding this, didn't ya? Imagine my embarassment if I had written a similar tool only to find that not only pcmag, but Paul Vickery has also overtook me 
Nish
Author of the romantic comedy
Summer Love and Some more Cricket [New Win]
Buy it, read it and admire me 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
PC Magazine had a utility called ButtonBoogie that let you rearrange taskbar buttons by clicking and dragging. Works on 9x/NT/2k, but not XP (the taskbar in XP is apparently implemented differently).
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I stumbled on ButtonBoogie while searching the web for "MSTaskSwWClass". It's very good.
It does what I ultimately was hoping to achieve, which is to allow the user to simply drag and drop the buttons, and remember which apps the user prefers in which position.
I guess it makes my utility a little superfluous...
--- "The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I always used a side effect of WatchCat to do this... Ie. I hide the applications and restore them in the order I want.
I will stick with it, since it does much more, but your idea is nice and useful, since it does it automatically.
Regards.
--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=-- Philippe Lhoste (Paris -- France) Professional programmer and amateur artist http://jove.prohosting.com/~philho/
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I never felt any need for it but now that there is such a utility I like it. What made you write something like this?
..this is a VB Programmers' world and we all are just visitors - Someone in a MSJ article
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
It's been on my list of "things to do when i have time" for a while now.. I always have programs open in a specific order, and when that order is mucked around with, then i just... well... i don't like it 
this is a cool program..
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I found that I liked my buttons to be in the same place each time I wanted to get at them, and was annoyed if I restarted an app and its button was re-added at the end of the taskbar. It seems from the comments that I'm not the only one who's that picky!
--- "The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Nice work Paul! I was tempted to do an app of this kind before but didn't have the final push on myself to get my hands dirty with it.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
Thank you for this interesting tool, nice idea !
When launched, it reads the windows in unsorted order, would it be possible to have it in the current order ?
Laurent Kempé Tech Head
--- Old programmers never die, they just branch to a new address.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Laurent,
Unfortunately (as I said in my article I cannot find any way of asking the taskbar what it has on it, or the order in which they are displayed.
One thing I have thought is that I could try and remember the order a user usually has things in and offer that on starting up the utility, but even that would be difficult as app titles change when viewing different files etc. 
Any ideas you or anyone else may have would be greatly appreciated! 
Paul.
--- "The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sorry I'd better try to read the article in details
Thanks for your answer.
Laurent Kempé Tech Head
--- Old programmers never die, they just branch to a new address.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Excellent, I have needed a program like this for a while.
I think you can determine the order of the buttons on the taskbar by doing the following:HWND hTaskbarWnd = FindWindowEx(NULL, NULL, "Shell_TrayWnd", NULL); HWND hContainerWnd = FindWindowEx(hTaskbarWnd, NULL, "MSTaskSwWClass", NULL); HWND hTabCtl = FindWindowEx(hContainerWnd, NULL, "SysTabControl32", NULL); UINT uItemCount = SendMessage(hTabCtl, TCM_GETITEMCOUNT, 0, 0); TCITEM item; for(UINT uIndex = 0; uIndex < uItemCount; ++uIndex) { SendMessage(hTabCtl, TCM_GETITEM, uIndex, &item); // item.pszText should be the Window's title. } In order for this to work the code would need to be “injected” into the taskbar’s address space so TCM_GETITEM works properly (separate memory for separate processes). Also, you would need to consider the different operating system’s taskbars; Win95/NT have a different taskbar than Win98/Me/2000/XP. Spy++ is your friend.
There’s probably an easier way of doing this though.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|