własny tray - WinAPI

0

Może już ktoś kiedyś próbował stworzyć swój własny tray na oknie, ciężko coś znaleźć na ten temat na sieci, już nie mówiąc o polskich stronach(pustka na ten temat).

Chodzi mi po prostu, o pobranie i umieszczenie na swoim oknie ikon taskbara, tak jak to robi explorer, oraz obsłużenie ich

za każdy pomocny link z góry dziękuję

0

tu odpowiedz (na tej samej stronie co ten watek)
http://4programmers.net/Forum/viewtopic.php?id=113603
(jest co prawda w delphi no ale z jezykami to jak z mlotkiem: gwozdz da sie wbic i murarskim i ciesielskim). Przepisanie tego to raczej dlubanina na wieczory i dlatego malo jest w sieci bo i malo przydatne.

ps. ostatnio toczyla sie dysputa na temat poziomu, kiedys taki watek polecial by do kosza ...

0

Bóg zapłać Reichel,
co do Delphi, to powierzchownie język znam(choć się go nie uczyłem, jakoś samo przyszło ;) )
2 pytania:
czym się różni

[code]
type
ITrayIcon = interface (IBasic) ['{4BFE6700-C522-11D3-A530-00005A180D69}'];
ITrayIcons = interface (ICustomBasicList) ['{4BFE6701-C522-11D3-A530-00005A180D69}'];
[/code]

type to deklaracja typu struktury/klasy ITrayIcons na podstawie IBasic?, bo tego nie znam

oraz czym różni się property do function?

0

property to taka udawana zmienna, tzn możemy czytać i pisać (lub tylko czytać) jak zmienną. No a funkcję (czy raczej metodę, czyli funkcję związaną z pewnym obiektem) się wywołuje (stawiasz nazwias za jej nazwą), z opcjonalnymi parametrami. Jeśli brak parametrów to mamy procedurę i wywołuje się ją bez nawiasów.

0

a co z tym?

type
  ITrayIcon  = interface (IBasic)           ['{4BFE6700-C522-11D3-A530-00005A180D69}'];
  ITrayIcons = interface (ICustomBasicList) ['{4BFE6701-C522-11D3-A530-00005A180D69}'];

ITrayIcon = interface (IBasic) - ? ITrayIcon i IBasic to struktury/klasy, jak po takim zapisie ma się jedno do drugiego?

0
crayze napisał(a)

a co z tym?

type
  ITrayIcon  = interface (IBasic)           ['{4BFE6700-C522-11D3-A530-00005A180D69}'];
  ITrayIcons = interface (ICustomBasicList) ['{4BFE6701-C522-11D3-A530-00005A180D69}'];

ITrayIcon = interface (IBasic) - ? ITrayIcon i IBasic to struktury/klasy, jak po takim zapisie ma się jedno do drugiego?
Dokładniej interface'y czyli takie specjalne klasy posiadające jedynie czyste metody wirtualne, czyli po prostu zestaw metod bez zdefiniowanego ciała. Mając obiekt z jakimś interfejsem możemy używać tych metod, bez względu na to jak je ktoś zaimplementował. Zresztą co się będę rozpisywał, poczytaj o interfejsach jak cię to interesuje. Na sieci sporo jest materiałów.

type to deklaracja typu struktury/klasy ITrayIcons na podstawie IBasic?
mniej więcej tak. W tym przypadku działa to jak typedef w C(++).

0

http://help.madshi.net/TrayIcons.htm
Przeczytałem te treści...
Koleś tutaj przedstawia swoją szaloną bibliotekę :) jest tam opis funkcji tej biblioteki, które operują na trayu, ale niestety nie dopatrzyłem sie kodu tych funkcji, same prezentacje funkcji :( Nie chcę uzywać jego klas(szczególnie że są w innym języku ;) ), ale wolę sam napisać obsługe traya poprzez bezpośrednie wywołania funkcji windosowych...

To teraz z innej beczki, nie wie przypadkiem ktoś w której bibliotece lib siedzi struktura IID_IOleCommandTarget, która jest zdefiniowana w docobj.h, bo w libole32.a jej nie ma, na necie nie mogę znleźć, a sprawdziłem kilka podobny nazwowo bibliotek, dołączając je ale to jak szukanie igły w snopie siana

0

co do interfejsu to yu napisane gdzie jest (a IID mozna znalezc przeszukujac pliki *.h)
http://msdn2.microsoft.com/en-us/library/ms683797.aspx

Co do ikonek w trayu to do obslugi nie ma gotowych funkcji, trzeba pisac samemu (bedzie to polegac na przechwyceniu funkcji dodajacych ikone do traya, aby poznac jaka aplikacja to robi, oraz zlapaniu uchwytu do traya i wylistowaniu ikonek - to zwykla klasa Toolbar32).

Jak wspomnialaem na dlugie wieczory ....

0

z tego co do tej pory ustaliłem to klasa tollbara traya powinna nazywać się "Shell_TrayWnd", a jakieś okno potomne na nim, pewnie z ikoną dla pojedynczej aplikacji powinno nazywać się "TrayNotifyWnd", nie wiem czy to ktoś wymyslił, czy po prostu funkcja NotifyShell(ta od dodawania ikon do zasobniaka) wysyła komunikat właśnie do procedury klasy o tej nazwie, spotkałem te nazwy w dwóch niezależnych przykładach, więc przypuszczam, że tak powinno być...

w każdym razie jeszcze trzeba zarejestrować okno jako okno shellowe i co do tego też nie wiem jak, w róznych przykładach jest inaczej, na jakiejś ruskiej stronie i jeszcze innej znalazłem funkcję RegisterShellHookWindow, w innym przykładzie jest to zrobione jeszcze jakoś inaczej, właśnie przy pomocy obiektów COM(dlatego pytałem sie o tą strukturę)

Jest jeszcze kwestia magicznego DWORD:
SetWindowLong (m_hMainWindow, GWL_USERDATA, magicDWord);
jakaś wartość w którą trzeba wyposażyć okno, właście to też do końca nie wiem po co

Jest jeszcze rejestracja komunikatu "SHELLHOOK"
WM_SHEELHOCK=RegisterWindowMessage("SHEELHOOK");
być może to ten którym transportowane są wiadomości do traya, jeszcze kwestia obsłużenia go, co oznaczają parametry, jak taki komunikat obsłużyć?

trochę zbyt dużo niewiadomych, aby zrobić ten tray, ale coż, reszta powłoki pójdzie jak z płatka, może za pare miesięcy dojdę z tym trayem ;)

0

IID_IOleCommandTarget i większość IID jest w uuid.lib lub libuuid.a.

0
crayze napisał(a)

ciężko coś znaleźć na ten temat na sieci, już nie mówiąc o polskich stronach(pustka na ten temat).

http://darkcult.gamedev.pl/kursy/apitray.html

Moze to ci pomoze. Daj znac czy o to chodzilo ;)

0
sapero napisał(a)

IID_IOleCommandTarget i większość IID jest w uuid.lib lub libuuid.a.

O to właśnie chodziło, dzięki sapero

Tutaj znalazłem dość pomocny kod źródłowy, dość ciekawej powłoki...
http://xoblite.net/source/TrayManager.cpp.html

Może coś z tego będzie :)

Mendoza napisał(a)
crayze napisał(a)

ciężko coś znaleźć na ten temat na sieci, już nie mówiąc o polskich stronach(pustka na ten temat).

http://darkcult.gamedev.pl/kursy/apitray.html

Moze to ci pomoze. Daj znac czy o to chodzilo ;)

Nie o to, tutaj jest o dodawaniu ikonki do traya i jej obsługi, ja chcę napisać program, który zastąpi traya z explorera, tzn. będzie wyświetlał te ikony w trayu,
na stronie, którą podałeś są doskonale omówione komunikaty, które powinien odbierać i wysyłać program, mający ikonę w trayu, to m sie przyda, bo te komunikaty, które są tam opisane, mają trafiać właśnie do mojego programu...

0

http://xoblite.net/source/TrayManager.cpp.html
Więcej ciekawostek znajdziesz szukając "enumerating tray icons"

0

Po zapoznaniu się z dotychczas zebranymi materiałami, uznaję, że już wiem jak obsługiwać traya, czyli nic innego jak obsługiwać komunikaty wysyłane przez programy do traya (docelowo mojego okna), a także wysyłać je w przypadku wykonania akcji na ikonie...

Oczywiście zakładając, że takie komunikaty będę odbierał, bo zostaje juz tylko problem przekierowania komunikatów do mojego okna, tzn. ostatnim problemem jest skierowanie komuniaktów Shell_Notify() do mojej procedury,
myślałem o Hooku, ktory bedzie przechwycal komuniakty, jeszcze nie miałem potrzeby używać hooka, ale teoretycznie wiem do czego służy :) da radę coś takiego zrobić?

http://www.cs.kent.edu/~kschaffe/sdn/articles/systray.html

Chyba jedyna strona w necie, w której jest wyjaśnione działanie traya....

Nie wiem czy wszystkoe dobrze rozumiem więc się spytam:

w podpunkcie "Informing Applications that the System Tray is Ready", powiadamiam inne aplikacje, ale nie wiem czy to o to chodzi, robię tak:

UINT WM_TSKBRCRT=RegisterWindowMessage("TaskbarCreated");
EnumWindows(EnumWindowsProc,0);

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM)
{
  if(!hwnd) return 0;
  else
  {
    SendMessage(hwnd,WM_TSKBRCRT,0,0);
    return 1;
  }
}

I jeszcze jak załadować obiekty o których mowa w dziale "Windows 2000/XP"

0

Zamiast SendMessage uzyj PostMessage lub SendMessageTimeout.
W EnumWindowsProc nie licz na to, że hwnd będzie zerem.

#define UNICODE
#include <objbase.h>
#include <docobj.h>
#include <shlguid.h>
#include <wchar.h>


int main()
{
	CPointerList *objects;

	CoInitialize(0);
	if (LoadShellTrayObjects(&objects))
	{
		MessageBoxW(0, L"press OK to free", 0, 0);
		FreeShellTrayObjects(objects);
	}
	CoUninitialize();
	return 0;
}

void FreeShellTrayObjects(CPointerList *objects)
{
	if (objects)
	{
		void *pos = objects->GetFirst();
		while (pos)
		{
			IOleCommandTarget *cmd = objects->GetData(pos);
			cmd->Exec(CGID_ShellServiceObject, 3, 0, NULL, NULL);
			cmd->Release();
			pos = objects->GetNext(pos);
		}
		objects->RemoveAll(false);
		delete objects;
	}
}


int LoadShellTrayObjects(CPointerList **ppv)
{
	CPointerList *objects = new CPointerList;

	int count = 0;
	HKEY hk;
	if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad", 0, KEY_READ, &hk))
	{
		DWORD values;
		if (!RegQueryInfoKey(hk, 0,0,0,0,0,0,&values,0,0,0,0))
		{
			for (DWORD index=0; index<values; index++)
			{
				WCHAR wszText[256];
				WCHAR wszClsid[42];
				DWORD cch1 = 256*2, cch2 = 42*2, type;
				if (!RegEnumValue(hk, index, wszText, &cch1, 0, &type, wszClsid, &cch2) && (type=REG_SZ) && (cch2 > (37*2)))
				{
					wszClsid[cch2/2] = 0;
					CLSID _cls;
					if (!CLSIDFromString(wszClsid, &_cls))
					{
						IOleCommandTarget *pcmd;
						if (!CoCreateInstance(&_cls, 0, CLSCTX_INPROC_SERVER, IID_IOleCommandTarget, (void**)&pcmd))
						{
							if (!pcmd->Exec(CGID_ShellServiceObject, 2, 0, NULL, NULL))
							{
								objects->Add(pcmd);
								count++;
							}
							else
								pcmd->Release();
						}
					}
				}
			}
		}
		RegCloseKey(hk);
	}
	if (!count) delete objects;
	*ppv = objects;
	return count;
}
0

wszystko fajno, tylko skąd mam wziąć CPointerList??
'CPointerList' undeclared (first use this function)

0

CPointerList to tylko kontener. Użyj czego chcesz np 'list<IOleCommandTarget*>' z stl'a.

0

Ech nadal ten tray coś nie chce wysyłać do mnie komunikatów, według informacji z różnych źródeł, mdzn z tego: http://www.cs.kent.edu/~kschaffe/sdn/articles/systray.html

Komunikaty wysyłane funkcją Shell_NotifyIcon(), mają trafiać do okna utworzonego z klasy o nazwie "Shell_TrayWnd", bo jest to klasa okna explorera i tutaj moje spostrzeżenie:

Rejestrując swoją klasę okna "Shell_TrayWnd" pod explolerem, powinien wystąpić błąd skoro explorer już używa takiej klasy, raczej nie może być dwóch klas okien o takich samych nazwach, rejestracja mojej klasy "Shell_TrayWnd" kończy sie pomyślnie, co by oznaczało, że explorer takiej klasy nie ma, wniosek taki, że okno traya w WinXP wcale nie wywodzi się z klasy o nazwie "Shell_TrayWnd", więc nie będą tam trafiać komunikaty, tylko dlaczego we wszystkich źródłach podają, że to "Shell_TrayWnd", czyżby panowie z MS w explorerze WinXP zmienili nazwę klasy traya, idzie jakoś sprawdzić nazwę klasy okna traya????

0

No bo jeśli twoja klasa nie jest globalna (CS_GLOBAL) lub klasa Shell_TrayWnd explorera jest lokalna to są to dwie różne klasy. Zresztą w mom mniemaniu powinieneś założyć message-hook na explorera i wyłapywać wszystkie komunikaty pędzące do okna tray'a. Nie wiem na pewno (powinieneś to wyjaśnić), ale wydaje mi się że wszystkie komunikaty które mają trafić do tray'a są wysyłane prosto do procesu explorera.

//edit
Sprawdziłem. Shell_TrayWnd to klasa okna którym jest cały dolny pasek zawierający tray'a, przycisk "start" itd. Nie jest to klasa globalna.

Klasa okna tray'a to TrayNotifyWnd. Również nie jest globalna.

//edit again
doczytałem w linku jaki podałeś

here is actually no magic in the Shell_NotifyIcon function. All it does is package its parameters into a WM_COPYDATA message which it sends to the shell. Specifically it locates a top-level window whose class name is "Shell_TrayWnd"; this is the taskbar window when Explorer is the shell. An alternate shell can intercept all system tray requests by simply creating its own "Shell_TrayWnd" window and catching the WM_COPYDATA messages

Z tego wynika, że okno twojej klasy Shell_TrayWnd musi być top level. I musi się znajdować nad oknem Shell_TrayWnd explorera w z-order, lub nawet Shell_TrayWnd explorera musi być zamknięte.

0
#define UNICODE
#include <windows.h>
#include <objbase.h>
#include <docobj.h>
#include <shlguid.h>
#include <wchar.h>
#include <list>
#include <vector>

UINT WM_TSKBRCRT;

using namespace std;

LRESULT CALLBACK WndProc1(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);

INT WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,INT nShow)
{
  MSG msgs;
  WNDCLASSEX wc;
  ZeroMemory(&wc,sizeof(WNDCLASSEX));
  wc.lpfnWndProc=WndProc1;
  wc.hInstance=GetModuleHandle(0);
  wc.lpszClassName=L"Shell_TrayWnd";
  wc.cbSize=sizeof(WNDCLASSEX);
  if(!RegisterClassEx(&wc)) return 0;
  HWND VirtualTrayWnd=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,L"Shell_TrayWnd",0,WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,0,0,NULL,NULL,GetModuleHandle(0),NULL);
  if(!VirtualTrayWnd) return 0;
  //----------------------------------------------------------------------------
  wc.lpszClassName=L"TrayNotifyWnd";
  if(!RegisterClassEx(&wc)) return 0;
  HWND VirtualNotifyWnd=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,L"Shell_TrayWnd",0,WS_CHILD,0,0,0,0,VirtualTrayWnd,NULL,GetModuleHandle(0),NULL);
  //============================================================================
  WM_TSKBRCRT=RegisterWindowMessage(L"TaskbarCreated");
  EnumWindows(EnumWindowsProc,0);
  //============================================================================
  CoInitialize(0);
  list<IOleCommandTarget*> objects;
  int count = 0;
  HKEY hk;
  if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad",0,KEY_READ,&hk))
  {
    DWORD values;
    if (!RegQueryInfoKey(hk,0,0,0,0,0,0,&values,0,0,0,0))
    {
      for (DWORD index=0;index<values;index++)
      {
        WCHAR wszText[256];
        WCHAR wszClsid[42];
        DWORD cch1=256*2,cch2=42*2,type;
        if (!RegEnumValue(hk,index,wszText,&cch1,0,&type,(BYTE*)wszClsid,&cch2)&&(type=REG_SZ)&&(cch2>(37*2)))
        {
          wszClsid[cch2/2]=0;
          CLSID _cls;
          if (!CLSIDFromString(wszClsid, &_cls))
          {
            IOleCommandTarget *pcmd;
            if (!CoCreateInstance(_cls,0,CLSCTX_INPROC_SERVER,IID_IOleCommandTarget,(void**)&pcmd))
            {
              if (!pcmd->Exec(&CGID_ShellServiceObject, (DWORD)2,(DWORD) 0, NULL, NULL))
              {
                objects.push_back(pcmd);
                count++;
              }
              else pcmd->Release();
            }
          }
        }
      }
    }
    RegCloseKey(hk);
  }
  while(GetMessage(&msgs,0,0,00))
  {
    TranslateMessage(&msgs);
    DispatchMessage(&msgs);
  }
  CoUninitialize();
  return msgs.wParam;
}

LRESULT CALLBACK WndProc1(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar)
{
  switch(msg)
  {
    case WM_COPYDATA:
      //----------------------------------------------------------
      MessageBox(0,L"O lol dziala",0,0);
      //----------------------------------------------------------
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hwnd,msg,wPar,lPar);
  }
  return 0;
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM)
{
  PostMessage(hwnd,WM_TSKBRCRT,0,0);
  return 1;
}

Q: nie < code> tylko < cpp> !

O lol, chyba działa, ot co na razie takie testowe wyskrobałem, komunikat WM_COPYDATA działa....
No to chyba moge sie brać za obróbkę komunikatów, dzięki wszystkim za pomoc, ale to zapewne nie koniec moich kłopotów z trayem.
Co do Hooka to wolałbym bez, hook będzie deczko spowalniał przepływ komunikatów, jeżeli uda się bez to spróbuję zrobić bez hooka...

0

Żeby nie zakładać oddzielnego wątku....
Sprawa tyczy się maksymalizacji okien, mam pasek, jako okno WS_EX_TOPMOST, teraz chcę, aby było ono jak pasek explorera, obszar maksymalizacji go nie obejmował, po prostu chcę ograniczyć obszar zmaksymalizowanego okna,
coś mi się obiło o uszy, że takie rzeczy można zrobić przez SetWindowPlacement(), jeżeli tak dla każdego okna musiałbym oddzielnie wywoływać funkcję, czy można to zrobić globalnie dla wszystkich okien?

0

SystemParametersInfo z flagą SPI_SETWORKAREA - pvParam=RECT*

0

wielkie dzięki sapero o to chodziło,

następny problem, a tyczy się on ikon, mam uchwyt do ikony traya i teraz przydało by się ją narysować, a żeby ją narysować musi być bitmapą, chodzi <ort>po prostu</ort> o konwersję z ikony do bitmapy

0

Nie musi, DrawIcon{Ex} akceptuje uchwyt ikonki. Ale jeśli już chcesz bitmapy, to GetIconInfo(hicon,ICONINFO*) tworzy i zwraca dwie bitmapy - kolorową i maskę. Pamiętaj by obie usunąć po użyciu.

0

Jakaś imitacja traya już jest ;-P na razie w mocno okrojonej funkcjonalności bo ikonki się tylko wyświetlają, ale sukces że aplikacja juz obsługuje traya....

Oto co do tej pory zdzialalem:
http://lublin.webd.pl/crayze/tray.rar

Jedno z okienek to log komunikatów jakie dostaje tray, swoją drogą niezły syf, jak to bywa w windowsie :-D teraz muszę jeszcze doszlifować obróbkę komunikatów, nie wiem dlaczego niektóre z ikonek sie nie pojawiaja, lub pojawiaja sie na chwile skoro w logu są poprawne komunikaty, a DrawIconEx zwraca 1 :-( czyzby to taka ikonka ze nic na niej nie ma?

Objaśnienia logów:

Command: (rodzaj komunikatu, add, mod lub del), pierwszy parametr NotifyIcon()
Titl: Tytuł okna z którego pochodzi komunikat, pobrane GetWindowText()
From: uchwyt okna(właściciela komunikatu), hWnd z NOTIFYICON
ID: numer ID komunikatu, uID z NOTIFYICON
CLBKMG: komunikat zwrotny, uCallbackMessage z NOTIFYICON
ICON: uchwyt ikony, hIcon z NOTIFYICON
Table: ilość elementów w trayu

Wymagania: na Win98 i starszym nie odpali, z kilku powodów, głównie z tego powodu: SetLayeredWindowAttributes(BarWnd,0,trans,LWA_ALPHA); na viście chyba działa</ort>

No to odświeżamy :D
Pytanie brzmi, jakie warunki muszą być spełnione, żeby okno się nie pokazywało na pasku zadań explorera, pierwszy to styl WS_EX_TOOLWINDOW, drugi to WS_DISABLED i nic więcej nie przychodzi mi do głowy, a muszą być jeszcze jakieś, bo zbyt dużo okien się pokazuje, które się nie powinny pokazywać...

0

Hm... np. Blackbox /a raczej jego taskbary/ ma problem z oknami MDI, mdi child window jest wyświetlane na taskbarze jako oddzielne okno. Zajmij się wykrywaniem okien MDI, powinno być już dobrze.

0
deus napisał(a)

Hm... np. Blackbox /a raczej jego taskbary/ ma problem z oknami MDI, mdi child window jest wyświetlane na taskbarze jako oddzielne okno. Zajmij się wykrywaniem okien MDI, powinno być już dobrze.

Nie pomaga, jest jeszcze kwestia traktowania okna jeżeli nie ma ikony (wc.hIcon==0) czy go nie wyświetlać czy dać mu domyślną ikonę, explorer chyba je wyświetla, chyba znowu będę musiał zajrzeć do kodu BlackBoxa skoro tam jest to zrobione

void WndsClass::RefreshWnds(HWND hwnd)
{
  //WS_EX_TOOLWINDOW
  LONG ExStyle=GetWindowLong(hwnd,GWL_EXSTYLE);
  if(ExStyle&WS_EX_TOOLWINDOW) return;
  //WS_DISABLED
  ExStyle=GetWindowLong(hwnd,GWL_STYLE);
  if(ExStyle&WS_DISABLED) return;
  //Okno rodzica(tylko potomne do pulpitu lub 0, eliminacja okien MDI)
  ExStyle=GetWindowLong(hwnd,GWL_HWNDPARENT);
  if(ExStyle!=(LONG)GetDesktopWindow()&&ExStyle!=0) return;
  WCHAR WndText[256];
  for(UINT i=0;i<Wnds.size();i++) if(Wnds[i].hwnd==hwnd)//szukanie okna w istniejących
  {
    Wnds[i].Checked=1;
    GetWindowText(hwnd,WndText,256);
    for(UINT a=0;Wnds[i].szText[a]!='\0';a++) if(Wnds[i].szText[a]!=WndText[a])
    {
      Change=1;
      UINT b=0;
      while(WndText[b]!='\0')
      {
        if(b==255) break;
        Wnds[i].szText[b]=WndText[b];
        b++;
      }
      Wnds[i].szText[b]='\0';
      return;
    }
    return;
  }
  //dodawanie okna
  WndStruct Wnd;
  Wnd.hwnd=hwnd;
  GetWindowText(hwnd,WndText,256);
  UINT b=0;
  while(WndText[b]!='\0')
  {
    if(b==255) break;
    Wnd.szText[b]=WndText[b];
    b++;
  }
  Wnd.szText[b]='\0';
  HICON Icon=(HICON)GetClassLong(hwnd,GCL_HICON);
  
  //tutaj także nie wiem jak to potrakotwać, jeżeli okno nie ma swojej ikony, explorer chyba je wyświetla
  if(Icon) Wnd.hIcon=Icon;
  //else return;//jeżeli nie ma ikony to nie wyświetlamy okna
  else Wnd.hIcon=CButtons->DefIcon;//jeżeli nie ma ikony to przypisujemy mu domyślną ikonę w powłoce
  
  
  Wnd.Checked=1;
  Change=1;
  Wnds.push_back(Wnd);
}

Problem jednak tkwi w schowanym oknie(SW_HIDE), bo właśnie takie się pokazują, a nie powinny, nie działa sprawdzenie bitu WS_DISABLED z GetWindowLong, ani IsWindowEnabled() :-/

IsWindowVisible pomogło, już jest dobrze

Kolejny problem, tyczy się minimalizacji, gdy zamkniemy explorer'a okna minimalizowane są do belki w lewym dolnym rogu, może ktoś się zetknął z czymś takim i może coś na to zaradzić [???]

chodzi o coś takiego:
http://img261.imageshack.us/img261/6247/scrfi8.jpg</img>

Z braku odpowiedzi mam rozumieć że nie wiadomo jak schować te belki zminimalizowanych okien...

Ja rozkminiłem coś takiego:
Hook, przechwytuje wszystkie WM_MINIMIZED, i tam wykonuje pewne operacje, mam 2 warianty:

w1: minimalizacja polega na przesunięciu okna poza obszar ekranu, wtedy okna nie widać, natomiast cały czas jest VISIBLE więc widać go na pasku, wadą tego wariantu jest to, że funkcje IsIconic nie będą działały bo okno teoretycznie cały czas jest wyświetlane(nigdy zminimalizowane), chyba, żeby ręcznie oznaczyć okno jako zminimalizowane...

w2: minimalizacja polega na nadaniu statusu SW_HIDE i zapiasaniu w strukturze mojego programu, że to okno jest zminimalizowane i żeby pomimo SW_HIDE wyświetlać go na pasku, nie wiem jak zachowuje się funkcja IsIconic przy oknie SW_HIDE, ale pewnie zwraca true, bo okno wyświetlane nie jest....

który sposób lepszy, albo coś prostszego może ktoś zna [???]

0

To już nie tray a taskbar, do tego jest oddzielny interface.
Popatrz jak to zrealizowano w alternatywych powłokach - LiteStep czy Blackbox.

0
deus napisał(a)

To już nie tray a taskbar, do tego jest oddzielny interface.

Wątek już dawno nie dotyczy traya, tray już dawno opanowany :-)

deus napisał(a)

Popatrz jak to zrealizowano w alternatywych powłokach - LiteStep czy Blackbox.

Przejrzałem BlackBox'a i przy akcji minimalizacji znalazłem takie coś:

...
Window = WindowList[mousex].Window;
ShowWindow(Window, SW_MINIMIZE);
SendMessage(hBlackboxWnd, BB_WINDOWMINIMIZE, 0, (LPARAM)Window);

Odpowiedzią na moje pytanie prawdopodobnie jest obsługa tego komunikatu BB_WINDOWMINIMIZE, czyli po zminimalizowaniu rzeczywiście powłoka zajmuje się tym, żeby schować tą belkę, niestety przeszukałem resztę opublikowanych plików źródłowych z http://xoblite.net/source/ i w żadnym z nich nie znalazłem obsługi tego komunikatu, czyżby nie opublikowali wszystkiego?

0

Microsoft stworzył funkcję RegisterShellHookWindow (user32.dll), jednak odradza jej używania bo w przyszłości ją usunie. Jej użycie powoduje że wybrane okno otrzymuje różnorakie powiadomienia dotyczące m.in. akcji na oknach. Mechanizm jest tu podobny do shellowego hooka WH_SHELL.
Zobacz też co oferuje SetWinEventHook. A nóż widelec.
W SDK pisze też, że aplikacja powinna wywołać SystemParametersInfo(SPI_SETMINIMIZEDMETRICS) zanim zainstaluje shellowego hooka.

Sets the metrics associated with minimized windows

Posiadasz spy++ lub Spy Window? Zerkij, co się dzieje z oknem po minimalizacji. W XP zmienia się tylko jego rozmiar do 0*0. I zacznij czytać! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1