home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / drgmon.zip / drgdrop.doc < prev    next >
Text File  |  1993-12-05  |  14KB  |  269 lines

  1. DRGDROP.EXE is a sample program for OS/2 Drag/Drop facilities (aka Direct
  2. Manipulation). It is useful as a Drag/Drop monitoring program to dynamically
  3. see what is taking place during a direct manipulation operation.
  4.  
  5. DRGDROP starts out by creating 2 container windows, each being a container
  6. control which is a child of a frame window. One of the containers has some
  7. icons in it. Each icon represents a temporary file that is created at the
  8. beginning of the program and used to drag to other windows during program
  9. operation. The other container is empty. Once you drag some icons to the
  10. empty container it functions just like the container with the icons. Both
  11. containers start out at the bottom of the screen, each being half the width of
  12. the screen and 1/3 the height of the screen.
  13.  
  14. Since the icons in the first container represent actual files, these icons can
  15. be dragged and dropped on either the other DRGDROP container or other windows
  16. that support Drag/Drop.
  17.  
  18. In order to see what is going on during the Drag/Drop operation, 2 additional
  19. windows are created. I call these 'debug' windows. They are listboxes that are
  20. children of frame windows. All Drag/Drop activity is displayed in these windows.
  21. The windows are displayed on the top of the screen - one on the left and one on
  22. the right. They are tied to the container windows that are below them, i.e.
  23. any Drag/Drop activity that happens for the container below them gets output in
  24. their listbox. So the screen looks like this:
  25.  
  26.  
  27.                  ┌────────────┬───────────────┬────────────┐
  28.                  │ Container 1│               │ Container 2│
  29.                  │   Debug    │               │   Debug    │
  30.                  │  Window    │               │  Window    │
  31.                  │            │               │            │
  32.                  ├────────────┘               └────────────┤
  33.                  │                                         │
  34.                  │                                         │
  35.                  │                                         │
  36.                  │                                         │
  37.                  │                                         │
  38.                  ├────────────────────┬────────────────────┤
  39.                  │   Container #1     │   Container #2     │
  40.                  │      Window        │      Window        │
  41.                  │                    │                    │
  42.                  │              │                    │
  43.                  └────────────────────┴────────────────────┘
  44.  
  45.  
  46. Of course you can move these window anywhere you like. Their positions are not
  47. 'remembered' so the next time you bring up the program they will start out as
  48. above.
  49.  
  50. Drag/Drop all centers around PM messages and data structures. In order to
  51. understand it, you must understand these messages and structures and the
  52. sequences of events that causes the messages to be generated. That's where the
  53. Debug windows come in. Whenever the container's owner gets a Drag/Drop message,
  54. it calls program functions that dump the name of the message and the contents
  55. of the passed structures to the Debug window.
  56.  
  57. Once you get the hang of Drag and Drop, it will be handy to experiment with
  58. what happens when you start changing the values you set into the Drag/Drop data
  59. structures before the drag starts. To do this, a Settings Notebook is provided.
  60.  
  61. You can bring up the Settings notebook at any time by using the context-menu
  62. keystroke (the Right Mouse Button by default, unless it was changed because
  63. you are left-handed or something like that). This context menu gives you 4
  64. options, each will bring up the same Settings Notebook but opened to a different
  65. page. The 4 pages of the settings notebook are as follows:
  66.  
  67.  
  68.  DragInfo page - This page lets you alter all fields of the DRAGINFO strucure
  69.                  and its DRAGITEM structures. These structures are set up by
  70.                  source window in the Drag/Drop, i.e. the window that the Drag
  71.                  was started in. The only field that isn't set on this page is
  72.                  the RMF settings. Since there are a number of options for the
  73.                  RMF field, it has its own page.
  74.  
  75.  RMF page      - This sets up a field in the DRAGITEM structure (hstrRMF). RMF
  76.                  stands for Rendering Mechanism/Format. Listboxes display the
  77.                  available options for the Mechanism and the Format. These are
  78.                  not mutually exclusive options so they are multiple-select
  79.                  listboxes. Each listbox has an entryfield below it that lets
  80.                  you enter your own additional strings for the mechanism or
  81.                  format. Your strings, if you enter any, will be placed first
  82.                  in the RMF string (before the ones in the listboxes).
  83.  
  84.                  As you enter these strings or select listbox items, the hstrRMF
  85.                  field is updated to reflect your new selections. This is
  86.                  displayed in the 'generated RMF' MLE. This is a read-only MLE
  87.                  so you can't change it. If you are in the middle of one of the
  88.                  entryfields and want the RMF string to be generated (it is
  89.                  normally re-generated when you exit the entryfield), hit the
  90.                  'Generate' pushbutton. This pushbutton is only enabled when
  91.                  changes have been made to either of the entryfields.
  92.  
  93.                  There is also a 'Use Manual RMF' checkbox and a 'Manual RMF'
  94.                  MLE. If you check this checkbox and enter a string in the MLE,
  95.                  that string will be used for hstrRMF instead of the generated
  96.                  one.
  97.  
  98.  Reply page    - Some Drag/Drop messages require a reply (returncode) in order
  99.                  to determine what will happen next. This page lets you select
  100.                  the reply that will be used during execution of the program.
  101.                  You can change the replies from any Printer or Shredder drops
  102.                  as well as being able to decide what will be returned from the
  103.                  DM_DRAGOVER messages.
  104.  
  105.  Misc page     - This page contains miscellaneous options. First, you can choose
  106.                  between letting the containers accept all kinds of drops on
  107.                  them and only allowing drops with a mechanism of DRM_OS2FILE.
  108.                  DRM_OS2FILE is the most common type of Rendering Mechanism.
  109.  
  110.                  Also on this page are choices on how the Debug windows will
  111.                  function. In default mode, the Debug windows will display all
  112.                  structures from all Drag/Drop messages. Also, if you drag more
  113.                  than one icon, all structures related to all items will be
  114.                  displayed. This can be very useful if you need to know
  115.                  everything that's going on. It can also be quite verbose and
  116.                  slow down the drag. So if you don't need to know all the
  117.                  information, there are some choices you can make on this
  118.                  notebook page that affect the Debug window operation. You can
  119.                  choose to only display the message names rather than all the
  120.                  structures involved and you can choose to only display the
  121.                  output from the first Drag Item rather than all of them on a
  122.                  multi-item drag.
  123.  
  124. All Settings Notebook options take affect immediately, i.e. the next time you do
  125. a Drag/Drop operation they will be used. You don't need to close the notebook.
  126. In fact it is convenient to keep it open to experiment with changing the options
  127. and then trying out the new changes and doing it again, etc.
  128.  
  129. NOTE: The options on the settings notebook are stored in drgdrop.ini when the
  130. program is shut down. So your settings are persistent between program
  131. invokations.
  132.  
  133.  
  134. A little about Drag N' Drop
  135. ───────────────────────────
  136.  
  137. This program uses containers to implement Drag/Drop. The reason for this is that
  138. the container control is very conducive to direct manipulation and makes it easy
  139. on a program to implement it. The concepts illustrated in this program are
  140. directly transferrable to Drag/Drop in a regular PM window and any other PM
  141. control.
  142.  
  143. The CN_ messages that are used in this program are WM_CONTROL messages sent by
  144. the container to its owner when it gets the normal PM messages. The reason for
  145. these messages is so that the container can provide its owner with more
  146. information than it would normally get with the regular PM messages. The mapping
  147. goes like this:
  148.  
  149.   PM message (container gets this)       Message sent by container to owner
  150.   ────────────────────────────────       ──────────────────────────────────
  151.  
  152.   WM_BEGINDRAG ......................... CN_INITDRAG
  153.   DM_DRAGOVER .......................... CN_DRAGOVER
  154.   DM_DROP .............................. CN_DROP
  155.  
  156. The ValueSet control also provides this type of interface to its owner.
  157. Obviously if your program just uses a normal client window you would use the
  158. messages on the left-hand side.
  159.  
  160. THE MOST IMPORTANT THING that you need to know about Drag/Drop is that the
  161. information passed between the source and target is in shared memory so it has
  162. to be freed by both sides when they are done with it. Since you don't allocate
  163. the shared memory (PMDRAG.DLL does), it is more difficult to think in terms of
  164. freeing it. The memory that has to be freed is the DRAGINFO structure and all
  165. the string handles in it and its attached DRAGITEM structures, and any
  166. DRAGTRANSFER structures that were used if rendering takes place (this program
  167. does not do any rendering - my DRGRENDR and DRGTHRND samples do if you need
  168. some sample code for that).
  169.  
  170. You use DrgFreeDraginfo() to free the DRAGINFO structure and
  171. DrgFreeDragtransfer() to free the DRAGTRANSFER structures. The DRAGINFO
  172. structure is allocated by the source when it starts the drag (using the
  173. DrgAllocDraginfo() API), and PM takes care of disbursing this memory to
  174. processes that need it when they call DrgAccessDraginfo(). The DRAGTRANSFER
  175. structures are allocated by the target (using the DrgAllocDragtransfer() API)
  176. when drop processing starts. Whenever it communicates with the source, it uses
  177. DrgSend/PostTransferMsg() API's that cause PM to give their process access to
  178. the DRAGTRANSFER structure.
  179.  
  180. Here are the documented times for freeing these structures when no rendering is
  181. involved. Since this program doesn't do any rendering, I won't go into that
  182. aspect. When rendering is involved, things change a little:
  183.  
  184. SOURCE
  185. ──────
  186.  
  187. If DrgDrag() returns NULLHANDLE (which it will if the user hits F1 or Esc during
  188. the drop so that there is no target window), it should make the following calls:
  189.  
  190.     DrgDeleteDraginfoStrHandles();
  191.     DrgFreeDragInfo();
  192.  
  193. DrgDeleteDraginfoStrHandles() deletes all the string handles in all the
  194. DRAGITEMs associated with the DRAGINFO structure. DrgFreeDraginfo() frees the
  195. DRAGINFO structure.
  196.  
  197. If DrgDrag() doesn't return NULLHANDLE, that means a drop occurred and the
  198. return value is the target's window handle. In this case, it is the target's
  199. responsibility to delete the string handles but the source needs to free the
  200. DRAGINFO structure. Here's what it should do:
  201.  
  202.   Under DM_ENDCONVERSATION, when the DM_ENDCONVERSATION for the *last* DRAGITEM
  203.   comes thru, the source needs to call DrgFreeDraginfo(). Keep in mind that
  204.   this means a global counter must be used (or store it in a window word like
  205.   this program does) so it can keep track of when the last one comes thru.
  206.  
  207.  
  208. TARGET
  209. ──────
  210.  
  211. The target needs to make the following calls under the CN_DROP (or DM_DROP if
  212. not a container owner) message:
  213.  
  214.     DrgDeleteDraginfoStrHandles();
  215.     DrgFreeDraginfo();
  216.  
  217. DRGDROP frees these structures when the documentation recommends freeing them
  218. (as illustrated above). Unfortunately the documentation isn't real clear on
  219. this and you have to search to find it. REMEMBER THAT IF YOUR APPLICATION DOES
  220. NOT FREE THESE STRUCTURES WHEN IT IS SUPPOSED TO THAT YOUR APP COULD SCREW UP
  221. OTHER APPS IF IT ALLOWS DIRECT MANIPULATION TO OCCUR WITH OTHER APPS. This is
  222. an important thing to note. If direct manipulation is not done properly it
  223. could lead to a PM resource leak because shared memory might never be freed
  224. that should be freed.
  225.  
  226. NOTE: If rendering takes place after the drop, this scenario changes a bit. So
  227. as not to confuse things, I'm leaving this little bit of trivia out of this
  228. sample. For that info, find my DRGRENDR or DRGTHRND sample programs. DRGRENDR
  229. does rendering on the main thread. DRGTHRND does rendering on secondary threads.
  230.  
  231. DRGDROP.EXE is built from 10 source modules:
  232.  
  233. DRGDROP.C  - Main source module that starts things off.
  234. DEBUGWIN.C - Debug window code that creates/handles Drag/Drop output windows.
  235. NOTEBOOK.C - Settings Notebook code (exclusive of the dialogs).
  236. DLGDRAGI.C - DragInfo dialog within the Settings Notebook.
  237. DLGMISC.C  - Miscellaneous Options dialog within the Settings Notebook.
  238. DLGREPLY.C - Reply dialog within the Settings Notebook.
  239. DLGRMF.C   - RMF dialog within the Settings Notebook.
  240. DRAG.C     - All Drag/Drop code.
  241. MENU.C     - Handles the context menu.
  242. SHOW.C     - Displays Drag/Drop data structures in the debug windows.
  243.  
  244. I know that this little document doesn't go nearly into enough detail about
  245. Drag/Drop. The problem is that there is enough information on direct
  246. manipulation to fill a book. For more information, look at the information in
  247. the Programming Guide that comes with the IBM toolkit technical library. There
  248. is a sample program called DRAGDROP that comes with the toolkit that is a very
  249. good sample.
  250.  
  251. Hope this sample program helps someone.
  252.  
  253. ===============================================================================
  254. GLOBAL HISTORY
  255.  
  256. 07-27-93 - Completed coding.
  257. 12-05-93 - Fix bug where the ntsType.szName was being used for hstrType instead
  258.            of ntsType.szString. Also made the CB_TYPE combobox a DROPDOWN vs. a
  259.            DROPDOWNLIST so you can enter your own type.
  260.  
  261. ===============================================================================
  262.  
  263. Rick Fishman
  264. Code Blazers, Inc.
  265. 4113 Apricot
  266. Irvine, CA 92720
  267.  
  268. CIS ID: 72251,750
  269.