Pobieranie tekstu z ikony w trayu w WinAPI

Pobieranie tekstu z ikony w trayu w WinAPI
Markness
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 2 lata
0

witam! czy jest możliwość za pomocą winapi (lub innym sposobem) pobrać tekst który pojawia się kiedy najedziemy na jakąś ikonkę w trayu (ten w dymku)? Jeśli tak to jaka funkcja? z góry dzięki!

flowCRANE
To się Hint nazywa;
Markness
dzięki, jednak u wujka dalej nie znalazłem odpowiedzi..
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:21 minut
  • Lokalizacja:Gorlice
1

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
Markness
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 2 lata
0

program rzeczywiście wyciąga dokładnie tą informacje którą szukam, niestety muszę chyba odpuścić ponieważ z moją wiedzą nie jestem w wyłuskać prawidłowego kodu, dzięki kAzek za fatyge

olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
1

Z tego co widze, najwązniejszy kod dla ciebie jest w pliku ShellTrayInfoView.cpp i zaczyna się od tekstu void CShellTrayInfoView::ListTrayIcons. Sam próbowałem znalezione w google kody w Delphi z użyciem komunikatu TB_GETBUTTON przerobić i uzupełnić aby odczytywały też tak zwany ToolTip, ale nie bardzo mi to wyszło.


Pozdrawiam.
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:21 minut
  • Lokalizacja:Gorlice
0

Wersja dla Delphi (ale odpowiedzialne za pobranie info funkcje to WinApi więc można sobie przetłumaczyć na inny język) pobierania info o ikonach w trayu może komuś się przyda:
Na formie ListView, ImageList i Button
ListView ma 3 kolumny i przypisany jako SmallImages ImageList

Kopiuj
//do uses CommCtrl, PsApi

//zwraca sciezkę i nazwe proceu parametr to PID
function GetFilenameFromPid(PID: Cardinal): string;
var
  hProcess: Cardinal;
  buff: array[0..MAX_PATH - 1] of Char;
begin
  result:= '';
  hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  if (hProcess > 0) then
  begin
    if GetModuleFileNameEx(hProcess, 0, buff, MAX_PATH) > 0 then
      result:= buff;
    CloseHandle(hProcess);
  end;
end;

//zwraca uchwyt toolbara traya
function FindTrayToolbarWindow: Cardinal;
const
  WND_CLASS_ARRAY: array [0..3] of string =
    ('Shell_TrayWnd', 'TrayNotifyWnd', 'SysPager', 'ToolbarWindow32');
var
  i: Integer;
begin
  i:= Low(WND_CLASS_ARRAY);
  result:= FindWindow(PAnsiChar(WND_CLASS_ARRAY[i]), nil);
  Inc(i);
  while ((result > 0) and (i <= High(WND_CLASS_ARRAY))) do
  begin
    result:= FindWindowEx(result, 0, PAnsiChar(WND_CLASS_ARRAY[i]), nil);
    Inc(i);
  end;
end;

procedure TForm1.btnLoadTrayIconsInfoClick(Sender: TObject);

type
  _EXTRADATA = packed record
    hWnd: THandle;
    uID: UINT;
    uCallbackMessage: UINT;
    Reserved: array [0..1] of DWORD;
    hIcon: HICON;
  end;

var
  pTrayBtnData: Pointer;
  hTray, hProcessExplorer: Cardinal;
  dwExplorerProcessID, dwBytesRead, dwTrayButtonCount: Cardinal;
  ButtonData: _TBBUTTON;
  ExtraData: _EXTRADATA;
  ToolTip: array [0..1024] of WideChar;
  pIconInfo: _ICONINFO;
  i: Integer;

  dwInfoProcessID: Cardinal;
  sInfoProcessName: string;
  sInfoToolTip: string;
  hInfoIcon: Cardinal;

  li: TListItem;
  ico: TIcon;
begin
  ImageList1.Clear;
  ListView1.Clear;

  hTray:= FindTrayToolbarWindow;
  if hTray = 0 then exit;
  if (GetWindowThreadProcessId(hTray, dwExplorerProcessID) = 0) then exit;
  hProcessExplorer:= OpenProcess(PROCESS_ALL_ACCESS, False, dwExplorerProcessID);
  if (hProcessExplorer = 0) then exit;
  pTrayBtnData:= VirtualAllocEx(hProcessExplorer, nil, SizeOf(_TBBUTTON),
    MEM_COMMIT, PAGE_READWRITE);
  if (Assigned(pTrayBtnData)) then
  begin
    dwTrayButtonCount:= SendMessage(hTray, TB_BUTTONCOUNT, 0, 0);
    for i:= 0 to dwTrayButtonCount - 1 do
    begin
      SendMessage(hTray, TB_GETBUTTON, i, Longint(pTrayBtnData));
      if ReadProcessMemory(hProcessExplorer, pTrayBtnData, @ButtonData,
           SizeOf(_TBBUTTON), dwBytesRead) and (dwBytesRead = SizeOf(_TBBUTTON)) then
      begin
        sInfoProcessName:= '';
        hInfoIcon:= 0;
        if ReadProcessMemory(hProcessExplorer, Pointer(ButtonData.dwData),
             @ExtraData, SizeOf(_EXTRADATA), dwBytesRead) and
             (dwBytesRead = SizeOf(_EXTRADATA)) then
        begin
          GetWindowThreadProcessId(ExtraData.hWnd, dwInfoProcessID);
          sInfoProcessName:= GetFilenameFromPid(dwInfoProcessID);
          hInfoIcon:= ExtraData.hIcon;
        end;
        sInfoToolTip:= '';
        if ReadProcessMemory(hProcessExplorer, Pointer(ButtonData.iString),
             @ToolTip, 1024, dwBytesRead) and (dwBytesRead = 1024) then
        sInfoToolTip:= WideCharToString(ToolTip);

        li:= ListView1.Items.Add;
        li.SubItems.Add(sInfoToolTip);
        li.SubItems.Add(sInfoProcessName);
        li.ImageIndex:= -1;
        if GetIconInfo(hInfoIcon, pIconInfo) then
        begin
          ico:= TIcon.Create;
          try
          ico.Handle:= hInfoIcon;
          li.ImageIndex:= ImageList1.AddIcon(ico);
          finally
          ico.Free;
          end;
        end;

      end;
    end;
    VirtualFreeEx(hProcessExplorer, pTrayBtnData, 0, MEM_RELEASE);
  end;
  CloseHandle(hProcessExplorer);
end;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

@kAzek: rozumiem, że kod działa u Ciebie prawidłowo? Bo u mnie efekt jego działania jest widoczny na obrazie poniżej. Za pewne "winny" jest tutaj 64 bitowy system. Jednak kody znalezione na google dla wersji 64 bitowej, wprawdzie na podobnej zasadzie, ale tylko dla odświeżenia obszaru Tray, też nie pomogły mi sklecić nic samodzielnie. Po prostu if po hInfoIcon := 0; nie wykonuje się, a poza tym nawet jeżeli by z niego zrezygnować to ExtraData.hWnd pokazuje zawsze ten sam uchwyt. Masz może pomysł jak zmusić do prawidłowego działania Twój kod na systemie Windows 7 Ultimate 64 bit? Bo moze trzeba było by jakoś "scalić" kod z http://www.delmadang.com/community/bbs_print.asp?bbsNo=3&bbsCat=0&indx=428067 który działa ok jeśli chodzi o odświeżanie i przetumaczyć kod z http://www.haogongju.net/art/1282689 na Delphi, który uwzględnia bitowośc systemu.
kazek_code_test.jpg


Pozdrawiam.
edytowany 1x, ostatnio: olesio
KA
Ja jeszcze ciągle na 32 bit XP. Ile u Ciebie wynosi SizeOf(_EXTRADATA) ? Kod z demo z tamtej strony działa normalnie?
KA
A już widzę są różnice w TBBUTTON64 i Pointer(ButtonData.dwData) nie wiadomo na co wskazuje w 64bit pewnie przez to zaraz to obczaję...
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

@kAzek: próbowałem tłumaczyć kod z: http://www.haogongju.net/art/1282689 - stamtąd można zobaczyć różnicę w ustawianiu offsetu. tyle co potrafiłem to przetłumaczyłem na Delphi, ale chyba nie do konca prawidłowo. Próbując zapisać albo wyświetlić zmienną buff otrzymuje jakieś znaczki ASCII. Może spojrzysz - kod i exek w załączniku. Natomiast, tak jak pisałem kod z tej strony jeżeli chodzi o odświeżanie działa ok na 64 bitach, tylko nie umiem go zaadaptować do odczytania informacji takich jak ToolTip oraz ewentualnie ikonka danego procesu: http://www.delmadang.com/community/bbs_print.asp?bbsNo=3&bbsCat=0&indx=428067 - jak uda się Tobie coś wykombinować i bedzie to uniwersalny kod dla 32 bitów oraz 64 bitów to proszę daj przykład. Do sprawdzania bitowości systemu najprościej będzie chyba wykorzystać poniższą funkcję, która kompiluje się oczywiście również pod starszymi wersjami Delphi, jak siódemka.

Kopiuj
function IsWow64 : boolean;
type
  TIsWow64Process = function(hProcess : THANDLE; Wow64Process : PBOOL) : BOOL; stdcall;
var
  IsWow64Process : TIsWow64Process;
begin
  IsWow64Process := GetProcAddress(GetModuleHandle('kernel32'), 'IsWow64Process');
  if Assigned(IsWow64Process) then
  begin
    IsWow64Process(GetCurrentProcess, @Result);
  end;
end;

Pozdrawiam.
Azarien
To nie jest dobra funkcja. Bo co jeśli nie jest Assigned? Co wtedy zwracasz? Poza tym, jeśli program jest 64-bitowy to IsWow64Process zwróci false, czyli znowu źle...
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:21 minut
  • Lokalizacja:Gorlice
0

@olesio sprawdź nową wersję kodu jest zgodna z nowymi wersjami Delphi, teoretycznie powinna działać pod 64bit ale nie sprawdziłem bo nie mam jak. Jeżeli nadal nie działa to myślę że pod 64 _EXTRADATA też trzeba inaczej zdefiniować :/ Jak coś to napisz co się dzieje tym razem.

Kopiuj
//do uses CommCtrl, PsApi

//zwraca sciezkę i nazwe proceu parametr to PID
function GetFilenameFromPid(PID: Cardinal): string;
var
  hProcess: Cardinal;
  buff: array[0..MAX_PATH - 1] of Char;
begin
  result:= '';
  hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  if (hProcess > 0) then
  begin
    if GetModuleFileNameEx(hProcess, 0, buff, MAX_PATH) > 0 then
      result:= buff;
    CloseHandle(hProcess);
  end;
end;

//zwraca uchwyt toolbara traya
function FindTrayToolbarWindow: Cardinal;
const
  {$IFDEF UNICODE}
  WND_CLASS_ARRAY: array [0..3] of PWideChar =
      ('Shell_TrayWnd', 'TrayNotifyWnd', 'SysPager', 'ToolbarWindow32');
  {$ELSE}
  WND_CLASS_ARRAY: array [0..3] of PAnsiChar =
      ('Shell_TrayWnd', 'TrayNotifyWnd', 'SysPager', 'ToolbarWindow32');
  {$ENDIF}
var
  i: Integer;
begin
  i:= Low(WND_CLASS_ARRAY);
  result:= FindWindow(WND_CLASS_ARRAY[i], nil);
  Inc(i);
  while ((result > 0) and (i <= High(WND_CLASS_ARRAY))) do
  begin
    result:= FindWindowEx(result, 0, WND_CLASS_ARRAY[i], nil);
    Inc(i);
  end;
end;

function IsWow64: Boolean;
type  //tak to musi byc bo inaczej sie wyklada w nowych Delphi
  TIsWow64Process = function(hProcess : THANDLE; var Wow64Process: BOOL): BOOL; stdcall;
var
  IsWow64: BOOL;
  IsWow64Process: TIsWow64Process;
begin
  result:= False;
  @IsWow64Process := GetProcAddress(GetModuleHandle('kernel32'), 'IsWow64Process');
  if Assigned(IsWow64Process) then
  begin
    IsWow64Process(GetCurrentProcess, IsWow64);
    result:= IsWow64;
  end;
end;

procedure TForm1.btnLoadTrayIconsInfoClick(Sender: TObject);
type
  {$IFNDEF _TBBUTTON}
  _TBBUTTON = packed record
    iBitmap: Integer;
    idCommand: Integer;
    fsState: Byte;
    fsStyle: Byte;
    bReserved: array[1..2] of Byte;
    dwData: Longint;
    iString: Integer;
  end;
  {$ENDIF}

  {$IFNDEF _TBBUTTON64}
  _TBBUTTON64 = packed record
    iBitmap: Integer;
    idCommand: Integer;
    fsState: Byte;
    fsStyle: Byte;
    iReserved: Integer;
    bReserved2: array[1..2] of Byte;
    dwData: Longint;
    iString: Integer;
  end;
  {$ENDIF}

  _EXTRADATA = packed record
    hWnd: THandle;
    uID: UINT;
    uCallbackMessage: UINT;
    Reserved: array [0..1] of DWORD;
    hIcon: HICON;
  end;

const
  {$IFNDEF TB_GETBUTTON}
  TB_GETBUTTON = WM_USER + 23;
  {$ENDIF}
  {$IFNDEF TB_BUTTONCOUNT}
  TB_BUTTONCOUNT = WM_USER + 24;
  {$ENDIF}
var
  pTrayBtnData: Pointer;
  dwTrayBtnDataSzie: Cardinal;
  pButtonData: Pointer;

  hTray, hProcessExplorer: Cardinal;
  dwExplorerProcessID, dwTrayButtonCount: Cardinal;
  {nie wiem dokladnie od jakiej wersji musi byc NativeUInt zakladam w ciemno że od XE jak nie chce sie kompilowac to trzeba zmienic}
  {$IF CompilerVersion >= 22}
  dwBytesRead: NativeUInt;
  {$ELSE}
  dwBytesRead: Cardinal;
  {$IFEND}
  ExtraData: _EXTRADATA;
  ToolTip: array [0..1024] of WideChar;
  pIconInfo: _ICONINFO;
  i: Integer;

  dwInfoProcessID: Cardinal;
  sInfoProcessName: string;
  sInfoToolTip: string;
  hInfoIcon: Cardinal;

  li: TListItem;
  ico: TIcon;

  nDataOffset: Integer;
  nStrOffset: Integer;

  bIs64bit: Boolean;
begin
  {$IFNDEF WIN64} //czy 64bit wersja aplikacji
  bIs64bit:= IsWow64;
  {$ELSE} //no bez jaj pod Mac OS to i tak nie pojdzie wiec nie ma co sie p...c
  bIs64bit:= True;
  {$ENDIF}

  if bIs64bit then
    dwTrayBtnDataSzie:= SizeOf(_TBBUTTON64)
  else
    dwTrayBtnDataSzie:= SizeOf(_TBBUTTON);

  ImageList1.Clear;
  ListView1.Clear;


  hTray:= FindTrayToolbarWindow;
  if hTray = 0 then exit;
  if (GetWindowThreadProcessId(hTray, dwExplorerProcessID) = 0) then exit;
  hProcessExplorer:= OpenProcess(PROCESS_ALL_ACCESS, False, dwExplorerProcessID);
  if (hProcessExplorer = 0) then exit;
  pTrayBtnData:= VirtualAllocEx(hProcessExplorer, nil, dwTrayBtnDataSzie,
    MEM_COMMIT, PAGE_READWRITE);
  if (Assigned(pTrayBtnData)) then
  begin
    pButtonData:= AllocMem(dwTrayBtnDataSzie);
    dwTrayButtonCount:= SendMessage(hTray, TB_BUTTONCOUNT, 0, 0);
    for i:= 0 to dwTrayButtonCount - 1 do
    begin
      SendMessage(hTray, TB_GETBUTTON, i, Longint(pTrayBtnData));
      if ReadProcessMemory(hProcessExplorer, pTrayBtnData, pButtonData,
           dwTrayBtnDataSzie, dwBytesRead) and (dwBytesRead = dwTrayBtnDataSzie) then
      begin
        if bIs64bit then
        begin
          nDataOffset:= _TBBUTTON64(pButtonData^).dwData;
          nStrOffset:= _TBBUTTON64(pButtonData^).iString;
        end
        else
        begin
          nDataOffset:= _TBBUTTON(pButtonData^).dwData;
          nStrOffset:= _TBBUTTON(pButtonData^).iString;
        end;

        dwInfoProcessID:= 0;
        sInfoProcessName:= '';
        hInfoIcon:= 0;
        if ReadProcessMemory(hProcessExplorer, Pointer(nDataOffset),
             @ExtraData, SizeOf(_EXTRADATA), dwBytesRead) and
             (dwBytesRead = SizeOf(_EXTRADATA)) then
        begin
          GetWindowThreadProcessId(ExtraData.hWnd, dwInfoProcessID);
          sInfoProcessName:= GetFilenameFromPid(dwInfoProcessID);
          hInfoIcon:= ExtraData.hIcon;
        end;
        sInfoToolTip:= '';
        if ReadProcessMemory(hProcessExplorer, Pointer(nStrOffset),
            @ToolTip, 1024, dwBytesRead) and (dwBytesRead = 1024) then
          sInfoToolTip:= WideCharToString(ToolTip);

        li:= ListView1.Items.Add;
        li.SubItems.Add(sInfoToolTip);
        li.SubItems.Add(sInfoProcessName);
        li.ImageIndex:= -1;
        if GetIconInfo(hInfoIcon, pIconInfo) then
        begin
          ico:= TIcon.Create;
          try
          ico.Handle:= hInfoIcon;
          li.ImageIndex:= ImageList1.AddIcon(ico);
          finally
          ico.Free;
          end;
        end;

      end;
    end;
    FreeMem(pButtonData);
    VirtualFreeEx(hProcessExplorer, pTrayBtnData, 0, MEM_RELEASE);
  end;
  CloseHandle(hProcessExplorer);
end;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 1x, ostatnio: kAzek
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Dziękuję za poświęcenie czasu @kAzek. Ale niestety, w przypadku dwóch procesów pokazują się tylko ich prawidłowe ścieżki (akurat mialem uruchomiony WinAPI i mój program, który globalnym hookiem wykrywa i przebindowuje działanie jednego z klawiszy na klawiaturze). Nadal jednek brak ikonek oraz ToolTipów. A @Azarien: jaką funkcję do tego proponujesz i czy masz może pomysł jak pod Delphi rozwiązać problem poruszony w wątku dla 64 `itowego systemu. Może jednak kod z http://www.haogongju.net/art/1282689 dobrze przetłumaczony na Delphi by zadziałał jak trzeba?


Pozdrawiam.
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:21 minut
  • Lokalizacja:Gorlice
0

@olesio nie ma sensu tłumaczyć tamtego kodu bo to na jedno wychodzi :/
Na razie błąd to deklaracja _TBBUTTON64 zaraz wyjaśnię o co chodzi:
Według kodu ze strony którą podałeś tam jest:

Kopiuj
int nDataOffset = sizeof(TBBUTTON) - sizeof(INT_PTR) - sizeof(DWORD_PTR);  //12
  int nStrOffset = 18;
  if ( IsWow64() ){
        //to sie zgadza  bo dochodza 4 bajty przed _TBBUTTON64.dwData
        nDataOffset+=4;
        //a to z dupy wziete bo size of Integer = 4, sizeof longint = 4  sizeof UInt64 = 8 to
        //do cholery jakiego typu jest  _TBBUTTON64.nDataOffset jak chcą aby zajmowal 6 bajtow
        nStrOffset+=6;
  }
Kopiuj
 Więc można spróbować deklarować tak:

   {$IFNDEF _TBBUTTON64}
  _TBBUTTON64 = packed record
    iBitmap: Integer;
    idCommand: Integer;
    fsState: Byte;
    fsStyle: Byte;
    bReserved: array[1..6] of Byte;
    dwData: Longint;
    bReserved: array[1..2] of Byte; //tu dodamy te 2 'zgubione' bajty
    iString: Integer;
  end;
  {$ENDIF}

i wtedy teoretycznie powinno działać.

Ale na msdn znalazłem:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553%28v=vs.85%29.aspx
i tam:

Kopiuj
typedef struct
{
  INT       iBitmap;
  INT       idCommand;
  BYTE      fsState;
  BYTE      fsStyle;
  BYTE      bReserved[6];
  UINT64    dwData;
  UINT64    iString;
} TBBUTTON64;

a więc TBBUTTON64.dwData i TBBUTTON64.iString są typu UINT64 a ten zajmuje 8 bajtów więc jestem głupi można spróbować zadeklarować tak:

Kopiuj
  {$IFNDEF _TBBUTTON64}
  _TBBUTTON64 = packed record
    iBitmap: Integer;
    idCommand: Integer;
    fsState: Byte;
    fsStyle: Byte;
    bReserved: array[1..6] of Byte;
    dwData: UINT64;
    iString: UINT64;
  end;
  {$ENDIF}

tyle że w kodzie jest rzutowanie na Pointer i znowu do d**y ale spróbuj obie wersje.

PS: Brak ikony moze być z kolei błędem w deklaracji _EXTRADATA (też moze sie różnić na 64 bit) ale to na razie niw ważne trzeba ToolTip obczaić pierwsze a nie w 2 miejscach grzebać jednocześnie


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 2x, ostatnio: kAzek
olesio
Ok, dziękuję i tak za poświecony temu czas. Pytającemu powinny wstarczyć linki i wklejone tutaj fragmenty kodów. Ja jakoś bez takiego programu przeżyję na 64 bitowym systemie. Może w przyszłości ktoś coś zkleci, co będzie w Delphi działać pod 64 bitowym OS i się z nami tym rozwiązaniem podzieli, to fajnie, nie to też ok.
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:21 minut
  • Lokalizacja:Gorlice
0

Chyba jednak w pierwszej wersji (w tej co podałem cały kod nowej wersij) deklaracja _TBBUTTON64 jest ok tylko spróbuj zamiast tamtego _EXTRADATA wszędzie (do testu na razie na sztywno) użyć _EXTRADATA64 jak i stopniowo zwiększaj wielkosć tablicy Reserved2 (myślę że nie więcej niż do 16) jak będzie będzie ok to powinna być ikonka:

Kopiuj
_EXTRADATA64 = packed record
    hWnd: THandle;
    uID: UINT;
    uCallbackMessage: UINT;
    Reserved: array [1..2] of DWORD;
    Reserved2: array[1..n] of Byte;
    hIcon: HICON;
  end;

Co do ToolTip to sprawa taka że nie wiem ReadProcessMemory odczytuje?
Moze tam nie ma być WideCharToString albo ToolTip: array [0..1024] of WideChar; ma być Char czy coś najlepiej w Watches sobie podglądnij co masz w zmiennej ToolTip po ReadProcessMemory.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Przy założeniu, że n = 2 i poprawieniu typów, efekt jest taki sam. U mnie ToolTip pokazuje w MessageBoxie same znaki zapytania, a po konwersji wykonanej jak u Ciebie - jest to pusty string. Trudno, ja sam nie mam ochoty dociekać co i jak, a Ty bez 64 bitowego systemu też nie dojdziesz. Może ktoś inny się jeszcze właczy w ten wątek i wymyśli uniwersalny kod, który zadziała też pod 64 bitowym systemem. Niemniej jednak - jeszcze raz, dziękuje Tobie za czas jaki poświęciłeś aby to w ogóle działąlo chociaż na 32 bitowym systemie kompilując pod Delphi.


Pozdrawiam.
RE
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:11 miesięcy
0

Zawaliliście cały wątek niedziałającymi kodami w Delphi nie pytając nawet autora w jakim języku pisze. A najprawdopodobniej chodzi o C#, ew. C++.

edytowany 1x, ostatnio: Rev
KA
Gdybyś nie zauważył to te kody działają tyle że tylko pod 32 bit zresztą chodzi o WinApi wszędzie (mam na myśli pod "normalny" Windows i oczywiście zdaję sobie sprawę że w starszych i mobilnych systemach nie ma niektórych funkcji) jest takie samo... to nie miał być GOTOWIEC ale przykład jakich funkcji użyć aby to zrobić. Zresztą dla C++ ma podane min. 2 linki.
olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

No to już autor powinien sprecyzowac. Nie nasz wina. A w WinAPI oczywiście równie dobrze można pisać i pod Delphi. Natomiast podałem też link do kodu w C++ gdzie ze screenshotów wynika, że działa. I jest sprawdzanie czy mamy do czynienia z uruchomieniem pod 64 bitowym systemem oraz odpowiednią reakcją na ten fakt.


Pozdrawiam.
edytowany 1x, ostatnio: olesio
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 9 godzin
0

@Azarien: jaką funkcję do tego proponujesz i czy masz może pomysł jak pod Delphi rozwiązać problem poruszony w wątku dla 64 `itowego systemu.

Funkcja jest dobra (IsWow64Process), tylko jej użycie nie.

Nie mam pod ręką gotowego przykładu, ale należy użyć jej tak:
• jeśli nasz program jest 64-bitowy (a to możemy sprawdzić jakimś ifdefem, albo sizeof(pointer)), to jest oczywiste, że system jest 64-bitowy. inaczej program by się przecież nie uruchomił...
• jeśli nasz program jest 32-bitowy, to system może być 32-, albo 64-bitowy. i teraz sprawdzamy tak:
· jeśli funkcji IsWow64Process nie da się załadować, to system jest na pewno 32-bitowy.
· jeśli funkcja zwraca true, to system jest 64-bitowy,
· jeśli funkcja zwraca false, to system jest 32-bitowy.

IsWow64Process() zwraca true tylko dla programu 32-bitowego uruchomionego pod systemem 64-bitowym. czyli w programach 64-bitowych zwraca false.

edytowany 2x, ostatnio: Azarien
Markness
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 2 lata
0

Przepraszam za pierwszy post byłem pewny że uwzględniłem preferowana technologię, jest to c# w ostateczności c++. Niestety raczej muszę jednak zrezygnować z tego projektu ;)

olesio
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

@Markness: jak uważasz, ale może nie poddawaj się. Kody, które podal @kAzek działają na systemie 32 bitowym. Tak on twierdzi, a ja nie mam podstaw by mu nie wierzyć. Poza tym kod w C++ z pod jednego, z adresów. które podałem również powinien działać, jeżeli wierzyć autorowi dołaczonych do wpisu na stronie zrzutów ekranowych. W tym drugim przypadku uniknął byś konieczności tlumaczenia tego z Delphi.


Pozdrawiam.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)