home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / tpw / owldemos / progtalk.pas < prev    next >
Pascal/Delphi Source File  |  1991-05-20  |  10KB  |  345 lines

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