home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cnradv.zip / cnradv.doc < prev    next >
Text File  |  1993-07-23  |  17KB  |  332 lines

  1. CNRADV.EXE is a sample program for container controls that builds on the
  2. CNRMENU.EXE sample program. I will go into the additions at the end of this
  3. little doc. Please read those notes as there are some things that you
  4. probably need to know if you will implement these features in your own
  5. containers.
  6.  
  7. CNRMENU.EXE and its source code is downloadable from Compuserve (OS2DF1 forum,
  8. PM section) as CNRMNU.ZIP. It is a sample program that demonstrates setting up
  9. a container control, context menus, sorting, source emphasis and direct
  10. editing. CNRADV takes CNRMENU a little further by demonstrating drag/drop,
  11. ownerdraw, and Mini Icons.
  12.  
  13. CNRADV creates a standard window with a container as a child of the client
  14. window. Once created, the files found in a directory are inserted into the
  15. container and any subdirectories are traversed and inserted into the container
  16. in a tree format. This directory can be specified on the command line (i.e.
  17. 'CNRADV path'). If not specified it defaults to the current directory.
  18.  
  19. NOTE: Unless you need a client window, you should make the container a client
  20. of the frame window (give it a parent of hwndFrame and an id of FID_CLIENT).
  21. This will work around a bug in the container where it doesn't send its owner a
  22. CN_CONTEXTMENU message on a Shift-F10 keystroke unless it is a client window to
  23. the frame. This program has too much client-window code at this point to take
  24. out the client window so it works around this bug by catching WM_CHAR messages
  25. and processing the Shift-F10 manually.
  26.  
  27. A secondary thread is employed to fill the container since filling it could
  28. take a while depending on what directory was specified and how many
  29. subdirectories it has, and how many subdirectories that has (you get the
  30. picture <g>). This allows the user to interact with the container while it is
  31. being filled.
  32.  
  33. The Directory window uses DosFindFirst/DosFindNext to get a directory listing
  34. in order to populate the container. By using the context menu while over a
  35. subdirectory's icon or doubleclicking on a subdirectory's icon you can create
  36. another directory window that represents that subdirectory. When that window
  37. is created, its container uses the records from the first one so it doesn't
  38. need to do the FindFirst/FindNext. This is a capability of the container
  39. control (shared records). It substantially reduces memory requirements in a
  40. program that has multiple views of the same container (like the WPS does with
  41. folders).
  42.  
  43. The context menu changes depending on whether the mouse pointer is over a
  44. directory when the right mouse button is pressed.
  45.  
  46. My coding style uses extensive error-checking. This, combined with the fact
  47. that this program gets rather involved, makes this a relatively difficult
  48. sample program to follow. I've tried to include as many comments as possible
  49. but admittedly you still may have problems following it. Please get ahold of
  50. me on Compuserve if you have questions.
  51.  
  52. CNRADV.EXE is built from 9 source modules:
  53.  
  54. CNRADV.C   - base code and client window procedure
  55. COMMON.C   - functions common to all modules
  56. CREATE.C   - code related to creating the directory windows
  57. CTXTMENU.C - code related to context menus
  58. EDIT.C     - code related to direct editing
  59. POPULATE.C - code related to populating the containers (separate thread)
  60. SORT.C     - code related to container sorting
  61. DRAG.C     - code related to Drag/Drop
  62. DRAW.C     - code related to Ownerdraw
  63.  
  64. The following displays the initialization of the container as it relates to
  65. the 4 source modules that make up CNRADV.EXE initialization. The extern
  66. functions in the source modules are shown.
  67.  
  68.  
  69.   PRIMARY THREAD                           SECONDARY THREAD
  70.  
  71. ┌────────────────────┐                    ┌─────────────────────────────┐
  72. │           ┌────────┤                    │                             │
  73. │ CNRMENU.C │        │        (4)         │         POPULATE.C          │
  74. │   │  │    │       <─UM_CONTAINER_FILLED───────────                    │
  75. ││  │  │    │WinProc │                    │                             │
  76. ││  │  │    │        │                    │  ┌─> PopulateContainer()    │
  77. ││  │  │    │        │                    │  │                          │
  78. └│──│──│────┴────────┘                    └──│──────────│───────────────┘
  79.  │  │  │                                     │          │
  80.  │  │ (1)                                    │          │
  81.  │  │  │                                     │          │
  82.  │ (2) │                                     │          │
  83.  │  │  │                                     │          │
  84. ┌│──│──│────────────────────────┐            │          │
  85. ││  │  │                        │       _beginthread()  │
  86. ││  │  │    CREATE.C            │            │          │
  87. ││  │  │                        │            │          │
  88. ││  │  │                        │            │          │
  89. ││  │  └─> CreateDirectoryWin() │            │          │
  90. ││  │                           │            │          │
  91. ││  └─> CreateContainer() ────────────(3)────┘          │
  92. ││                              │                       │
  93. └│──────────────────────│───────┘                       │
  94.  │                      │                               │
  95.  │                   ┌──│───────────────────────────────│───┐
  96.  │                   │  v                               v   │
  97.  │                   │                                      │
  98.  │                   │              COMMON.C                │
  99.  └──────────────────────>                                   │
  100.                      │                                      │
  101.                      │     SetWindowTitle()                 │
  102.                      │     Msg()                            │
  103.                      │     FullyQualify()                   │
  104.                      │                                      │
  105.                      └──────────────────────────────────────┘
  106.  
  107.  
  108. (1) - Create the frame/client window.
  109. (2) - Create the container window as a child of the client.
  110. (3) - Start a thread that will fill the container with records.
  111. (4) - When the thread has filled the container, it posts a UM_CONTAINER_FILLED
  112.       message to the client window.
  113.  
  114.  
  115. New features not in CNRMENU.EXE
  116. ===============================
  117.  
  118. SelectionType submenu
  119. ---------------------
  120.  
  121. The context menu now has a SelectionType submenu that allows you to choose
  122. between CCS_SINGLESEL, CCS_EXTENDSEL, and CCS_MULTIPLESEL container styles. The
  123. containers start off in CCS_EXTENDSEL (Extended selection). Using this submenu
  124. will allow you to see how these three selection techniques differ.
  125.  
  126.  
  127. New Folder Icon
  128. ---------------
  129.  
  130. WinLoadFileIcon does not differentiate between normal files and directories.
  131. This didn't bother me during the first couple of iterations of this sample
  132. program but irritated me as time went on. So I created my own folder icon and
  133. load it at program init time. Now directories use this folder icon rather than
  134. the 'normal file' icon used by directories in CNRBASE and CNRMENU.
  135.  
  136.  
  137. MiniIcons
  138. ---------
  139.  
  140. The View submenu now offers MiniIcons as the last menu item. The CV_MINI flag
  141. is still not working as of the Service Pack. If it were, you could use this
  142. flag to implement MiniIcons easily. If your icons had mini icons in the .ICO
  143. file, using CV_MINI would cause the container to use that format. Otherwise the
  144. container would compress the icon to a 'mini' size. This however is not working.
  145.  
  146. Peter Haggar, one of the container developers, posted a workaround on CIS that
  147. CNRADV uses if you choose the MiniIcons menu item. Unfortunately this workaround
  148. just compresses the icon to a 'mini' size (the height of an action bar). So the
  149. nice mini icons that are displayed by the WPS folders do not show up. Instead,
  150. all icons are compressed. Some look good, some don't. The 'normal file' icon
  151. that the directory windows display the most don't look good compressed against
  152. a white background. They don't look bad against a red one though.
  153.  
  154. The MiniIcons menu item toggles between MiniIcons and not. A checkmark will
  155. display if it is selected (of course it should be obvious by looking at the
  156. icons <g>).
  157.  
  158.  
  159. Ownerdraw
  160. ---------
  161.  
  162. CNRADV implements two types of Ownerdraw. The first one uses the
  163. CA_OWNERPAINTBACKGROUND container attribute to paint the background of the
  164. container. This attribute causes the container to send itself a
  165. CM_PAINTBACKGROUND message at paint time. CNRADV subclasses the container to get
  166. this message (this is the recommended technique in the docs) and processes it by
  167. painting the container background. The second type of ownerdraw sets up a
  168. Details-view column as CFA_OWNER and draws that column.
  169.  
  170.    *** CA_OWNERPAINTBACKGROUND ***
  171.  
  172. There is a new submenu in the context menu - Background. This allows you to
  173. choose between a few colors and 'Bitmap' and demonstrates using the
  174. CA_OWNERPAINTBACKGROUND container attribute. If you choose a color, CNRADV does
  175. nothing except a WinFillRect for that color under the CM_PAINTBACKGROUND message
  176. in the subclassed container window procedure. This could have been implemented
  177. easier by just using WinSetPresParam on the container but since CNRADV was
  178. trying to demonstrate the CA_OWNERPAINTBACKGROUND attribute, I figured I'd let
  179. the user choose a few colors.
  180.  
  181. The main reason you'd use the CA_OWNERPAINTBACKGROUND is to do something like
  182. paint a bitmap on the background. 'Bitmap' is the last option on the
  183. 'Background' submenu. The bitmap you'll see is one that I did using the icon
  184. editor. You will appreciate that I am no artist <g>.
  185.  
  186. Drawing the bitmap shows the complexity of using CA_OWNERPAINTBACKGROUND. I was
  187. using this attribute in a few of my containers just to change the background
  188. color and it was very simple. But using the bitmap showed what was really
  189. happening behind the scenes and it creates a nightmare for using a bitmap
  190. backdrop on the container.
  191.  
  192. It turns out that the container sends itself a CM_PAINTBACKGROUND message for
  193. each of its windows - there are many windows in a view such as Details view.
  194. It also sends itself this message when the user selects a record or unselects
  195. the record so that the background of that record can be repainted. Herein lies
  196. the difficulty.
  197.  
  198. Since you get a lot of these messages, you don't want to create and delete the
  199. bitmap in each message. So what CNRADV does is create the bitmap at program
  200. init time and use that bitmap handle during CM_PAINTBACKGROUND processing, It
  201. stretches the bitmap to the rectangle being painted. Well, you can imagine the
  202. way it looks when each window of Details view has the same bitmap stretched to
  203. a different size. And each container record has a different version of the
  204. bitmap under it when the user selects or unselects it. But you don't have to
  205. imagine it! Just run CNRADV and choose Bitmap from the Background submenu of
  206. the context menu and you'll see what I mean.
  207.  
  208. It is also *very* slow drawing the bitmap on a 16mhz 386, especially when all
  209. you do is select a new record and re-stretches the bitmap each time.
  210.  
  211. For a 'productional' program you'd obviously want to fix this. I will probably
  212. create a different presentation space for each window and stretch the bitmap
  213. within that PS to that window's size every time the directory window gets
  214. resized. Then come time to CM_PAINTBACKGROUND, I'll just BitBlt the appropriate
  215. section of the appropriate bitmap to the container window.
  216.  
  217. In any case, CA_OWNERPAINTBACKGROUND is now OR'ed with the other flWindowAttr
  218. attributes in CtxtmenuSetView. The code for subclassing and everything else is
  219. in draw.c.
  220.  
  221.    *** CFA_OWNER ***
  222.  
  223. I added a new Details-view column to display file attributes. This is an
  224. Ownerdraw column (CFA_OWNER). This will demonstrate what you have to do to
  225. draw a column, both with and without selection emphasis.
  226.  
  227.  
  228. Drag/Drop
  229. ---------
  230.  
  231. FOR A GREAT EXAMPLE OF A FULL IMPLEMENTATION OF DRAG/DROP, SEE THE SAMPLE CODE
  232. PROVIDED BY IBM IN TOOLKT20\C\SAMPLES\DRAGDROP.
  233.  
  234. CNRADV adds Drag/Drop capability to the directory windows that it creates. You
  235. may have noticed that without implementing drag/drop the records in a container
  236. cannot even be moved. Thus programming a container in Icon view will probably
  237. create a need to implement drag/drop.
  238.  
  239. There are many different ways to implement drag/drop depending on the complexity
  240. of the transfer of information between the source and target windows. CNRADV
  241. uses a rather rudimentary protocol. It uses the OS2FILE rendering mechanism and
  242. doesn't provide any drop-time rendering. Essentially it can use the information
  243. available at drop time to do what it has to do so the directory windows don't
  244. have to communicate with their partner to get any more information after it
  245. gets a 'drop' message. Because it doesn't have to do this, a large part of
  246. drag/drop is not covered by this program. But enough is covered so that you can
  247. see it in action and see what is going on. Implementing rendering should not
  248. use that many more facilities of Direct Manipulation than are used here.
  249.  
  250. At this point, if you don't know what rendering is, don't worry. All it really
  251. means is that a protocol is established between the source and target windows
  252. and they must abide by those rules to figure out what needs to happen when the
  253. user drops icons on the target window.
  254.  
  255. CNRADV processes these WM_CONTROL messages from the container to implement
  256. drag/drop:
  257.  
  258.   CN_DRAGINIT  - drag is starting
  259.   CN_DRAGOVER  - during drag, mouse is over your container
  260.   CN_DRAGAFTER - same as CN_DRAGOVER except you're in Details view and are
  261.                  using ordered or mixed target emphasis.
  262.   CN_DROP      - user is dropping icons on your container.
  263.  
  264. Also, the DM_DISCARDOBJECT and DM_PRINTOBJECT messages are processed so as to
  265. demonstrate dropping container records on a printer or shredder.
  266.  
  267. NOTE that I have experienced some problems after the Service Pack with dropping
  268. onto my Epson dot matrix printer. Essentially the document makes it to the
  269. printer object on the desktop but doesn't print. The icon that represents
  270. the job has a diagonal line between the printer and document meaning the job
  271. is just sitting there. This happens sporadically. I believe it to be a bug in
  272. the Service Pack because it prints fine under GA. When this happens I just
  273. delete the job. I don't know how many of you will also be affected by this...
  274.  
  275. To get the drag/drop working, I added CA_MIXEDTARGETEMPH to the attributes that
  276. are set in CtxtmenuSetView and added the catching of the CN_ messages to
  277. cnradv.c. I also added drag.c which handles all of the drag/drop stuff.
  278.  
  279. You can drag and drop within a container. You can also drag from one of the
  280. directory windows to another. Also, you can drag to the WPS folders but only
  281. a copy operation is permitted so that you don't accidentally delete your files
  282. from the directory that the directory window represents. You can drag from a
  283. WPS folder to a directory window but only if it is a folder that originated
  284. from the Drives folder. The reason for this is that all WPS folders except
  285. those originating from the Drives folder don't use the 'OS2FILE' rendering
  286. mechanism so we have no way of getting the file name from them.
  287.  
  288. You can drag more than one record if you have Extended or Multiple selection
  289. on (using the SelectionType submenu).
  290.  
  291. FOR A GREAT EXAMPLE OF A FULL IMPLEMENTATION OF DRAG/DROP, SEE THE SAMPLE CODE
  292. PROVIDED BY IBM IN TOOLKT20\C\SAMPLES\DRAGDROP.
  293.  
  294. Hope this sample program helps someone.
  295.  
  296. ===============================================================================
  297. GLOBAL HISTORY (KEPT SINCE 1/31/93 - Before that, kept on a per-module basis)
  298.  
  299. 1-31-93 - Added the right way to do mini icons based on information from IBM'er
  300.           Dan Kehn.
  301.              - changed cnradv.h to include definition of CCS_MINIICONS
  302.              - changed ctxtmenu.c to use this new definition.
  303.  
  304. 3-27-93 - Changed PSZ szArg[] to char *argv[] in cnradv.c because of 3/93
  305.           compiler bug.
  306.  
  307. 6-06-93 - Added AutoPosition to top-level menu, checked SelType menu item.
  308.           Added TargetEmphasis submenu (most changes in ctxtmenu.c).
  309.  
  310. 6-30-93 - Added FilterDirectories menu item and processing
  311.           (most changes to ctxtmenu.c).
  312.  
  313. 7-06-93 - Added DM_ENDCONVERSATION processing to drag.c.
  314.  
  315. 7-19-93 - Took out all references to folder.ico. It appears that OS/2 2.1 fixed
  316.           the bug in WinLoadFileIcon that caused it not to use the folder icon
  317.           for directories...
  318.  
  319. 7-23-93 - Catch WM_CHAR to get the Shift-F10 keystroke so we can send the
  320.           client window a CN_CONTEXTMENU message. This compensates for a bug in
  321.           the container that doesn't send this message if the container is not
  322.           a child of the frame window.  All changes in draw.c.
  323.  
  324. ===============================================================================
  325.  
  326. Rick Fishman
  327. Code Blazers, Inc.
  328. 4113 Apricot
  329. Irvine, CA 92720
  330.  
  331. CIS ID: 72251,750
  332.