29-05-2011, 07:01 PM
وعليكم السلام
التابع SHFileOperation للأسف لا يقبل CallBack
تابع CallBack هو تابع/إجراء يتم إرساله إلى تابع (كمَعلَم) آخر للقيام بهمة محددة (في مثالنا مشاهدة تقدم العملية)
للمزيد انظر:
في نظام Vista يمكن استخدام الواجهة IFileOperation عوضا عن الاكتفاء بـ SHFileOperation لاستخدام CallBack ومشاهدة تقدم العملية مع إمكانية إيقافها...
إذن، لا يوجد حل!
كلا، بل هناك حلول... لكنها تتطلب مبرمج متمرس ومتمكن من API
يمكنك محاكاة عمل CallBack بنفسك من خلال رسائل Windows، مثال يوضح المبدأ بـ C
حل آخر باستخدام واجهة ICopyHook
من المصدر MSDN، المزيد حول SHFileOperation
وبالتالي عليك برمجة واجهة ICopyHook واستخدامها كـ CallBack
هناك أكيد من سبقنا إلى ذلك، جرب:
ابحث عن المزيد...
كلمات مفتاحية للبحث ICopyHook ShFileOperation CallBack
احتمال وارد للحل باستخدام CopyHook كما يؤكد Madshi، جرب مكتبته:
بالتوفيق.
التابع SHFileOperation للأسف لا يقبل CallBack
تابع CallBack هو تابع/إجراء يتم إرساله إلى تابع (كمَعلَم) آخر للقيام بهمة محددة (في مثالنا مشاهدة تقدم العملية)
للمزيد انظر:
كود :
http://delphi.about.com/od/windowsshellapi/a/callback_delphi.htmإذن، لا يوجد حل!
كلا، بل هناك حلول... لكنها تتطلب مبرمج متمرس ومتمكن من API
يمكنك محاكاة عمل CallBack بنفسك من خلال رسائل Windows، مثال يوضح المبدأ بـ C
PHP كود :
(btw there I have got a real problem with SHFileOperation - if FOF_SIMPLEPROGRESS flag is set and shos.lpszProgressTitle is not empty, SHFileOperation causes an error in kernel32.dll - tested under WinXP)
HWND hwndMain;
const int width=320;
const int height=240;
...
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow){
if(!RegisterClass()) //”inline” function for the sake of lucidity
return 0;
hwndMain=CreateWindow("MyWndClass","MyWindow",WS_POPUP|WS_BORDER|WS_VISIBLE,(GetSystemMetrics(SM_CXSCREEN)-width)/2,(GetSystemMetrics(SM_CYSCREEN)-height)/2,width+2,height+2,NULL,NULL,hInstance,NUL);
if(!hwndMain)
return 0;
char pFrom[MAX_PATH]="C:\\0"; //must be double-null terminated
char pTo[MAX_PATH]="D:\\0";
SHFILEOPSTRUCT shos;
shos.hwnd=GetDesktopWindow();
shos.pFrom=pFrom;
shos.pTo=pTo;
shos.wFunc=FO_COPY;
shos.fFlags=FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_RENAMEONCOLLISION;
SHFileOperation(&shos); //suppose it takes several minutes to complete this transfer
//NO message loop, does not quit until SHFileOperation is cmopleted, yet
//handles all the messages in WindowProc (here reduced to WM_PAINT and WM_LBUTTONDOWN)
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
switch(msg){
case WM_LBUTTONDOWN:
SendMessage(hwndMain, WM_NCLBUTTONDOWN, HTCAPTION, 0);
break;
case WM_PAINT:
//blah blah – it works
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}
كود :
If a copy callback handler is exposed and registered, SHFileOperation calls it unless you set a flag such as FOF_NOCONFIRMATION in the fFlags member of the structure pointed to by lpFileOp. See ICopyHook::CopyCallback for details on implementing copy callback handlers.كود :
http://msdn.microsoft.com/en-us/library/bb762164%28v=vs.85%29.aspxكود :
http://msdn.microsoft.com/en-us/library/bb776048%28v=vs.85%29.aspxPHP كود :
unit CopyHookImpl;
interface
uses
Windows, ComObj, ShlObj, ShellApi;
type
TCopyHook = class(TComObject, ICopyHook)
protected
{Declare ICopyHook methods here}
function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT;
pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD;
pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;
end;
TCHClassFactory = class(TComObjectFactory)
public
procedure UpdateRegistry(Register: Boolean); override;
end;
const
Class_CopyHook: TGUID = '{9090D650-0ACE-11D3-B3DF-0040F67455FE}';
implementation
uses ComServ;
{ TCopyHook }
function TCopyHook.CopyCallback(Wnd: HWND; wFunc, wFlags: UINT;
pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar;
dwDestAttribs: DWORD): UINT;
var
OpString: string;
begin
case wFunc of
FO_MOVE: OpString := ' move ';
FO_COPY: OpString := ' copy ';
FO_DELETE: OpString := ' delete ';
FO_RENAME: OpString := ' rename ';
end;
Result := MessageBox(Wnd, PChar('Are you sure you want to ' + OpString +
pszSrcFile + '?'), 'CopyHookDemo', MB_YESNOCANCEL);
end;
{ TCHClassFactory }
procedure TCHClassFactory.UpdateRegistry(Register: Boolean);
begin
inherited UpdateRegistry(Register);
if Register then begin
CreateRegKey('directory\shellex\CopyHookHandlers\' + ClassName,
'', GUIDToString(ClassID));
end else begin
DeleteRegKey('directory\shellex\CopyHookHandlers\' + ClassName);
end;
end;
initialization
{$IFDEF VER100}
TCHClassFactory.Create(ComServer, TCopyHook, Class_CopyHook,
'CopyHook', '', ciMultiInstance);
{$ELSE}
TCHClassFactory.Create(ComServer, TCopyHook, Class_CopyHook,
'CopyHook', '', ciMultiInstance, tmApartment);
{$ENDIF}
end.
كلمات مفتاحية للبحث ICopyHook ShFileOperation CallBack
احتمال وارد للحل باستخدام CopyHook كما يؤكد Madshi، جرب مكتبته:
كود :
http://help.madshi.net/ApiCodeHooking.htmبالتوفيق.

