Stacks Library
#21
Posted 05 April 2009 - 03:26 AM
1. Taking snapshots of minimized apps takes time (I have tested it and it might take up to four seconds to get the task list if many windows are minimized.
2. Taking snapshots of only the normal windows (shown) is much faster (since it would not require to do all the transparent-show-minimize stuff needed to generate the snapshot) but it yields those windows without a nice icon... I could use a generic icon combined with the large app icon for those.
3. As in snapshot 2, the hi-res vista icon looks great to... problem is that I have not found a reliable way to retrieve the proper icon.
#22
Posted 06 April 2009 - 01:27 AM
Lot's of apps do screenshots... WinExposé, Devrextster's dExpose, Smaky's Task Docklet, TaskSwitch XP, etc...
I'm serioulsy considering to write a PrintWindow API hihack to allow for window cache. It would look something like this:

<edit>in picture, where it says "original PW api" it refers to interaction between pw cache app and currently running applications.</edit>
Explanation of the Java/GTK stuff: I've experimented with Pidgin/other GTK apps, and Java apps a lot of time ago (now I use Digsby instead of Pidgin) and found you can just set them to layered (SetWindowLong (gtkappwindow, ... Or WS_EX_LAYERED) then SetLayeredWindowAttributes (blablabla, alpha = 0xFF, ...)) and it happens you can then just use GetWindowDC and BitBlt instead of PrintWindow, and you get the window contents instead of just a black window. However you can't use this technique with other apps such as DirectX accelerated apps, Windows Media Player flickers and freezes, and other problems. Of course this is a Windows XP specific topic, for Vista and 7 just use the DWM API instead.
#23
Posted 06 April 2009 - 08:23 AM
for visual tooltip, i do a windows hook to cache minimized screenshot :
SetWindowsHookEx : WH_CBT
-> if code=HCBT_MINMAX (before windows is minimized)
and LOWORD(lParam)==SW_MINIMIZE or SW_FORCEMINIMIZE or SW_SHOWMINIMIZED or SW_SHOWMINNOACTIVE)
-> do the screenshot with printwindow and cache it.
test code=HCBT_MOVESIZE to intercept resizing and update the cache.
#24
Posted 07 April 2009 - 12:04 AM
When you hook into the WH_CBT message, how do you do the actual "cache" of the bitmap. Is the image saved to a location where Visual Tooltip takes it? Is it sent via a intra-process read/write operation?
Thansk.
ChristianS, on Apr 6th 2009, 03:23 AM, said:
for visual tooltip, i do a windows hook to cache minimized screenshot :
SetWindowsHookEx : WH_CBT
-> if code=HCBT_MINMAX (before windows is minimized)
and LOWORD(lParam)==SW_MINIMIZE or SW_FORCEMINIMIZE or SW_SHOWMINIMIZED or SW_SHOWMINNOACTIVE)
-> do the screenshot with printwindow and cache it.
test code=HCBT_MOVESIZE to intercept resizing and update the cache.
#26
Posted 07 April 2009 - 09:03 PM
re there any considerations I should take to create a message hook (I have neved done that before) at least not in windows... oh god, that made me remember my old DOS days!)
Another thing... while reading the MSDN docs I get the impression that the DLL containing the hook's code should be in an independent dll from the application one (in my case the Docklet's dll), so I should use LoadLibrary at DockletCreate to load the docklet dll. The hook dll should only contain the hook procedure? nothing else?
This post has been edited by Smaky: 07 April 2009 - 09:21 PM
#27
Posted 08 April 2009 - 03:21 AM
The hook code must be in a DLL. This is the reason why they say "separate from application". In this case, "application" is RocketDock, ObjectDock or whatever. Your docklet is already a DLL
Fiuuu this was too large, I should have sent you it in spanish via PM, but at least any other coder reading this will find it useful too.
I'm thinking about using Windows hooks to perform session-wide API hooking (the DLL would intercept API functions at DLLMain (reason = DLL_ATTACH_PROCESS)). Though I'm not convinced about CBT to do this... because I don't know if it fits my future plans:
- PrintWindow cache.
- Intercept TrackPopupMenu[Ex] to show skinned menus a-la Leopard.
- Remove window menu bar and add something like McBar and Rosie do.
- Intercept DefWindowProc for WM_NCPAINT and WM_NCACTIVATE, WM_NCHITTEST etc... and draw buttons to the left and icon to the middle, just like AppleMinMax but without dirty tricks (ok, maybe this is a dirtier trick... depends on your point of view).
- Intercept scrollbar painting to fix track button background (in Leopard track button background remains fixed, doesn't travel with track button, this was requested in some thread at AquaSoft some time ago and I verified in a Mac and it's true it behaves like that).
- Animated... errr... progress bars...
Mmm... I think I had more ideas but can't remember them just now. Whatever, don't expect any of these to be implemented in any time soon, I have a lot to study, prepare for exams, polish lot of stuff at work, etc...
#28
Posted 08 April 2009 - 07:53 AM
//-----------------------------------------------------------------------------------------------------------------------------
/////// MAIN WINDOW
//-----------------------------------------------------------------------------------------------------------------------------
//DLL Loading and call
typedef LRESULT (WINAPI *ATTACH_FUNCTION_POINTER)(HWND _parent);
typedef LRESULT (WINAPI *DETACH_FUNCTION_POINTER)();
ATTACH_FUNCTION_POINTER pfAttach;
DETACH_FUNCTION_POINTER pfDetach;
HMODULE hInjectDLL = NULL;
hInjectDLL = LoadLibrary(HOOKDLL);
if(hInjectDLL != NULL)
{
pfAttach = (ATTACH_FUNCTION_POINTER)GetProcAddress(hInjectDLL, "InstallHook");
pfDetach = (DETACH_FUNCTION_POINTER)GetProcAddress(hInjectDLL, "UnInstallHook");
if(pfAttach == NULL || pfDetach == NULL )
{
MessageBox("Error in DLL", "Error", MB_OK|MB_ICONERROR);
return;
}
if(pfAttach(m_hWnd) == FALSE)
{
MessageBox("Error install hook","Error",0);
}
}
..../.....
void CVisualToolTipMain::OnDestroy()
{
if (hInjectDLL==TRUE)
{
FreeLibrary(hInjectDLL);
pfDetach();
}
CDialog::OnDestroy();
}
//-----------------------------------------------------------------------------------------------------------------------------
// DLL
//-----------------------------------------------------------------------------------------------------------------------------
// Hooks.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <objbase.h>
#include <Shellapi.h>
#include <commctrl.h>
// constant /////////////////////////////////////////////////////////////////////////
//
#define MYWM_HOOKMINIMIZED (WM_USER+3)
#define MYWM_HOOKQUIT (WM_USER+4)
#define MYWM_HOOKEXCLU (WM_USER+5)
// define share section for all hooked process //////////////////////////////////////
#pragma data_seg(".JOE")
HHOOK g_hCBTHook = NULL;
HWND hwndParent=0;
#pragma data_seg()
#pragma comment(linker, "/section:.JOE,rws")
// global variables /////////////////////////////////////////////////////////////////
//
HINSTANCE ghModule = NULL;
// function prototype ///////////////////////////////////////////////////////////////
//
LRESULT CALLBACK cbtHOOK(int nCode, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
// reserve the DLL handle
ghModule = (HINSTANCE)hModule;
//
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL WINAPI InstallHook(HWND _parent)
{
hwndParent=_parent;
g_hCBTHook = SetWindowsHookEx(WH_CBT, cbtHOOK, ghModule, 0);
if( g_hCBTHook == NULL )
{
return FALSE;
}
return TRUE;
}
BOOL WINAPI UnInstallHook()
{
// unhook
return UnhookWindowsHookEx(g_hCBTHook);
}
LRESULT CALLBACK cbtHOOK(int nCode, WPARAM wParam, LPARAM lParam)
{
// return immediately if system required
if (nCode < 0)
{
return CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
}
HWND hwnd;
switch(nCode)
{
case HCBT_DESTROYWND:
PostMessage(hwndParent,MYWM_HOOKQUIT,wParam,0); // to deleted cached screenshot
break;
case HCBT_MINMAX:
hwnd=(HWND)wParam;
if (::IsWindowVisible(hwnd))
{
int command=LOWORD(lParam);
if (command==SW_MINIMIZE||command==SW_FORCEMINIMIZE||command==SW_SHOWMINIMIZED||
command==SW_SHOWMINNOACTIVE)
{
if (SendMessage(hwndParent,MYWM_HOOKEXCLU,(WPARAM)(hwnd),0)==0) // If the minimized window is excluded, don't screenshot
{
SendMessage(hwndParent,MYWM_HOOKMINIMIZED,(WPARAM)(hwnd),0);
}
}
}
break;
}
return CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
}
#29
Posted 08 April 2009 - 06:10 PM
Youe sample clarifies a few things, as I thought you are sending the hWnd to the application via SendMessage where it is processed by its Message loop with a PrintWindow, thanks man!
Additionally I've read a 1996 (or it was 1997) Under the HoodMSJ article from Matt Prietek which states thet the gobal hook will be injected to every process ran, so we should take special care with the dll's footprint in order to mantain it as slim as possible. So it would be advisable in my environment (where I have already a DLL - the docklet's DLL) to have a sepparate DLL for the Hook stuff or should I include it on the docklet's DLL?
#30
Posted 08 April 2009 - 06:25 PM
Maybe Windows implements copy-on-write for data/bss segments? (at least Linux and other systems do) in such case dll footprint would be no problem at all, indeed you would get roughly 4 kbyte additional memory consumption for each running process, in theory.
#31
Posted 08 April 2009 - 09:32 PM
Right now I am seeing the messages being passed from the Hook, I still need to implement them in my Docklet... but for now I'm leaving on vacation until next monday.
Have a great week! Thank you both again.
Edit:
Ok, I have created a TaskListHook.dll which sends messages to the TaskList Docklet whenever an app is being minimized. Giving it the opportunity to create a spnapshot of the app before it is actually minimized. Messages are working just fine!
Matonga, I have one question here, since the images are being updated dynamically (whenever an app is minimized) how should I "tell" stacklibrary of the change. Currently inside MyProviderInit the stack icons are created out of the actual icon images of my (internal dynamic array) task list items (which includes the application icon & scaled snapshot). MyProviderInit is called whenever the stack is shown (and, of course all items are destroyed upon stack hide... which was something I want to optimize).
Is there a way to update the stack items and/or icons without freeing it completely first, thus the need for recreating them?
Edit 2:
I am having problems with the IconToAlphaBitmap function, for some application icons it is not retreiving the actual icon bitmap... further investigation on the issue has shown that
Bitmap::FromHBITMAP(ii.hbmColor, 0);
returns Bitmap object with PixelFormat32bppRGB format... but later during the call to:
Gdiplus::Bitmap *dstBitmap = new Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat32bppARGB, (BYTE*) (bmData.Scan0));
it is being interpreted as a PixelFormat32bppARGB bitmap.
The problem is that if I use PixelFormat32bppRGB in the previous statement, no icon is lost, but they are created with a black background instead of a transparent one. In fact, the Alpha info is lost (which is expected) but, when using PixelFormat32bppARGB some icons are lost, a completely transparent image is generated. What could be causing this?
Further investingation on this issue showed that the probles lies with applications that do not have a large icon associated to them, for example regedit.exe, if you open this application no icon is retrieved with the original code, but with PixelFormat32bppRGB it shows it's icon.
Edit 3:
With the following code the icon is not lost and the transparent areas are preserved but the alpha channel data seems to be lost since pixels which previously where semi transparent are now opaque (they look black).
Gdiplus::Bitmap *IconToAlphaBitmap(HICON hIcon, UINT size = 0)
{
Gdiplus::Bitmap *pIcon = Gdiplus::Bitmap::FromHICON(hIcon);
Gdiplus::Bitmap *pBitmap = new Gdiplus::Bitmap(pIcon->GetWidth(), pIcon->GetHeight(), PixelFormat32bppARGB);
Gdiplus::Graphics *graphics = Gdiplus::Graphics::FromImage(pBitmap);
graphics->SetInterpolationMode(Gdiplus::InterpolationModeHighQuality);
graphics->SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
graphics->SetCompositingMode(Gdiplus::CompositingModeSourceOver);
graphics->DrawImage(pIcon, 0, 0, pIcon->GetWidth(), pIcon->GetHeight());
delete graphics;
delete pIcon;
return pBitmap;
}Edit 4:
Unfortunately, all that code does the very same as just:
Gdiplus::Bitmap *pIcon = Gdiplus::Bitmap::FromHICON(hIcon); return pIcon;
Edit 5:
Well, after a lot of trial & error and loads of debugging I found that the problem occurs for such applications that do not have a native ARGB icon (like regedit.exe). These apps carry only a 32x32 16 color icon with no alpha channel data at all, just transparent pixels. The problem is that with the original IconToAlphaBitmap there seems to be data at the alpha channel (most of it with values close to cero), but nevertheless between 0-255. So IsAlphaBitmap is being set and the icon is retrieved from the Gdiplus::Bitmap and not from the HICON directly. So, as a workaround while I found a better way to distinguish these icons, I am calculating the weighted alpha value for all pixels in the icon, if I get a value lesser than 0.3 then I assume it is a RBG icon and use FromHICON instead of the Gdiplus Bitmap... this way it seems to work, normal icon have shown (so far with my own testing) to have a weighted alpha value close to 1, and are properly shown unsing the (correct) alpha bits from the icon. Check the current TaskList Docklet to see the result.
This post has been edited by Smaky: 17 April 2009 - 10:17 PM
#33
Posted 21 May 2009 - 12:25 PM
i'm working on StandaloneStack 2 with the stack library, i have a problem to retrieve the icon of the files.
2 ways :
FIRST :
appObject->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlLocal, IID_IExtractIcon, NULL,(void**)&extractIcon); extractIcon->GetIconLocation(0, iconLocation, MAX_PATH, &iconIndex, &iconFlags); extractIcon->Extract(iconLocation, iconIndex , &icon, &tmpIcon, MAKELONG(iconSize, 16)); return icon;
Works good but icon quality not perfect.
SECOND :
SHFILEINFO fi;
HIMAGELIST * imagelist;
ZeroMemory(&fi, sizeof(fi));
SHGetFileInfo((LPCWSTR) pidlLocal, -1, &fi, sizeof(fi),SHGFI_SYSICONINDEX|SHGFI_PIDL );
hr=SHGetImageList( isVista?SHIL_JUMBO:SHIL_EXTRALARGE,IID_IImageList,(void**) &imagelist);
if(SUCCEEDED(hr))
{
((IImageList*)imagelist)->GetIcon(fi.iIcon,ILD_IMAGE|ILD_TRANSPARENT,&icon);
((IImageList*)imagelist)->Release();
}
if (icon)
{
extractIcon->Release();
return icon;
}Works good too, icon quality is very good but it retreive default icon of .exe ( the icon of all executable, not the specific icon of the file) and some icon( pdf from Foxit PDF Reader for example ) is small (but iconinfo says 256x256 pixels !).
So i don't know how to distinguish good quality icon and poor quality icon (and default exe...)
what is the real technic to extract a high resolution icon !?
2 questions for stack library :
- is it possible to dynamically change the images in the stack (openned), i see FanStack_Repaint but it does nothing.
i've tried to change the buffer in STACK_ITEM (*pixels) but it doesn't work, i suppose that the library do a copy of this buffer.
It would be cool if we can change the image when the stack if openned ( for exemple : Grid/FanStack_UpdateImage(int index,void * pixels ) )
- what does special_last_item ? it seems that true of false does the same thing ?
#34
Posted 23 May 2009 - 06:57 PM
I'm working at another project, not at XWD. But, for now I know how to extract High Quality Icons. If you want me to publish this code, I can
I just copy from my sources, therefore if you need anything else, just tell me
function GetLargeIconSize(const FileName: String): Integer;
type
TIconDirEntry = packed record
bWidth: Byte;
bHeight: Byte;
bColorCount: Byte;
bReserved: Byte;
wPlanes: Word;
wBitCount: Word;
dwBytesInRes: DWord;
dwImageOffset: DWord;
end;
TArrayIconDirEntry = array[0..0] of TIconDirEntry;
PArrayIconDirEntry = ^TArrayIconDirEntry;
TIconDir = packed record
idReserved: Word; // = 0 ?
idType: Word; // = 1 ?
idCount: Word;
end;
var
f: File;
IconDir: TIconDir;
IconEntries: PArrayIconDirEntry;
i: Integer;
begin
Result := GetSystemMetrics(SM_CXICON);
{$I-}
AssignFile(f, FileName);
Reset(f, 1);
FillChar(IconDir, SizeOf(TIconDir), 0);
BlockRead(f, IconDir, SizeOf(TIconDir));
if (IconDir.idReserved = 0) and (IconDir.idType = 1) then
begin
GetMem(IconEntries, IconDir.idCount * SizeOf(TIconDirEntry));
BlockRead(f, IconEntries^, IconDir.idCount * SizeOf(TIconDirEntry));
for i:= 0 to IconDir.idCount - 1 do
begin
if (Result < IconEntries^[i].bWidth) then
Result := IconEntries^[i].bWidth;
end;
FreeMem(IconEntries);
end;
CloseFile(f);
{$I+}
end;
function GetIconFromFile(FileName: String): HICON;
function IS_INTRESOURCE(const ARes: DWord): Boolean;
begin
Result := ((ARes shr 16) = 0);
end;
type
PEnumData = ^TEnumData;
TEnumData = record
Name: String;
Index: Integer;
Counter: Integer;
end;
function EnumResNameProc(hModule: DWord; lpszType: PWChar; lpszName: PWChar; EnumData: PEnumData): Boolean; stdcall;
begin
if (EnumData^.Counter = EnumData^.Index) then
begin
if IS_INTRESOURCE(DWord(lpszName)) then
EnumData^.Name := Format('#%d', [DWord(lpszName)])
else
EnumData^.Name := lpszName;
Result := False;
end else
begin
Inc(EnumData^.Counter);
Result := True;
end;
end;
var
hModule: DWord;
hResource: DWord;
hMem: DWord;
lpResource: Pointer;
nID: Integer;
EnumData: TEnumData;
Ext: String;
IconSize: Integer;
sfi: TSHFileInfo;
FileType: (ftAnother, ftExecutable, ftIcon);
ImageList: HIMAGELIST;
Flags: DWord;
PIDL: PItemIDList;
begin
Result := 0;
PIDL := SHSimpleIDListFromPath(PWChar(FileName));
if DirectoryExists(FileName) then
begin
FillChar(sfi, SizeOf(TSHFileInfoW), 0);
SHGetFileInfo(PWChar(FileName), 0, sfi, SizeOf(sfi), SHGFI_ICONLOCATION);
if (sfi.szDisplayName[0] <> #0) then
FileName := sfi.szDisplayName;
end else
if Assigned(PIDL) then
begin
FillChar(sfi, SizeOf(TSHFileInfoW), 0);
SHGetFileInfo(PWChar(PIDL), 0, sfi, SizeOf(sfi), SHGFI_ICONLOCATION or SHGFI_PIDL);
if (sfi.szDisplayName[0] <> #0) then
FileName := sfi.szDisplayName;
end;
Ext := ExtractFileExt(FileName);
FileType := ftAnother;
if (CompareStr(Ext, '.exe') = 0) or (CompareStr(Ext, '.ocx') = 0) or
(CompareStr(Ext, '.dll') = 0) or (CompareStr(Ext, '.scr') = 0) or
(CompareStr(Ext, '.bin') = 0) or (CompareStr(Ext, '.cpl') = 0) then
FileType := ftExecutable
else
if (CompareStr(Ext, '.ico') = 0) or (CompareStr(Ext, '.icon') = 0) then
FileType := ftIcon;
case FileType of
ftExecutable:
begin
hModule := LoadLibraryEx(PWChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
if (hModule > 0) then
begin
if (sfi.iIcon >= 0) then
begin
EnumData.Index := sfi.iIcon;
EnumData.Counter := 0;
EnumResourceNames(hModule, MakeIntResource(3 + DIFFERENCE), @EnumResNameProc, Integer(@EnumData));
end else
EnumData.Name := Format('#%d', [-sfi.iIcon]);
hResource := FindResource(hModule, PWChar(EnumData.Name), MakeIntResource(3 + DIFFERENCE));
if (hResource > 0) then
begin
hMem := LoadResource(hModule, hResource);
lpResource := LockResource(hMem);
if Assigned(lpResource) then
begin
nID := LookupIconIdFromDirectoryEx(lpResource, True, $200, $200, LR_DEFAULTCOLOR);
hResource := FindResource(hModule, MakeIntResource(nID), MakeIntResource(3));
if (hResource > 0) then
begin
hMem := LoadResource(hModule, hResource);
lpResource := LockResource(hMem);
if Assigned(lpResource) then
Result := CreateIconFromResourceEx(lpResource, SizeofResource(hModule, hResource),
True, $00030000, 0, 0, LR_DEFAULTCOLOR);
end;
end;
end;
FreeLibrary(hModule);
end;
end;
ftIcon:
begin
IconSize := GetLargeIconSize(FileName);
Result := LoadImage(0, PWChar(FileName), IMAGE_ICON, IconSize, IconSize, LR_LOADFROMFILE or LR_COLOR);
end;
end;
if (Result = 0) and Assigned(PIDL) then
begin
SHGetFileInfo(PWChar(PIDL), 0, sfi, SizeOf(sfi), SHGFI_TYPENAME or SHGFI_PIDL);
Flags := SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_PIDL;
if (sfi.szTypeName = 'Shortcut') then
Flags := Flags or SHGFI_LINKOVERLAY;
ImageList := SHGetFileInfo(PWChar(PIDL), SFGAO_SHARE, sfi, SizeOf(sfi), Flags);
if (ImageList > 0) then
Result := ImageList_GetIcon(ImageList, sfi.iIcon, ILD_NORMAL);
end;
if Assigned(PIDL) then
FreePIDL(PIDL);
end;And TDIB - it's my class for working with HBITMAP + HDC + Gdiplus::GpBitmap (not Gdiplus::Bitmap)
I hope you will understand
procedure GetBitmapFromIcon(Icon: HICON; DIB: TDIB); var ii: TIconInfo; maskDC, mainDC: HDC; maskOld, mainOld: HBITMAP; BitmapData: BITMAP; p: PARGB; i: Integer; Check: Boolean; begin GetIconInfo(Icon, ii); GetObject(ii.hbmColor, SizeOf(BITMAP), @BitmapData); mainDC := CreateCompatibleDC(0); maskDC := CreateCompatibleDC(0); maskOld := SelectObject(maskDC, ii.hbmMask); mainOld := SelectObject(mainDC, ii.hbmColor); DIB.Resize(BitmapData.bmWidth, BitmapData.bmHeight); if (BitmapData.bmBitsPixel < 32) then begin BitBlt(DIB.DC, 0, 0, BitmapData.bmWidth, BitmapData.bmHeight, maskDC, 0, 0, SRCCOPY); BitBlt(DIB.DC, 0, 0, BitmapData.bmWidth, BitmapData.bmHeight, maskDC, 0, 0, DSTINVERT); BitBlt(DIB.DC, 0, 0, BitmapData.bmWidth, BitmapData.bmHeight, mainDC, 0, 0, SRCAND); end else begin BitBlt(DIB.DC, 0, 0, BitmapData.bmWidth, BitmapData.bmHeight, mainDC, 0, 0, SRCCOPY); end; // Check old icons >> 32 bits Check := True; p := DIB.Bits; for i:= 0 to DIB.Width * DIB.Height - 1 do begin if (p^.a > 0) then begin Check := False; Break; end; inc(p); end; if Check then begin p := DIB.Bits; for i:= 0 to DIB.Width * DIB.Height - 1 do begin if (p^.c > 0) and (p^.a = 0) then p^.a := 255; inc(p); end; end; SelectObject(maskDC, maskOld); SelectObject(mainDC, mainOld); DeleteDC(maskDC); DeleteDC(mainDC); DeleteObject(ii.hbmMask); DeleteObject(ii.hbmColor); end;
#37
Posted 01 August 2009 - 08:22 AM
I need some help with hooks. In XP it is okay, as usual
case HCBT_MINMAX:
{
HWND wnd = /*some window*/;
if(IsWindow((HWND)wParam) && wnd)
{
switch(LOWORD(lParam))
{
case SW_MINIMIZE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_SHOWMINNOACTIVE:
{
SendMessage(wnd, xxx, wParam, xxx);
}
break;So, a lot of windows (for example explorer's windows) minimize through this hook, but when I try to minimize IE it seems that it doesn't go trhough this hook. Any solutions ? RocketDock minimize IE well, as addition.
Thanks.
#38
Posted 03 August 2009 - 12:33 AM
case HCBT_MINMAX:
if (::IsWindowVisible((HWND)wParam))
{
int command = LOWORD(lParam);
if (command == SW_MINIMIZE||command==SW_FORCEMINIMIZE||command==SW_SHOWMINIMIZED|| command==SW_SHOWMINNOACTIVE)
{
if (SendMessage(hwndParent, MYWM_HOOKEXCLU, wParam,0) == 0) // If the minimized window is excluded, don't screenshot
{
SendMessage(hwndParent, MYWM_HOOKMINIMIZED, wParam, 0);
}
}
}
break;I have not noticed that IE is not being handled by the hook, but I have noticed some erratic behaviour with FireFox (as if it minimize/restore) multiple times.
#39
Posted 03 August 2009 - 04:31 AM
I just wonder, at first in the Window Proc RocketDock do this
1. Find ROCKETDOCK window
2. Check if the minimized window is visible and not iconic
3. Call OpenProcess to get BaseName of application's window
4. Then try to get properties of Rocketdock's window "FILTER", may be it checks if window can be minimized into the dock.
5. PostMessage to let the dock about minimizing window.
I just can't understand why they use GetAsyncKeyState in the hook, and I can not find a "swtich()" section, where thet check if it is HCBT_MINMAX and then minimize it.
Thanks.
Edit:
Okay, I think found it:
mov eax, [esp+4E8h+nCode] sub eax, 1 // 1 - it is HCBT_MINMAX mov esi, [esp+4E8h+uMsg] jz short loc_10001B05
But it seems that this hook doesn't work for IE (may be some other apps). May be I should install hook or load library using another way, or may be some aspects which I should know about, because it works perfect in Xp.
#40
Posted 23 September 2009 - 08:21 PM
matonga, on Apr 6th 2009, 02:27 AM, said:
Lot's of apps do screenshots... WinExposé, Devrextster's dExpose, Smaky's Task Docklet, TaskSwitch XP, etc...
I'm serioulsy considering to write a PrintWindow API hihack to allow for window cache. It would look something like this:

<edit>in picture, where it says "original PW api" it refers to interaction between pw cache app and currently running applications.</edit>
Explanation of the Java/GTK stuff: I've experimented with Pidgin/other GTK apps, and Java apps a lot of time ago (now I use Digsby instead of Pidgin) and found you can just set them to layered (SetWindowLong (gtkappwindow, ... Or WS_EX_LAYERED) then SetLayeredWindowAttributes (blablabla, alpha = 0xFF, ...)) and it happens you can then just use GetWindowDC and BitBlt instead of PrintWindow, and you get the window contents instead of just a black window. However you can't use this technique with other apps such as DirectX accelerated apps, Windows Media Player flickers and freezes, and other problems. Of course this is a Windows XP specific topic, for Vista and 7 just use the DWM API instead.
Hey Matonga.
Are you still thinking/working on it ? I just want to develop it, or connect to you to help and continue working on this library.
What do you think?
Edit
May be, we can modify StackLib to make it faster and liked Snow Leopard's one. What do you think? I just do not want to begin coding it from the begining.








Sign In »
Register Now!
Help


MultiQuote