home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l040 / 11.ddi / OWLDEMOS.ZIP / PROGTALK.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-27  |  10.0 KB  |  344 lines

  1. {************************************************}
  2. {                                                }
  3. {   Demo program                                 }
  4. {   Copyright (c) 1991 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. program ProgTalk;
  9.  
  10. uses WinTypes, WinProcs, OWindows, ODialogs, Strings;
  11.  
  12. {$R PROGTALK}
  13.  
  14. const
  15.  
  16. { Resource IDs }
  17.  
  18.   id_DDEDialog    = 100;
  19.   id_AddDialog    = 101;
  20.   id_CreateDialog = 102;
  21.  
  22. { DDE dialog item IDs }
  23.  
  24.   id_ListBox     = 100;
  25.   id_AddItem     = 101;
  26.   id_DeleteItem  = 102;
  27.   id_ClearItems  = 103;
  28.   id_CreateGroup = 104;
  29.  
  30. { Add and Create dialog item IDs }
  31.  
  32.   id_InputLine = 100;
  33.  
  34. type
  35.  
  36. { TInputDialog is the object type used to represent the Add Item and
  37.   Create Group dialogs. }
  38.  
  39.   PInputDialog = ^TInputDialog;
  40.   TInputDialog = object(TDialog)
  41.     Buffer: PChar;
  42.     BufferSize: Word;
  43.     constructor Init(AParent: PWindowsObject;
  44.       AName, ABuffer: PChar; ABufferSize: Word);
  45.     procedure SetupWindow; virtual;
  46.     function CanClose: Boolean; virtual;
  47.     procedure InputLine(var Msg: TMessage);
  48.       virtual id_First + id_InputLine;
  49.   end;
  50.  
  51. { TDDEWindow is the main window of the application. It engages in a DDE
  52.   conversation with the Program Manager to create program groups with a
  53.   user specified list of program items. }
  54.  
  55.   PDDEWindow = ^TDDEWindow;
  56.   TDDEWindow = object(TDlgWindow)
  57.     ListBox: PListBox;
  58.     ServerWindow: HWnd;
  59.     PendingMessage: Word;
  60.     constructor Init;
  61.     procedure SetupWindow; virtual;
  62.     function GetClassName: PChar; virtual;
  63.     procedure InitiateDDE;
  64.     procedure TerminateDDE;
  65.     procedure AddItem(var Msg: TMessage);
  66.       virtual id_First + id_AddItem;
  67.     procedure DeleteItem(var Msg: TMessage);
  68.       virtual id_First + id_DeleteItem;
  69.     procedure ClearItems(var Msg: TMessage);
  70.       virtual id_First + id_ClearItems;
  71.     procedure CreateGroup(var Msg: TMessage);
  72.       virtual id_First + id_CreateGroup;
  73.     procedure WMDDEAck(var Msg: TMessage);
  74.       virtual wm_First + wm_DDE_Ack;
  75.     procedure WMDDETerminate(var Msg: TMessage);
  76.       virtual wm_First + wm_DDE_Terminate;
  77.     procedure WMDestroy(var Msg: TMessage);
  78.       virtual wm_First + wm_Destroy;
  79.   end;
  80.  
  81. { TDDEApp is the application object. It creates a main window of type
  82.   TDDEWindow. }
  83.  
  84.   TDDEApp = object(TApplication)
  85.     procedure InitMainWindow; virtual;
  86.   end;
  87.  
  88. { TInputDialog }
  89.  
  90. { Input dialog constructor. Save the input buffer pointer and size
  91.   for later use. }
  92.  
  93. constructor TInputDialog.Init(AParent: PWindowsObject;
  94.   AName, ABuffer: PChar; ABufferSize: Word);
  95. begin
  96.   TDialog.Init(AParent, AName);
  97.   Buffer := ABuffer;
  98.   BufferSize := ABufferSize;
  99. end;
  100.  
  101. { SetupWindow is called right after the dialog is created. Limit the
  102.   edit control to the maximum length of the input buffer, and disable
  103.   the Ok button. }
  104.  
  105. procedure TInputDialog.SetupWindow;
  106. begin
  107.   SendDlgItemMessage(HWindow, id_InputLine, em_LimitText,
  108.     BufferSize - 1, 0);
  109.   EnableWindow(GetDlgItem(HWindow, id_Ok), False);
  110. end;
  111.  
  112. { CanClose is called when the user presses Ok. Copy the contents of
  113.   the edit control to the input buffer and return True to allow the
  114.   dialog to close. }
  115.  
  116. function TInputDialog.CanClose: Boolean;
  117. begin
  118.   GetDlgItemText(HWindow, id_InputLine, Buffer, BufferSize);
  119.   CanClose := True;
  120. end;
  121.  
  122. { Edit control response method. Enable or disable the Ok button
  123.   based on whether the edit control contains any text. }
  124.  
  125. procedure TInputDialog.InputLine(var Msg: TMessage);
  126. begin
  127.   if Msg.LParamHi = en_Change then
  128.     EnableWindow(GetDlgItem(HWindow, id_Ok),
  129.       SendMessage(Msg.LParamLo, wm_GetTextLength, 0, 0) <> 0);
  130. end;
  131.  
  132. { TDDEWindow }
  133.  
  134. { DDE window constructor. Create a TListBox object to represent the
  135.   dialog's list box. Clear the DDE server window handle and the
  136.   pending DDE message ID. }
  137.  
  138. constructor TDDEWindow.Init;
  139. begin
  140.   TDlgWindow.Init(nil, PChar(id_DDEDialog));
  141.   ListBox := New(PListBox, InitResource(@Self, id_ListBox));
  142.   ServerWindow := 0;
  143.   PendingMessage := 0;
  144. end;
  145.  
  146. { SetupWindow is called right after the DDE window is created.
  147.   Initiate the DDE conversation. }
  148.  
  149. procedure TDDEWindow.SetupWindow;
  150. begin
  151.   TDlgWindow.SetupWindow;
  152.   InitiateDDE;
  153. end;
  154.  
  155. { Return window class name. This name corresponds to the class name
  156.   specified for the DDE dialog in the resource file. }
  157.  
  158. function TDDEWindow.GetClassName: PChar;
  159. begin
  160.   GetClassName := 'DDEWindow';
  161. end;
  162.  
  163. { Initiate a DDE conversation with the Program Manager. Bring up a
  164.   message box if the Program Manager doesn't respond to the
  165.   wm_DDE_Initiate message. }
  166.  
  167. procedure TDDEWindow.InitiateDDE;
  168. var
  169.   AppAtom, TopicAtom: TAtom;
  170. begin
  171.   PendingMessage := wm_DDE_Initiate;
  172.   AppAtom := GlobalAddAtom('PROGMAN');
  173.   TopicAtom := GlobalAddAtom('PROGMAN');
  174.   SendMessage(HWnd(-1), wm_DDE_Initiate, HWindow,
  175.     MakeLong(AppAtom, TopicAtom));
  176.   GlobalDeleteAtom(AppAtom);
  177.   GlobalDeleteAtom(TopicAtom);
  178.   PendingMessage := 0;
  179.   if ServerWindow = 0 then
  180.     MessageBox(HWindow, 'Cannot establish DDE link to Program Manager.',
  181.       'Error', mb_IconExclamation or mb_Ok);
  182. end;
  183.  
  184. { Terminate the DDE conversation. Send the wm_DDE_Terminate message
  185.   only if the server window still exists. }
  186.  
  187. procedure TDDEWindow.TerminateDDE;
  188. var
  189.   W: HWnd;
  190. begin
  191.   W := ServerWindow;
  192.   ServerWindow := 0;
  193.   if IsWindow(W) then PostMessage(W, wm_DDE_Terminate, HWindow, 0);
  194. end;
  195.  
  196. { Add item button response method. Bring up the Add item dialog to
  197.   input a program item string, and add that item to the list box. }
  198.  
  199. procedure TDDEWindow.AddItem(var Msg: TMessage);
  200. var
  201.   Name: array[0..63] of Char;
  202. begin
  203.   if Application^.ExecDialog(New(PInputDialog, Init(@Self,
  204.     PChar(id_AddDialog), Name, SizeOf(Name)))) <> id_Cancel then
  205.     ListBox^.AddString(Name);
  206. end;
  207.  
  208. { Delete item button response method. Delete the currently selected
  209.   item in the list box. }
  210.  
  211. procedure TDDEWindow.DeleteItem(var Msg: TMessage);
  212. begin
  213.   ListBox^.DeleteString(ListBox^.GetSelIndex);
  214. end;
  215.  
  216. { Clear items button response method. Clear the list box. }
  217.  
  218. procedure TDDEWindow.ClearItems(var Msg: TMessage);
  219. begin
  220.   ListBox^.ClearList;
  221. end;
  222.  
  223. { Create group button response method. Bring up the Create Group
  224.   dialog to input the program group name. Then, if a DDE link has
  225.   been established (ServerWindow <> 0) and there is no DDE message
  226.   currently pending (PendingMessage = 0), build a list of Program
  227.   Manager commands, and submit the commands using a wm_DDE_Execute
  228.   message. To build the command list, first calculate the total
  229.   length of the list, then allocate a global memory block of that
  230.   size, and finally store the command list as a null-terminated
  231.   string in the memory block. }
  232.  
  233. procedure TDDEWindow.CreateGroup(var Msg: TMessage);
  234. const
  235.   sCreateGroup = '[CreateGroup(%s)]';
  236.   sAddItem = '[AddItem(%s)]';
  237. var
  238.   Executed: Boolean;
  239.   I, L: Integer;
  240.   HCommands: THandle;
  241.   PName, PCommands: PChar;
  242.   Name: array[0..63] of Char;
  243. begin
  244.   if Application^.ExecDialog(New(PInputDialog, Init(@Self,
  245.     PChar(id_CreateDialog), Name, SizeOf(Name)))) <> id_Cancel then
  246.   begin
  247.     Executed := False;
  248.     if (ServerWindow <> 0) and (PendingMessage = 0) then
  249.     begin
  250.       L := StrLen(Name) + (Length(sCreateGroup) - 1);
  251.       for I := 0 to ListBox^.GetCount - 1 do
  252.         Inc(L, ListBox^.GetStringLen(I) + (Length(sAddItem) - 2));
  253.       HCommands := GlobalAlloc(gmem_Moveable or gmem_DDEShare, L);
  254.       if HCommands <> 0 then
  255.       begin
  256.         PName := Name;
  257.         PCommands := GlobalLock(HCommands);
  258.         WVSPrintF(PCommands, sCreateGroup, PName);
  259.         for I := 0 to ListBox^.GetCount - 1 do
  260.         begin
  261.           ListBox^.GetString(Name, I);
  262.           PCommands := StrEnd(PCommands);
  263.           WVSPrintF(PCommands, sAddItem, PName);
  264.         end;
  265.         GlobalUnlock(HCommands);
  266.         if PostMessage(ServerWindow, wm_DDE_Execute, HWindow,
  267.           MakeLong(0, HCommands)) then
  268.         begin
  269.           PendingMessage := wm_DDE_Execute;
  270.           Executed := True;
  271.         end else GlobalFree(HCommands);
  272.       end;
  273.     end;
  274.     if not Executed then
  275.       MessageBox(HWindow, 'Program Manager DDE execute failed.',
  276.         'Error', mb_IconExclamation or mb_Ok);
  277.   end;
  278. end;
  279.  
  280. { wm_DDE_Ack message response method. If the current DDE message
  281.   is a wm_DDE_Initiate, store off the window handle of the window
  282.   that responded. If more than one window responds, terminate all
  283.   conversations but the first. If the current DDE message is a
  284.   wm_DDE_Execute, free the command string memory block, focus our
  285.   window, and clear the list box. }
  286.  
  287. procedure TDDEWindow.WMDDEAck(var Msg: TMessage);
  288. begin
  289.   case PendingMessage of
  290.     wm_DDE_Initiate:
  291.       begin
  292.         if ServerWindow = 0 then
  293.           ServerWindow := Msg.WParam
  294.         else
  295.           PostMessage(Msg.WParam, wm_DDE_Terminate, HWindow, 0);
  296.         GlobalDeleteAtom(Msg.LParamLo);
  297.         GlobalDeleteAtom(Msg.LParamHi);
  298.       end;
  299.     wm_DDE_Execute:
  300.       begin
  301.         GlobalFree(Msg.LParamHi);
  302.         PendingMessage := 0;
  303.         SetFocus(HWindow);
  304.         ListBox^.ClearList;
  305.       end;
  306.   end;
  307. end;
  308.  
  309. { wm_DDE_Terminate message response method. If the window signaling
  310.   termination is our server window (the Program Manager), terminate
  311.   the DDE conversation. Otherwise ignore the wm_DDE_Terminate. }
  312.  
  313. procedure TDDEWindow.WMDDETerminate(var Msg: TMessage);
  314. begin
  315.   if Msg.WParam = ServerWindow then TerminateDDE;
  316. end;
  317.  
  318. { wm_Destroy message response method. Terminate the DDE link and
  319.   call the inherited WMDestroy. }
  320.  
  321. procedure TDDEWindow.WMDestroy(var Msg: TMessage);
  322. begin
  323.   TerminateDDE;
  324.   TDlgWindow.WMDestroy(Msg);
  325. end;
  326.  
  327. { TDDEApp }
  328.  
  329. { Create a DDE window as the application's main window. }
  330.  
  331. procedure TDDEApp.InitMainWindow;
  332. begin
  333.   MainWindow := New(PDDEWindow, Init);
  334. end;
  335.  
  336. var
  337.   DDEApp: TDDEApp;
  338.  
  339. begin
  340.   DDEApp.Init('ProgTalk');
  341.   DDEApp.Run;
  342.   DDEApp.Done;
  343. end.
  344.