home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / PROGMAN.PAK / PROGMANX.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  7KB  |  240 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //----------------------------------------------------------------------------
  4. #include <owl\owlpch.h>
  5. #include <owl\dialog.h>
  6. #include <owl\framewin.h>
  7. #include <owl\applicat.h>
  8. #include <owl\listbox.h>
  9. #include <owl\inputdia.h>
  10. #include <string.h>
  11. #include <ddeml.h>
  12. #include "progmanx.h"     // Dialog item IDs
  13.  
  14.  
  15. //
  16. // TDDEProgTalk is the main window of the application. 
  17. // It engages in a DDE conversation with the Program Manager
  18. // to create program groups with a
  19. // user specified list of program items.
  20. //
  21. // See DDEML example
  22.  
  23.  
  24. class TDDEProgTalk : public TDialog{
  25.   public:
  26.     //  Create a TListBox object to represent the
  27.     //  dialog's list box.
  28.     //
  29.     TDDEProgTalk(TWindow* parent, TResId resId) :
  30.       TDialog(parent, resId),
  31.       CallBackProc((FARPROC)CallBack) {
  32.       ListBox = new TListBox(this, ID_LISTBOX);
  33.     }
  34.     ~TDDEProgTalk();
  35.  
  36.   private:
  37.     void SetupWindow();
  38.     void CmAddItem();
  39.     void CmDeleteItem();
  40.     void CmClearItems();
  41.     void CmCreateGroup();
  42.     void EvDDEAck(HWND hWnd, LONG lParam);
  43.  
  44.     TListBox* ListBox;
  45.  
  46.     //DDEML
  47.     static HDDEDATA FAR PASCAL _export CallBack(WORD, WORD, HCONV, HSZ, HSZ,
  48.                                                 HDDEDATA, DWORD, DWORD);
  49.     DWORD   InstId;
  50.     HCONV   HConv;
  51.     HSZ     Service;
  52.     HSZ     Topic;
  53.     TProcInstance CallBackProc;
  54.     
  55.   DECLARE_RESPONSE_TABLE(TDDEProgTalk);
  56. };
  57.  
  58. static TDDEProgTalk* This = 0;
  59.  
  60. DEFINE_RESPONSE_TABLE1(TDDEProgTalk, TDialog)
  61.   EV_COMMAND(CM_ADDITEM, CmAddItem),
  62.   EV_COMMAND(CM_DELETEITEM, CmDeleteItem),
  63.   EV_COMMAND(CM_CLEARITEMS, CmClearItems),
  64.   EV_COMMAND(CM_CREATEGROUP, CmCreateGroup),
  65. END_RESPONSE_TABLE;
  66.  
  67. TDDEProgTalk::~TDDEProgTalk()
  68. {
  69.   // This clean up is required for those resources that were allocated during
  70.   // the DDEML conversation.
  71.   //
  72.   if (HConv)
  73.     DdeDisconnect(HConv);     // Let the other party know we are leaving
  74.  
  75.   if (InstId) {
  76.     DdeFreeStringHandle(InstId, Service);
  77.     DdeFreeStringHandle(InstId, Topic);
  78.     DdeUninitialize(InstId);
  79.   }
  80. }
  81.  
  82. //  SetupWindow is called right after the DDE window
  83. //  is created.  Initiate the DDE conversation.
  84. //
  85. void
  86. TDDEProgTalk::SetupWindow() {
  87.   InstId = 0;         // MUST be 0 the first time DdeInitialize() is called!
  88.   HConv = 0;
  89.   Service = Topic = 0;
  90.   This = this;
  91.  
  92.   TDialog::SetupWindow();
  93.  
  94.   // The code below sets up the DDEML call back function that is used by the
  95.   // DDE Management Library to carry out data transfers between
  96.   // applications.
  97.   //
  98.   if (CallBackProc) {
  99.     if (DdeInitialize(&InstId, (PFNCALLBACK)(FARPROC)CallBackProc, APPCMD_CLIENTONLY, 0) == DMLERR_NO_ERROR) {
  100.       Service = DdeCreateStringHandle(InstId, "PROGMAN", CP_WINANSI);
  101.       Topic = DdeCreateStringHandle(InstId, "PROGMAN", CP_WINANSI);
  102.       if (!Service || !Topic) {
  103.         MessageBox("Creation of strings failed.", Title, MB_ICONSTOP);
  104.         PostQuitMessage(0);
  105.       }
  106.     } else {
  107.       MessageBox("Initialization failed.", Title, MB_ICONSTOP);
  108.       PostQuitMessage(0);
  109.     }
  110.   } else {
  111.     MessageBox("Setup of callback failed.", Title, MB_ICONSTOP);
  112.     PostQuitMessage(0);
  113.   }
  114.  
  115. }
  116.  
  117. //
  118. // Add item button response method. Bring up the Add item dialog to
  119. // input a program item string, and add that item to the list box.
  120. //
  121. void
  122. TDDEProgTalk::CmAddItem()
  123. {
  124.   char name[64] = "";
  125.  
  126.   if (TInputDialog(this, "Add an Item to the Group", "Item &name:",
  127.                    name, sizeof(name)).Execute() != IDCANCEL)
  128.     ListBox->AddString(name);
  129. }
  130.  
  131. //
  132. // Delete item button response method. Delete the currently selected
  133. // item in the list box.
  134. //
  135. void
  136. TDDEProgTalk::CmDeleteItem()
  137. {
  138.   ListBox->DeleteString(ListBox->GetSelIndex());
  139. }
  140.  
  141. //
  142. // Clear items button response method. Clear the list box.
  143. //
  144. void
  145. TDDEProgTalk::CmClearItems()
  146. {
  147.   ListBox->ClearList();
  148. }
  149.  
  150. //
  151. // Create group button response method. Bring up the Create Group
  152. // dialog to input the program group name.
  153. //
  154. void
  155. TDDEProgTalk::CmCreateGroup()
  156. {
  157.   char* createGroup = "[CreateGroup(%s)]";
  158.   char* addItem = "[AddItem(%s)]";
  159.  
  160.   char name[64] = "";
  161.  
  162.   if (TInputDialog(this,
  163.                    "Create a new group", "&Name of new group:",
  164.                    name, sizeof(name)).Execute() != IDCANCEL) {
  165.     // Connect to the prog manager
  166.     HConv = DdeConnect(InstId, Service, Topic, 0);
  167.     if (!HConv) {
  168.       MessageBox("Can't start conversation.\nMake sure PROGMAN is running.", Title, MB_ICONSTOP);
  169.       return;
  170.       }
  171.  
  172.       // Subtract 2 for the '%s' in 'createGroup', plus 1 for null terminator.
  173.       //
  174.       int len = strlen(name) + strlen(createGroup) - 2 + 1;
  175.       int count = ListBox->GetCount();
  176.       for (int i = 0; i < count; i++)
  177.         // Subtract 2 for the '%s' in 'addItem'.
  178.         len += ListBox->GetStringLen(i) + strlen(addItem) - 2;
  179.  
  180.       LPSTR commands = new char[len];
  181.       LPSTR ptr=commands;      
  182.       wsprintf(ptr, createGroup, (LPSTR)name);
  183.       for (i = 0; i < count; i++) {
  184.         ListBox->GetString(name, i);
  185.         ptr += strlen(ptr);
  186.         wsprintf(ptr, addItem, (LPSTR)name);
  187.       }
  188.  
  189.       //Send command to progman
  190.       if (DdeClientTransaction((LPBYTE)commands, len, HConv, 0L, CF_TEXT, XTYP_EXECUTE, 1000, 0))
  191.         ListBox->ClearList();
  192.  
  193.       delete commands;
  194.   }
  195. }
  196.  
  197. //
  198. // This call back function is the heart of interaction between this program
  199. // and DDEML.  Because Windows doesn't pass C++ 'this' pointers to call
  200. // back functions, a static 'this' pointer was used.  If you wanted to
  201. // create a Client that would allow for more than one conversation, using a
  202. // List of conversations and their associated 'this' pointers would be one
  203. // possible method to try.  The XTYP_ constants are described in detail in
  204. // the online help.
  205. //
  206. HDDEDATA FAR PASCAL _export
  207. TDDEProgTalk::CallBack(WORD type, WORD, HCONV /*hConv*/, HSZ, HSZ, HDDEDATA /*hData*/,
  208.                     DWORD, DWORD)
  209. {
  210.   switch (type) {
  211.     case XTYP_DISCONNECT:
  212.       This->MessageBox("Disconnected.", This->Title, MB_ICONINFORMATION);
  213.       This->HConv = 0;
  214.       break;
  215.  
  216.     case XTYP_ERROR:
  217.       This->MessageBox("A critical DDE error has occured.", This->Title, MB_ICONINFORMATION);
  218.   }
  219.   return 0;
  220. }
  221.  
  222. //----------------------------------------------------------------------------
  223.  
  224. // TDdeApp is the application object. It creates a main window of type
  225. // TDDEProgTalk.
  226. //
  227. class TDDEApp : public TApplication {
  228.   public:
  229.     TDDEApp() : TApplication() {}
  230.     void InitMainWindow() {
  231.       MainWindow = new TFrameWindow(0, "ProgTalk", new TDDEProgTalk(0, IDD_PROGTALK), TRUE);
  232.     }
  233. };
  234.  
  235. int
  236. OwlMain(int /*argc*/, char* /*argv*/ [])
  237. {
  238.   return TDDEApp().Run();
  239. }
  240.