Important alert: (current site time 7/16/2013 2:37:29 AM EDT)
 

winzip icon

SelfSub 2.1 updates and additions. Apr 13

Email
Submitted on: 4/13/2006 5:34:17 PM
By: Paul Caton 
Level: Intermediate
User Rating: By 49 Users
Compatibility: VB 6.0
Views: 23701
 
     What: the latest version of my subclassing components. Why: this update fixes DEP (Data Execution Prevention) issues on 64bit Windows and XP SP2 with NX/XD cpu support. Additionally, I’ve eliminated the public callback; here the self-sub callback is the final private method. Who: whilst this submission will mostly interest UserControl authors, the cSelfSub sample class, cShadow, should be of general appeal. SelfSub 2.1 Apr 13 Additions: general purpose callback thunks. Updates: see comments

 
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 13 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 Intermediate 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
4/4/2006 7:47:04 PMRichard Mewett

This is what we have all been waiting for :) Only had a quick scan so far but I know I can safely vote *****. I look forward to testing it out in some new controls!
(If this comment was disrespectful, please report it.)

 
4/4/2006 11:33:40 PMLaVolpe

Yepper, me too; X-mas almost 9 months early. Thanx for sticking with this & improving it. Will place copies in safe places should this ever disappear.
(If this comment was disrespectful, please report it.)

 
4/5/2006 4:23:38 AMLight Templer

Hi Paul, finaly! Thx alot for all the work! I know, you are not out for votes, but maybe a screenshot with the great form shadow example would help to get the very owned COTM ... ;-))) Kind regards - LiTe
(If this comment was disrespectful, please report it.)

 
4/5/2006 5:30:27 AMPaul Caton

Hi, all... if you downloaded before this post, download again, please. LiTe, I was making that exact change as your email arrived :)
(If this comment was disrespectful, please report it.)

 
4/5/2006 5:58:31 AMLight Templer

Yep, my msg and your screenshot upload has overlapped. WITH this screenie I 'll bet on COTM ! ;-)))
(If this comment was disrespectful, please report it.)

 
4/5/2006 6:21:13 AMPhilip Zac

Every day waiting for this update.....thanks for sharing... VB LOvers always remember you for ur contribution to the vb community...:) Five Starts to the superstar....
(If this comment was disrespectful, please report it.)

 
4/5/2006 6:40:58 AMPhantom Man

It's obvious you have put a lot of time, effort and research into this component. and It's greeted with great admiration.

Thanks for continuing and Improving an already great subclassing component in it's own right.

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

 
4/5/2006 7:18:28 AMOption Explicit

Thanks for the update to an already classic submission Paul. Can't wait to start exploring its possibilities.
(If this comment was disrespectful, please report it.)

 
4/5/2006 9:26:52 AMTerriTop

As always your code, examples and mastery of this art form are astounding!! I look forward to playing with the newest of the Caton toys...Thanks for sharing!! TerriTop
(If this comment was disrespectful, please report it.)

 
4/5/2006 9:40:15 AMEric O''Sullivan

fantastic job. I started something like this a while back but never found the time to complete it. You've saved me quite a job - without a doubt, 5 from me! :-)
(If this comment was disrespectful, please report it.)

 
4/5/2006 1:38:31 PMLaVolpe

Paul, if you must post any updates, would you consider adding an optional custom-use Long (uParam) to be provided in sc_Subclass and passed via zWndProc?
Thoughts are that coders can keep a flag/objPtr associated with any subclassed window. If not, SetProp/GetProp will work just fine.
(If this comment was disrespectful, please report it.)

 
4/5/2006 3:21:01 PMHeriberto Mantilla Santamaria

Hi Paul.

Wow thx so much for this update, I wait this for a long time.

All my controls have your fantastic subclassing, thx for this.
(If this comment was disrespectful, please report it.)

 
4/5/2006 4:03:01 PMHeriberto Mantilla Santamaria

Thx Paul, now the subclass permit 2 or more control without error when I close the form with X button.

The code is more little than first one, now not need the public event and the all code is more easy to read and understand.

Thx so much Paul for this hard work for all PSC comunity.

I reupload all my controls with this new subclassing in the next months.
(If this comment was disrespectful, please report it.)

 
4/5/2006 7:22:03 PMPaul Caton

Be warned folks, I'm receiving a few requests, so expect some small changes in the near future. On the subject of which, either later this month or early next, I plan to extend the submission to include hooks and api windows.... plus an additional self-sub UserControl that includes a built-in keyboard hook.
(If this comment was disrespectful, please report it.)

 
4/6/2006 6:14:46 PMAlain

I've always been weary of all that ASM Thunk and SubClass stuff. I am still using SetCapture ReleaseCapture and GetCapture to detect Mouse Enter/Exit lol... Maybee i should start taking a closer look at this ...
Anyway small bug detected since first submition of Shadow control years ago. Still there so here is my contribution to PSC...;) Used on child forms on an mdi document, if the mdi doc has controls with aligned properties on it like picture box as side panel, the shadow is not drawn in the correct position . Had played around with it at the time and was able to fix it. But don't think i have the code around. Need to get the rect on the client area of the mdi and offset from there...
Cheers ....


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

 
4/6/2006 10:44:30 PMDean Dusenbery

Thank you Paul. Your creativity and coding prowess continue to astound. One question, since you’re scanning for method signatures to determine the address of the last private function why don’t you also look at the object signature to detect the object type and thus the appropriate starting offset instead of hard coding the offset for the three supported object types?
(If this comment was disrespectful, please report it.)

 
4/7/2006 5:54:07 AMPaul Caton

Alain, the Enter/Leave demo is just a simple sample... _not_ the raison d'être for self-subclassing a UserControl. I'll take a look at the MDI child issue but I fear that the best I can manage is a wobbly kludge. Correcting the MDIChild shadow positions is trivial, getting the the MDIChild shadows to move with the parent... ditto. Other MDI behaviours, however, seem to be next to impossible… time will tell.
(If this comment was disrespectful, please report it.)

 
4/7/2006 6:55:03 AM-= XeRoX =-

Woow, you did it again... 5 globes from me!!! One Q: is there a way to change the Shadow Color to make it more customable?
(If this comment was disrespectful, please report it.)

 
4/7/2006 8:21:10 AMPaul Caton

XeroX - I'll add the shadow colour for the next update... plus some level of MDIChild functionality for Alain.
(If this comment was disrespectful, please report it.)

 
4/8/2006 4:30:24 AMTheCardinal

WHOAA!!! at last! let the new user controls flow people! :)
(If this comment was disrespectful, please report it.)

 
4/9/2006 2:25:59 PMHossein Moradi

First sorry for my poor english

i`m using your first subclasser "Fastest, safest subclasser, no module!"

because the other subclasser using external dependencies or public callback.

but now i`m have used your new subclasser and added to all of my projects but there is two Problem for me.

first : when i`m using your cSubclass with usercontrols, when the userconrol terminated in the IDE for example adding an removing the control it will crash then IDE.

second : when debuging (Using F8) the code if the subclassed window received a message that has been added then the "Proc" don`t be called.
for example when debuging the code and then subclassed socket recived a message it wont call the iSubclass_Proc.

this two problems was not exist in your first subclasser but that has it`s own bugs and problems

can you pleeeeeeeeeeeease fix this problems. thanks
(If this comment was disrespectful, please report it.)

 
4/9/2006 4:05:03 PMHossein Moradi

here is the first example that you can test
add a usercontrol to your pSample project inside "\SelfSub II\Samples\cSubclass"
add this code to the usercontrol

'
Option Explicit
Implements iSubclass
Private SubClasser As New cSubclass
Private Sub UserControl_Initialize()
SubClasser.Subclass hwnd, Me
SubClasser.AddMsg hwnd, WM_SETFOCUS
End Sub
Private Sub UserControl_Terminate()
SubClasser.UnSubclass hwnd
End Sub
Private Sub iSubclass_WndProc(ByVal bBefore As Boolean, bHandled As Boolean, lReturn As Long, ByVal lng_hWnd As Long, ByVal uMsg As eMsg, ByVal wParam As Long, ByVal lParam As Long)
Debug.Print "SetFocus"
End Sub
'

save it because your IDE Will crash
add the usercontrol to your form and then remove it
or add the usercontrol to your form and then close the form designer

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

 
4/9/2006 4:10:13 PMHossein Moradi

here is the second example that you can test
add this code to your form in your pSample project inside "\SelfSub II\Samples\cSubclass"

'in declaration
Private Declare Sub SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)

'line 6 after "oSub.Subclass Me.hWnd, Me" in your form load
oSub.AddMsg hWnd, WM_TIMER
SetTimer hWnd, 1, 1000, 0
'line 2 in "iSubclass_WndProc" procedure
If uMsg = WM_TIMER Then Debug.Print "Timer"


after adding this code to your form you must get a timer message every second
but if you are in debug mode in IDE (with F8) it wont get eny message but it work on your first subclasser
this is important when working with socket API

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

 
4/11/2006 8:29:24 PMPaul Caton

I believe I've fixed all of the current issues. Expect a *MAJOR* update tomorrow - so major that I'm half tempted to delete this entry and re-submit.
(If this comment was disrespectful, please report it.)

 
4/12/2006 1:03:18 AMPSC Moderators

Paul, I strongly advise against deleting-and-resubmitting, since we will not accept the new submission. Please update your project; those without the setting to hide updates from the new submissions view and code ticker will see your project as if it was reposted and you will get the visibility you wish.

Regards,
PSC Moderator 625205
(If this comment was disrespectful, please report it.)

 
4/12/2006 7:26:28 AMOption Explicit

As you said in your comment in my MorphOptionCheck submission, I guess I was way premature... oh well, any time I get to play with cool new code is fine with me! Looking forward to the update.
(If this comment was disrespectful, please report it.)

 
4/12/2006 3:47:00 PMOption Explicit

I think it's amusing that "PSC Moderator 625205" won't let you post an update as new, when just this morning I saw a VB submission just approved that apparently did nothing but extoll the virtues of marijuana... Paul maybe you should roll up your new submission like a joint, then "Moderator 625205" might let you post it as new :D
(If this comment was disrespectful, please report it.)

 
4/12/2006 4:21:43 PMHossein Moradi

here i have tested this subclasser too

"Updated 3/07 - VB+ASM Subclass, Hook, Timer, Api-Window class thunks, w/ Form fade/shadow sample "

but it do not have these bugs too

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

 
4/12/2006 9:38:45 PMPaul Caton

Hossein, twice I've sent you something to try by email, but I've not received any reply. Anyway, I will be updating very soon.
(If this comment was disrespectful, please report it.)

 
4/13/2006 12:27:34 PM-= XeRoX =-

Hi Paul, Need your advice on one issue!
I am trying to add your subclassing method within a usercontrol I made, but cannot get WM_LBUTTONDOWN and WM_MOUSELEAVE work at the same time. When mouse is down control redraws as intended. Holding mouse button down and moving out of the control area doesn't redraw the control. It worked well with VBAccelerator's subclassing method, but your method is so great that I want to use it so much. :-)
Do you know why this happens?

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

 
4/13/2006 1:29:13 PMPaul Caton

Xerox - your reply address bounced on me. Could you email me a sample that demonstrates your problem? It's difficult to guess from your description. My address is in the source... join the many that email me daily :)
(If this comment was disrespectful, please report it.)

 
4/13/2006 2:09:36 PMPaul Caton

Xerox, have you got another email address? Replies bounce back to me. Anyway, what I said was: the "problem" is that the TrackMouseEvent api sends the WM_MOUSELEAVE event *after* WM_LBUTTONUP.

If you want different behaviour, you could try the "capture" method.
(If this comment was disrespectful, please report it.)

 
4/13/2006 6:34:18 PMPaul Caton

Update: the subclasser has acquired a user-defined parameter for the callback. A sample demonstrates how you can pass a control or object, and how this might be useful.
(If this comment was disrespectful, please report it.)

 
4/13/2006 6:38:13 PMPaul Caton

Update: sc_subclass has a new optional parameters that let you specify a different callback object and callback ordinal. Meaning that a sublasser could call back to a differnt object than the one the code is running in. Additionally that callback opbject can either a class, a form or a UserControl. By specifying the ordinal, you could, for example, subclass two hWnds in a UserControl and have them callback to their own individual callback routines.
(If this comment was disrespectful, please report it.)

 
4/13/2006 6:40:05 PMPaul Caton

Update: I've added an optional parameter to sc_Subclass so users can if they wish disable IDE protection. This will come in handy for UserControl design time subclassing. But I'm not quite ready for that, comming soon.
(If this comment was disrespectful, please report it.)

 
4/13/2006 6:48:02 PMPaul Caton

Additions: general purpose callback thunks. These are great for a myriad of api's that takes a function callbak address, such as the enumeration api's. However it's quite remarkable the ends to which they can be put, timers, hooks, lightweight subclassing... even private communication channels between classes (thx to Mr LaVolpe for that one). On top of which, just like the subclass components, you can specify the callback object and ordinal. My head has been spinning trying to grasp the possibilities and look forward to the imaginative uses you folks will undoubtedly come up with. I'm frazzled... good night!
(If this comment was disrespectful, please report it.)

 
4/13/2006 7:09:22 PMPaul Caton

Oh, I almost forgot... I should credit Dean who was looking for a way to use a zip library callback api that reported progress. See? the callback thunks are very flexible.
(If this comment was disrespectful, please report it.)

 
4/13/2006 9:09:12 PMDean Dusenbery

Thanks again Paul, these components are really a great addition to VB. The callback thunks are terrific!
(If this comment was disrespectful, please report it.)

 
4/14/2006 2:36:14 AMHossein Moradi

this is great you have 5 from me
(If this comment was disrespectful, please report it.)

 
4/14/2006 8:54:20 AMPaul Caton

Xerox, it's *very* frustrating not being able to reply to your emails... please fix. Again, this problem has nothing to do with the subclasser. I put the tracking code in a regular module-based subclasser with (to no surprise from me) EXACTLY the same result. This is how windows works, if you click in a control and then drag the mouse outside of the control with the button still held down, windows continues to send mouse messages to the UserControl, it has captured the mouse. The solution to your problem is simple, when you receive a mouse move event, unpack the lParam parameter to get the mouse position, if either x or y is less than 0, or (assumeing you set the UserControl to ScaleMode = Pixels) If x > ScaleWidth Or y > ScaleHeight then bInCtrl = False. If this is the behaviour that you want, you won't need any of tracking api stuff. I'd send the code, but it won't get through.
(If this comment was disrespectful, please report it.)

 
4/14/2006 9:11:49 AMLaVolpe

Yepper, the callbacks are an excellent addition to your thunks; thank you.
As for timer callbacks; if ppl pass an hWnd to SetTimer, it will be End safe since O/S kills timer when window dies.
A very flexible project; for instance I plan on passing pointers vs Objects to cb_AddressOf & modifying it was easy!
Paul, a challenge for you. Would you consider adding your own version of CallWndProcA that can pass an arbritrary nr of params? This would add a bit more flexibility.
(If this comment was disrespectful, please report it.)

 
4/14/2006 10:50:39 AMPaul Caton

News: there will be another update that'll fix the issue with design time subclassing of UserControls. Problem solved (with side benefits).
(If this comment was disrespectful, please report it.)

 
4/15/2006 6:09:07 PMOption Explicit

Looking forward to the design time subclassing update, but in the meantime your last update works like a charm!
(If this comment was disrespectful, please report it.)

 
4/15/2006 7:17:53 PMPaul Caton

I'm going to have a big loud notice in the next source update saying: ALL SUBCLASSER/CALLBACK CODE MUST BE AT THE BOTTOM OF THE SOURCE, JUST ABOVE THE CALLBACK. Sounds weird, but it's the price to be paid for an IDE-Safe, Private callback routine.
(If this comment was disrespectful, please report it.)

 
4/16/2006 11:35:29 AMHossein Moradi

is it safe that we only have one public cSubclass object in the project, and use it in all of class and usercontrols ?
(If this comment was disrespectful, please report it.)

 
4/16/2006 12:49:54 PMPaul Caton

@Hossein, you mean a single instance of the class, I presume. Well, it worked just fine in my tests. You should be able to set the callback object so that messages go to the appropriate object… or, that all of your subclassing callbacks go to the same object… or some combination of those two, or… that different hWnd messages go to the same object but a different callback ordinal. Flexibility by design… if not, let me know because I want to fix it.
(If this comment was disrespectful, please report it.)

 
4/18/2006 12:01:11 AMMTIG

Paul, this is great! I used to write code in 1's and 0's but gave that up a when the processors went past 8 registers and 8 mhz. I love the VB6 middleware and you have just made it much better! Now I don't have to pull out my old dec2hex brain cells.

One question: I'm working on several projects that subclass foreign processes. I have been successful at injecting the subclassing code and catching the callback in a module. I'm trying to figure out how to implement your code so that I can catch the callbacks in a class so I can call events. I realize I could just remove the code that does the actual subclassing and any errors referencing foreign processes. I'm just not totally clear on how to set your subclasser to take WM's from foreign code. Can I just use the zAddressOf method to pass the callback address to my injected code? It sounds a little too simple. Thanks for all your efforts and for sharing. ***** from me!
(If this comment was disrespectful, please report it.)

 
4/18/2006 11:44:57 PMHossein Moradi

can you make an option that the subclasser and it`s Wnd_Proc work in another thread
(If this comment was disrespectful, please report it.)

 
4/19/2006 1:28:23 PMPaul Caton

Hossein, the subclass thunk executes on the thread that calls it. The thunk receives its messages from the message loop (GetMessage/DispatchMessage) inside the VB runtime. I imagine that the VB runtime uses a NULL hWnd parameter to GetMessage and thus retrieves messages for all windows created in the VB runtime thread. You could (probably) run a custom loop in your own thread, using specific hWnd parameters to GetMessage, but, in light of thread multi-tasking, how could you guarantee that the VB message loop wouldn't retrieve the message instead of your own loop? The only way I can think of excluding the VB runtime message loop, is if the window was created in your own thread, but then it wouldn't be a VB window, rather an api window. IMO
(If this comment was disrespectful, please report it.)

 
4/22/2006 6:16:34 PMDreamstruct.com

Great job, beautiful work. Keep it up :)
(If this comment was disrespectful, please report it.)

 
4/24/2006 11:42:17 AMJuan Carlos San Román

Excellent job, five from me!!!!!
(If this comment was disrespectful, please report it.)

 
6/11/2006 10:11:31 PMseliSoft Softwareentwicklung

Hello Paul,
It seems there is a problem with your "cSubclass" samples (iSubclass and Type library version).
Both programs will never show "After ...". Would you please take a look?
Thank you very much for your code, i still use a modified version 1.0 ;)


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

 
8/23/2006 11:16:53 AMVesa Piittinen

A small trick with collections: you don't need to have "h" & when adding numeric keys. You can do just CStr(hWnd) and then the key is valid and saves nicely without a need for adding a character :)

Great code however, I'll be switching my new UniLabel and UniControls project to the new user control subclassing code (I used your WinSubHook code from 2003 earlier).
(If this comment was disrespectful, please report it.)

 
8/23/2006 2:41:03 PMVesa Piittinen

I found a "major" bug in the usercontrol code: bBefore is never either True or False; instead, it seems to contain some other value that I can't really track what it is. But it is never -1 or 0. I replaced the Boolean with Long and it is probably a pointer to a variable, but I can't figure out how I can get the contents of that variable to know if the value is -1 or 0.

I'm processing WM_PAINT in both BEFORE and AFTER and atm I can't do that.
(If this comment was disrespectful, please report it.)

 
9/3/2006 2:26:58 AMTai Chi Minh Ralph Eastwood

The problem really is:
EDX contains whether its bBefore or not, however, this flag is stored in EDX, prior to calling IsBadCodePtr API function.
IsBadCodePtr API modifies EDX, giving some irrelevant value - always not 0, thus giving a value that equates to True in VB terms.
(If this comment was disrespectful, please report it.)

 
10/2/2006 8:57:30 AMPaul Turcksin

Paul. In the simple sample (pSample.vbp) I moved the Usercontrol's ReadProperties and Terminate sub's down (after the zWndProc1), and it crahes in yhe IDE. The obvious solution is of course: don't do this. But maybe you have suggestions/rules on where to place additional sub's in the usercontrol? Thanks.
(If this comment was disrespectful, please report it.)

 
10/31/2006 9:14:42 AMTai Chi Minh Ralph Eastwood

You will need to increment the function ordinal number by 2 in that case.
But, yes keep the zWndProc1 at the bottom - that is the best way...
(If this comment was disrespectful, please report it.)

 
11/20/2006 6:02:53 PMHector

This piece of code is great for subclassing controls, however it seems to have serious problems when trying to subclass some parent form messages (either that or I don't know how to do it correctly, which is the most possible solution heh...).

For example, I'd like to get the parent window WM_NCACTIVATE/WM_KILLFOCUS messages in order to know when a control shouldn't be active. However when doing this in a MDI child with multiple controls the program crashes if closing directly from the MDI. Any help?
(If this comment was disrespectful, please report it.)

 
3/12/2007 7:28:42 PMDavid Ross Goben

5 Globes from me. The documentation within the code is most welcomed. The style is from someone well-schooled in the C domain, which, on a professional level, we document code to death (I've been doing it for 30 years, now). Thinking this beyond VB, I had previously written most of these classes as ActiveX C DLL's callable from VB. Glad to see someone proving once again how versatile VB6 can be, and sorry for my short-sightedness!
(If this comment was disrespectful, please report it.)

 
5/8/2007 5:47:03 PMMohammed Sayed

Hi Paul;
I came here to ask you about how it can be used in a Keyboard hook ( a global one using SetWindowsHookEx ) but in one Class (to make an ActiveX DLL) & I saw that you said "I plan to extend the submission to include hooks and api windows.... plus an additional self-sub UserControl that includes a built-in keyboard hook." where is them please ?

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

 
12/3/2007 9:59:45 PMLala

hello Paul,
Thanks for directing me to this more recent masterpiece of yours =)
I was looking at the code you posted 5+ years ago i think.
As for my problem, it was resolved by simply using VirtualAlloc instead of the GlobalAlloc before calling the SetWindowLongA function.
When i have time (i hope soon!), il try to pattern your new design to my code. Thanks again!

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

 
7/29/2008 8:36:12 PMJim Billig

Paul,
Thanks for another great subclassing submission. I've been trying to combine your form fading from your previous version, but I can't seem to find assemble all the pieces (different TLBs and implementations). Before I beat myself up any more, or settle for another transparency submission, I was just wondering if you plan any updates? Thanks and keep up the great submissions!
(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.