?
Solved

Hooking and Subclassing Notepad

Posted on 2003-02-24
7
Medium Priority
?
1,310 Views
Last Modified: 2012-05-04
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
Comment
Question by:StonedRaider
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 
LVL 6

Expert Comment

by:PlanetCpp
ID: 8013851
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
 
LVL 6

Expert Comment

by:PlanetCpp
ID: 8013870
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
 

Author Comment

by:StonedRaider
ID: 8013994
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.

 
LVL 6

Expert Comment

by:PlanetCpp
ID: 8014056
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
 
LVL 6

Accepted Solution

by:
PlanetCpp earned 270 total points
ID: 8014076
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
 

Author Comment

by:StonedRaider
ID: 8014659
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
 
LVL 11

Expert Comment

by:bcladd
ID: 9845913
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

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses
Course of the Month13 days, 3 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question