NotfiyIcon Liste
-
Hallo.
Ist es möglich, unter WinXP eine Liste aller NotifyIcons zu bekommen, um diese dann auszublenden o.Ä.?
Hintergrund: Ich möchte das Symbol "Hardware sicher entfernen" KOMPLETT ausblenden. Es nervt mich und ich brauche es nicht.Gruß
-
Du kannst dies doch über die Eigenschaften des Taskbar machen.
Eine API dafür gibt es nicht.
-
Schade

Das Icon dass ich entfernen möchte kann man so nicht entfernen. Man kann es zwar einklappen ("Inaktive Symbole"), aber das nervt immer noch.Egal - damit muss ich dann wohl leben.
Gruß und Danke

-
@Martin Richter:
Die Aussage, dass es dafür keine API gibt, stimmt so nicht.Für dein Vorhaben benötigst benötigst du im Grunde folgende API-Befehle:
- SendMessage
- TB_GETBUTTONINFO
- TB_HIDEBUTTON
Mehr benötigst du dazu nicht.
Hier ein kleines Beispiel in C++ (VCL) gschrieben:
Icons auslesen und in ein Map-Container schreiben.:void __fastcall TF_Hauptformular::vf_Generate_TrayList(HWND hwndTrayNotifyWND,std::map<int,structTrayItemInfo> *mapTrayItems) { //Struct welches die Daten aufnimmt structTrayItemInfo stiiTrayInformations; int iAnzahlItems; //Definition der Variabeln zur Auslesung der Informationen TBBUTTONINFOA tbBtnInfo, *_tbBtnInfo; //Struktur zur Auslesung der Button Informationen char cButtonText[256],*_cButtonText; //Speichert den Text des Buttons //Definition der Processvariabeln NMHDR nmMessageStructure; HANDLE hwProcess; unsigned long ulProcessID; //Auslesen der Anzahl Elemente iAnzahlItems=SendMessage(hwndTrayNotifyWND,TB_BUTTONCOUNT,0,0); //Auslesen der ProcessorID des Fensters (Speicherung in ulProcessID) //Starten eines neuen Prozesses mit lese und schreibrechten //Das Ganze in einer Informationsabfrage GetWindowThreadProcessId(hwndTrayNotifyWND, &ulProcessID); hwProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ| PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, ulProcessID); //Freigabe des Speichers (Buffer) für das Element und den Text _tbBtnInfo=(TBBUTTONINFOA*)VirtualAllocEx(hwProcess, NULL, sizeof(TBBUTTONINFOA), MEM_COMMIT, PAGE_READWRITE); _cButtonText=(char*)VirtualAllocEx(hwProcess, NULL, 256, MEM_COMMIT, PAGE_READWRITE); for (int i = 0; i < iAnzahlItems; i++) { //dwMask (TBIF_COMMAND) -> Ermitteln mittels eindeutigen Identifikator //dwMask (TBIF_TEXT) -> Auslesen des Textes //dwMask (TBIF_STYLE) -> Auslesen des Styles, damit Gruppierbuttons nicht beachtet werden //(pszText) Angabe der Textgrösse; (pszText) Pointer zur Variabel welche den Text aufnimmt //(cbSize) Übergabe der Grösse der Struktur, damit die Informationen abgeholt werden können tbBtnInfo.dwMask=TBIF_COMMAND | TBIF_BYINDEX | TBIF_STATE | TBIF_TEXT; tbBtnInfo.cchText=256; tbBtnInfo.pszText=_cButtonText; tbBtnInfo.cbSize=sizeof(TBBUTTONINFOA); //Freigabe des Buffers, damit die Informationen reingeschrieben werden können WriteProcessMemory(hwProcess, _tbBtnInfo, &tbBtnInfo, sizeof(TBBUTTONINFOA), NULL); //Senden der Informationen, welche gelesen werden sollen SendMessage(hwndTrayNotifyWND, TB_GETBUTTONINFO, (WPARAM)i, (LPARAM)_tbBtnInfo); //Auslesen der Angaben des Textes und der anderen Informationen ReadProcessMemory(hwProcess, _tbBtnInfo, &tbBtnInfo, sizeof(TBBUTTONINFOA), NULL); ReadProcessMemory(hwProcess, _cButtonText, cButtonText, 256, NULL); //Der Button wird nur hinzugefügt, wenn dieser auch sichtbar ist if (static_cast<BOOL>(tbBtnInfo.fsStyle & TBSTATE_HIDDEN)==false) { //Hinzufügen des Eintrags zur Map stiiTrayInformations.~structTrayItemInfo(); stiiTrayInformations.iID=tbBtnInfo.idCommand; stiiTrayInformations.sCaption=static_cast<UnicodeString>(cButtonText); mapTrayItems->insert(std::pair<int,structTrayItemInfo>(stiiTrayInformations.iID,stiiTrayInformations)); } } //Freigeben des Reservierten Speichers VirtualFreeEx(hwProcess, _tbBtnInfo, 0, MEM_RELEASE); VirtualFreeEx(hwProcess, _cButtonText, 0, MEM_RELEASE); } //---------------------------------------------------------------------------Ermitteln des Notify-Handels (Also der Leiste)
HWND __fastcall TF_Hauptformular::Get_Tray_Handle() { HWND hwndReturnValue; //Als erstel wir die komplette Taskleiste ermittels hwndReturnValue=FindWindow("Shell_TrayWnd", NULL); //Anschliessend wird der 2 Bereich gesucht, welcher die Traysymbole beinhaltet hwndReturnValue=FindWindowEx(hwndReturnValue,NULL,"TrayNotifyWnd",NULL); //Nun kann die Leiste mit den Traysymbolen ermittelt werden hwndReturnValue=FindWindowEx(hwndReturnValue,NULL,"Syspager",NULL); //Und nochmals ein unterelement hwndReturnValue=FindWindowEx(hwndReturnValue,NULL,NULL,"Infobereich"); return hwndReturnValue; }Verstecken des Buttons:
void __fastcall srmWindows::ChangeIconVisibility(int iButtonID) { SendMessage(Get_Tray_Handle(), TB_HIDEBUTTON, (WPARAM)iButtonID, (LPARAM)MAKELONG(false, 0)); }Wie du siehst ist sogar dass möglich, da es sich um eine normale Toolbar handelt.
Jetzt müsstest du das Ganze nur noch ein bisschen Umschreiben (wenn du den C++Builder benutzt). Ansonsten sind für andere Programmiersprachen glaube ich noch ein Paar anpassungen mehr notwendig.!!! Wichtig: Der oben gezeigte Sourcecode wurde unter Windows XP und Vista getestet. Ob er noch bei Windows 7 funzt, müsstet du prüfen
!!!Falls es dich interessiert, habe ich dazu noch eine Beispielanwendung zur Verfügung gestellt. Jedoch werden da nicht die Symbole ausgeblendet, sondern dessen Positionen im Tray ermittelt.
http://rrworldfiles.foroomy.com/download/file.php?id=6Edit:
Mit der oben genannten Methode kannst du ebenfalls die Taskleisteneinträge bis Windows Vista auslesen.
-
Genial!
Werde mir das mal anschauen.
Respekt und fettes dankeschön
Für Vista und Seven braucht man sowas nicht, da kann man das Icon ausschalten

Gruß
-
Deforation schrieb:
@Martin Richter:
Die Aussage, dass es dafür keine API gibt, stimmt so nicht.Doch es stimmt. Den Du nimmst undokumentiertes Verhalten als gegeen und kannst damit natürlich nicht sagen ob Dein Code unter Windows 7 noch funktioniert.
Auch wenn Du die API verwendest gibt es keine Befehle, die direkten Zugriff hier auf die Shell erlauben. Aus Deiner Sicht gesehen ist jedermiese Hook natürlich eine Lösung weil er ja selbst wieder die API verwendet.
-
Das mag ja sein.
1. Ich kann nicht sagen, ob es 100%ig unter Windows 7 funktioniert, weil da ja die Taskleiste komplett umgebaut wurde und ich es dort noch nicht getestet habe.
2. Es mag ja ein Eingriff in de fremden Prozess sein, schlussendlich sind es jedoch wieder die API-Commands welche die Auslese ermöglichen (Wie du ja geschrieben hast).
(Was ist daran mies? Es ist immerhin eine Möglichkeit zur Problemlösung. Statt einer Aussage, dass es nicht funktioniert.)
-
Deforation schrieb:
(Was ist daran mies? Es ist immerhin eine Möglichkeit zur Problemlösung. Statt einer Aussage, dass es nicht funktioniert.)
1. Du nimmst einem Programm ein Item weg, dass es erzeugt hat! Weißt Du was in dem LPARAM Wert des Toolbar Items gespeichert war? Wein Zeiger evtl. der freigegeben werden muss?
2. Weißt Du wie die Shell auf einmal reagiert, wen Du Ihr einen Button wegnimms.
Gesetzt den Fall es gibt einen internen Array, dermit den Button Indiezes übereinstimmt! Waspassiert dann?
Was passiert wenn nun über diesen Index zugegriffen wird?Du weißt nicht was das fremde Programm (Shell) mit den Einträgen macht und wie es Sie verwaltet.
In der Annahme: Es geht ja, wird es gut geheißen.Hast Du das mit dem Application-Verifier geprüft, dass die Shell jetzt intern keine Exceptions bekommt?
Ich bleibe dabei: Meines Wissens stellt die Shell an dieser Stelle keine API zur Verfügung. Auch das mag sich geändert haben, alles unter Windows 7 kenne ich auch noch nicht.
Allgemein zu meiner Haltung:
Ich bin an dieser Stelle Purist und es mag sein, dss meine Haltung hier evtl. extrem ist. Für mich ist eine Lösung noch lange keine Lösung "weil es funktioniert".
Schau doch selbst wieviel "Schrottcode" wird in diesen Foren (alleine hier) als Lösung propagiert?
Und der nächste "minderbemittelte Entwickler" kopiert den Mist, weil es ja im Internet stehtund funktioniert.Ich bin allergisch gegen alles was Read/WritePorcessMemory benutzt.
Ich bin allergisch wenn Fenster manipuliert werden, die man selber nicht erzeugt hat und deren Verwednung und Nutzung mam nicht kennt.
-
Ja. Da kann ich muss sagen, da kann ich dir wirklich nicht wiedersprechen.
Aber ich denke dass man auch zeigen sollte, dass es einen Lösungsansatz gibt. Auch wenn es nicht der optimale Weg ist. Wie und ob man ihn dann einsetzt, sollte jedem einzelnen überlassen werden. Denn ich will ja schwer hoffen, dass man einen Sourcecode bevor man ihn blind links kopiert mindestens einmal betrachtet und versucht zu versehen, was dieser überhaupt macht und was dort passiert.
Aber naja, ich schweiffe wohl gerade vom Thema ab.
