طريقة نسخ مجلد باستعمال brogressbar
#6
وعليكم السلام
التابع SHFileOperation للأسف لا يقبل CallBack
تابع CallBack هو تابع/إجراء يتم إرساله إلى تابع (كمَعلَم) آخر للقيام بهمة محددة (في مثالنا مشاهدة تقدم العملية)
للمزيد انظر:
كود :
http://delphi.about.com/od/windowsshellapi/a/callback_delphi.htm
في نظام Vista يمكن استخدام الواجهة IFileOperation عوضا عن الاكتفاء بـ SHFileOperation لاستخدام CallBack ومشاهدة تقدم العملية مع إمكانية إيقافها...

إذن، لا يوجد حل!
كلا، بل هناك حلول... لكنها تتطلب مبرمج متمرس ومتمكن من 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;
} 
حل آخر باستخدام واجهة ICopyHook
كود :
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.
من المصدر MSDN، المزيد حول SHFileOperation
كود :
http://msdn.microsoft.com/en-us/library/bb762164%28v=vs.85%29.aspx
وبالتالي عليك برمجة واجهة ICopyHook واستخدامها كـ CallBack
كود :
http://msdn.microsoft.com/en-us/library/bb776048%28v=vs.85%29.aspx
هناك أكيد من سبقنا إلى ذلك، جرب:
PHP كود :
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

بالتوفيق.
الرد


الردود في هذا الموضوع
طريقة نسخ مجلد باستعمال brogressbar - بواسطة kachwahed - 29-05-2011, 07:01 PM

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم