|
| | Submitted on: 2/1/2002 5:50:20 AM
By: Cakkie
Level: Advanced User Rating:
By 33 Users Compatibility:
Users have accessed this article 7125 times. | (About the author) |
| | No, we are not going to do anything illegal here. We are going to hack the MsgBox and InputBox. Let me start by saying that this is !NOT! one of those custom messagebox classes, but this uses the real MsgBox and InputBox functions from VB. This article has accompanying files | |
| | Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article 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 article (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 article 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 article or article's description. | If you ask someone the question "How to change the text of the buttons in a messagebox", the result would probably be that 99 times out of 100 you get the answer "I don't think that can be done". The other 1 time you probably asked me (or someone like me) and got the answer "Simple, just hook it".
So how do you hook it? Simple, it only takes a few lines.
The hook will need to know a few things, first of all, where is the hook coming from? We can get that by making a call to GetWindowLong API function, specifying that we need the instance of our window.
Another thing it needs to know is the thread that's calling it. For this we use the GetCurrentThreadID API.
Finally we need to specify where it should send the messages to, and that would be a function we wrote. We now have everything to make the call. When calling, we specify that we are setting up a CBT hook, and off we go.
After that, we can show our messagebox. This will send several messages to our function (in this case, 4 + the number of buttons), but we are only interested in the Activate, since this is when the messagebox is build completely. Our function must look like this (I called it Manipulate, since we are manipulating the box):
Public Function Manipulate(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
We can disregard lParam, but lMsg contains the message and wParam will contain the hWnd of the message/inputbox.
Once we have the hWnd, we can search for buttons. Since a button is actually a window of the class button, we can use the FindWindowEx API to find them. Once we have it, we can change the text using the SetWindowText API.
After we done the processing, we need to release the hook. If we don't release the hook, our program can just disappear. With this I mean that it would be the same as just killing a process using the task manager, resulting is a possible loss of data, and a memory leak.
Also, when debugging, NEVER place a break between the place where you place your hook and release it, because this will probably result in the same effect as above.
This can also be applied to the InputBox. The example code shows both.
The MSGBOX function will still return the selected value, so if you change the Yes button to "Yeah", it will still return vbYes (and not vbYeah ;)
The INPUTBOX function returns the text entered, so basically nothing changes on the use, you just add a bit of a preparation.
I think this code I wrote opens a new perspective. Since we are able to get the hWnd of the box and the buttons, we could easely use most of the WIndow APIs on it. This could maybe lead to custom shaped messageboxes, apply different window styles etc. Also, since we have a hWnd, we could get a hDC, which would allow us to use functions like BitBlt on it, and create boxes with pictures on the buttons rather than text. I haven't got time to test this, and I'm kinda busy lately, so if you manage to do anything cool with it, let me know.
As usual, feedback and votes appriciated, and in this case expecially the feedback. | | Download article
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 Winzipto 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.
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 article, you agree to the following terms...
1) You may use
this article 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 article (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 article 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 article or article's description. | Other 11 submission(s) by this author
| | | Report Bad Submission | | | Your Vote! |
See Voting Log | | Other User Comments | 2/1/2002 8:54:40 AM:KrisR Please could you send me a copy of your
article to kradmall@hotmail.com as i
can not download it. p.s i gave u 5
globes
| 2/1/2002 9:20:01 AM:Real RedNeck I would like to view Your Message/Input
Box code. I can't download the article
it just says that page can't be
found.
Thanks
| 2/1/2002 10:38:41 AM:Cakkie Hmm, it seems that this is a problem
with all codes (since I cannot download
any!), and I noticed that the
screenshots aren't coming through
either. I'll send a feedback message to
the site.
| 2/1/2002 12:55:16 PM:Cakkie I upped it to my personal site, you can
download it
here:
http://home.planetinternet.be/~ae
rts1/vb/MsgBoxManipulation.zip
| 2/1/2002 10:15:13 PM:Joe Nice code =) 5 globes!
| 2/2/2002 4:26:41 PM:Alex you can use CreateTimer to check for
msgbox, then enum that window to get
the controls, then if button
setwindowtext i think that could be
easier.
| 2/2/2002 5:11:39 PM:Sean Cakkie,
Cool post. I'm curious,
aside from BitBlt, is there a way to
hook the icon used in the message box
and replace it with another, say
something in an ImageList? Also, where
did you learn how to hook the right
stuff? Are there methods of listing
hookable threads in an item (like
message boxes, or menus, etc), or good
books about it? I really liked the
post. When you get more time I'd like
to see more involving hooking threads
to modify things. Pretty cool! =)
| 2/3/2002 2:51:59 AM:M. Highlander psc seemes to be having problems with
upload/download ?
| 2/3/2002 1:13:05 PM:Cory J. Geesaman why do people keep submiting input/msg
box examples!!
| 2/3/2002 3:50:54 PM:Cakkie Sean, I learned about hooking from an
msdn article, describing how you could
place a hook on a messagebox in order
to place it at another
position
Cory, why do people keep
posting meaningless feedback...
| 2/6/2002 2:58:04 PM:LCensoni Great!! 5Gs
| 2/25/2002 8:26:54 PM:Robert Morris Great code! (I also have a submission
here, popup balloons. Cory's feedback
wasn't very nice, either, Cakkie. ;)
| 3/13/2002 12:10:40 PM:Mike Rossi I am not that familiar yet hooking, but
can this be put into a class module
that could easily be called? Please
email me.
| 7/1/2002 8:38:37 AM:Cesare Imperiali Nice job, LampedGuru...!
| 8/18/2002 6:59:35 PM:Real RedNeck I do it the easy
Way<br><br><br>
Private Sub
Command1_Click()<br><br>
Dim Retval As
Variant<br>
Dim ms As String<br>
Dim
tl As String<br><br>
ms = "Now , isn
't this a strange looking box?" &
vbCrLf<br>
ms = ms & "If anyone says
this cannot be done, you" &
vbCrLf<br>
ms = ms & "have proof it
can."<br><br>
tl = "Now We can Do It
!"<br><br>
Retval =
MsgBox(txtMessage.Text,
vbAbortRetryIgnore, tl)<br>
If Retval
= 3 Then MsgBox "You Choose Abort":
Exit Sub<br>
If Retval = 4 Then MsgBox
"You Choose Retry": Exit Sub<br>
If
Retval = 5 Then MsgBox "You Choose
Ignor": Exit Sub
Exit Sub
| | Add Your Feedback! | Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.
NOTICE: The author of this article has been kind enough to share it with you. If you have a criticism, please state it politely or it will be deleted.
For feedback not related to this particular article, please click here. | | |