3,7 → 3,7 |
// E-MAIL: info@daniel-marschall.de // |
// WEB: www.daniel-marschall.de // |
//////////////////////////////////////////////////////////////////////////////////// |
// Revision: 14 JUN 2010 // |
// Revision: 16 JUN 2010 // |
// This unit is freeware, but please link to my website if you are using it! // |
//////////////////////////////////////////////////////////////////////////////////// |
// Successful tested with: // |
55,6 → 55,9 |
Problem: bei win95(ohne ie4) und win2000 gleichzeitiger installation: es existiert info UND info2!!! |
Neue Funktionen: GetCurrentRecyclerIcon, GetFullIcon, GetEmptyIcon |
Bei Vista gibt es manchmal einen c0000013 Fehler. (Auslesen des ganzen Papierkorbs) |
Windows 7 miteinbeziehen! |
Implement SETTER functions to every kind of configuration thing. (percentage etc) |
Registry CURRENT_USER: Funktionen auch für fremde Benutzer zur Verfügung stellen? |
|
- Future - |
|
113,7 → 116,8 |
|
uses |
Windows, SysUtils, Classes, {$IFDEF DEL6UP}DateUtils,{$ENDIF} |
ShellApi{$IFNDEF DEL6UP}, FileCtrl{$ENDIF}, Registry, ShellStateUnit; |
ShellApi{$IFNDEF DEL6UP}, FileCtrl{$ENDIF}, Registry, |
BitOps, Messages; |
|
type |
EUnknownState = class(Exception); |
199,6 → 203,7 |
function RecyclerAddFileOrFolder(FileOrFolder: string): boolean; overload; |
|
function RecyclerConfirmationDialogEnabled: boolean; |
procedure RecyclerConfirmationDialogSetEnabled(NewSetting: boolean); |
|
function RecyclerGetCurrentIconString: string; |
function RecyclerGetDefaultIconString: string; |
253,6 → 258,52 |
|
implementation |
|
type |
SHELLSTATE = record |
Flags1: DWORD; |
(* |
BOOL fShowAllObjects : 1; |
BOOL fShowExtensions : 1; |
BOOL fNoConfirmRecycle : 1; |
|
BOOL fShowSysFiles : 1; |
BOOL fShowCompColor : 1; |
BOOL fDoubleClickInWebView : 1; |
BOOL fDesktopHTML : 1; |
BOOL fWin95Classic : 1; |
BOOL fDontPrettyPath : 1; |
BOOL fShowAttribCol : 1; // No longer used, dead bit |
BOOL fMapNetDrvBtn : 1; |
BOOL fShowInfoTip : 1; |
BOOL fHideIcons : 1; |
BOOL fWebView : 1; |
BOOL fFilter : 1; |
BOOL fShowSuperHidden : 1; |
BOOL fNoNetCrawling : 1; |
*) |
dwWin95Unused: DWORD; // Win95 only - no longer supported pszHiddenFileExts |
uWin95Unused: UINT; // Win95 only - no longer supported cbHiddenFileExts |
|
// Note: Not a typo! This is a persisted structure so we cannot use LPARAM |
lParamSort: Integer; |
iSortDirection: Integer; |
|
version: UINT; |
|
// new for win2k. need notUsed var to calc the right size of ie4 struct |
// FIELD_OFFSET does not work on bit fields |
uNotUsed: UINT; // feel free to rename and use |
Flags2: DWORD; |
(* |
BOOL fSepProcess: 1; |
// new for Whistler. |
BOOL fStartPanelOn: 1; //Indicates if the Whistler StartPanel mode is ON or OFF. |
BOOL fShowStartPage: 1; //Indicates if the Whistler StartPage on desktop is ON or OFF. |
UINT fSpareFlags : 13; |
*) |
end; |
LPSHELLSTATE = ^SHELLSTATE; |
|
const |
{$IFDEF MSWINDOWS} |
shell32 = 'shell32.dll'; |
263,6 → 314,31 |
advapi32 = 'libwine.borland.so'; |
{$ENDIF} |
|
// Masks for the shellstate |
SSF_SHOWALLOBJECTS = $00000001; |
SSF_SHOWEXTENSIONS = $00000002; |
SSF_HIDDENFILEEXTS = $00000004; |
SSF_SERVERADMINUI = $00000004; |
SSF_SHOWCOMPCOLOR = $00000008; |
SSF_SORTCOLUMNS = $00000010; |
SSF_SHOWSYSFILES = $00000020; |
SSF_DOUBLECLICKINWEBVIEW = $00000080; |
SSF_SHOWATTRIBCOL = $00000100; |
SSF_DESKTOPHTML = $00000200; |
SSF_WIN95CLASSIC = $00000400; |
SSF_DONTPRETTYPATH = $00000800; |
SSF_SHOWINFOTIP = $00002000; |
SSF_MAPNETDRVBUTTON = $00001000; |
SSF_NOCONFIRMRECYCLE = $00008000; |
SSF_HIDEICONS = $00004000; |
SSF_FILTER = $00010000; |
SSF_WEBVIEW = $00020000; |
SSF_SHOWSUPERHIDDEN = $00040000; |
SSF_SEPPROCESS = $00080000; |
SSF_NONETCRAWLING = $00100000; |
SSF_STARTPANELON = $00200000; |
SSF_SHOWSTARTPAGE = $00400000; |
|
// ********************************************************** |
// COMPATIBILITY FUNCTIONS |
// ********************************************************** |
288,6 → 364,8 |
resourcestring |
LNG_UNEXPECTED_STATE = 'Cannot determinate state of "%s" because of an unknown value in the configuration of your operation system. Please contact the developer of the Recycler Bin Unit and help improving the determination methods!'; |
LNG_API_CALL_ERROR = 'Error while calling the API. Additional information: "%s".'; |
LNG_NOT_CALLABLE = '%s not callable'; |
LNG_ERROR_CODE = '%s returns error code %s'; |
|
function _GetBit(B: Byte; BitPos: TBitPos): boolean; overload; |
var |
1945,8 → 2023,10 |
dwFlags: DWORD): |
HRESULT; stdcall; |
var |
SHEmptyRecycleBin: TSHEmptyRecycleBin; |
PSHEmptyRecycleBin: TSHEmptyRecycleBin; |
LibHandle: THandle; |
const |
C_SHEmptyRecycleBinA = 'SHEmptyRecycleBinA'; |
begin |
result := true; |
LibHandle := LoadLibrary(shell32) ; |
1953,10 → 2033,10 |
try |
if LibHandle <> 0 then |
begin |
@SHEmptyRecycleBin:= GetProcAddress(LibHandle, 'SHEmptyRecycleBinA'); |
if @SHEmptyRecycleBin <> nil then |
@PSHEmptyRecycleBin:= GetProcAddress(LibHandle, C_SHEmptyRecycleBinA); |
if @PSHEmptyRecycleBin <> nil then |
begin |
SHEmptyRecycleBin(hInstance, nil, flags); |
PSHEmptyRecycleBin(hInstance, nil, flags); |
end |
else |
result := false; |
1964,7 → 2044,7 |
else |
result := false; |
finally |
@SHEmptyRecycleBin := nil; |
@PSHEmptyRecycleBin := nil; |
FreeLibrary(LibHandle); |
end; |
end; |
2015,17 → 2095,151 |
end; |
|
function RecyclerConfirmationDialogEnabled: boolean; |
type |
TSHGetSettings = procedure (var lpss: SHELLSTATE; dwMask: DWORD) stdcall; |
const |
C_SHGetSettings = 'SHGetSettings'; |
var |
lpss: SHELLSTATE; |
bNoConfirmRecycle: boolean; |
|
PSHGetSettings: TSHGetSettings; |
RBHandle: THandle; |
|
reg: TRegistry; |
rbuf: array[0..255] of byte; |
begin |
PSHGetSettings := nil; |
result := false; // Avoid warning message |
|
RBHandle := LoadLibrary(shell32); |
if(RBHandle <> 0) then |
begin |
PSHGetSettings := GetProcAddress(RBHandle, C_SHGetSettings); |
if (@PSHGetSettings = nil) then |
begin |
FreeLibrary(RBHandle); |
RBHandle := 0; |
end; |
end; |
|
if (RBHandle <> 0) and (Assigned(PSHGetSettings)) then |
begin |
ZeroMemory(@lpss, SizeOf(lpss)); |
SHGetSetSettings(lpss, SSF_NOCONFIRMRECYCLE, False); |
bNoConfirmRecycle := (lpss.Flags1 and 4) = 4; // fNoConfirmRecycle |
PSHGetSettings(lpss, SSF_NOCONFIRMRECYCLE); |
// bNoConfirmRecycle := (lpss.Flags1 and 4) = 4; // fNoConfirmRecycle |
bNoConfirmRecycle := GetByteBit(lpss.Flags1, 3); |
|
result := not bNoConfirmRecycle; |
end |
else |
begin |
reg := TRegistry.Create; |
try |
// API function call failed. Probably because Windows is too old. |
// Try to read out from registry. |
// Warning: This method may be unsafe. In newer Windows versions |
// (Windows 2003 and higher) the 3rd bit of byte #5 seems to have |
// toggled in its behavior!! But for these newer Windows versions, our |
// API function should always be available. |
|
reg.RootKey := HKEY_CURRENT_USER; |
if (reg.OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Explorer')) then |
begin |
ZeroMemory(@rbuf, SizeOf(rbuf)); |
reg.ReadBinaryData('ShellState', rbuf, SizeOf(rbuf)); |
|
// Lese 3tes Bit vom 5ten Byte |
// bNoConfirmRecycle := ((rbuf[4] and 4) = 4); |
bNoConfirmRecycle := GetByteBit(ord(rbuf[4]), 3); |
result := not bNoConfirmRecycle; |
|
reg.CloseKey; |
end |
else |
begin |
raise EAPICallError.CreateFmt(LNG_API_CALL_ERROR, [Format(LNG_NOT_CALLABLE, [C_SHGetSettings])]); |
end; |
finally |
reg.Free; |
end; |
end; |
|
if (RBHandle <> 0) then FreeLibrary(RBHandle); |
end; |
|
procedure RecyclerConfirmationDialogSetEnabled(NewSetting: boolean); |
type |
TSHGetSetSettings = procedure (var lpss: SHELLSTATE; dwMask: DWORD; bSet: BOOL) stdcall; |
const |
C_SHGetSetSettings = 'SHGetSetSettings'; |
var |
lpss: SHELLSTATE; |
|
PSHGetSetSettings: TSHGetSetSettings; |
RBHandle: THandle; |
|
reg: TRegistry; |
rbuf: array[0..255] of byte; |
begin |
PSHGetSetSettings := nil; |
|
RBHandle := LoadLibrary(shell32); |
if(RBHandle <> 0) then |
begin |
PSHGetSetSettings := GetProcAddress(RBHandle, C_SHGetSetSettings); |
if (@PSHGetSetSettings = nil) then |
begin |
FreeLibrary(RBHandle); |
RBHandle := 0; |
end; |
end; |
|
if (RBHandle <> 0) and (Assigned(PSHGetSetSettings)) then |
begin |
ZeroMemory(@lpss, SizeOf(lpss)); |
PSHGetSetSettings(lpss, SSF_NOCONFIRMRECYCLE, false); // Get |
lpss.Flags1 := SetByteBit(lpss.Flags1, 3, NewSetting); |
PSHGetSetSettings(lpss, SSF_NOCONFIRMRECYCLE, true); // Set |
|
// TODO: Do we need a WM_SETTINGCHANGE message to send? |
end |
else |
begin |
reg := TRegistry.Create; |
try |
// API function call failed. Probably because Windows is too old. |
// Try to read out from registry. |
// Warning: This method may be unsafe. In newer Windows versions |
// (Windows 2003 and higher) the 3rd bit of byte #5 seems to have |
// toggled in its behavior!! But for these newer Windows versions, our |
// API function should always be available. |
|
reg.RootKey := HKEY_CURRENT_USER; |
if (reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Explorer', false)) then |
begin |
ZeroMemory(@rbuf, SizeOf(rbuf)); |
reg.ReadBinaryData('ShellState', rbuf, SizeOf(rbuf)); // Get |
rbuf[4] := SetByteBit(rbuf[4], 3, NewSetting); |
reg.WriteBinaryData('ShellState', rbuf, SizeOf(rbuf)); // Set |
|
// TODO: Check if that's OK... |
Sendmessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,LParam(PChar('Environment'))); |
|
reg.CloseKey; |
end |
else |
begin |
raise EAPICallError.CreateFmt(LNG_API_CALL_ERROR, [Format(LNG_NOT_CALLABLE, [C_SHGetSetSettings])]); |
end; |
finally |
reg.Free; |
end; |
end; |
|
if (RBHandle <> 0) then FreeLibrary(RBHandle); |
end; |
|
function RecyclerGetCurrentIconString: string; |
begin |
if RecyclerIsEmpty then |
2579,14 → 2793,11 |
|
function RecyclerGetAPIInfo(Path: String): TSHQueryRBInfo; |
var |
SHQueryRecycleBin: TSHQueryRecycleBin; |
PSHQueryRecycleBin: TSHQueryRecycleBin; |
RBHandle: THandle; |
res: HRESULT; |
resourcestring |
LNG_NOT_CALLABLE = '%s not callable'; |
LNG_ERROR_CODE = '%s returns error code %s'; |
begin |
SHQueryRecycleBin := nil; |
PSHQueryRecycleBin := nil; |
|
// Ref: http://www.delphipraxis.net/post1291.html |
|
2593,8 → 2804,8 |
RBHandle := LoadLibrary(shell32); |
if(RBHandle <> 0) then |
begin |
SHQueryRecycleBin := GetProcAddress(RBHandle, C_SHQueryRecycleBin); |
if(@SHQueryRecycleBin = nil) then |
PSHQueryRecycleBin := GetProcAddress(RBHandle, C_SHQueryRecycleBin); |
if(@PSHQueryRecycleBin = nil) then |
begin |
FreeLibrary(RBHandle); |
RBHandle := 0; |
2604,9 → 2815,9 |
fillchar(result, SizeOf(TSHQueryRBInfo),0); |
result.cbSize := SizeOf(TSHQueryRBInfo); |
|
if (RBHandle <> 0) and (Assigned(SHQueryRecycleBin)) then |
if (RBHandle <> 0) and (Assigned(PSHQueryRecycleBin)) then |
begin |
res := SHQueryRecycleBin(PChar(Path), result); |
res := PSHQueryRecycleBin(PChar(Path), result); |
// if Succeeded(res) then |
if res = S_OK then |
begin |