unit JDWin7;
interface
uses
Forms
, Types
, Windows
, SysUtils
, ComObj //<---
, Controls
, Graphics
, Themes;
const
TASKBAR_CID: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}';
TBPF_NOPROGRESS = 0;
TBPF_INDETERMINATE = 1;
TBPF_NORMAL = 2;
TBPF_ERROR = 4;
TBPF_PAUSED = 8;
type
TTaskBarProgressState = (tbpsNone, tbpsIndeterminate, tbpsNormal, tbpsError, tbpsPaused);
ITaskBarList3 = interface(IUnknown)
['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}']
function HrInit(): HRESULT; stdcall;
function AddTab(hwnd: THandle): HRESULT; stdcall;
function DeleteTab(hwnd: THandle): HRESULT; stdcall;
function ActivateTab(hwnd: THandle): HRESULT; stdcall;
function SetActiveAlt(hwnd: THandle): HRESULT; stdcall;
function MarkFullscreenWindow(hwnd: THandle; fFullscreen: Boolean): HRESULT; stdcall;
function SetProgressValue(hwnd: THandle; ullCompleted: UInt64; ullTotal: UInt64): HRESULT; stdcall;
function SetProgressState(hwnd: THandle; tbpFlags: Cardinal): HRESULT; stdcall;
function RegisterTab(hwnd: THandle; hwndMDI: THandle): HRESULT; stdcall;
function UnregisterTab(hwndTab: THandle): HRESULT; stdcall;
function SetTabOrder(hwndTab: THandle; hwndInsertBefore: THandle): HRESULT; stdcall;
function SetTabActive(hwndTab: THandle; hwndMDI: THandle; tbatFlags: Cardinal): HRESULT; stdcall;
function ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall;
function ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall;
function ThumbBarSetImageList(hwnd: THandle; himl: THandle): HRESULT; stdcall;
function SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar): HRESULT; stdcall;
function SetThumbnailTooltip(hwnd: THandle; pszDescription: PChar): HRESULT; stdcall;
function SetThumbnailClip(hwnd: THandle; var prcClip: TRect): HRESULT; stdcall;
end;
var
GlobalTaskBarInterface: ITaskBarList3;
HasGlobalTaskBarForm: Bool; //<---
GlobalTaskBarForm: HWND; //<---
function InitializeTaskbarAPI(FormHandle: HWND): Boolean; overload; //<---
function InitializeTaskbarAPI: Boolean; overload; //<---
function SetTaskbarProgressState(const AState: Cardinal): Boolean; overload;
function SetTaskbarProgressState(const AState: TTaskBarProgressState): Boolean; overload;
function SetTaskbarProgressValue(const ACurrent:UInt64; const AMax: UInt64): Boolean;
function SetTaskbarOverlayIcon(const AIcon: THandle; const ADescription: String): Boolean; overload;
function SetTaskbarOverlayIcon(const AIcon: TIcon; const ADescription: String): Boolean; overload;
function SetTaskbarOverlayIcon(const AList: TImageList; const IconIndex: Integer; const ADescription: String): Boolean; overload;
function InitWin7Form(FormHandle: HWND; const Color: TColor): Bool; //<---
function InitWin7App(AppHandle: HWND): Bool; //<---
procedure GlassForm(FormHandle: HWND; cBlurColorKey: TColor = clFuchsia);
implementation
procedure SetFormColor(FormHandle: HWND; Color: TColor); //<---
var
C: TCanvas;
begin
//Make C the canvas of the form from FormHandle
//Fill the canvas with the specified Color
end;
procedure GlassForm(FormHandle: HWND; cBlurColorKey: TColor = clFuchsia);
const
WS_EX_LAYERED = $80000;
LWA_COLORKEY = 1;
type
_MARGINS = packed record
cxLeftWidth: Integer;
cxRightWidth: Integer;
cyTopHeight: Integer;
cyBottomHeight: Integer;
end;
PMargins = ^_MARGINS;
TMargins = _MARGINS;
DwmIsCompositionEnabledFunc = function(pfEnabled: PBoolean): HRESULT; stdcall;
DwmExtendFrameIntoClientAreaFunc = function(
destWnd: HWND; const pMarInset: PMargins): HRESULT; stdcall;
SetLayeredWindowAttributesFunc = function(
destWnd: HWND; cKey: TColor; bAlpha: Byte; dwFlags: DWord): BOOL; stdcall;
var
hDWMDLL: Cardinal;
osVinfo: TOSVERSIONINFO;
fDwmIsCompositionEnabled: DwmIsCompositionEnabledFunc;
fDwmExtendFrameIntoClientArea: DwmExtendFrameIntoClientAreaFunc;
fSetLayeredWindowAttributesFunc: SetLayeredWindowAttributesFunc;
bCmpEnable: Boolean;
mgn: TMargins;
begin
ZeroMemory(@osVinfo, SizeOf(osVinfo));
OsVinfo.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
if ((GetVersionEx(osVInfo) = True) and
(osVinfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and
(osVinfo.dwMajorVersion >= 6)) then
begin
hDWMDLL := LoadLibrary('dwmapi.dll');
if hDWMDLL <> 0 then
begin
@fDwmIsCompositionEnabled :=
GetProcAddress(hDWMDLL, 'DwmIsCompositionEnabled');
@fDwmExtendFrameIntoClientArea :=
GetProcAddress(hDWMDLL, 'DwmExtendFrameIntoClientArea');
@fSetLayeredWindowAttributesFunc :=
GetProcAddress(GetModulehandle(user32), 'SetLayeredWindowAttributes');
if ((@fDwmIsCompositionEnabled <> nil) and
(@fDwmExtendFrameIntoClientArea <> nil) and
(@fSetLayeredWindowAttributesFunc <> nil)) then
begin
fDwmIsCompositionEnabled(@bCmpEnable);
if bCmpEnable = True then begin
SetFormColor(FormHandle, cBlurColorKey); //Not done yet //<---
SetWindowLong(FormHandle, GWL_EXSTYLE,
GetWindowLong(FormHandle, GWL_EXSTYLE) or WS_EX_LAYERED);
fSetLayeredWindowAttributesFunc(FormHandle, cBlurColorKey, 0, LWA_COLORKEY);
ZeroMemory(@mgn, SizeOf(mgn));
mgn.cxLeftWidth := -1;
mgn.cxRightWidth := -1;
mgn.cyTopHeight := -1;
mgn.cyBottomHeight := -1;
fDwmExtendFrameIntoClientArea(FormHandle, @mgn);
end;
end;
FreeLibrary(hDWMDLL);
end;
end;
end;
//Used explicitly for a particular form
// in attempt to overcome problem with swapping app's secret form
function InitializeTaskbarAPI(FormHandle: HWND): Boolean; //<---
begin
HasGlobalTaskBarForm:= True;
GlobalTaskBarForm:= FormHandle;
Result:= InitializeTaskbarAPI;
end;
//Used for the application's secret form
function InitializeTaskbarAPI: Boolean;
var
Unknown: IInterface;
Temp: ITaskBarList3;
begin
//What if I wanted 3 forms to each have
// their own progress indicator in the taskbar? //<---
if GlobalTaskBarForm = 0 then
GlobalTaskBarForm:= Application.Handle;
if Assigned(GlobalTaskBarInterface) then begin
Result := True;
Exit;
end;
try
//Creates COM object - FAILS saying CoInitialize hasn't been called
Unknown := CreateComObject(TASKBAR_CID); //<---
if Assigned(Unknown) then begin
Temp := Unknown as ITaskBarList3;
if Temp.HrInit() = S_OK then begin
GlobalTaskBarInterface := Temp;
end;
end;
except
GlobalTaskBarInterface := nil;
end;
Result:= Assigned(GlobalTaskBarInterface);
end;
function CheckAPI: Boolean;
begin
Result:= Assigned(GlobalTaskBarInterface);
end;
function SetTaskbarProgressState(const AState: Cardinal): Boolean;
begin
Result:= False;
if CheckApi then begin
Result:= GlobalTaskBarInterface.SetProgressState(GlobalTaskBarForm, AState) = S_OK;
end;
end;
//Sets the state of the progress indicator in the taskbar icon
function SetTaskbarProgressState(const AState: TTaskBarProgressState): Boolean;
var
Flag: Cardinal;
begin
Result := False;
if CheckAPI then begin
case AState of
tbpsIndeterminate: Flag := TBPF_INDETERMINATE;
tbpsNormal: Flag := TBPF_NORMAL;
tbpsError: Flag := TBPF_ERROR;
tbpsPaused: Flag := TBPF_PAUSED;
else
Flag:= TBPF_NOPROGRESS;
end;
Result:= GlobalTaskBarInterface.SetProgressState(GlobalTaskBarForm, Flag) = S_OK;
end;
end;
//Sets the position of the taskbar icon's progress indicator
function SetTaskbarProgressValue(const ACurrent: UInt64; const AMax: UInt64): Boolean;
begin //Is UInt64 DLL safe?
Result:= False;
if CheckAPI then begin
Result := GlobalTaskBarInterface.SetProgressValue(
GlobalTaskBarForm, ACurrent, AMax) = S_OK;
end;
end;
function SetTaskbarOverlayIcon(const AIcon: THandle; const ADescription: String): Boolean;
begin //Replace with PChar
Result := False;
if CheckAPI then begin
Result := GlobalTaskBarInterface.SetOverlayIcon(
GlobalTaskBarForm, AIcon, PAnsiChar(ADescription)) = S_OK;
end;
end;
//I would need to use ShareMem to export these ones //<---
function SetTaskbarOverlayIcon(const AIcon: TIcon;
const ADescription: String): Boolean;
begin
Result := False;
if CheckAPI then begin
if Assigned(AIcon) then
begin
Result := SetTaskbarOverlayIcon(AIcon.Handle, ADescription);
end else begin
Result := SetTaskbarOverlayIcon(THandle(nil), ADescription);
end;
end;
end;
function SetTaskbarOverlayIcon(const AList: TImageList;
const IconIndex: Integer; const ADescription: String): Boolean;
var
Temp: TIcon;
begin
Result := False;
if CheckAPI then begin
if (IconIndex >= 0) and (IconIndex < AList.Count) then begin
Temp := TIcon.Create;
try
AList.GetIcon(IconIndex, Temp);
Result := SetTaskbarOverlayIcon(Temp, ADescription);
finally
Temp.Free;
end;
end else begin
Result := SetTaskbarOverlayIcon(nil, ADescription);
end;
end;
end;
//Master initialization of a single form
function InitWin7Form(FormHandle: HWND; const Color: TColor): Bool;
begin
//How should I do this if I want the progress indicator to work in multiple forms?
ShowWindow(FormHandle, SW_HIDE); //<---
SetWindowLong(FormHandle, GWL_EXSTYLE, GetWindowLong(FormHandle, GWL_EXSTYLE)
and not WS_EX_APPWINDOW or WS_EX_TOOLWINDOW);
ShowWindow(FormHandle, SW_SHOW);
end;
//Master initialization of an application
function InitWin7App(AppHandle: HWND): Bool;
begin
Result:= InitializeTaskbarAPI; //<---
Sleep(500);
end;
initialization //<---
CoInitialize(nil); //Isn't working??? //<---
GlobalTaskBarInterface:= nil;
HasGlobalTaskBarForm:= False;
GlobalTaskBarForm:= 0;
finalization //<---
GlobalTaskBarInterface:= nil;
HasGlobalTaskBarForm:= False;
GlobalTaskBarForm:= 0;
CoUninitialize;
end.