|
Why is this article in the web development category? I would think a better place for it would be here:
Articles » Desktop Development » Desktop Gadgets » General
Overall, I like your application.
As you had noted, though, the order of the list of applications initially shown is something that can be improved (if that's possible).
Regards,
Mike
|
|
|
|
|
There aren't enough explain on that article.And it's not an article i think.
|
|
|
|
|
|
That, when u has enabled the option "Group similar taskbar buttons" in the taskbar properties the app doesnt work.
The windows simply re-appear in the original order.
Just a constructive comment.
Usefull program dude !
modified on Tuesday, December 30, 2008 6:21 PM
|
|
|
|
|
Hi,
Yes, this is a limitation, though this post[^] has some code which says it will make my app work with XP's grouping. I've not tried the posted code though.
Paul.
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Thanks Paul. I changed the code as says the post and still doesnt work.
I dont know Visual C++ but I'll try to debug it.
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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();
}
|
|
|
|
|
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!
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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)
|
|
|
|
|
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
|
|
|
|
|
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).
|
|
|
|
|
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)
|
|
|
|
|
Hello Paul
Your utility is definitely not superflous
Regards
|
|
|
|
|
I always used a side effect of WatchCat <http: vbourdo.cjb.net=""> 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/
|
|
|
|
|
They released an updated version that works in XP as well.
--
Synetech
|
|
|
|
|
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
|
|
|
|
|
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..
|
|
|
|
|