LinkExecute from Visual Basic Disables Windows Messages

ID Number: Q80441

1.00

WINDOWS

buglist1.00

Summary:

In a dynamic data exchange (DDE) conversation with Visual Basic as the

client and any other DDE-capable application as the server, all

Windows events (such as mouse clicks) are disabled when a LinkExecute

is issued. The events are disabled until the routine invoked by the

LinkExecute method has ended. If the server shows either a message box

or a non-modal form, the OK button or control boxes are disabled, and

eventually a run-time error (286) "Time-out while waiting for DDE

response" occurs. If the routine invoked by LinkExecute takes too long

to end, the same error is generated. The problem does not occur if

Visual Basic is the server to a non-Visual Basic application.

This problem can occur for any DDE operation. If the other application

attempts to bring up a dialog or message box in response to a DDE

message, the same problem will occur. Normally, this would only happen

for a custom DDE application, because most DDE-aware applications do

not bring up dialog boxes in response to WM_DDE_* messages.

Microsoft has confirmed this to be a problem in Microsoft Visual Basic

programming system version 1.0 for Windows. We are researching this

problem and will post new information here as it becomes available.

More Information:

Steps to Reproduce Problem

--------------------------

1. Run Visual Basic, or if Visual Basic is already running, choose

New Project from the File menu (ALT, F, N). Form1 will be created

by default.

2. Add a text box (Text1) to Form1.

3. Add the following code to the LinkExecute event of Form1:

Sub Form_LinkExecute (cmdstr As String, Cancel As Integer)

MsgBox cmdstr, 0, "You cannot select OK" 'This will cause a

'DDE time-out error

Text1.Text = cmdstr

Cancel = 0 'Indicate that LinkExecute succeeded

End Sub

4. From the File menu, choose Make EXE File (ALT, F, K).

5. In the Make EXE File dialog box, enter DDESVR.EXE as the filename

and choose the OK button.

6. From the File menu, choose New Project. You will have the option to

save the current project. Choose the appropriate Yes or No buttons

for each dialog box and take the appropriate action. Form1 will be

created by default.

7. Add a text box to Form1.

8. Add the following code in the Form_Click event procedure for

Form1:

Sub Form_Click ()

Text1.LinkMode = 0

Text1.LinkTopic = "DDESVR|Form1" 'LinkTopic for Visual Basic DDE

'server

Text1.LinkItem = "Text1" 'Text box on DDE server

Text1.LinkMode = 2 'Establish a cold link

Text1.LinkExecute "Testing" 'Send the contents of the text

'box to the DDE server as the

'LinkExecute command string

End Sub

9. Add the following code to the Form_Load event procedure for Form1:

Sub Form_Load ()

x% = Shell("DDESVR.EXE", 1) 'Execute the DDE server

End Sub

10. From the Run menu, choose Start (ALT, R, S) to run the program.

When the message box is displayed, Windows will not respond to

user actions (including CTRL+C if in the Visual Basic

environment). Eventually a "Time-out while waiting for DDE

response" error will occur.

To work around this behavior, add a timer control (Timer1) to the

Visual Basic server application (created by following steps 1-5

above). You should change the Form_LinkExecute event procedure

(created in step 3 above) to contain the following code:

Sub Form_LinkExecute (cmdstr As String, Cancel As Integer)

Global_CmdStr = cmdstr

Timer1.Interval = 1 'Set the timer interval to 1 millisecond

Timer1.Enabled = -1 'Activate the timer

Cancel = 0 'Indicate LinkExecute success

End Sub

You should add a global variable to the general Declarations section

of Form1 to hold the contents of CmdStr, as follows:

Dim Global_CmdStr As String

The original contents of the Form_LinkExecute event procedure for

Form1 can be moved to the Timer1_Timer event procedure for Timer1.

After you make this change, the Timer1_Timer event procedure should

appear as follows:

Sub Timer1_Timer ()

Timer1.Enabled = 0 'Disable the timer

MsgBox Global_CmdStr, 0, "You can now select OK"

Text1.text = Global_CmdStr

End Sub

To recreate an .EXE file for the server application, follow steps 4

and 5 above.

When the client application (created by following steps 6-9 above) is

run, you should be able to choose the OK button in the message box.

Another Workaround

------------------

If you are using a non-Visual-Basic client application such as

WINWORD.EXE or EXCEL.EXE, you can still set up a timed call to a macro

by using the OnTime (WordBasic) or ON.TIME (Excel macro) statement.

For example:

1. Visual Basic performs a LinkExecute to Word macro #1

2. Word macro #1 uses the OnTime statement to set up a timer that will

execute Word macro #2 (the actual macro you want to run) the next

time WINWORD.EXE receives CPU time.

3. Word macro #1 completes and returns to Visual Basic, allowing the

LinkExecute statement to complete.

4. Visual Basic performs an AppActivate to give Word the focus, then

executes a few calls to DoEvents() to release the CPU to Word.

5. Word receives some CPU time and the OnTime event (the actual macro

you want to run) goes off. Because you are not currently executing

a Visual Basic LinkExecute statement, there should be no problem

with events being disabled.

Additional reference words: 1.00