VBA loses flow of control when button calls new window using user32 libraries - vba

I am using VBA with user32 libraries to manipulate windows. In the application I am making, when I click on a certain button for which I already have the handle, a new window appropriately pops up. I need to then press a button on that new window. But after the code clicks the first button, the code doesn't move forward anymore.
If I had originally initiated the code by pressing F8 to step through, then I can manually close the new window, manually reopen it, and then continue stepping through my code and it works just fine to finish the program. If I initially pressed F5 to just run the program without ever having stepped through, then I still have to manually close the window and code just gets stuck after opening the new window so no progress is made.
How do I ensure that the program doesnt lose control after the button is clicked and the new window pops up?
'assume the objects are declared already and the functions are correctly imported.
printDialogWindow = FindWindow(vbNullString, "Print")
preferencesButton = findwindowEx(printDialogWindow, 0&, "Button", "P&references")
Call SendMessage(PreferencesButton, BY_CLICK, 0, ByVal 0&)
'code stalls here
printPreferencesWindow = FindWindow(vbNullString,"Printing Preferences")

Ok, so the solution I found in simple terms was to use the Win32 "PostMessage" function instead of the "SendMessage". SendMessage will wait for a response before it returns control back to the calling program. PostMessage puts the message in a queue and then gives control back to the calling program right away. In my case, because there are no other messages in the queue for that window, it processes the message right away, so there are no issues.

Related

WM_MOUSELEAVE sometimes occurs after WM_MOUSEMOVE on another control when compiled

Here is a short summary of the problem:
I move the mouse pointer quickly from control 1 to control 2.
In IDE, the sequence is this:
Control 1: Enter
Control 1: Leave
Control 2: Enter
Control 2: Leave
When compiled, the sequence is this (sometimes, but not always):
Control 1: Enter
Control 2: Enter
Control 1: Leave
Control 2: Leave
Here is the full description of the problem:
I'm subclassing a usercontrol.
I process WM_MOUSEMOVE and WM_MOUSELEAVE.
When WM_MOUSEMOVE occurs, and the mouse pointer hasn't been on the control before, I detect it as "Enter".
Then I track the mouse event using the following code:
'Track the mouse leaving the indicated window
Private Sub TrackMouseLeave(ByVal lng_hWnd As Long)
Dim tme As TRACKMOUSEEVENT_STRUCT
With tme
.cbSize = Len(tme)
.dwFlags = TME_LEAVE
.hwndTrack = lng_hWnd
End With
Call TrackMouseEvent(tme)
End Sub
When WM_MOUSELEAVE occurs, I know that the mouse pointer has left the control.
It works perfectly: fine.
When I move the mouse pointer inside the control, the "Enter" event occurs.
When I move the mouse outside the control, the "Leave" enter occurs.
Now I try the same again with very rapid mouse movements where I move the mouse pointer quickly into and out of control. It works perfectly fine, no matter how fast I do it. The Enter-Leave-Enter-Leave sequence is perfectly fine: Enter-Leave-Enter-Leave, etc.
Now I duplicate the control so that I have 2 of them next to each other:
I quickly move the mouse pointer from control 1 to control 2.
The sequence is still perfectly fine: Enter-Leave-Enter-Leave.
Now I compile the project and run the exe:
I do the same: I quickly move the mouse pointer from control 1 to control 2.
Now the following sequence occurs:
Control 1: Enter
Control 2: Enter
Control 1: Leave
Control 2: Leave
I thought that the sequence was fixed and not as "variable" as could be observed here.
What have I not thought of?
What baffles me is that it works as expected in IDE, but not predictable when compiled.
To debug what is happening, I have tried Spy++, but it only reports WM_MOUSEMOVE, so I have no idea what else I could try now to find out if the message pumps receives it in the "correct" order, and for some reason, it just gets messed up in my application.
Thank you for any help.

Visual Basic: Force App to Stop

How can I simulate; app has stopped
After I click a button? I'm trying to make my program display that (exactly) after I click a button.
easy way to do this is,
let your app crash in the first place ( cause some sort of exception) take a screenshot from that exact message.
Create a new form called mCrashForm, place a picturebox with the screenshot of that message ( leave out the close Program button.
Create a button in your main Form to open the crashForm with mCrashForm.Show()
Create a Button in mCrashForm which says "Close program" which executes this code snippet when pressed mCrashForm.Close()

How could my Application form in vb be closing by itself?

I have a form in a Pocket PC app that is set to be the Application form using:
Application.Run(New frmMain())
Somehow this form is getting closed for no reason while working on another form. No closing event is fired and nowhere in my code can you close the main form anyway. It is only closed by clicking the OK button at the top right of the window. When this is clicked, the user is prompted if he/she really wants to close the application. However, this is not occurring either.
Basically, I am on another form which adds a new record to the database. After adding the record the gotFocus event is somehow called for frmMain. When the code in the gotFocus event reaches a reference to a control on the form, there is an exception that states that the object is disposed.
When I bypass the code in the gotFocus event, the application just closes completely. I verify this by checking that it is not running in the device's memory.
I have been stepping through code for 2 hours and I have absolutely no idea why this could be occurring. Anyone possibly have a tip?
This sounds as an exception being raised anywhere. Maybe an exception on another thread? Look at the output window to see what it says.

play sound triggered by click on form control

I'm trying to trigger a sound by clicking on a form control in Excel 11. The handler for the click event tries to play a sound using sndPlaySound32 if it finds certain text on the clipboard.
I've declared the function sndPlaySound32, and call it with (simplified)
whatSound$ = "C:\WINDOWS\Media\Office97\Drop.wav"
sndPlaySound32 whatSound$, &H0
As long as Excel is the front app when I click the control then everything works fine and the sound plays (if the target text is found on the clipboard), but if I'm bringing the text in on the clipboard from another app like Notepad, where Excel is not the front app when the click occurs, then the first click on the control doesn't produce any sound. Subsequent clicks work normally. Other events on the form have no problem with this and continue to respond normally to the first click.
How can I make the sound play on the first click of the control when Excel is not the front app?
Edit 11/25/10:
I can't make the board Comments work. I click Add Comment but my comments aren't shown, so this is a reply to Boost.
I think it's something deeper than just bringing Excel to the front with the first click, because there are several of other actions that are triggered successfully by this first click on the control, (while another app is in front), and they all work just fine. It's only the playSound that doesn't work until subsequent clicks.
I've tried moving the playSound command both to the front and to the end of the list of other actions (e.g. font changes, text resizing etc.) that are supposed to happen with each click, and also tried putting delays in various places, but no joy. If I step through the code, the playSound procedure gets called correctly on the first click but it doesn't produce a sound.
I don't think there's a fix here. An application will not accept mouse events until it is "in focus." If Notepad is in focus, you will transfer focus from it to Excel with the first click, then Excel's event handlers will come into play and respond to subsequent events.
You could (and I don't know if it's even possible) put a transparent windows over the whole screen and interpret mouse-clicks in that context, and pass them to the appropriate underlying windows. SMOP, I suppose.
I finally found a workaround that's simple, reliable, and ugly. Since it won't play the sound on the first click, I just give it another chance. So now, in place of the code in my original post, it looks like this:
whatSound$ = "C:\WINDOWS\Media\Office97\Drop.wav"
sndPlaySound32 whatSound$, &H0
sndPlaySound32 whatSound$, &H0
It still ignores the first playSound command, but it plays the second one every time on the first click.

Can not get Process to die in VB.net

I've inherited some VB.net code. My task is to find out why it isn't working. I have 2 applications. The first one
is run as a service, infinitely checking a table to see if there are any tasks to be handled. If it finds one, its supposed to fire off the second application to handle the task then returns to the loop and checks for another. Both these applications are forms but they do not show any windows. The problem I'm having is after the second application is finished, the first application never gets a signal it is done so it is waiting forever, thus it can't move onto the next task. If I go into TaskManager and kill the second application, the first one gets that notification and proceeds as it should. Below is how I am creating the process and waiting for it. I've tried several different ways of creating and waiting for the process (using a Shell/OpenProcess, WaitForSingleObject,etc) and I can't get it to work. I've searched all over the internet, StackOverflow and the MSDN site but nothing I've tried works. I've been messing with this for 2 days!!
Form 1 Load:
Dim ProcessProperties As New ProcessStartInfo
ProcessProperties.FileName = strExeFullPath
ProcessProperties.Arguments = " /project " & l_project
ProcessProperties.CreateNoWindow = True
Dim myProcess As Process = Process.Start(ProcessProperties)
myProcess.WaitForExit()
When Form2 is finished, it does a Me.Close() and Exit Sub in the load subroutine but the process is still showing in the TaskManager and never returns to Form1 so Form1 is in WaitForExit forever. I've tried closing every open file and connection and setting them to Nothing in Form2, Me.Dispose,etc. I've tried Application.Exit as the last line of Form2. That stupid thing will not die!! Why won't it DIE!!??!!
What am I missing?
If I go into TaskManager and kill the second application, the first one gets that notification
Keep your eyes on the ball, the real problem is that this second application is not exiting by itself. And thus myProcess.WaitForExit() isn't going to return. So this is not a problem in your code snippet.
Why the 2nd app doesn't want to quit is completely unclear from your question. Given that it is a Windows Forms app, do keep in mind that there is nobody to click the Close button of the form. Application.Exit() should make it stop, Environment.Exit() is a rude abort that cannot be veto-ed by a FormClosing event handler.
Anyway use this:
ProcessProperties.Arguments = String.Format("/project {0}", 1_project)
No leading space is required and code becomes more readable.
Cheers!
I suspect Form2 is trying to show some modal dialog (maybe a message box, maybe an unhandled exception box) before quitting. Since App2 is launched by App1, which is a service, Form2 cannot interact with the desktop and just sits there waiting for a button click that will never happen.
Try to allow the App1 service to interact with the desktop (you can find that option on the Log On tab of the service properties dialog box) and check if Form2 actually pops up a dialog before quitting.