• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1334
  • Last Modified:

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
0
StonedRaider
Asked:
StonedRaider
  • 4
  • 2
1 Solution
 
PlanetCppCommented:
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.
0
 
PlanetCppCommented:
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)
0
 
StonedRaiderAuthor Commented:
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
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
PlanetCppCommented:
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.
0
 
PlanetCppCommented:
i meant shouldnt** have to.
while im making another post might as well write what you data segment should look like
#pragma data_seg("SHARED")
HHOOK          hHook;
HWND          hNotepad;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")

WNDPROC     WndProc; //now it's not shared
0
 
StonedRaiderAuthor Commented:
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





0
 
bcladdCommented:
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 (http://www.experts-exchange.com/help.jsp#hi73).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now