AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Handle einer Form aus Taskbareintrag erhalten
Thema durchsuchen
Ansicht
Themen-Optionen

Handle einer Form aus Taskbareintrag erhalten

Ein Thema von Mazel · begonnen am 22. Apr 2007 · letzter Beitrag vom 25. Apr 2007
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Mazel
Mazel

Registriert seit: 11. Nov 2005
Ort: Leipzig
831 Beiträge
 
#1

Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 10:12
Hallo,

ich suche nach einer Möglichkeit, über ein Klick mit der mittleren Maustaste auf ein Taskbareintrag einer Form, das Handle der jeweiligen Form zu ermitteln.
Ich habe folgendes ausprobiert, jedoch bekomme ich da selber nur das Handle der Taskbar und nicht der einzelnen Einträge:
Delphi-Quellcode:
GetCursorPos(Pos);
Wnd := WindowFromPoint(Pos);
Ein Klick mit der Mausstaste fange ich folgendermaßen ab:
Delphi-Quellcode:
{--[MouseHookProc]-------------------------------------------------------------}

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  If nCode = HC_ACTION then
   begin
    If lParam <> 0 then with PEventMsg(lParam)^ do
     begin
      If Message = WM_MBUTTONDOWN then
       begin
        GetCursorPos(Pos);
        Wnd := WindowFromPoint(Pos);
       end;
     end;
   end;
  Result := CallNextHookEx(Main.MouseHook, nCode, wParam, lParam);
end;
Hat jemand einen Rat für mich?

Gruß
Mazel
Marcel Jänicke
www.mj-software.net
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#2

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 11:16
Hallo Mazel

Zitat von msdn2.microsoft.com:
TB_HITTEST Message
Determines where a point lies in a toolbar control.
Zudem musst du mit OpenProcess / VirtualAllocEx / WriteProcessMemory arbeiten.

Habe ein Beispiel in C gefunden.

Code:
  POINT pt;
    GetCursorPos(&pt);
    if (WindowFromPoint(pt)!=hwndTW) return 0;
    ScreenToClient(hwndTW,&pt);
    HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pidTB);// pidTB is the process ID of the taskbar
    LPVOID lpPoint=VirtualAllocEx(hProc,NULL,sizeof(POINT),MEM_COMMIT,PAGE_READWRITE);
    WriteProcessMemory(hProc,lpPoint,&pt,sizeof(POINT),NULL);
    int i=(int)SendMessage(hwndTW,TB_HITTEST,0,(LPARAM)(LPPOINT)lpPoint);
    VirtualFreeEx(hProc,lpPoint,NULL,MEM_RELEASE);
    CloseHandle(hProc);

Meine Delphi Umsetzung ist wahrscheinlich noch nicht ganz richtig. Konnte sie auch nicht testen.


Delphi-Quellcode:
function getTaskbarHWND: HWND;
var
  ShellTrayWnd: HWnd;
  ReBarWindow32: HWnd;
  MSTaskSwWClass: HWnd;
begin
  Result := 0;
  ShellTrayWnd := FindWindow('Shell_TrayWnd', nil);
  if ShellTrayWnd = 0 then begin ShowMessage('No taskbar found'); Exit; end;
  ReBarWindow32 := FindWindowEx(ShellTrayWnd, 0, 'ReBarWindow32', nil);
  if ReBarWindow32 = 0 then begin ShowMessage('Error with taskbar'); Exit; end;
  MSTaskSwWClass := FindWindowEx(ReBarWindow32, 0, 'MSTaskSwWClass', nil);
  if MSTaskSwWClass = 0 then begin ShowMessage('Error inside taskbar'); Exit; end;
  Result := FindWindowEx(MSTaskSwWClass, 0, 'ToolbarWindow32', nil); // not for Win95 *
 end;
end;
Delphi-Quellcode:
var
  pt: TPOINT;
  TaskbarHWND: HWND;
  hProc: THandle;
  PID: THandle;
  lpNumberOfBytesWritten: DWORD;
  i: Integer;
  lpPoint: Pointer;
begin
 Sleep(2000);
  TaskbarHWND := getTaskbarHWND;
  GetCursorPos(pt);
  if (WindowFromPoint(pt) <> TaskbarHWND) then Exit;
  Windows.ScreenToClient(TaskbarHWND, pt);

  GetWindowThreadProcessId(TaskbarHWND, @PID);
  hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, PID);
  lpPoint := VirtualAllocEx(hProc, nil, SizeOf(TPoint), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

  FillChar(pt, SizeOf(TPOINT), 0);
  lpNumberOfBytesWritten := 0;

  WriteProcessMemory(hProc, lpPoint, @pt, SizeOf(TPOINT), lpNumberOfBytesWritten);
  i := SendMessage(TaskbarHWND, TB_HITTEST, 0, lParam(lpPoint)); //????
  Caption := IntToStr(i);
  VirtualFreeEx(hProc, lpPoint, NULL, MEM_RELEASE);
  CloseHandle(hProc);
Danach muesste man den Code mit folgendem Kombinieren, um an das Window Handle zu kommen:

Code:
// find Windows Taskbar (Note: works under XP and 2k3)
HWND hwndTaskbar = FindWindow("Shell_TrayWnd", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "ReBarWindow32", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "MSTaskSwWClass", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "ToolbarWindow32", NULL);i - &#1101;&#1090;&#1086; &#1080;&#1085;&#1076;&#1077;&#1082;&#1089; &#1082;&#1085;&#1086;&#1087;&#1082;&#1080; &#1085;&#1072; &#1090;&#1072;&#1089;&#1082;&#1073;&#1072;&#1088;&#1077;
// variables that needed to open taskbar (explorer) process
DWORD taskbarProcessID;
const int BUFFER_SIZE = 0x1000;

// obtain taskbar process id - by window
GetWindowThreadProcessId(hwndTaskbar, &taskbarProcessID);
// open taskbar process
HANDLE taskbarProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, taskbarProcessID);

// variable that helds pointer to a remote buffer in taskbar process
DWORD_PTR taskbarProcessBuffer;

// allocate space for remote buffer in taskbar process
taskbarProcessBuffer = (DWORD_PTR)VirtualAllocEx(taskbarProcessHandle, NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);

// declare and prepare variables that will held data
// about PRESSED button in a taskbar
TBBUTTON tbButton;
TBBUTTON* pTBButton = &tbButton;
DWORD_PTR lpTBButton = (DWORD_PTR)pTBButton;

// Now, retrieve information about the PRESSED button in a taskbar
// Note: data is placed in remote buffer
SendMessage(hwndTaskbar, TB_GETBUTTON, i, taskbarProcessBuffer);

// And now, the remote data about PRESSED button is transferred to a local variable
DWORD dwBytesRead = 0;
ReadProcessMemory(taskbarProcessHandle, (LPVOID)taskbarProcessBuffer, (LPVOID)lpTBButton, sizeof(TBBUTTON), &dwBytesRead);

// ------------------------------------------------------------------
// Where is keeped the window handle?
// It is in dwData field of TBBUTTON structure (the first 4 bytes) :))
// MSDN doesn't specify anything about this!
// ------------------------------------------------------------------

// Retrieve window handle of pressed btn
BYTE localBuffer[BUFFER_SIZE];
BYTE* pLocalBuffer = localBuffer;
DWORD_PTR ipLocalBuffer = (DWORD_PTR)pLocalBuffer;

// window handle
pLocalBuffer = localBuffer;
ipLocalBuffer = (DWORD_PTR)pLocalBuffer;

// initialize remote buffer
DWORD_PTR lpRemoteData = (DWORD_PTR)tbButton.dwData;

// and read the dwData fields of a TBBUTTON from remote process
ReadProcessMemory(taskbarProcessHandle, (LPVOID)lpRemoteData, (LPVOID)ipLocalBuffer, sizeof(DWORD_PTR), &dwBytesRead);

// obtain window handle
// copy first 4 bytes
HWND windowHandle;
memcpy(&windowHandle, (void *)ipLocalBuffer, 4);
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Mazel
Mazel

Registriert seit: 11. Nov 2005
Ort: Leipzig
831 Beiträge
 
#3

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 12:52
Hallo,

danke für die schnelle Antwort.

Zunächst werde ich versuchen müssen, den C Code in Delphi zu übersetzten. Da ich keinerlei Kentnisse in C habe, wird das sicher lange dauern, aber ich versuche es, denn ein paar kleine Dinge sind in Dephi nicht viel anders, dennoch werde ich da Hilfe brauchen.

Was ich gleich nicht verstanden habe ist: DWORD_PTR taskbarProcessBuffer;
Was beudetet PTR? Das selbe finde sich auch in der TBBUTTON Struktur.

Gruß
Mazel
Marcel Jänicke
www.mj-software.net
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 12:54
Das ist ein Pointer auf ein DWORD, also sowas wie "CardinalPtr", glaub ich. Die ganze Zeile ist eine Variablendeklaration.

EDIT: Wenn Delphi keine passenden Typ dafür hat, kannst du es auch als Pointer oder gleich als Cardinal deklarieren. Jenachdem, was in C alles damit gemacht wird, ist das eien oder das andere besser.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von Mazel
Mazel

Registriert seit: 11. Nov 2005
Ort: Leipzig
831 Beiträge
 
#5

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 13:46
Danke DGL-luke, diese Bezeichnung war mir nicht bekannt.

Ich habe mal in der Suche etwas herumgesucht und dabei folgendes Thema gefunden:
Taskbar aktualisieren

Nun kann man sicher den Code so umstellen, dass zumdindest ein paar Teile genutzt werden können. Ich habe das eben probiert, aber mir ist mein Rechner abgestürzt. Daher ist auch der von mir schon teilweise angepasste Code aus dem übernommen Code weg. Jetzt brauch ich erstmal Abstand um später einen neuen Versuch zu starten.

Eventuell weis jemand von euch, wie ich den Code am besten zusammensetze.

Gruß
Mazel
Marcel Jänicke
www.mj-software.net
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#6

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 17:51
Vielleicht koennte jemand noch helfen, diese 3 Codefragemente nach Delphi zu uebersetzen

1.
Code:
SendMessage(hwndTW,TB_HITTEST,0,(LPARAM)(LPPOINT)lpPoint);
2.
Code:
TBBUTTON tbButton;
TBBUTTON* pTBButton = &tbButton;
DWORD_PTR lpTBButton = (DWORD_PTR)pTBButton;
3.
Code:
// Retrieve window handle of pressed btn
BYTE localBuffer[BUFFER_SIZE];
BYTE* pLocalBuffer = localBuffer;
DWORD_PTR ipLocalBuffer = (DWORD_PTR)pLocalBuffer;
pLocalBuffer = localBuffer;
ipLocalBuffer = (DWORD_PTR)pLocalBuffer
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 18:26
1.
SendMessage(hwndTW,TB_HITTEST,0,Integer(lpPoint)); 2.
Delphi-Quellcode:
var
  tbButton: TBButton;
  PtbButton: Pointer;

PtbButton := @TBButton;
3.
Delphi-Quellcode:
// Retrieve window handle of pressed btn
var
  localBuffer: array[0..BUFFER_SIZE-1] of Byte;
  pLocalBuffer: ^Byte; //"BytePointer", könnte sein dass Delphi schon "PByte" definiert hat, das ist dann schöner
  ipLocalBuffer: Pointer;

pLocalBuffer := @localBuffer[0];
ipLocalBuffer := pLocalBuffer;
WObei mir die etwas sinnlos erscheinen, die Codestückchen, insbesondere wenn man was erst initialisiert und ihm dann den sleben wert nochmal zuweist.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#8

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 18:30
Danke erstmal. Habe das 1. Codestueck ueberarbeitet und es liefert schonmal erfolgreich den Index des Buttons unter der Maus.

Delphi-Quellcode:
var
  pt: TPOINT;
  TaskbarHWND: HWND;
  hProc: THandle;
  PID: THandle;
  NumBytes: DWORD;
  iButtonIndex : Integer;
  lpPoint: Pointer;
begin
  TaskbarHWND := getTaskbarHWND;
  GetCursorPos(pt);
  if (WindowFromPoint(pt) <> TaskbarHWND) then Exit;
  Windows.ScreenToClient(TaskbarHWND, pt);
  PID := 0;
  GetWindowThreadProcessId(TaskbarHWND, @PID);
  hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, PID);
  if hProc <> 0 then
  try
    lpPoint := VirtualAllocEx(hProc, nil, SizeOf(TPoint), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
    NumBytes := 0;
    WriteProcessMemory(hProc, lpPoint, @pt, SizeOf(TPOINT), NumBytes);
    // Index ermittlen
    iButtonIndex := SendMessage(TaskbarHWND,TB_HITTEST,0,Integer(lpPoint));
    Caption := IntToStr(iButtonIndex );
    if Assigned(lpPoint) then
      VirtualFreeEx(hProc, lpPoint, 0, MEM_RELEASE);
  finally
    CloseHandle(hProc);
  end;
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#9

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 18:39
Anbei schonmal ein Entwurf meiner Delphi Uebersetzung des 2. Codefragmentes.
Es liefert von einem gegebenem Buttonindex das Handle des zugehoerigen Fensters.


Delphi-Quellcode:
function GetHandleFromButtonIndex(ButtonIndex: Word): HWND;
const
  BUFFER_SIZE = $1000;
var
  hwndTaskbar: HWND;
  // variables that needed to open taskbar (explorer) process
  taskbarProcessID: DWORD;
  taskbarProcessHandle: THandle;
 // variable that helds pointer to a remote buffer in taskbar process
  taskbarProcessBuffer: Pointer;
  i: Integer;
  dwBytesRead: DWORD;
  lpRemoteData: Pointer;
  tbButton: TTBBUTTON;
  PtbButton: Pointer;
  localBuffer: array[0..BUFFER_SIZE - 1] of Byte;
  pLocalBuffer: ^Byte;
  ipLocalBuffer: Pointer;
  btnWindowHandle: HWND;
begin
  Result := 0;
  // find Windows Taskbar
  hwndTaskbar := getTaskbarHWND;
  if hwndTaskbar <> 0 then
  begin
    // obtain taskbar process id - by window
    GetWindowThreadProcessId(hwndTaskbar, @taskbarProcessID);
    // open taskbar process
    taskbarProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, taskbarProcessID);
    if taskbarProcessHandle <> 0 then
    try
      // allocate space for remote buffer in taskbar process
      taskbarProcessBuffer := VirtualAllocEx(taskbarProcessHandle, nil, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
      if Assigned(taskbarProcessBuffer) then
      begin
        // declare and prepare variables that will held data
        // about PRESSED button in a taskbar
        PtbButton := @tbButton;
        // Now, retrieve information about the PRESSED button in a taskbar / data is placed in remote buffer
        SendMessage(hwndTaskbar, TB_GETBUTTON, ButtonIndex, Integer(taskbarProcessBuffer));
        // And now, the remote data about PRESSED button is transferred to a local variable
        dwBytesRead := 0;
        ReadProcessMemory(taskbarProcessHandle, taskbarProcessBuffer, PtbButton, SizeOf(TBBUTTON), dwBytesRead);
        // the window handle is in dwData field of TBBUTTON structure (the first 4 bytes)
        pLocalBuffer := @localBuffer[0];
        ipLocalBuffer := pLocalBuffer;
        // initialize remote buffer
        lpRemoteData := @tbButton.dwData;
        // and read the dwData fields of a TBBUTTON from remote process
        dwBytesRead := 0;
        ReadProcessMemory(taskbarProcessHandle, lpRemoteData, ipLocalBuffer, SizeOf(Pointer), dwBytesRead);
        // obtain window handle, copy first 4 bytes
        Move(ipLocalBuffer, btnWindowHandle, 4);
        Result := btnWindowHandle;
        if Assigned(taskbarProcessBuffer) then
          VirtualFreeEx(taskbarProcessHandle, taskbarProcessBuffer, 0, MEM_RELEASE);
      end;
    finally
      CloseHandle(taskbarProcessHandle);
    end;
  end;
end;
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Mazel
Mazel

Registriert seit: 11. Nov 2005
Ort: Leipzig
831 Beiträge
 
#10

Re: Handle einer Form aus Taskbareintrag erhalten

  Alt 22. Apr 2007, 19:00
Das ist ja wirklich super

Ich habe eben den ersten Codeabschnitt kopiert und eingefügt und das funktioniert auch ohne Probleme. Der 2. Abschnitt geht aber noch nicht ganz. Egal welchen Button ich betätige, es wird immer der selbe Wert zurückgegeben.
Ich bin sicher, das Problem wird auch noch gelöst. Jetzt werde ich aber nichts mehr machen, morgen steht Geschichte Abi-Prüfung an.

Gruß
Mazel
Marcel Jänicke
www.mj-software.net
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz