Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / January 2007

Tip: Looking for answers? Try searching our database.

Converting VB DDE Client program to VC++

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Cindy - 13 Jan 2007 19:29 GMT
Hi all,

I am trying to connect to a electromyograph machine for my thesis project,
and I have a VB DDE client whose DDE functionality I want to convert to VC++.
However I can't make my VC++ version connect to the DDE server somehow --
DdeConnect(idInst,hszService, hszTopic, NULL) is not working

I am not sure if it's because DDEML doesn't support the connection, or if
it's because my code is incorrect (I'm not familiar with VB, so I'm just
guessing on how the service/topic strings should look like in C++).

Thanks so much!
Cindy

-----------------------------------------------------
Here is the VB program frm:
-----------------------------------------------------
VERSION 5.00
Begin VB.Form DDEForm
  Caption         =   "Destination"
  ClientHeight    =   5655
  ClientLeft      =   60
  ClientTop       =   345
  ClientWidth     =   4740
  LinkTopic       =   "SAM1|DDEForm"
  ScaleHeight     =   5655
  ScaleWidth      =   4740
  StartUpPosition =   3  'Windows Default
  Begin VB.CommandButton Command1
     Caption         =   "Command1"
     Height          =   495
     Left            =   3120
     TabIndex        =   11
     Top             =   2880
     Visible         =   0   'False
     Width           =   1215
  End
  Begin VB.TextBox saveFileName
     Height          =   375
     Left            =   1560
     TabIndex        =   9
     Text            =   "c:\cpi\data\test"
     Top             =   1680
     Width           =   2655
  End
  Begin VB.ComboBox Combo1
     Height          =   315
     Left            =   240
     Style           =   2  'Dropdown List
     TabIndex        =   8
     Top             =   2280
     Width           =   1335
  End
  Begin VB.Timer Timer1
     Interval        =   5000
     Left            =   240
     Top             =   5040
  End
  Begin VB.CommandButton Poke
     Caption         =   "Poke"
     Height          =   495
     Index           =   2
     Left            =   1680
     TabIndex        =   7
     Top             =   3360
     Width           =   1215
  End
  Begin VB.TextBox Text2
     Height          =   495
     Index           =   2
     Left            =   240
     TabIndex        =   6
     Top             =   3360
     Width           =   1215
  End
  Begin VB.CommandButton Poke
     Caption         =   "Poke"
     Height          =   495
     Index           =   1
     Left            =   1680
     TabIndex        =   5
     Top             =   2760
     Width           =   1215
  End
  Begin VB.TextBox Text2
     Height          =   495
     Index           =   1
     Left            =   240
     TabIndex        =   4
     Top             =   2760
     Width           =   1215
  End
  Begin VB.TextBox Text2
     Height          =   495
     Index           =   0
     Left            =   3000
     LinkTimeout     =   -1
     TabIndex        =   3
     Top             =   2160
     Visible         =   0   'False
     Width           =   1215
  End
  Begin VB.CommandButton Request
     Caption         =   "Request"
     Height          =   495
     Left            =   3120
     TabIndex        =   2
     Top             =   840
     Width           =   1215
  End
  Begin VB.CommandButton Poke
     Caption         =   "Poke"
     Height          =   495
     Index           =   0
     Left            =   1680
     TabIndex        =   1
     Top             =   2160
     Width           =   1215
  End
  Begin VB.TextBox Text1
     Height          =   495
     Left            =   240
     LinkTimeout     =   5000
     TabIndex        =   0
     Text            =   "Text1"
     Top             =   240
     Width           =   4095
  End
  Begin VB.Label Label1
     Caption         =   "Aquire File Name:"
     Height          =   375
     Left            =   120
     TabIndex        =   10
     Top             =   1680
     Width           =   1335
  End
End
Attribute VB_Name = "DDEForm"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Const AUTOMATIC = 1, MANUAL = 2, NONE = 0
Dim FileOpen As Boolean
Dim AppReady As Boolean
Dim FileNum3 As Integer
Dim buffer() As Byte

Private Sub Option1_Click()

End Sub

Private Sub AutomaticLink_Click()

     Request.Visible = False   'No need for button with automatic link.
     Text1.LinkMode = NONE     'Clear DDE Link.

     Text1.LinkMode = AUTOMATIC   'Reestablish new LinkMode.
 
End Sub

Private Sub Command1_Click()
     Text2(0).LinkExecute Text2(0).Text

End Sub

Private Sub Combo1_Change()
     If Combo1.Text = "FILE" Then
        Text2(0).Text = Combo1.Text & " " & saveFileName.Text
     Else
       Text2(0).Text = Combo1.Text
     End If
End Sub

Private Sub Combo1_Click()
     If Combo1.Text = "FILE" Then
        Text2(0).Text = Combo1.Text & " " & saveFileName.Text
     Else
       Text2(0).Text = Combo1.Text
     End If

End Sub

Private Sub Form_Load()
Dim z As Long
   AppReady = False
 
     'This procedure will start the VB source application.

     z = Shell("c:\cpi\sam2", 1)
     z = DoEvents()   'Causes Windows to finish processing Shell command.
   
     Combo1.AddItem "FILE"
     Combo1.AddItem "START"
     Combo1.AddItem "STOP"
     Combo1.AddItem "AQUIRE"
     Combo1.AddItem "HIDE"
     Combo1.AddItem "SHOW"
     Combo1.AddItem "SETUP"
     Combo1.AddItem "BEGIN"
     If Combo1.Text = "FILE" Then
        Text2(0).Text = Combo1.Text & " " & saveFileName.Text
     Else
       Text2(0).Text = Combo1.Text
     End If
     Text1.LinkMode = NONE   'Clears DDE link if it already exists.
   
     Do While Not AppReady
       DoEvents
     Loop
   
     Text1.LinkTopic = "sam2|frmDDE"   'Sets up link with VB source.
     Text1.LinkItem = "Text1"           'Set link to text box on source.
     Text1.LinkMode = MANUAL            'Establish a manual DDE link.
   
     For i = 0 To 2
       Text2(i).LinkTopic = "sam2|frmDDE"   'Sets up link with VB source.
       Select Case i
           Case 0
              Text2(i).LinkItem = "Text2"           'Set link to text box
on source.
           Case 1
              Text2(i).LinkItem = "Text3"           'Set link to text box
on source.
           Case 2
              Text2(i).LinkItem = "Text4"           'Set link to text box
on source.
       End Select
       Text2(i).LinkMode = MANUAL            'Establish a manual DDE link.
     Next i
   
     Text1.LinkTopic = "sam2|frmDDE"   'Sets up link with VB source.
     Text1.LinkItem = "Text1"           'Set link to text box on source.
     Text1.LinkMode = MANUAL            'Establish a manual DDE link.
 
     AutomaticLink_Click
   
     If FileOpen = False Then
         FileNum3 = FreeFile
         Open "Outputdata.txt" For Output As #FileNum3
         FileOpen = True
     End If


End Sub

Private Sub ManualLink_Click()

     Request.Visible = True    'Make request button valid.
     Text1.LinkMode = NONE     'Clear DDE Link.
     Text1.LinkMode = MANUAL   'Reestablish new LinkMode.
 
End Sub

Private Sub Form_Unload(Cancel As Integer)
   Close #FileNum3
End Sub

Private Sub Poke_Click(Index As Integer)

     'With any DDE link, this button will be visible, and when it's
     'selected, will poke information from the destination application
     'into the source application.
     Text2(Index).LinkPoke
 
End Sub

Private Sub Request_Click()

     'With a manual DDE link, this button will be visible, and when
     'selected it will request an update of information from the source
     'application to the destination application.
     Text1.LinkRequest
 
End Sub

Private Sub Text1_Change()
Print #FileNum3, Text1.Text
End Sub
Private Sub Timer1_Timer()
Timer1.Enabled = False
AppReady = True
End Sub

-----------------------------------------------------
Here are snippets of my VC++ code that deals with the DDE:
-----------------------------------------------------
//Initialize DDE
UINT ui;

idInst = 0;
HINSTANCE hinst;
                       
ui = DdeInitialize(&idInst,         // receives instance identifier
(PFNCALLBACK) DdeCallback, // pointer to callback function
CBF_FAIL_EXECUTES |        // filter XTYPE_EXECUTE
CBF_SKIP_ALLNOTIFICATIONS, // filter notifications
0);

if (ui != DMLERR_NO_ERROR)
{
    richTextBox1->Text = "Failed to initialize as DDE client\n";
}

//Now try connecting to server
LPSTR lpszService = "c:\\CPI\\SAM2.EXE";
LPSTR lpszTopic = "frmDDE";
LPSTR lpszItem = "FILE c:\\CPI\\data\\MyFileName";

HSZ hszTopic = DdeCreateStringHandle(idInst, lpszTopic, CP_WINANSI);
HSZ hszService = DdeCreateStringHandle(idInst, lpszService, CP_WINANSI);
hconvNew = DdeConnect(idInst,hszService, hszTopic, NULL);

// Free the HSZs now
DdeFreeStringHandle(idInst, hszTopic);
DdeFreeStringHandle(idInst, hszService);
         
if (!hconvNew)
{
    richTextBox1->AppendText("Couldn't connect to: ");
    richTextBox1->AppendText(lpszService);
    richTextBox1->AppendText(lpszTopic);
    richTextBox1->AppendText("\n");
    return;
}
                   
// Try to get the item we are interrested in
DWORD dwResult;
                   
HSZ hszItem = DdeCreateStringHandle(idInst,lpszItem,CP_WINANSI);

HDDEDATA hDDEData =
DdeClientTransaction(NULL,0,hconvNew,hszItem,CF_TEXT,XTYP_REQUEST,1000,&dwResult);
                   
DdeFreeStringHandle(idInst, hszItem);
                   
if (hDDEData)
{
    // Lock the data so we can access it
    BYTE FAR* pData;
    DWORD dwLength;
    pData = DdeAccessData(hDDEData, &dwLength);

    if (pData)
    {
         // Just show it
         richTextBox1->AppendText( (*pData).ToString() );
         richTextBox1->AppendText("\n");
    }

    // Done with the data
    DdeUnaccessData(hDDEData);
    DdeFreeDataHandle(hDDEData);

}
else
{
    richTextBox1->AppendText("couldn't get any data");
}

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

// Callback function for DDE messages
    static HDDEDATA CALLBACK DdeCallback(UINT wType,
                        UINT wFmt,
                        HCONV hConv,
                        HSZ hsz1,
                        HSZ hsz2,
                        HDDEDATA hDDEData,
                        DWORD dwData1,
                        DWORD dwData2)
{
    BYTE FAR *pData;
    DWORD dwLength;

    switch (wType)
    {
         case XTYP_ADVDATA:
                        return (HDDEDATA) DDE_FACK;

         case XTYP_DISCONNECT:
                        return (HDDEDATA) NULL;

         default:
                        return NULL;
                        break;
    }
}
Brian Gideon - 15 Jan 2007 00:23 GMT
> //Now try connecting to server
> LPSTR lpszService = "c:\\CPI\\SAM2.EXE";
> LPSTR lpszTopic = "frmDDE";
> LPSTR lpszItem = "FILE c:\\CPI\\data\\MyFileName";

The service name looks wrong to me.  Shouldn't it just be "sam2"?
Cindy - 16 Jan 2007 04:56 GMT
Yes, I have tried changing the service name, and it seems to connect now (at
least hconvNew is returning 1), thanks so much for the tip!

However, I still can't get the commands to my server, and I've been trying
different Item names. Right now I'm using (in VC++):

LPSTR lpszItem = "FILE c:\\CPI\\data\\MyFileName";

and I'm sending this command by:

HSZ hszItem = DdeCreateStringHandle(idInst,lpszItem,CP_WINANSI);

HDDEDATA hDDEData =
DdeClientTransaction(NULL,0,hconvNew,hszItem,CF_TEXT,XTYP_REQUEST,1000,&dwResult);

I've also tried using XTYP_POKE, but to no avail. Does anyone have any
suggestions?

Your help is much appreciated!
Cindy

> > //Now try connecting to server
> > LPSTR lpszService = "c:\\CPI\\SAM2.EXE";
> > LPSTR lpszTopic = "frmDDE";
> > LPSTR lpszItem = "FILE c:\\CPI\\data\\MyFileName";
>
> The service name looks wrong to me.  Shouldn't it just be "sam2"?
Brian Gideon - 26 Jan 2007 02:46 GMT
Hi,

I apologize for the extremely late reply.  Somehow I lost track of this
thread.  Anyway, have you tried the XTYP_EXECUTE transaction type?

Brian

> Yes, I have tried changing the service name, and it seems to connect now (at
> least hconvNew is returning 1), thanks so much for the tip!
[quoted text clipped - 23 lines]
>
> > The service name looks wrong to me.  Shouldn't it just be "sam2"?- Hide quoted text -- Show quoted text -

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.