Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Looking 4 help (https://www.delphipraxis.net/3128-looking-4-help.html)

Mr.Sade 25. Feb 2003 02:14


Looking 4 help
 
does anybody understand english here ?
sorry, I dont know how to read german, just English and Spanish.
if so, I looking for your help!!
thank you

Darty 25. Feb 2003 06:44

Sure, anyone would understand english. You don't found help in your language ?

Mr.Sade 25. Feb 2003 07:53

Cool :)
 
I have look for help in my language, but they have not work on Hooks, Subclassing, and MMF.

I would like to Subclass Notepad, I have set a CBT hook to know when windows are created and destroyed.
If the window's created class is equal to "Notepad" I subclass it and store some values on Memory with MMF to share the data.
Inside my new Notepad WNDPROC function I add a dynamic menu to it, and when I click in it, I will show a messagebox like You clicked item 1, etc.

Everything works good with with 1 instance, but when I open more than one instance of notepad it crashes.
I think I need an array to stored the values that SetWindowLong returns
for each instance of Notepad
If someone would like to help me to finish my proyect I will send you my Dll Code.
It's about Hooks, Subclassing and MMF.
Thanks

P.S: my ICQ number is you would like to contact me: 102211848

janjan 25. Feb 2003 08:15

Have you ever tried http://www.experts-exchange.com/?

Luckie 25. Feb 2003 09:23

Hello MrSade,
even english speaking members are always welcome in this message board. But we would appreciate it if you would choose a better title for your thread next time.

Concerning your problem: The first step would be to use an array of pointer for the values that are returned by SetWindowLong. But the problem which instance of Notepad is activated still remains. For that problem I don't know a solution either - sorry.

Mr.Sade 27. Feb 2003 08:06

SetWindowLong and GWL_USERDATA error
 
Hello people

I'm sorry about the title :oops:

I'm having another problem.
I'm using SetWindowLong with GWL_USERDATA to store a pointer, doing that I dont have to declare a dinamic array to store the values returned by SetWindowLong and GWL_WNDPROC.
So I have this to store a pointer to the window:

Delphi-Quellcode:
procedure NotepadCreated(Handle: HWND);
var
  Win: PWinInfo;
begin
  New(Win);
  Win^.Handle := Handle;
  Win^.OldPtr := GetWindowLong(Handle, GWL_WNDPROC);
  { lets subclass it }
  SetWindowLong(Handle, GWL_WNDPROC, Integer(@NotepadProc));
  { assign pointer to window }
  SetWindowLong(Handle, GWL_USERDATA, Integer(@Win));
end;
when the hook sends me a message that notepad is clossing I have this:
Delphi-Quellcode:
procedure NotepadDestroyed(Handle: HWND);
var
  Win: PWinInfo;
begin
  Win := PWinInfo(GetWindowLong(Handle, GWL_USERDATA));
  { set oldptr back}
  SetWindowLong(Handle, GWL_WNDPROC, Win^.OldPtr);
  { free memory pointer}
  Dispose(Win);
end;
Well, that works good.
The problem is when closing my application.
I have to set back all notepad pointers so I call CleanNotepadPtrs.
Delphi-Quellcode:
function EnumWins(Handle: HWND; lParam: LPARAM): Boolean;
    stdcall;
var
  szClass: array [0..256] of Char;
  Win: PWinInfo;
begin
  ZeroMemory(@szClass, 256);
  GetClassName(Handle, szClass, 256);
  if szClass = 'Notepad' then
  begin
    Win := PWinInfo(GetWindowLong(Handle, GWL_USERDATA));
    { set back ptr }
    SetWindowLong(Handle, GWL_WNDPROC, Win^.OldPtr);
    { free memory }
    Dispose(Win);
  end;
  Result := True;
end;

procedure CleanNotepadPtrs;
begin
  EnumWindows(@EnumWins, 0);
end;
Well, You see, It's the same as before, but Notepad crashes.
do you know what could I been doing wrong ?
I have also tried to send a message inside NotePadWndProc and
read the pointer (GWL_USERDATA) and then that sets back the pointer (GWL_WNDPROC), but also causes an error

Thank You.

Luckie 27. Feb 2003 13:15

procedure:
Delphi-Quellcode:
procedure NotepadDestroyed(Handle: HWND);
var
  Win: PWinInfo;
begin
  Win := PWinInfo(GetWindowLong(Handle, GWL_USERDATA));
  { set oldptr back}
  SetWindowLong(Handle, GWL_WNDPROC, Win^.OldPtr);
  { free memory pointer}
  Dispose(Win);
end;
Does Win^.OldPtr really have a valid value? Try this:
Delphi-Quellcode:
Win^.OldPtr := PWinInfo(GetWindowLong(Handle, GWL_USERDATA));

Mr.Sade 27. Feb 2003 18:48

Hello people

I think all is working now.
I haven't try it with delphi, because I am at school right now,
but I will do it later, when I get home.
I have ported my delphi code to assembly language, MASM32
and I have change some parts and it works good :)

the parts that I changed are:
Delphi-Quellcode:
procedure NotepadCreated(Handle: HWND);
var
  OldPtr: Integer;
begin
  { invoke SetWindowLong, Handle, GWL_WNDPROC, ADDR NotepadProc
    invoke SetWindowLong, Handle, GWL_USERDATA, eax }

  { lets subclass it and assign pointer }
  OldPtr := SetWindowLong(Handle, GWL_WNDPROC, Integer(@NotepadProc));
  SetWindowLong(Handle, GWL_USERDATA, OldPtr);
end;
and when cleaning everything:
Delphi-Quellcode:
{ EnumWins proc Handle:DWORD, lParam:LPARAM
    invoke RtlZeroMemory, ADDR Buffer, 256
    invoke GetClassName, Handle, ADDR Buffer, 256
    invoke lstrcmpi, ADDR Buffer, ADDR Notepad
    .IF eax == 0
        invoke SendMessage, Handle, WM_STOPSUBCLASSING, 0, 0
    .ENDIF
    mov    eax, TRUE
    ret
EnumWins endp }
function EnumWins(Handle: HWND; lParam: LPARAM): Boolean;
    stdcall;
var
  szClass: array [0..256] of Char;
begin
  ZeroMemory(@szClass, 256);
  GetClassName(Handle, szClass, 256);
  if szClass = 'Notepad' then
    SendMessage(Handle, WM_STOPSUBCLASSING, 0, 0);
  Result := True;
end;

Inside NotepadWndProc:
Delphi-Quellcode:
  { Msg == WM_STOPSUBCLASSING
      invoke GetWindowLong, Handle, GWL_USERDATA
      invoke SetWindowLong, Handle, GWL_WNDPROC, eax }
  WM_STOPSUBCLASSING:
  begin
    OldPtr := GetWindowLong(Handle, GWL_USERDATA);
    SetWindowLong(Handle, GWL_WNDPROC, OldPtr);
  end;

so if it works with MASM, it should work with Delphi6
Thank You for your time

jbg 27. Feb 2003 19:00

Zitat:

EnumWin:
Delphi-Quellcode:
  if szClass = 'Notepad' then
  begin
    Win := PWinInfo(GetWindowLong(Handle, GWL_USERDATA));
    { set back ptr } 
    SetWindowLong(Handle, GWL_WNDPROC, Win^.OldPtr);
    { free memory } 
    Dispose(Win);
  end;

I see the problem within Dispose(). Dispose uses the memory manager of the calling process. But your Hook-Dll is executed in many processes. So what you do in this code is freeing memory not allocated by this process.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:33 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