
Эксперт
   
Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006
Репутация: 1 Всего: 88
|
Я это сделал! Вобщем ситуация такова:работает только если одновременно запущен лишь один экземпляр, не имеет отношения к ActiveX/СОМ/CORBA и если какая-нибудь программа после того как ты добавил иконку трей сразу (очень выстро) добавит свою, то мой код будет перехватывать драгУндДроп с ее (чужой) иконки  В общем, работает ДАЛЕКО не идеально, но РАБОТАЕТ! Состоит из двух модулей. 1. Екзе (привожу модуль формы): Код | unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ShellAPI;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); protected procedure WndProc(var Message: TMessage); override; public procedure HandleDroppedFiles(hDrop:THandle); end;
var Form1: TForm1;wnd:HWND;
implementation var ICON_MESSAGE,TARGET_WND_MESSAGE,ICON_REMOVED_MESSAGE:dword; {$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); var nid:NOTIFYICONDATA;PID,TID:DWORD;hMod:THANDLE;proc:pointer;hook:HHOOK; begin TARGET_WND_MESSAGE:=RegisterWindowMessage('This is a target window'); ICON_MESSAGE:=RegisterWindowMessage('Event on our tray icon'); nid.cbSize:=SizeOf(nid); nid.Wnd:=handle; nid.uID:=0; nid.uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP; nid.uCallbackMessage:=ICON_MESSAGE; nid.hIcon:=application.icon.Handle; nid.szTip:='WOW!!'; wnd:=FindWindow('Shell_TrayWnd',nil); wnd:=FindWindowEx(wnd,0,'TrayNotifyWnd',nil); wnd:=FindWindowEx(wnd,0,'SysPager',nil); wnd:=FindWindowEx(wnd,0,'ToolbarWindow32',nil); TID:=GetWindowThreadProcessID(wnd,@PID); hMod:=LoadLibrary('lib.dll'); proc:=GetProcAddress(hMod,'HookProc'); hook:=SetWindowsHookEx(WH_CALLWNDPROCRET,proc,hMod,TID); Shell_NotifyIcon(NIM_ADD,@nid); SendMessage(wnd,TARGET_WND_MESSAGE,integer(handle),0); UnhookWindowsHookEx(hook); FreeLibrary(hMod); DragAcceptFiles(handle,true); end;
procedure TForm1.HandleDroppedFiles(hDrop:THandle); var i,count,length:integer;buf:PChar;sl:TStringList; begin sl:=TStringList.Create; count:=DragQueryFile(hDrop,$FFFFFFFF,nil,0); for i:=0 to count-1 do begin length:=DragQueryFile(hDrop,i,nil,0); GetMem(buf,length+1); DragQueryFile(hDrop,i,buf,length+1); sl.Add(buf); FreeMem(buf,length+1); end; DragFinish(hDrop); ShowMessage(sl.text); sl.free end;
procedure TForm1.WndProc(var Message: TMessage); begin if message.Msg=ICON_MESSAGE then if message.LParam=WM_LBUTTONDOWN then showmessage('Left click on tray icon') else //... else if message.Msg=WM_DROPFILES then HandleDroppedFiles(THandle(message.WParam)) else inherited; end;
procedure TForm1.FormDestroy(Sender: TObject); var nid:NOTIFYICONDATA; begin nid.cbSize:=SizeOf(nid); nid.Wnd:=handle; nid.uID:=0; nid.uFlags:=0; Shell_NotifyIcon(NIM_DELETE,@nid); ICON_REMOVED_MESSAGE:=RegisterWindowMessage('Tray icon removed'); SendMessage(wnd,ICON_REMOVED_MESSAGE,0,0); end;
end.
|
И Длл: Код | library lib; uses windows,ShellAPI,messages; type TBBUTTON=packed record iBitmap,idCommand:integer; fsState,fsStyle:byte; bReserved:array[1..2] of byte; dwData,iString:integer; end; const TB_HITTEST=WM_USER+69; TB_GETBUTTON=WM_USER+23; var TARGET_WND_MESSAGE,ICON_REMOVED_MESSAGE:dword; OldWndProc:pointer;TargWnd:HWND;idCommand:integer;
function UnloadThread(ptrNil:pointer):DWORD;stdcall; begin result:=0; FreeLibraryAndExitThread(GetModuleHandle('lib'),0); end;
procedure StartUnloading(wnd:HWND); var TID:DWORD;h:THANDLE; begin SetWindowLong(wnd,GWL_WNDPROC,integer(OldWndProc)); h:=CreateThread(nil,0,@UnloadThread,nil,CREATE_SUSPENDED,TID); SetThreadPriority(h,THREAD_PRIORITY_IDLE); ResumeThread(h); CloseHandle(h); end;
function NewWndProc(wnd:HWND;msg:dword;wparam:WPARAM;lparam:LPARAM):dword;stdcall; var index:integer;btn:TBBUTTON;p:TPoint; begin result:=0; case msg of WM_DROPFILES:begin DragQueryPoint(wparam,p); index:=abs(CallWindowProc(OldWndProc,wnd,TB_HITTEST,0,integer(@p))); CallWindowProc(OldWndProc,wnd,TB_GETBUTTON,index,integer(@btn)); if btn.idCommand=idCommand then PostMessage(TargWnd,msg,wparam,lparam); DragFinish(wparam); end; WM_DESTROY:begin StartUnloading(wnd); result:=CallWindowProc(OldWndProc,wnd,msg,wparam,lparam) end else if msg=ICON_REMOVED_MESSAGE then StartUnloading(wnd) else result:=CallWindowProc(OldWndProc,wnd,msg,wparam,lparam); end; end;
function HookProc(code:integer;wparam:wparam;var info:CWPRETSTRUCT):lresult;stdcall; var pt:TPoint;index:integer;btn:TBBUTTON; begin if (code=HC_ACTION) and (info.message=TARGET_WND_MESSAGE) then begin OldWndProc:=pointer(GetWindowLong(info.HWND,GWL_WNDPROC)); pt.x:=1;pt.y:=1; index:=abs(CallWindowProc(OldWndProc,info.HWND,TB_HITTEST,0,integer(@pt))); CallWindowProc(OldWndProc,info.HWND,TB_GETBUTTON,index,integer(@btn)); idCommand:=btn.idCommand; LoadLibrary('lib.dll'); DragAcceptFiles(info.HWND,true); TargWnd:=HWND(info.wParam); SetWindowLong(info.HWND,GWL_WNDPROC,integer(@NewWndProc)); end; result:=0; end;
exports HookProc; begin TARGET_WND_MESSAGE:=RegisterWindowMessage('This is a target window'); ICON_REMOVED_MESSAGE:=RegisterWindowMessage('Tray icon removed'); end.
|
 Плииииз, если доведешь до ума, оставь свой вариант в этой теме
--------------------
Обижено школьников: 8
|