Aqua-Soft Forums: Stacks Library - Aqua-Soft Forums

Jump to content

  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

Stacks Library Rate Topic: ***** 1 Votes

#1 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 01 February 2009 - 02:14 PM

Edit

http://www.matiasmor...b-prebeta-5.rar

StackLib-prebeta-5.rar (@File2Go)

StackLib-prebeta-4.rar (@File2Go)

http://www.matiasmor...b-prebeta-3.rar

This one comes with:

* Some suggestions from Smaky in the .h file.
* New settings structure for compatibility with future .dll versions.
* Fan.
* Grid.
* An attempt to make .h and .lib files for C/C++ developers (untested).


Posted Image

OMG it's 4 a.m.! And I'm supposed to get up at 6 a.m. to go to work.

Ok... this will be fast:

http://www.matiasmor...b-prebeta-2.rar

It is complete with fan and grid modes, and a Demo project for Delphi.

If anyone feels free to do a port of unitStackLib.pas to C/C++ please contact me.

Posted Image

I publish this into Developer's Hangout, as it is intended for developers.

I'm about to publish a pre-beta version of the stacks library.

Do you remember Stacks Docklet? I'm rewriting it from scratch. Part of this process includes writing first a .dll for any coder to use (as long as for private use or with my authorization) (you'll probably be authorized is your app/docklet/widget/whatever is freeware or similar).

I'll be publishing it this night, because I have some important stuff to do now.

The pre-beta version of the library I'm about to publish will have support only for Fan mode, popping upwards (Grid mode and other stuff to come later).

Here is a preview without examples yet:

http://www.matiasmor...b-prebeta-1.rar

It doesn't have a .h and (.def? .lib? .a?) files for C coders yet, tough I'll eventually add it, with an example too.

Also it is missing some functionality I want to add yet.

Posted Image

Edit

I'm almost done with the library.

I can't finish it just now because I'm rushing to a friend's birthday.

I'll publish the library later this night or tomorrow.

0

#2 User is offline   Smaky Icon

  • Group: Member
  • Posts: 585
  • Joined: 19-April 08

Posted 07 February 2009 - 02:46 AM

Right now I do not have much spare time to spend on porting it to C++... but surely I will try.
0

#3 User is offline   PoulNyrup Icon

  • Group: Member
  • Posts: 107
  • Joined: 09-November 07

Posted 08 February 2009 - 02:22 PM

Pardon my ignorance dude, but is this meant as a docklet for docks just like the Stacks Docklet, or...?
0

#4 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 08 February 2009 - 09:36 PM

PoulNyrup;523218 said:

Pardon my ignorance dude, but is this meant as a docklet for docks just like the Stacks Docklet, or...?


It is meant for developers, to use it in their own applications.

I've completely stopped development of Stacks Docklet, and I've recently begun to write Stacks Docklet 2.0 based on this library. ;)
0

#5 User is offline   PoulNyrup Icon

  • Group: Member
  • Posts: 107
  • Joined: 09-November 07

Posted 09 February 2009 - 11:00 PM

Ahhh... ok... Good luck with 2.0 dude... :)
0

#6 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 12 March 2009 - 12:34 PM

Thanks for upgrading the sdk, i'm working on it for StandaloneStack...

the .h is good.
i don't use the .lib , i do a dynamic call.


A request for the futur:

in the structure ( fan_settings, grid_settings,....) add a field BYTE reserved[1000] at the end.
So, when you add some fields in the next version (like in beta4), you do it at the end ( and change the size reserved[1000] to reserved[996] for ex. ) then the next dll will be compatible with the caller without recompile ( as i do a dynamic call of the dll, i could upgrade to the next version without recompile )
of course you need to manage default value of the fields because all the bytes of reserved will be set to 0, so you will have 0 in the new field ( if the caller use an old version of the structure ).



And if you have a code sample for using IShellFolder... :rolleyes:

Good job !

This post has been edited by ChristianS: 12 March 2009 - 12:50 PM

0

#7 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 12 March 2009 - 03:55 PM

Ok, so...

Code sample for using IShellFolder... I used VFolder something or etc... from Delphi "Cool Demos" folder... or something else (my job peer is testing an alarm and I can't think with all this noise hahaha).

I'll find it at home... anyway the demo was recommended to me by someone else in this same forum... can't remember where and... f...ck...ng alarm noise, ok I promise I'll write you here when back home.

BTW I wont add a 1000 reserved byte array, there is a better way: a size member at the beginning of the structure ;) (like windows.h cbSize ones) so you just would need this instead (for example):

fan_settings_t settings;
bzero (&settings, sizeof(settings));
settings.size = sizeof(settings);
...


Delphi coders:

var
	settings: TFanSettings;
begin
	FillChar (settings, sizeof(settings), 0);
	settings.size = sizeof(settings);
	...


Thanks for suggestions, and... alarm sound is driving me crazy... need to move to another room... bye.

PS: you just fill in size member and my library would take care of the rest, with future version it will use default values for missing stuff... etc... this makes coding the library more complicated but as it is destinated to other codes I'll just do it. :)
0

#8 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 12 March 2009 - 09:15 PM

ok, good.

i've found a good example of ishellfolder ( in c++ ):

http://netez.com/2xE...as_xplore2.html

and even to extract icons :

http://netez.com/2xE.../bas_infos.html


so that's ok for me.

thanks.
0

#9 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 14 March 2009 - 08:56 PM

Well, with this example i can't get beautiful icons... how do you extract the icons !?
mine are so ugly :(
0

#10 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 15 March 2009 - 05:12 PM

ok found a way to take big icon :

	  #include <shlobj.h> 
	  #include <shlguid.h> 
	  #include <shellapi.h> 
	  #include <commctrl.h> 
	  #include <commoncontrols.h> 

	  // Get the icon index using SHGetFileInfo 
	 SHFILEINFOW sfi = {0}; 
	 SHGetFileInfo(filePath, -1, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX); 
	 // Retrieve the system image list. 
	 // To get the 48x48 icons, use SHIL_EXTRALARGE 
	 // To get the 256x256 icons (Vista only), use SHIL_JUMBO 
	  HIMAGELIST* imageList; 
	 HRESULT hResult = SHGetImageList(SHIL_EXTRALARGE, IID_IImageList, (void**)&imageList); 

	  if (hResult == S_OK) { 
		// Get the icon we need from the list. Note that the HIMAGELIST we retrieved 
		// earlier needs to be casted to the IImageList interface before use. 
		HICON hIcon; 
	   hResult = ((IImageList*)imageList)->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hIcon); 

	   if (hResult == S_OK) { 
		 // Do something with the icon here. 
		 // For example, in wxWidgets: 
		 wxIcon* icon = new wxIcon(); 
		 icon->SetHICON((WXHICON)hIcon); 
		 icon->SetSize(48, 48); 
		} 
	  }


http://pogopixels.com/blog/getting-the-48x...ile-on-windows/
0

#11 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 15 March 2009 - 08:53 PM

well, :wacko: my icons are bigger now but i have a black shadow in the grid for some icons.
i use the gdi+ Bitmap::FromHIcon(hIcon from previous source) to get a bitmap and extract the bytes for the stack, but it seems that the alpha channel is missing from the imagelist....
do you have some trick for me ?
0

#12 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 15 March 2009 - 09:15 PM

View PostChristianS, on Mar 15th 2009, 05:53 PM, said:

well, :wacko: my icons are bigger now but i have a black shadow in the grid for some icons.
i use the gdi+ Bitmap::FromHIcon(hIcon from previous source) to get a bitmap and extract the bytes for the stack, but it seems that the alpha channel is missing from the imagelist....
do you have some trick for me ?


Gdiplus really sucks at this. It looses the alpha channel :( so you have to do it by hand.

If icon is 32 bits, I get direct access to pixel bits instead:

function TIconProvider.GetAssociatedIcon(filename: WideString): TGpImage;
var
  hi : HICON;
  ii : TIconInfo;
  bi : TBitmapInfo;
  pixels : PByteArray;
  buffer : array[0..MAX_PATH] of widechar;
  name_part : PWideChar;
begin
  // Primero determinar la ruta absoluta, parece que Windows no se lleva con las relativas acá
  GetFullPathNameW (PWideChar(filename), MAX_PATH, buffer, name_part);
  filename := buffer;

  // Buscar el icono asociado
  hi := unitGetIcon.GetAssociatedIcon (filename);

  Result := nil;
  If GetIconInfo (hi, ii) Then
  begin
	FillChar (bi.bmiHeader, sizeof(bi.bmiHeader), 0);
	bi.bmiHeader.biSize := sizeof(bi.bmiHeader);
	If GetDIBits (fDC, ii.hbmColor, 0, 0, nil, bi, 0) <> 0 Then
	begin
	  If bi.bmiHeader.biBitCount = 32 Then
	  begin
		GetMem (pixels, bi.bmiHeader.biWidth*bi.bmiHeader.biHeight*4);
		GetDIBits (fDC, ii.hbmColor, 0, bi.bmiHeader.biHeight, pixels, bi, 0);
		If Flip32 (pixels, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight) Then
		  Result := TGpBitmapExt.Create (bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, pixels);
		// NO HACER FreeMem SOBRE LOS PIXELES, AHORA SON DEL GpBitmap
	  end;
	end;
	DeleteObject (ii.hbmMask);
	DeleteObject (ii.hbmColor);
  end;
  If Result = nil Then
  begin
	Result := TGpBitmap.Create (hi);
  end;
  DestroyIcon (hi);
end;


FillChar -> memset
GetMem -> malloc
TIconInfo -> (windows.h) ICONINFO
TBitmapInfo -> (windows.h) BITMAPINFO

This is for old version of Stacks. For new version I just access icon bytes directly and extract everything by hand, but it seems not to work in many cases (though it allows to extract Vista 256x256 PNG icons under XP, rather impossible by other means). If you need such code I will send it to you, but you'll have to port it from pascal to c++.
0

#13 User is offline   ChristianS Icon

  • Group: Member
  • Posts: 56
  • Joined: 23-January 08

Posted 16 March 2009 - 09:11 PM

ok good trick, i've found another way in the site : http://dotnetrix.co.uk/misc.htm

translated in C++ :
Bitmap * IconToAlphaBitmap(HICON ico)
{
  ICONINFO ii;
  GetIconInfo(ico , &ii);

  Bitmap * bmp = Bitmap::FromHBITMAP(ii.hbmColor,0);

  DeleteObject(ii.hbmColor);
  DeleteObject(ii.hbmMask);

  UINT pixel=GetPixelFormatSize(bmp->GetPixelFormat());
  if (pixel < 32)
	 return Bitmap::FromHICON(ico);

  BitmapData bmData;
  Rect bmBounds(0,0,bmp->GetWidth(),bmp->GetHeight());

  bmp->LockBits(&bmBounds,ImageLockModeRead,bmp->GetPixelFormat(),&bmData);

  Bitmap * dstBitmap=new Bitmap(bmData.Width, bmData.Height, bmData.Stride,PixelFormat32bppARGB, (BYTE*) (bmData.Scan0));

  bool IsAlphaBitmap = false;

  for (int y=0; y <= bmData.Height-1; y++) 
  {  
	for (int x=0; x <= bmData.Width-1; x++)
	{
	  ARGB col=*((ARGB*) bmData.Scan0+(bmData.Stride * y) + (4 * x));
	  Color PixelColor(col);
	  if (PixelColor.GetA() > 0 & PixelColor.GetA() < 255)
	  {
		IsAlphaBitmap =true;
		break; 
	   }
	 }
	if (IsAlphaBitmap) break;
   }

  bmp->UnlockBits(&bmData);

  if (IsAlphaBitmap==true)
  {
   return dstBitmap;
  }
  else
  {
   delete dstBitmap;
   return Bitmap::FromHICON(ico);
  }
}


it works good for me.

Thank you for your help.
0

#14 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 17 March 2009 - 12:12 AM

@ChristianS:

Hey, actually your way (IconToAlphaBitmap function) seems to be much better. I didn't know Gdiplus preserves alpha information on HBITMAPs, plus it workarounds for when the supposed-to-be-with-alpha-channel 32 bit has no alpha channel at all (isAlphaBitmap variable) then it tries with HICON again.
0

#15 User is offline   Smaky Icon

  • Group: Member
  • Posts: 585
  • Joined: 19-April 08

Posted 29 March 2009 - 07:59 PM

I can confirm that the latest .h and .lib files worked just fine with VC++ 2008.
0

#16 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 29 March 2009 - 10:22 PM

View PostSmaky, on Mar 29th 2009, 04:59 PM, said:

I can confirm that the latest .h and .lib files worked just fine with VC++ 2008.


Hooray! Thanks! (thanks indeed as you oriented me on how to make the .lib file, haha :P ).
0

#17 User is offline   Smaky Icon

  • Group: Member
  • Posts: 585
  • Joined: 19-April 08

Posted 02 April 2009 - 12:14 AM

I am creating a task list docklet which will show the currently running tasks... I am able to retrieve the running tasks (those listed in the taskbar) and show them using the stack library. I have included a snapshot just for reference.

I have been following your discussion on extracting icons... although I am having no problem to extract and generate the appropiate icon for each running task, the icons I am retrieving are all low-res ones... how could I retrieve a higher quality icon for the running process. Currently I am doing something like:

lpItem->icon = GetWindowIcon(ent.hwnd, ICON_BIG);
.
.
.
Gdiplus::Bitmap *GetWindowIcon(HWND hWnd, DWORD icon_type)
{
	HICON hIcon = NULL;
	hIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM) icon_type, 0);
	if (hIcon == 0)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM);
	if (hIcon == 0)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICON);

	if (hIcon == 0)
		return NULL;

	return IconToAlphaBitmap(hIcon);
}


The bitmaps correspond to the appropiate application, but they look blurry.

Attached File(s)


This post has been edited by Smaky: 02 April 2009 - 12:23 AM

0

#18 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 02 April 2009 - 11:23 AM

You should pass GCL_HICON first (after WM_GETICON), then GCL_HICONSM.

But you'll still get low-res icons probably.

The best I can think of is to use WMI to get executable full path from hwnd, then extract first icon and use that.
0

#19 User is offline   Smaky Icon

  • Group: Member
  • Posts: 585
  • Joined: 19-April 08

Posted 02 April 2009 - 02:58 PM

Already done that... and low-res icons are still being shown. Could you explain the WMI stuff a litte bit more?

View Postmatonga, on Apr 2nd 2009, 05:23 AM, said:

You should pass GCL_HICON first (after WM_GETICON), then GCL_HICONSM.

But you'll still get low-res icons probably.

The best I can think of is to use WMI to get executable full path from hwnd, then extract first icon and use that.


Edit:

Never mind, I found a way to retrieve the module (executable) associated with a given running process (thanks to MSDN and to the GetModuleFileNameEx API. Ok, I've got the executable full path... from there what should I do?

Edit 2:

I have modified the procedure to retrieve icons like this:

Gdiplus::Bitmap *GetWindowIcon(HWND hWnd, PTCHAR szFullPath, DWORD icon_type)
{
	HICON hIcon = NULL;
	
	SHFILEINFO *lpSfi = new SHFILEINFO;
	ZeroMemory(lpSfi, sizeof(SHFILEINFO));
	SHGetFileInfo(szFullPath, 0, lpSfi, sizeof(SHFILEINFO), SHGFI_LARGEICON);
	hIcon = lpSfi->hIcon;
	
	if (hIcon == NULL)
		hIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM) icon_type, 0);
	if (hIcon == NULL)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICON);
	if (hIcon == NULL)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM);

	if (hIcon == NULL)
		return NULL;

	if (lpSfi)
		delete lpSfi;

	return IconToAlphaBitmap(hIcon);
}


but the icons are still low-res and look crappy when setting the stack icon to 128.

Edit 3:

Ok, I finally got it right! thanks to PogoPixel I found how to extract the hi-res icon out of the imagelist that windows keeps. This is the modified code:

Gdiplus::Bitmap *GetWindowIcon(HWND hWnd, PTCHAR szFullPath, DWORD icon_type)
{
	HICON hIcon = NULL;
	
	// Get the icon index using SHGetFileInfo 
	SHFILEINFO *lpSfi = new SHFILEINFO;
	ZeroMemory(lpSfi, sizeof(SHFILEINFO));
	SHGetFileInfo(szFullPath, 0, lpSfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX);
	
	// Retrieve the system image list.
	// To get the 48x48 icons, use SHIL_EXTRALARGE
	// To get the 256x256 icons (Vista only), use SHIL_JUMBO
	HIMAGELIST *imageList;   
	HRESULT hResult = SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&imageList);
	if (hResult == S_OK)
	{
		// Get the icon we need from the list. Note that the HIMAGELIST we retrieved
		// earlier needs to be casted to the IImageList interface before use.
		((IImageList*)imageList)->GetIcon(lpSfi->iIcon, ILD_TRANSPARENT, &hIcon);
	}

	if (hIcon == NULL)
		hIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM) icon_type, 0);
	if (hIcon == NULL)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICON);
	if (hIcon == NULL)
		hIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM);

	if (hIcon == NULL)
		return NULL;

	if (lpSfi)
		delete lpSfi;

	return IconToAlphaBitmap(hIcon);
}


Edit 4:

Unfortunately, further testing showed that this method does come with several problems... first, although in my dev system it retrieves the executable icons correctly on my host machine it does not work (all icons, no mather what executable is are being shown as the very same hi-res icon as if the image list were empty). Another problem is that for many running processes the executable icon is not always the running app icon (specially for items like explorer folders which do not correspond to the explorer.exe icon). I am not sure how to overcome this... maybe you already have dealt with this.

Edit 5:

Well I have still found no way to retrieve the appropiate hi-res icon for the running process, but thanks to vantha's help and his XWindowDock docklet I think I found a better way to show the tasks. Now it shows a snapshot of the application among the large icon of it. I have included a couple of snapshots here.

Anyway, there are many possibilities here...

1) To get the hi-res icon, how do you do that in the stacks docklet matonga?
2) To show the snapshot only for not minimized apps.
3) Do as now, show an snapshot of all windows (it cames with a price... performance, it takes some time to do the snapshot of minimized apps).

What do you think?

On the other hand, the docket could be much enhanced by adding some features to the stacklib:

1) Highlight of the current hovered item in the grid/fan (Matonga, I believe you might be working on that, if not that would be an excellent feature).
2) left-button click support so I would be able to add a context menu to say, show, hide, close, etc. the currently selected task.
3) Enable/disable state, that dimms (alpha channel) some item, this could help show minimized windows by dimming the a bit (this would be helpful for other scenarios like the RSS Feed docklet, so I could show items already read as dimmed).

Well... i think that's for now.

Attached File(s)


This post has been edited by Smaky: 04 April 2009 - 06:44 PM

0

#20 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 05 April 2009 - 01:46 AM

Wow, those window thumbnails look really cool.

Stacks Docklet has an easier time for icons, I just use IShellFolder::GetUIObjectOf (...) to get the IID_IExtractIcon interface, then I use IExtractIcon::GetIconLocation to get .dll/.ico file (if .dll I get icon index too), then I read the icon at low level instead of using Windows API (this allows me to use hi-res Vista icons under XP).

If you want, I can send you all this code (don't use it in commercial apps! please :) ) (you'll have to translate the code from pascal) just PM me.
0

  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users