Important alert: (current site time 7/23/2014 11:43:37 AM EDT)
 

winzip icon

SelfSub, SelfHook, SelfCallback by Paul Caton

Email
Submitted on: 7/21/2007 3:58:14 PM
By: LaVolpe 
Level: Advanced
User Rating: By 30 Users
Compatibility: VB 5.0, VB 6.0
Views: 55034
author picture
(About the author)
 
     Hooks END safe now, added Paul's CDECL class to project so we don't lose that one either. Continuing on where Paul Caton left off. Paul has moved on from VB and his thunks are too good to let die. The attached contains a complete revamping of his subclassing thunks and significant enhancements to other thunks. The subclassing thunks, I believe are now 100% IDE-safe. I have even placed END statements inside of the subclass procedure and IDE did not die. The usercontrol (UC) crashes occurring when subclassing parent by multiple UCs is now history too. See the top remarks in cSelfSubHookCallBk_Template for overview. The assembly code is provided in .ASM files and can be opened with notepad. 18Jul07: Minor tweak in subclass.asm to attempt crash on compiled app when END executed. 21Jul07: Believe hook thunks now 100% END safe, added CDECL class allowing one to call C++ APIs or ASM thunks. Workaround for making Hook thunks more END-safe is commented in remarks at top of Template class.

 
winzip iconDownload code

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
  3. Scan the source code with Minnow's Project Scanner

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com

 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.


Other 72 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Advanced category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

6/4/2007 8:54:19 AMZhu JinYong

Is it necessary to judge if IsUnicodeWindow is true,then use SetWindowLongW rather than SetWindowLongA?
(If this comment was disrespectful, please report it.)

 
6/4/2007 3:34:46 PMRussell Sanders

As your post are always worth the look, I'm sure this is no exception. I tried to do the same thing a wile back but the code was above my skill it will be nice to see what your approch was. Thanks for sharing, and even though I cant vote for it it's still worth the five.
(If this comment was disrespectful, please report it.)

 
6/4/2007 3:38:58 PMLaVolpe

Zhu, good point. But others should also be changed too: CallWindowProcW, SetWindowsHookExW, etc, etc. I'll play with it and post an update; though I am not willing to make any significant changes to his code. My sole purpose was to provide a way of including both hooking and/or callbacks in the same subclassing class.
(If this comment was disrespectful, please report it.)

 
6/5/2007 7:16:38 AMPaul Turcksin

I didn't even try hat Russell attempted ;) In other ords: thanks for the nice present.
(If this comment was disrespectful, please report it.)

 
6/5/2007 11:32:25 AMBasak Karpuz

ty, LaVolpe.
its a nice job ;)
(If this comment was disrespectful, please report it.)

 
6/5/2007 12:56:39 PMLaVolpe

Please no more votes on this post. If you like what you see, visit Paul's submissions and vote on that. This isn't my work and I don't want it to compete for the Code of the Month; not under my name anyway. Feel free to add any feedback however.
(If this comment was disrespectful, please report it.)

 
6/8/2007 6:48:41 AMCarles P.V.

I often use the '5 globes' not only for rating purpouses but as a way to make people pay attention to that work (which, obviously, I think it deserves a 5-globes-rating).
(If this comment was disrespectful, please report it.)

 
6/8/2007 6:52:24 AMCarles P.V.

By the way: thanks for your compilation and packaging. Regards.
(If this comment was disrespectful, please report it.)

 
6/8/2007 9:25:53 PMZhu JinYong

With this combination,Someone can start to re-write Vlad's Hookmenu V1.4 to solve MDI
System Menu / SDI Menu problem...
(If this comment was disrespectful, please report it.)

 
6/9/2007 12:08:05 PMHeriberto Mantilla Santamaria

Yeah Carles, if it does not have votes, many nor watched it, since PSC is a site in which the good codes are ignored not to be in the ranking.
(If this comment was disrespectful, please report it.)

 
6/14/2007 11:01:50 AMPaul Caton

Keith, I'm just back from an internet-free vacation... unfortunately work doesn't allow me the time to do this VB stuff anymore. So I'm voting, it's yours now :)
(If this comment was disrespectful, please report it.)

 
6/14/2007 4:18:54 PMLaVolpe

Paul, I for one, am sadened to see you go. Your success combining ASM and VB has made subclassing safe\easy; quite an accomplishment within the VB realm.
Additionally, your unique ideas and worthwhile postings will be sorely missed. Best wishes with your new endeavors. Ciao.
(If this comment was disrespectful, please report it.)

 
6/19/2007 9:26:37 AMAlfred Ramos

Possible Bug:

I have attached the subclasser into my usercontrol, i noticed that if multiple instances of the control subclass a hWnd particularly a container control (picturebox, sstab, frame) the system crashes whenever i close the form. My control works ok though if the subclassed window is the parent.hwnd, or if there is only one instance of the control in the container.

Thanks.

(If this comment was disrespectful, please report it.)

 
6/19/2007 3:06:25 PMLaVolpe

Alfred, replied off-line. Interesting. I do think it is a bug in the thunker when window subclassed multiple times. Also believe it is do to the order the unsubclassing occurs in.
To make a long story short. There is at least one immediate fix and I will post that, but am looking at other fixes too. The following fix should force the previous window procedure to be replaced. You will need to add the SendMessage API to your control.
In the ssc_Unsubclass routine, add the following after the last zDelMsg call:
SendMessage lng_hWnd, 0, 0, ByVal 0&
(If this comment was disrespectful, please report it.)

 
6/20/2007 5:12:34 AMAlfred Ramos

Keith,
Great!. that just did the trick. Thank you very much.
(If this comment was disrespectful, please report it.)

 
6/22/2007 7:54:12 PMchris fitzmartin

To Paul & Lavolpe ...
I was at VBits 97 when VB5 was unleashed. This bowl of worms kept coming up and the devs at microsoft finally got real pissed about it. They didnt know how to do this at all. These were some bright people. To be fair, they were really tired. Is Threading the last great challenge left ?

cheers
(If this comment was disrespectful, please report it.)

 
6/24/2007 1:39:31 PMTuanHai

Please tell me how to catch a message value when only the caption of form changed in MDIForm (My purpose is to catch only when the mdiform caption changed even (especially when a child has been showed).

Normaly I use the code like that:
[Code]
Private Sub cSubclasserHooker_SubclassMessage(ByVal Message As Long, ByVal wParam As Long, ByVal lParam As Long)
Dim sMessage As String

If Message = &H20 Then
'// Paint caption to Unicode
UnicodeForm Me, GetAppTitle
End If

End Sub
[/Code]

But it pain the form caption many time each time my mouse move.

Please help me to solve the problem.

TIA!
(If this comment was disrespectful, please report it.)

 
6/25/2007 8:36:53 AMLaVolpe

If you have questions,you may want to email me thru PSC (click on my handle). Maybe a bug? But I am not getting email on posted feedback and answering questions here is not really possible.
(If this comment was disrespectful, please report it.)

 
6/25/2007 11:17:16 AMRichard Mewett

Thanks for this update Keith. Great to see this all-time classic still improving. Might inspire me to a new control! *****
(If this comment was disrespectful, please report it.)

 
6/26/2007 2:35:30 AMSooekd

To LaVolpe, How can use it Hook, Subclass: Form, MDIForm, Menu. We can use it replace WinSubclass3 it really need for Hook and Subclass, but LaVolpe you can post some Ex about Menu, Form, MDIForm, Menu....
(If this comment was disrespectful, please report it.)

 
6/26/2007 4:24:45 AMSooekd

To LaVolpe
You can help use SelfSub, SelfHook, SelfCallback by Paul Caton Subclass code
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=49985&lngWId=1

ht tp://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=58782&lngWId=1
I
want replace subclass with SelfSub, SelfHook, SelfCallback by Paul Caton. Thanks
(If this comment was disrespectful, please report it.)

 
6/26/2007 10:21:08 AMLaVolpe

TuanHai. Answered off-line.
(If this comment was disrespectful, please report it.)

 
6/26/2007 10:31:26 AMLaVolpe

Sooekd. The hookmenu project would require some serious rewriting, but is completely doable. I am not willing to rewrite that project. Regarding Phantom Man's OutlookBar project, that one is rather easy; give it a go and if you have problems email me with what you have tried, then I might be able to help. You might want to ask the author if he will consider helping you.
(If this comment was disrespectful, please report it.)

 
6/27/2007 11:34:34 AMTuanHai

Thanks Lavolpe but I have changed my email to new: tuanhai@vnuni.n*t (replace * = e). cmc.com.vn is the my dead mail long time ago.

Please send me to this new email.

Thanks
(If this comment was disrespectful, please report it.)

 
6/27/2007 1:45:55 PMSooekd

TuanHai. You can upload your code.
(If this comment was disrespectful, please report it.)

 
6/28/2007 12:50:44 PMjames kahl

Keith, i thought i saw a feedback posting from Paul where he stated that this is your code now. I would have to agree with that statement. You have taken his code and brought it to another level. Kudos and 5 balls for both of you... just goes to show what can be accomplished when great minds work together
(If this comment was disrespectful, please report it.)

 
6/28/2007 5:25:42 PMLaVolpe

To all. Not quite happy with the way the thunks are releasing. They release, but you lose the message that caused the release.
ASM is coded to release its own memory and releasing the memory from VB can cause a crash if both attempt to do the same thing.
However, allowing ASM to do the unreleasing has the negative effect of "eating" the message that triggers the release. I find this undesirable, especially for keybd hooks, and am attempting to discover the right logic to allow memory release both by ASM (automatic) and via VB (user-directed) while still being 100% IDE-safe. When I have it, I will post the change here.
(If this comment was disrespectful, please report it.)

 
7/7/2007 4:35:48 PMLaVolpe

^^ Now happy ;)
(If this comment was disrespectful, please report it.)

 
7/10/2007 10:12:37 AMLaVolpe

2 minor things to still fix should you need them now. Will update at a later time. Want to closely look for other ByRef, ByVal conflicts.
1) Function zSet_lParamUser: change parameter from [newValue As Long] to [ByVal newValue As Long]
2. Property Let scc_lParamUser: Same thing.
(If this comment was disrespectful, please report it.)

 
7/10/2007 10:20:27 AMHeriberto Mantilla Santamaria

Nice update Keith, you can solved the memory crash.
(If this comment was disrespectful, please report it.)

 
7/10/2007 10:25:09 AMCarlos Alberto S.

@ LaVolpe

I was testing form2 features and I'd like to know:
(1) Is it possible to prevent the window to not be minimized by Win+D or Win+M too?
(2) Is it possible to use such approach to prevent a window to go to the foreground? E.g.: if I click a window that is partially behind another one it'll go to the foreground. I'm asking that in order to emulate a "pin to desktop" under Vista.
Thank you for sharing another great code with nice examples.
(If this comment was disrespectful, please report it.)

 
7/10/2007 11:27:17 AMLaVolpe

Carlos, answered off-line.
(If this comment was disrespectful, please report it.)

 
7/11/2007 12:33:50 AMhai2hai

Please tell me how to catch a message value when only the caption of form changed in MDIForm (My purpose is to catch only when the mdiform caption changed even (especially when a child has been showed in maximize mode).

Normaly I use the code like that:

Private Sub cSubclasserHooker_SubclassMessage(ByVal Message As Long, ByVal wParam As Long, ByVal lParam As Long)
Dim sMessage As String

If Message = &H20 Then
'// Paint caption to Unicode
UnicodeForm Me, GetAppTitle
End If

End Sub

@Lavolpe: Now I have changed my account in PSC, please help me again (I could not see previous offline msg).

Thanks!
(If this comment was disrespectful, please report it.)

 
7/11/2007 10:52:18 AMLorin

Where can we find tutorials on subclassing and hooking? What do we use this for? Why would we use this? Anybody?

(If this comment was disrespectful, please report it.)

 
7/11/2007 1:48:32 PMLaVolpe

Oops. In the APIwindow_Template class, change scc_AddMsg and scc_DelMsg param:
From ByVal When As eMsgWhen
To ByVal When As sccMsgWhen
I'll fix this too on next update.
(If this comment was disrespectful, please report it.)

 
7/11/2007 5:05:19 PMHeriberto Mantilla Santamaria

Hi again Keith now if I found a bug, run the app in the IDLE and press the first checkbox and move really faster the mouse (in down mode) to the title of the form the App crash and VB too :(
(If this comment was disrespectful, please report it.)

 
7/11/2007 6:55:57 PMLaVolpe

@ Heriberto. Requesting more info.
@ Lorin. Subclassing is advanced. It is a technique to intercept, modify, or remove messages sent between your application and the OS.
Why? Form some ideas, Google for: "how to" subclass windows
(If this comment was disrespectful, please report it.)

 
7/14/2007 2:19:23 PMLaVolpe

It does appear Heriberto is having intermitten crashes. We are working together to try to resolve & initial guesses are forcing ASM code alignment on 4-byte boundaries. Will post update when we do figure it out.
Another update that will be included is addung IDE-safe windowless-timer patch to the callback thunks. Will destroy a timer when IDE ends if the timer was not previously killed.
To be continued.
(If this comment was disrespectful, please report it.)

 
7/19/2007 1:10:02 PMSooekd

It will crash if i uese END when i wanna exit.
(If this comment was disrespectful, please report it.)

 
7/19/2007 9:36:49 PMLaVolpe

Ensure you do not set the optional bIDEsafety parameter to true. If you do, you will crash. On another note, will have to revisit the hook thunk for END safety. Interesting enough, print the return value to SetWindowsHookEX, unhook, set hook again and print the return value -- different values (at least on XP). The hook thunk will attempt to unhook after END and hook re-established; but the unhook address isn't valid any longer and you guessed it -- crash. You can verify this by setting keyboard hook, END, then start app again & press any key.
(If this comment was disrespectful, please report it.)

 
7/20/2007 8:42:05 AMLaVolpe

^^ Ugh, mis-spoke above. bIDEsafety must be True to prevent crashes in IDE, setting the parameter to False will invite crashes. Discovered a little more about why hooking ASM can allow crash with KeyBd hook & possibly others. Re-thinking validation routine within the ASM.
(If this comment was disrespectful, please report it.)

 
7/22/2007 9:23:51 AMLaVolpe

Hooks are now END safe, but not perfect. Looking for something that will uniquely identify an instance of the IDE project so that one knows whether the project restarted or not. The workaround used checks to see if the hook callback address is still used for the callback after project restart, and if it is, hook continues on as if END never happened. This won't cause a crash but isn't ideal either. If nothing is clear, one thing should be -- avoid using END in your apps. The thunks can prevent crashes in IDE but they do have some limitations.
(If this comment was disrespectful, please report it.)

 
7/23/2007 12:15:36 AMSooekd

Hi LaVolpe
Now i can use command END but i have a problem. I use a command button with END for exit my program. I will END not crash if i don't check Subclass this form, else my program crash. Hook can use END don't crash but Subclass ever crash when use END for exit program. Thanks
(If this comment was disrespectful, please report it.)

 
7/23/2007 9:05:53 AMLaVolpe

Sooekd, will look into it. END will probably crash most cases when compiled because of timer use to prevent crashes during IDE. Bottom line, don't use END. But I will take a look-see.
(If this comment was disrespectful, please report it.)

 
7/23/2007 1:06:16 PMLaVolpe

Sooekd, follow-up. I see where END placed in Form_Unload can cause crash when filtering on MSG_After while in IDE. I will post ASM patch to prevent that. However, using END when compiled may not be crash proof because the O/S will destroy virutal memory (the thunks) which may be causing the crash. This issue exists in original thunks too. Simple workaround: call routine that terminates subclassing/hooking before END is called; or simply don't use END.
(If this comment was disrespectful, please report it.)

 
7/29/2007 7:36:59 AMUlrich Korndoerfer

Hi,

in your assembler code you check often, if a pointer is valid. Eg in subclass.asm:

push dword addrCallback ;Push the callback address
call near fnIsBadCodePtr ;Check the code is live
jnz _set_bypass ;if non-zero, set bBypassing flag & bypass

First question:

IsBadeCodePtr according to MSDN Library returns a C-Bool in register eax. Nothing is said there about the processor flags being set. So for testing wether eax is zero or not, a test eax,eax should be done after the call.

Next: it does not make sense to test addrCallback , since this is a pointer to the classes method implementation code, which will not just vanish.

It would be better to test objOwner, because this is the This pointer of the instance. When the instance goes, the This pointer is invalid then.

Ulrich
(If this comment was disrespectful, please report it.)

 
8/8/2007 3:54:04 AMHamed Oveisi

Hi VB Professionals, I've a technical question, hope you can kindly help me.

Is it possible for a program to crash in runtime using subclassing? Currently I'm using vbAcclerator subclassing DLL new updated version from Marzo Torres Jr, my application jump out suddenly in runtime EXE and I can found the problem:( Any ideas,hint ...
(If this comment was disrespectful, please report it.)

 
8/8/2007 8:48:36 AMLaVolpe

VB professionals, click on his name/link and reply off-line, please do not use this post as a forum. I have replied off-line also
(If this comment was disrespectful, please report it.)

 
9/26/2007 7:32:00 AMDriss HANIB

So good team..
I'm not enough good to judge your version because i do not understand it to far, but i'm sure it's "royal"
thanks to PC and you for your shares..

(If this comment was disrespectful, please report it.)

 
6/5/2008 12:20:05 PMGiampaolo

Do you have updates?
Thanks
(If this comment was disrespectful, please report it.)

 
4/15/2009 7:13:08 AMLuca

Hi LaVolpe,
I have seen tha Carlos has ask you about "pin to desktop" under Vist.
I'm interested too.
Can you guide me?
(If this comment was disrespectful, please report it.)

 
3/13/2012 9:13:34 PMHennyere

SubClass causess Application crash (compiled exe) when attach a message in a usercontrol.extender.parent and this usercontrol.extender.parent was unloaded (runtime error 398 - Client side not available) on "sc_Terminate" function

Private Sub UserControl_Terminate()
sc_Terminate
End Sub

ThankYou
(If this comment was disrespectful, please report it.)

 
5/4/2012 2:07:27 PMSteffen

Because of DEP incompatibility I switched from Matthew Curland's to your subclassing code - it works great! But I encountered an error when implementing the myWndProc in a class with missing vTable entries. In such a case the application crashes.
(If this comment was disrespectful, please report it.)

 
4/15/2013 2:16:23 PMvbaddicts

Hey LaVolpe, Me, Robert Rayment, and Paul Caton are pretty much the main people on pscode.com that use assembly code with VB6. I'm David Fritts. Robert and Paul have since been slowly retiring from posting and doing projects anymore. I noticed you are familiar with the work. I'm working on a VB6 ActiveX DLL Injection Framework. I've got it about half done and its working but needs some polishing up. I was wondering if you would want to collaborate with me on this vb6+asm project or another vb6+asm project. I could really use the help cleaning up the ActiveX DLL Injection framework and making it ready to post on pscode.com. I'm looking forward to your reply, email me vbaddicts@gmail.com
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.