Link to home
Start Free TrialLog in
Avatar of StonedRaider
StonedRaider

asked on

Hooking and Subclassing Notepad

Hello Coders,
I need a hand with this problem.
I am trying to hook and subclass Notepad.
I have set a WH_CBT hook to keep track of windows creation.
if the window created is Notepad, I subclass the window and then I add an extra menu to it to add its funcionality.
IE:
this is my shared data
HHOOK          hHook;
HWND          hNotepad;
WNDPROC     WndProc;

my callback cbt function
long __stdcall CBTFunc(int nCode, WPARAM wParam, LPARAM lParam)
{
     char szClass[256] = {0};
     if (nCode == HCBT_CREATEWND)
     {
          GetClassName((HWND)wParam, szClass, 256);
          if (lstrcmpi(szClass, "Notepad") == 0)
          {
               hNotepad = (HWND)wParam;
               WndProc  = (WNDPROC)SetWindowLong(hNotepad,
                                                  GWL_WNDPROC,
                                                        (LPARAM)(WNDPROC)NotePadProc);
          }
     }
     return CallNextHookEx(hHook, nCode, wParam, lParam);
}

my new notepad winproc
long __stdcall NotePadProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
     HMENU hMenu;
     HMENU hNewMenu;
     WORD  Cmd;

     switch(uMsg)
     {
          case WM_SHOWWINDOW:
               hNewMenu = CreatePopupMenu();
               hMenu      = GetMenu(hWnd);

               AppendMenu(hNewMenu, MF_STRING, 10000, "Item1");
               AppendMenu(hNewMenu, MF_STRING, 10001, "Item2");
               AppendMenu(hNewMenu, MF_STRING, 10002, "Item3");
               AppendMenu(hNewMenu, MF_SEPARATOR, 0, "-");
               AppendMenu(hNewMenu, MF_STRING, 10003, "Item4");
               AppendMenu(hMenu, MF_POPUP, (UINT)hNewMenu, "Extra Menu");

               DestroyMenu(hNewMenu);
               break;

          case WM_COMMAND:
               Cmd = LOWORD(wParam);
               switch (Cmd)
               {
                    case 10000:
                         MessageBox(hWnd, "Item1 Clicked", "...", MB_OK);
                         break;
                    case 10001:
                         MessageBox(hWnd, "Item2 Clicked", "...", MB_OK);
                         break;
                    case 10002:
                         MessageBox(hWnd, "Item3 Clicked", "...", MB_OK);
                         break;
                    case 10003:
                         MessageBox(hWnd, "Item4 Clicked", "...", MB_OK);
                         break;
               }
               break;

          case WM_STOPSUBCLASS:
               SetWindowLong(hNotepad, GWL_WNDPROC, (long)WndProc);
               break;
     }
     return CallWindowProc(WndProc, hWnd, uMsg, wParam, lParam);
}

well everything works ok if one instance of notepad is running, but when running 2 or more instances of notepad are running, Notepad crashes.
How could I manage multiple Notepad windows or multiple instances of notepad, so it wont crash
right now I have only 90 points, I was trying to give 150 but I dont have that many right now
Thank You
Regards,
Stoned Raider
Avatar of PlanetCpp
PlanetCpp

this is COMPLETELY off the top of my head im actually wondering why setwindowslong worked.. i was under the impression (MSDN says so..) that if the hwnd specified is not within the callers thread space that it will fail, but if you said it works, then it works. i've only used setwindowlong on window procs to subclass my own stuff.
anyway, off the top of my head i see you have the wndproc variable shared, wouldn't this then make all the instances (hooks) of the dll go to the same notepad?
if the problem is that when you open a new notepad the hook seems to forget about the old one then thats probably it.
just to clarify what i eamnt real quick when i said go to the same notepad i mean when you call the old window proc.
the old notpad instances arent getting there winproc called (the default one)
Avatar of StonedRaider

ASKER

SetWindowLong worked because that is part of a DLL that is loaded into every single process.
Yes the variable gets overwritten with the new value.
that is why notepad crashes.
how can I implement a list or an array to keep track
of every notepad window.
if one notepad is created I add the WndProc to the list or array, if another instance of Notepad is created i add a new WndProc and when destroyed I remove them
How can I implemente a List or array
thanks
you should have to, the reason your using the shared memory data segment..you are using one right? it said shared memory and you kind of have to..., im assuming you used the pragma statment and declared that data segment as shared..is because if you didnt then each instance you make of that dll, or each hook, will get its own copy. let each one get its own copy of the wndproc, itll call that one when the time comes.
ASKER CERTIFIED SOLUTION
Avatar of PlanetCpp
PlanetCpp

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello,
Yes I have my shared data as:

#pragma data_seg("SHARED")
HHOOK          hHook;
HWND          hNotepad;
WNDPROC     WndProc;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")

that is not the problem.
the problem is when I open 2 or more instances of notepad
for example:

//executing code
if (lstrcmpi(szClass, "Notepad") == 0)
{
   hNotepad = (HWND)wParam;
   WndProc  = (WNDPROC)SetWindowLong(hNotepade,GWL_WNDPROC, (LPARAM)(WNDPROC)NotePadProc);
}

// just an example
First Instance
hNotepad = 200
WndProc  = 300

Second Instance
hNotepad = 400
WndProc  = 500

You see the values change because it uses just 3 shared variables only, that is why notepad crashes.
it have to have 2 shared variables form each instance of notepad.
it have to have like an array on the shared data or a kind of a list, so when executing the code 2 times there will be 2 hNotepad and 2 WndProc variable for each window, if executing 3 times, then 3 hNotepad and 3 WndProc variables for the 3 windows
I hope you understand what I mean
Thank you





No comment has been added lately, so it's time to clean up this TA. I will
leave a recommendation in the Cleanup topic area that this question is:

Answered: Points to PlanetCpp: Grade B

Please leave any comments here within the next seven days.

Experts: Silence means you don't care. Grading recommendations are made in light
of the posted grading guidlines (https://www.experts-exchange.com/help.jsp#hi73).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer