home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / celltk7b.zip / cell07b.zip / doc / article.eng next >
Text File  |  2000-10-25  |  9KB  |  196 lines

  1. NOTE: This article was originally published in EDM/2, issue 0604.
  2.  
  3.  
  4.  
  5. Split Views And Toolbars
  6.  
  7. Written by Sergey Yevtushenko
  8.  
  9. Foreword
  10.  
  11.   This article will try to explain techniques which can be used to build
  12. PM applications with more-or-less modern user interfaces.
  13.  
  14.   The term "modern user interface" means just some "bells and whistles"
  15. which will make your program at least as usable and user friendly as
  16. the best programs on the market.
  17.  
  18.   These "bells and whistles" can be divided into two relatively
  19. independent parts. First is split views. This is a representation of
  20. information in windows split (horizontally or vertically or both) into two
  21. or more parts. You can find this style in many commercial and shareware
  22. programs. For example look at PMMail or the mail and news clients in
  23. Netscape Navigator. The main thing in split views is the possibility for
  24. users to change the sizes of parts of the split views as they like. So,
  25. for example, a window split into two parts will really consist of three
  26. parts: two panels and the splitbar itself. The second part is toolbars.
  27. This theme is common in EDM/2 issues, but the main goal of previous
  28. articles in EDM/2 was to build toolbars with minimal effort for the
  29. developer, but not to build toolbars which really can improve usability
  30. and/or the look of application.
  31.  
  32.   These pieces were implemented in the usual way: I just subclass window
  33. procedures for many standard windows. To make the developer's life easy,
  34. the details of this were hidden behind a simple high level interface. I
  35. considered using the C language for implementation just because something
  36. written in C can be easily be used in C++ programs, but the reverse is not
  37. true. The second reason was even simpler: size and speed. With this
  38. package you can write very small applications, where the ratio of
  39. functionality code vs. interface code is near 1.
  40.  
  41. Using Package
  42.  
  43.   As I mentioned, the use of the package is very simple: you create some
  44. structures filled with constants, call one function and get a window
  45. created for you. Take a look at example code (simple.c):
  46.  
  47.  
  48.   CellDef cdLeftPane =
  49.   {
  50.       CELL_WINDOW,
  51.       WC_LISTBOX,
  52.       "List",
  53.       LS_NOADJUSTPOS | WS_VISIBLE,
  54.       ID_LPANE
  55.   };
  56.  
  57.  
  58. This declaration defines one panel for a split view which will consist of
  59. just a simple listbox. This listbox will have window ID ID_LPANE. Another
  60. declaration:
  61.  
  62.  
  63.   CellDef cdRightPane =
  64.   {
  65.       CELL_WINDOW,
  66.       WC_MLE,
  67.       "SampleText",
  68.       MLS_BORDER | WS_VISIBLE,
  69.       ID_RPANE
  70.   };
  71.  
  72.  
  73. This is also a simple MLE with window ID set to ID_RPANE, with border
  74. (MLS_BORDER is set) and with text "Sample Text" in it. The third
  75. declaration is more complicated:
  76.  
  77.  
  78.   CellDef mainClient =
  79.   {
  80.       CELL_VSPLIT | CELL_SPLITBAR | CELL_SPLIT30x70,
  81.       0,
  82.       "Simple",
  83.       FCF_TITLEBAR | FCF_SYSMENU  | FCF_MENU |
  84.       FCF_MINMAX   | FCF_TASKLIST | FCF_SIZEBORDER |
  85.       0,
  86.       MAIN_FRAME,
  87.       &cdLeftPane,
  88.       &cdRightPane,
  89.       0,
  90.       MainClientProc
  91.   };
  92.  
  93.  
  94. This declaration will define the main application window. You can note the
  95. difference in flags. Instead of CELL_WINDOW, we create a vertically split
  96. window (CELL_VSPLIT), which will have a splitbar (CELL_SPLITBAR),
  97. initially divided into 30/70% of the window width for left and right parts
  98. of the window, respectively. Window classes (second argument) have no
  99. meaning for this case, they are always WC_FRAME. Also, instead of window
  100. creation flags (fourth argument), there are frame creation flags. More
  101. detailed explanations of meanings of these flags can be found in the
  102. toolkit documentation. This window will have ID MAIN_FRAME, two panels
  103. (description for which is in cdLeftPane and cdRightPane respectively), and
  104. have client window procedure "MainClientProc". In doing this procedure, we
  105. subclass the procedure for the internal window class CELL_CLIENT. So, you
  106. need to call the subclassed procedure at the end of message processing.
  107. For this purpose you receive a pointer to structure WindowCellCtlData
  108. (defined in cell.h) by issuing a call to WinQueryWindowULong. For now this
  109. structure contains only one field, but you can add any necessary fields.
  110. Because this structure will be allocated for you in the package code and
  111. they need to know the size of it, you should recompile cell.c each time
  112. you make changes in WindowCellCtlData. The rest of the fields will be
  113. filled with 0 with the same code.
  114.  
  115.   Now we ready to create the main window for the application. This is
  116. done by calling CreateCell. This function takes three parameters:
  117. definition of the window (explained above), a window handle for the parent
  118. window and a window handle for the owner window. The last parameter for
  119. the main window should be 0. In all other cases, this parameter should be
  120. set to windows which will receive notification messages from other
  121. windows. Usually this is the main window of the application. You should
  122. note that the main application window definition does not have the flag
  123. WS_VISIBLE set. This is important, because after creating windows, we may
  124. need to do some other work before the application window will appear on
  125. the screen.
  126.  
  127.   What else do we need to do? We need fill controls with some data, add
  128. the toolbar and set the main window position on the screen.
  129.  
  130.   Creating the toolbar is similar to creating windows: you fill
  131. structures, call a function and get a toolbar in your application. The
  132. structure contains three elements: flags, toolbar ID and a pointer to an
  133. array of button ID's. Note that the last element in this array is 0. This
  134. signals the end of the toolbar button definitions. For all IDs listed in
  135. the button array, you should define bitmaps in the resource file and
  136. optionally an element in the stringtable. The element in the string table
  137. is needed only if in the toolbar flags you set the flag TB_BUBBLE. If you
  138. want to divide buttons into groups with gaps between them, you can use the
  139. predefined flag ID TB_SEPARATOR. For this ID you do not need to define
  140. bitmaps or stringtable elements (indeed, separators are not even buttons).
  141. The function CreateToolbar receives two parameters: a pointer to the
  142. toolbar definition structure and the handle of the parent window. Really,
  143. this is just a window with which the toolbar will communicate when
  144. attaching/detaching, and which will own (and receive messages from) the
  145. buttons contained in the toolbar. A few words about toolbar flags: they
  146. define the look of the toolbar only at the starting of the application and
  147. can be changed by user. The flags TB_ATTACHED_* define the side of the
  148. parent window to which the toolbar will be attached initially:
  149.  
  150.  
  151.   TB_ATTACHED_LT - left
  152.   TB_ATTACHED_TP - top
  153.   TB_ATTACHED_RT - right
  154.   TB_ATTACHED_BT - bottom
  155.  
  156.  
  157. If none of these are specified, the toolbar will float detached from the
  158. parent window. Setting the flag TB_VERTICAL together with one of the TB
  159. flags will be ignored. The user can at any time change the toolbar state.
  160. Toolbar have a "hand" for dragging, so the user can drag the attached
  161. toolbar and detach it from the window. By double-clicking with the left
  162. mouse button on this "hand" button, the user can change the orientation of
  163. the detached toolbar (horizontal/vertical). By double-clicking with the
  164. right mouse button on the "hand" you will disable/enable bubble help, if
  165. this was allowed by the developer (by setting the TB_BUBBLE flag). To fill
  166. controls with data you need to know the window handle of the control. This
  167. not a problem if you created this control, but this is not the case. For
  168. this purpose you can use the function CellWindowFromID.
  169.  
  170.   As you can see, this package is powerful enough to build applications
  171. with a modern user-friendly interface. Although this has not been
  172. explained before, your application is not restricted to having windows
  173. split into only two parts. Each panel can also be a split view. This can
  174. be achieved by specifying the proper flags in the subwindow definition
  175. structure. Another thing not explained is the possibility of having panels
  176. with fixed width. This can be done by toggling the flag CELL_FIXED.
  177. Furthermore, you can have panels with fixed absolute size and with fixed
  178. relative size. If you not specify the flag CELL_SPLITBAR, you will get
  179. windows with panels whose sizes will change with the main window's size,
  180. but the relationship between them remains intact. I should note that you
  181. can't have both panels with fixed absolute size, but this was not the goal :).
  182.  
  183. Final Words
  184.  
  185.   This package was developed for my own purpose and you should always keep
  186. in mind that package may not exactly respond to your needs. But you have
  187. the sources, so do what you need to yourself :) You can use this code as
  188. you wish, as long as you don't forget to send me e-mail about this fact.
  189. Also, I would be pleased to know about any bugs which you find in my code.
  190.  
  191. Regards,
  192.         Sergey I. Yevtushenko.
  193.  
  194. Autor can be contacted via email at : evsi@naverex.kiev.ua
  195.  
  196.