![]() |
Drag&Drop von Dateien auf TrayIcon
Ich führe hier mal eine spezielle Frage zum CoolTrayIcon weiter:
Mein Problem ist, dass ich gerne per Drag&Drop eine Datei (oder auch mehrere) aus dem Windows-Explorer auf mein TrayIcon ziehen möchte, damit ich diese analysieren kann. Auf meine Frage hat ![]() ![]() ![]() Jetzt hab ich aber ein Problem den ganzen Spaß umzusetzen: Die function auf der Seite, die das WindowHandle sucht, hab ich glaub ich soweit erfolgreich in Delphi umgesetzt (war gar nicht so schwer wie ich gedacht hatte :mrgreen: ):
Delphi-Quellcode:
Aber wie gehts jetzt weiter?
function FindTrayHWND: hWnd;
var MyhWnd: hWnd; begin MyhWnd:=FindWindow('Shell_TrayWnd', nil); if (MyhWnd <> 0) then begin MyhWnd:=FindWindowEx(MyhWnd, 0, 'TrayNotifyWnd', nil); if (MyhWnd <> 0) then begin MyhWnd:=FindWindowEx(MyhWnd, 0, 'SysPager', nil); if (MyhWnd <> 0) then begin MyhWnd:=FindWindowEx(MyhWnd, 0, 'ToolbarWindow32', nil); end; end; end; result:=MyhWnd; end; |
Re: Drag&Drop von Dateien auf TrayIcon
Liste der Anhänge anzeigen (Anzahl: 1)
Weiter geht's so:
Zitat:
Habe diese mal als Anhang hochgeladen, falls du kein Konto bei codeproject hast. |
Re: Drag&Drop von Dateien auf TrayIcon
Danke für deine Mühe, aber da blick ich überhaupt nicht durch.
Ich vermute mal, dass der wichtige Teil in der Drag-Drop.cpp steht, allerdings versteh ich da kaum was. :( |
Re: Drag&Drop von Dateien auf TrayIcon
Zitat:
Ist ein WH_GETMESSAGE Hook. Probiere mal einige Funktionen zu übersetzen. Diese sollte nicht allzu schwer sein.
Code:
BOOL FileDroppedAtIcon(const HWND a_hWndOwner, const int a_iButtonID, const PPOINT pPoint)
{ HWND hWndTray = FindTrayToolbarWindow(); //now we have to get an ID of the parent process for system tray DWORD dwTrayProcessID = -1; GetWindowThreadProcessId(hWndTray, &dwTrayProcessID); //here we get a handle to tray application process HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); //now we check how many buttons is there - should be more than 0 int iButtonsCount = SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); //We want to get data from another process - it's not possible //to just send messages like TB_GETBUTTON with a locally //allocated buffer for return data. Pointer to locally allocated //data has no usefull meaning in a context of another //process (since Win95) - so we need //to allocate some memory inside Tray process. //We allocate sizeof(TBBUTTON) bytes of memory - //because TBBUTTON is the biggest structure we will fetch. //But this buffer will be also used to get smaller //pieces of data like RECT structures. LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); BOOL bIconFound = FALSE; for(int iButton=0; iButton<iButtonsCount; iButton++) { //first let's read TBUTTON information //about each button in a task bar of tray DWORD dwBytesRead = -1; TBBUTTON buttonData; SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData); //we filled lpData with details of iButton icon of toolbar //- now let's copy this data from tray application //back to our process ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead); //let's read extra data of each button: //there will be a HWND of the window that //created an icon and icon ID DWORD dwExtraData[2] = { 0,0 }; ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData,dwExtraData, sizeof(dwExtraData), &dwBytesRead); HWND hWndOfIconOwner = (HWND) dwExtraData[0]; int iIconId = (int) dwExtraData[1]; if(hWndOfIconOwner != a_hWndOwner || iIconId != a_iButtonID) { continue; } //we found our icon - in WinXP it could be hidden - let's check it: if( buttonData.fsState & TBSTATE_HIDDEN ) { break; } //now just ask a tool bar of rectangle of our icon RECT rcPosition = {0,0}; SendMessage(hWndTray, TB_GETITEMRECT, iButton, (LPARAM)lpData); // ReadProcessMemory(hTrayProc, lpData, lprcPosition/*&rcPosition*/, sizeof(RECT), &dwBytesRead); ReadProcessMemory(hTrayProc, lpData, &rcPosition, sizeof(RECT), &dwBytesRead); MapWindowRect(hWndTray,NULL,&rcPosition); if (pPoint->x > rcPosition.left && pPoint->x < rcPosition.right && pPoint->y > rcPosition.top && pPoint->y < rcPosition.bottom) { OutputDebugString("Stuff dropped at our icon...!!!"); bIconFound = TRUE; break; } break; } VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE); CloseHandle(hTrayProc); return bIconFound; } |
Re: Drag&Drop von Dateien auf TrayIcon
Hui, das war vielleicht ein Akt. Und so alles verstanden hab ich auch noch nicht, manches konnte man ja auch simpel übernehmen...
Delphi-Quellcode:
Vermutung: Könnte man nicht jetzt schon die
function FileDroppedAtIcon(const a_hWndOwner: HWND; const a_iButtonID: integer; const PPoint: TPoint): boolean;
var hWndTray, hWndOfIconOwner: HWND; dwTrayProcessID, dwBytesRead: DWORD; hTrayProc: THandle; iButtonsCount, iButton, iIconId: integer; lpData: Pointer; buttonData: TTBBUTTON; bIconFound: BOOL; dwExtraData: array[0..1] of DWORD; rcPosition: TRect; begin hWndTray:=FindTrayHWND; {FindTrayHWND s.o.} //now we have to get an ID of the parent process for system tray dwTrayProcessID:=DWORD(-1); GetWindowThreadProcessId(hWndTray, dwTrayProcessID); //here we get a handle to tray application process hTrayProc:=OpenProcess(PROCESS_ALL_ACCESS, false, dwTrayProcessID); //now we check how many buttons is there - should be more than 0 iButtonsCount:=SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); //We want to get data from another process - it's not possible //to just send messages like TB_GETBUTTON with a locally //allocated buffer for return data. Pointer to locally allocated //data has no usefull meaning in a context of another //process (since Win95) - so we need //to allocate some memory inside Tray process. //We allocate sizeof(TBBUTTON) bytes of memory - //because TBBUTTON is the biggest structure we will fetch. //But this buffer will be also used to get smaller //pieces of data like RECT structures. lpData:=VirtualAllocEx(hTrayProc, nil, SizeOf(TTBBUTTON), MEM_COMMIT, PAGE_READWRITE); bIconFound:=false; for iButton := 0 to iButtonsCount - 1 do begin //first let's read TBUTTON information //about each button in a task bar of tray dwBytesRead:=DWORD(-1); SendMessage(hWndTray, TB_GETBUTTON, iButton, LPARAM(lpData)); //we filled lpData with details of iButton icon of toolbar //- now let's copy this data from tray application //back to our process ReadProcessMemory(hTrayProc, lpData, @buttonData, SizeOf(TTBBUTTON), dwBytesRead); //let's read extra data of each button: //there will be a HWND of the window that //created an icon and icon ID dwExtraData[0] := 0; dwExtraData[1] := 0; ReadProcessMemory(hTrayProc, Pointer(buttonData.dwData), @dwExtraData, SizeOf(dwExtraData), dwBytesRead); hWndOfIconOwner:=HWND(dwExtraData[0]); iIconId:=Integer(dwExtraData[1]); if (hWndOfIconOwner <> a_hWndOwner) or (iIconId <> a_iButtonID) then begin Continue; {sollte man hier nicht lieber den nachfolgenden Code reinschreiben, anstatt eine if Abfrage später auf Break zu prüfen?} end; //we found our icon - in WinXP it could be hidden - let's check it: if (buttonData.fsState and TBSTATE_HIDDEN) > 0 then begin Break; end; //now just ask a tool bar of rectangle of our icon SendMessage(hWndTray, TB_GETITEMRECT, iButton, LPARAM(lpData)); ReadProcessMemory(hTrayProc, lpData, @rcPosition, SizeOf(TRECT), dwBytesRead); MapWindowPoints(hWndTray, 0, rcPosition, 2); if (PPoint.X > rcPosition.Left) and (PPoint.X < rcPosition.Right) and (PPoint.Y > rcPosition.Top) and (PPoint.Y < rcPosition.Bottom) then begin //stuff dropped at our icon bIconFound:=true; Break; end; end; VirtualFreeEx(hTrayProc, lpData, 0, MEM_RELEASE); CloseHandle(hTrayProc); result:=bIconFound; end;
Delphi-Quellcode:
einsetzen? Da man ja weiß, dass etwas gedroppt wurde, braucht man doch jetzt nur noch die Pfade der gedropten Datei(en). :gruebel:
procedure WMDropFiles(var Msg: TMessage); Message WM_DropFiles;
Btw, ist das erste Mal, dass ich so windowsnah unterwegs bin. :!: |
Re: Drag&Drop von Dateien auf TrayIcon
Bist du inzwischen schon weiter gekommen?
|
Re: Drag&Drop von Dateien auf TrayIcon
Nein, bisher leider nicht. :(
Könntest du mir verraten, welche Funktionen ich aus der Drag-Drop.cpp und der DDHook.cpp genau brauche? Das mit der .dll hab ich nämlich nicht verstanden: braucht das Programm diese .dll, um den Drop zu erkennen? Und wie ich die einzelnen Funktionen zusammensetzte hab ich auch noch nicht herausgefunden. Nach welchem Ereignis muss ich den Ausschau halten? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz