question

KenKrugh-6537 avatar image
0 Votes"
KenKrugh-6537 asked KenKrugh-6537 commented

Use SendMesage in VBA

We have a VBA macro in Outlook for printing emails to a file using a printer that displays a very simple dialog with only a caption, a text box into which to type the filename, an OK and Cancel button.

Using the .Printout method brings up this dialog and we want to type a filename and hit the OK button with the macro. For some reason the SendKeys function makes the Outlook/this printer lock up on certain emails and we've not figured out why. It seems to have something to do with the email size as emails with many pictures in them are problematic.

Instead of SendKeys we've worked out using the FindWindow API to find the text box on the dialog, and the SendMessage API which is filling in the filename just fine. But we've been unsuccessful to using SendMessage to send an Enter key to "click" the OK button.

We were able to get the PostMessage API working to send an Enter key but it has the same problem on certain emails as SendKeys.

Is there a way to use SendMessage to "click" the OK button or can someone suggest an alternative?

Thanks a bunch,
Ken

office-vba-dev
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
1 Vote"
SimpleSamples answered SimpleSamples edited

If you can do what I describe in Clicking a Button in Another Application then that would be more reliable. If possible, you should get the control id of the text box and send a WM_SETTEXT message to fill in the filename then get the control id of the button to send a BN_CLICKED notification message. My sample code is for a C# Windows Forms application but I hope that is enough to get it working in VBA.

Here is a bit about BN_CLICKED. The documentation says:

The parent window of the button receives this notification code through the WM_COMMAND message.

So the message id in SendMesage is WM_COMMAND. The wParam is a combination of the button's control id and the notification code. Since the notification code is zero, for a BN_CLICKED you can omit it but you should make a comment in your code indicating something appropriate. The lParam is the window handle for the button. So in the following:

 int wParam = (BN_CLICKED << 16) | (ButtonId & 0xffff);

I am shifting BN_CLICKED (which is actually zero) and oring that with the button id; The & 0xffff just ensures that we use just 16 bits but that is likely not important. So it will likely work to just set wParam to the button's control id.

The advantage of BN_CLICKED is that it is just one message sent to the parent. It seems cleaner to me, at least.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

KenKrugh-6537 avatar image
0 Votes"
KenKrugh-6537 answered KenKrugh-6537 commented

Thanks very much for answering, Simple. We managed to find another example that got it working, doing something very similar.

We are doing exactly as you suggest, using the WM_SETTEXT with the handle of the text box, that part was working.

We found another code example here that uses WM_LBUTTONDOWN and WM_LBUTTONUP. We used these three lines to perform the click on the OK.

     OKHWnd& = FindWindowEx(WinHWnd&, 0, vbNullString, "OK")
     Call SendMessage(OKHWnd&, WM_LBUTTONDOWN, ByVal 1&, ByVal 0&)
     Call SendMessage(OKHWnd&, WM_LBUTTONUP, ByVal 0&, ByVal 0&)

Unfortunately I'm not familiar enough with C# to know what you're doing to set up the wParam in your example, or how to replicate it in VBA. Is there an advantage to using the BN_CLICKED that makes it worth trying to decipher?

Thanks again for answering.


· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I created a reply but it was too big for a comment so I will add it to my answer.

0 Votes 0 ·

And please, call me Sam or call me SimpleSamples but please don't call me simple.

0 Votes 0 ·

XD Thank you again!

0 Votes 0 ·