home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PMHINTS1.ZIP / PMHINTS.INF (.txt) < prev    next >
OS/2 Help File  |  1991-05-03  |  144KB  |  6,944 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Introduction ΓòÉΓòÉΓòÉ
  3.  
  4. This volume, the first of five on OS/2, is not intended to be a guide on how to 
  5. write Presentation Manager programs, but is a compilation of the solutions to 
  6. most of the common problems encountered by many in IBM, including myself, 
  7. whilst writing their own code. 
  8.  
  9. Where applicable I have provided code, and a sample program, to show how to 
  10. overcome the problems. You can use the clipboard to copy and paste the code 
  11. directly to your program or to a separate file. In addition you will find the 
  12. complete source and executables for all the sample programs on the diskette on 
  13. which this volume was supplied. Please note however, that these programs do not 
  14. have any great function and only serve to confirm that the tips covered in this 
  15. volume do work. For this reason I have ignored such things as error checking 
  16. and cleaning up on exit except where relevant. Also, please note that these 
  17. tips apply to Version 1.2 upwards. In fact all the code I wrote verifying these 
  18. tips was written using the 1.2 Toolkit on OS/2 Version 1.3.  However, you may 
  19. find that some hints, e.g.  WinSetPresParam, do not work completely 
  20. satisfactorily on Version 1.2. 
  21.  
  22. Note:  This volume is not yet complete. Further versions will be released at 
  23. regular intervals. 
  24.  
  25. Send any comments to - 
  26.  
  27.  
  28.    Bryan Goodyer
  29.    Personal Systems, Europe
  30.    IBM UK
  31.    Mountbatten House
  32.    Basingstoke
  33.    Hampshire
  34.    UK
  35.  
  36.    VNET (GOODYER @ WINVMB)
  37.  
  38.  
  39. ΓòÉΓòÉΓòÉ 2. Dialog Boxes and their Controls ΓòÉΓòÉΓòÉ
  40.  
  41. This section covers the following topics - 
  42.  
  43.  Action Bar 
  44.  Disabling Controls 
  45.  Entry Fields 
  46.  Errors 
  47.  Focus 
  48.  Icons 
  49.  Listboxes 
  50.  Main Window 
  51.  Menus 
  52.  Mnemonics 
  53.  Multi-line Entry Fields 
  54.  Position 
  55.  Push Buttons 
  56.  Radio Buttons 
  57.  Size 
  58.  Status 
  59.  Styles 
  60.  Tab Stops 
  61.  Text 
  62.  Window ID 
  63.  Sample Programs 
  64.  
  65.  
  66. ΓòÉΓòÉΓòÉ 2.1. Action Bar ΓòÉΓòÉΓòÉ
  67.  
  68.  
  69. ΓòÉΓòÉΓòÉ 2.1.1. Action Bar in a Dialog Box ΓòÉΓòÉΓòÉ
  70.  
  71. To add an action bar to your dialog box, first define the menu layout and add 
  72. it to your resource file.  You will then need to add a call to WinLoadMenu  and 
  73. send a WM_UPDATEFRAME  message to the frame to tell it to update.  If you omit 
  74. to update the frame then the menu will not appear until you minimize and 
  75. restore the box.  You should put this in your WM_INITDLG  case statement. 
  76.  
  77.  
  78. ΓòÉΓòÉΓòÉ 2.2. Disabling Controls ΓòÉΓòÉΓòÉ
  79.  
  80.  
  81. ΓòÉΓòÉΓòÉ 2.2.1. General ΓòÉΓòÉΓòÉ
  82.  
  83. To disable a control use WinEnableWindow with the second parameter set to 
  84. FALSE. To enable the control call it again with TRUE. 
  85.  
  86. This is a useful technique to use when you don't want your user to activate a 
  87. control until he has completed any prerequisites. For example, if you have a 
  88. delete pushbutton in your dialog you don't want the user pressing it until he 
  89. has selected an item to delete. Using this technique can save you a lot of 
  90. validation code. 
  91.  
  92.  
  93. ΓòÉΓòÉΓòÉ 2.2.2. Entry Fields ΓòÉΓòÉΓòÉ
  94.  
  95. If you need to disable an entry field which is the first control in the dialog 
  96. box then use WinEnableWindow as usual in your WM_INITDLG case statement but 
  97. alter the focus to another control. Failure to do this will allow the user to 
  98. enter data into the field until he tabs out to another control. It will only be 
  99. now that the entry field will become disabled. 
  100.  
  101. It is also important when changing focus in a WM_INITDLG to return TRUE 
  102. otherwise focus will not be changed. 
  103.  
  104.  
  105. ΓòÉΓòÉΓòÉ 2.3. Entry Fields ΓòÉΓòÉΓòÉ
  106.  
  107.  
  108. ΓòÉΓòÉΓòÉ 2.3.1. Changing the Default Length ΓòÉΓòÉΓòÉ
  109.  
  110. To change the default length of 32 for a text entry field send it an 
  111. EM_SETTEXTLIMIT message. 
  112.  
  113. Alternatively, you can modify your DLG file by adding control data to the 
  114. control(s) on which you want the length set. The example shows how to set the 
  115. entry field length to 5 bytes. 
  116.  
  117. The format of CTLDATA is 
  118.  
  119.  
  120.     CTLDATA size, length, minsel, maxsel
  121.  
  122.     where -
  123.       size   = 8 for 8 bytes of control data
  124.       length = number of characters allowed to be entered
  125.       minsel = 0 (minsel defines the first char to be initially selected)
  126.       maxsel = 0 (maxsel defines the last char to be initially selected)
  127.  
  128. Note:  If you use this latter approach beware if you use the Dialog Box Editor 
  129. as you will lose any changes you have made to the DLG file. 
  130.  
  131.  
  132. ΓòÉΓòÉΓòÉ 2.3.2. Cursor Not Appearing at Edge of Field ΓòÉΓòÉΓòÉ
  133.  
  134. The usual cause of this problem is a static field defined immediately to the 
  135. left of an entry field so that it overlaps it. This has the effect of the 
  136. system pointer not changing into the I-beam cursor when it moves into the 
  137. field, but as it is moved to the right it changes, if and when it reaches the 
  138. end of the static field. 
  139.  
  140.  
  141. ΓòÉΓòÉΓòÉ 2.3.3. Cursor Position ΓòÉΓòÉΓòÉ
  142.  
  143. To position the cursor in an entry field send the control an EM_SETSEL message. 
  144.  
  145. The third parameter MPFROM2SHORT(m, n) specifies where the cursor is to be 
  146. positioned and what part of the field needs to be selected, if any. 
  147.  
  148.  
  149. m specifies the offset of the first character in the selection
  150. n specifies the offset of the first character after the selection
  151.  
  152. If m = n there is no selection but the cursor is positioned at offset m.
  153. If m = 0, n >= text limit the entire text is selected.
  154.  
  155.  
  156. ΓòÉΓòÉΓòÉ 2.3.4. Invisible ΓòÉΓòÉΓòÉ
  157.  
  158. To make an entry field invisible so that it can be used for entering passwords 
  159. use the style ES_UNREADABLE. You must add this style manually to your entry 
  160. field in your DLG file so be careful if you use the Dialog Box Editor after 
  161. making this change as it does not support this style. 
  162.  
  163. You cannot change this style for an entry field in your program, i.e.  the code 
  164.  
  165. hPwd = WinWindowFromID(hwndDlg, ID_PASSWORD);
  166.  
  167. WinSetWindowULong(hPwd, QWL_STYLE,
  168.                  (WinQueryWindowULong(hPwd, QWL_STYLE) | ES_UNREADABLE));
  169.  
  170. WILL NOT  work.  The reason is that if changing this style flag meant that the 
  171. window changed from being unreadable to readable, or vice versa, anyone could 
  172. write a small program to flip the state of password entry fields and read them 
  173. making this a very insecure method of password protection. 
  174.  
  175.  
  176. ΓòÉΓòÉΓòÉ 2.3.5. Reading Data ΓòÉΓòÉΓòÉ
  177.  
  178. To read data from an entry field use WinQueryWindowText or WinQueryDlgItemText 
  179. for character data, or WinQueryDlgItemShort to convert the text to an integer 
  180. value. 
  181.  
  182.  
  183. ΓòÉΓòÉΓòÉ 2.3.6. Numeric Data Only ΓòÉΓòÉΓòÉ
  184.  
  185. To limit an entry field to numeric data you must subclass the entry field 
  186. window and throw away those keystrokes not required.  Don't forget that you 
  187. will probably need to keep some non-numeric keystrokes, for example - 
  188.  
  189.  o Backspace 
  190.  o Tab 
  191.  o Minus sign 
  192.  o Enter 
  193.  
  194.  
  195. ΓòÉΓòÉΓòÉ 2.3.7. Read-only ΓòÉΓòÉΓòÉ
  196.  
  197. If you require a read-only entry field then send the control an EM_SETREADONLY 
  198. message or add the style ES_READONLY to the control in your DLG file. 
  199.  
  200. Alternatively, you can make the control static and use WinSetWindowText or 
  201. WinSetDlgItemText to change the text. 
  202.  
  203.  
  204. ΓòÉΓòÉΓòÉ 2.3.8. Writing Data ΓòÉΓòÉΓòÉ
  205.  
  206. To write character data to an entry field use WinSetWindowText or 
  207. WinSetDlgItemText. 
  208.  
  209. Use WinSetDlgItemShort to convert an integer value directly to text. 
  210.  
  211. To clear data from an entry field just write null to it. 
  212.  
  213.  
  214. ΓòÉΓòÉΓòÉ 2.4. Errors ΓòÉΓòÉΓòÉ
  215.  
  216.  
  217. ΓòÉΓòÉΓòÉ 2.4.1. Dialog Box Causes Program to Abend ΓòÉΓòÉΓòÉ
  218.  
  219. If a dialog box causes your program to abend try increasing the stack size 
  220. defined in your DEF file. 
  221.  
  222.  
  223. ΓòÉΓòÉΓòÉ 2.5. Focus ΓòÉΓòÉΓòÉ
  224.  
  225.  
  226. ΓòÉΓòÉΓòÉ 2.5.1. Setting Focus ΓòÉΓòÉΓòÉ
  227.  
  228. The default dialog procedure sets the focus to the first control defined in the 
  229. dialog box's DLG file. To override this use WinSetFocus in your WM_INITDLG case 
  230. statement. However, you must return TRUE from WM_INITDLG  to tell it that the 
  231. focus has changed, otherwise the WinSetFocus  call will be overridden and the 
  232. focus will revert to the first control. 
  233.  
  234.  
  235. ΓòÉΓòÉΓòÉ 2.6. Icons ΓòÉΓòÉΓòÉ
  236.  
  237.  
  238. ΓòÉΓòÉΓòÉ 2.6.1. System Icon in a Dialog Box ΓòÉΓòÉΓòÉ
  239.  
  240. To include a system icon in a dialog box just add a CONTROL statement directly 
  241. into your DLG file. But, be careful if you use the Dialog Box Editor afterwards 
  242. as it will not handle it correctly and you will lose it. 
  243.  
  244. For all the "#n" and SPTR_xxx values see the PMWIN.H include file in the 
  245. \TOOLKTnn\C\INCLUDE directory. 
  246.  
  247.  
  248. ΓòÉΓòÉΓòÉ 2.6.2. User Icon in a Dialog Box ΓòÉΓòÉΓòÉ
  249.  
  250. To include your own icon in a dialog box use the Dialog Box Editor to define 
  251. and position the icon on the window and then add an ICON statement to your 
  252. resource file specifying which icon filename you want associated with the icon 
  253. ID, for example - 
  254.  
  255.  
  256. ICON  ID_DLGICON  hints.ico
  257.  
  258. The associated CONTROL statement generated by the Dialog Box Editor for this is 
  259.  
  260.  
  261. CONTROL ID_DLGICON, ID_DLGICON, 5, 35, 20, 16, WC_STATIC,
  262.         SS_ICON | WS_GROUP | WS_VISIBLE
  263.  
  264.  
  265. ΓòÉΓòÉΓòÉ 2.7. Listboxes ΓòÉΓòÉΓòÉ
  266.  
  267.  
  268. ΓòÉΓòÉΓòÉ 2.7.1. Columns Using Presentation Parameters ΓòÉΓòÉΓòÉ
  269.  
  270. The easiest way to have columns in listboxes is to use presentation parameters 
  271. to change the font to a non-proportional type, for example, Courier. 
  272.  
  273.  
  274. ΓòÉΓòÉΓòÉ 2.7.2. Columns Using Proportional Fonts ΓòÉΓòÉΓòÉ
  275.  
  276. If your columns are purely numeric, that also means no leading blanks, then it 
  277. doesn't matter what font you use. Numbers take up the same space so they will 
  278. line up even using a non-proportional font.  See the MLE/Radio Button program 
  279. for confirmation of this. 
  280.  
  281. However, if you need to display text in columns then you need to use a 
  282. ownerdraw listbox and do the drawing of items yourself. 
  283.  
  284. A very quick and easy way of putting your data into columns is to split your 
  285. item rectangle into separate rectangles, treating each rectangle as a column. 
  286. Each time you insert an item a WM_DRAWITEM  message is sent so that you can 
  287. draw the text the way you want it.  You must, of course, make sure you have 
  288. enough room in each column for the data. If you require horizontal scrolling 
  289. then you will need to change the start positions of the second and successive 
  290. columns. 
  291.  
  292. When an item is selected then you can decode the text in your LN_SELECT case 
  293. statement. 
  294.  
  295.  
  296. ΓòÉΓòÉΓòÉ 2.7.3. Deleting Items ΓòÉΓòÉΓòÉ
  297.  
  298. To delete an item from a listbox send it an LM_DELETEITEM message. Remember 
  299. that the item's index is zero-based. 
  300.  
  301. If you need to delete all items then send it an LM_DELETEALL message. 
  302.  
  303.  
  304. ΓòÉΓòÉΓòÉ 2.7.4. Deselecting Items ΓòÉΓòÉΓòÉ
  305.  
  306. To deselect an item in a listbox send it an LM_SELECTITEM message with the 
  307. second parameter set to FALSE. Remember that the item's index is zero-based. 
  308.  
  309. If you wish to deselect all items in a multiple selection listbox then you must 
  310. loop through the listbox deselecting each one separately. LIT_NONE for this 
  311. type of listbox is ignored since what you are saying is, select another item in 
  312. a multiple selection listbox, and of course this does not deselect any 
  313. previously selected item. 
  314.  
  315.  
  316. ΓòÉΓòÉΓòÉ 2.7.5. Inserting Items ΓòÉΓòÉΓòÉ
  317.  
  318. To insert items into a listbox send it an LM_INSERTITEM message. The first 
  319. parameter of this message indicates where the item is to be inserted. It can 
  320. either be at the end, in ascending or descending sequence, or at any position. 
  321.  
  322. One of the most common uses of listboxes is to display data extracted from a 
  323. database. In such cases it is often useful to store the key of each item so 
  324. that you can retrieve any extra data for that item later. A useful technique 
  325. for doing this is to use the item handle. 
  326.  
  327.  
  328. ΓòÉΓòÉΓòÉ 2.7.6. LS_NOADJUSTPOS Style ΓòÉΓòÉΓòÉ
  329.  
  330. If this style is included then the listbox control is drawn at the size 
  331. specified.  This can cause parts of an item to be shown at the bottom of the 
  332. box. This is very evident if you change to a large font in a listbox. If you do 
  333. not specify this style then the listbox is sized according to whatever font it 
  334. will be using once initialised so that only complete lines will be drawn. This 
  335. may make the box considerably smaller than intended. You should therefore bear 
  336. this in mind if you intend using a different font in a listbox. 
  337.  
  338. Furthermore, if you intend allowing the user to change the font at runtime then 
  339. if this style is not used then the listbox size will vary quite drastically 
  340. according to what font changes are taking place, so much so that eventually it 
  341. will be too small to read any items. 
  342.  
  343.  
  344. ΓòÉΓòÉΓòÉ 2.7.7. LS_NOVERTSCROLL Style ΓòÉΓòÉΓòÉ
  345.  
  346. This style, which causes a listbox not to have a vertical scroll bar, is 
  347. documented on page 16-1 of the Presentation Manager Programming Reference 
  348. Manual. However, it was never implemented in the product and so is not 
  349. available for use. 
  350.  
  351. If you do not want a vertical scroll bar in your listbox then see Removing 
  352. Scroll Bars. 
  353.  
  354.  
  355. ΓòÉΓòÉΓòÉ 2.7.8. Non-selectable Items ΓòÉΓòÉΓòÉ
  356.  
  357. If you have a requirement to prohibit selection of certain items in a listbox 
  358. then you must use an ownerdraw listbox and handle the selection yourself. In 
  359. the ownerdraw code for the listbox sample program you will notice that Finland 
  360. is not selectable. This is handled in the WM_DRAWITEM case statement where the 
  361. hilighting is handled. You must still code a trap for it in the LN_SELECT 
  362. statement, in this case just a warning beep. 
  363.  
  364. This can easily be extended to exclude all entries if desired. 
  365.  
  366.  
  367. ΓòÉΓòÉΓòÉ 2.7.9. Ownerdraw ΓòÉΓòÉΓòÉ
  368.  
  369. This topic has probably caused more problems than any other in Presentation 
  370. Manager. Briefly, if you want to do anything out of the ordinary with a listbox 
  371. the chances are you will have to resort to an ownerdraw listbox. What this 
  372. means is that you  are responsible for drawing the items in the box so it gives 
  373. you complete freedom to do as you please.  Probably the most common use of 
  374. ownerdraw listboxes is to arrange the data in columns, but their use is really 
  375. unlimited. 
  376.  
  377. As a simple introduction we will look at a listbox that centralises the data 
  378. and uses our own colours for hilighting.  Although this is a very simple 
  379. example it does show the basic steps that can be built on to produce something 
  380. more complex. 
  381.  
  382. So, to start with you must define your listbox with the style LS_OWNERDRAW, 
  383. this can be done manually or by using the Dialog Box Editor. Now, when you have 
  384. an ownerdraw listbox your application receives two messages, WM_MEASUREITEM and 
  385. WM_DRAWITEM. The purpose of the WM_MEASUREITEM  message is to establish the 
  386. height and width of the item to be drawn in the listbox, and the WM_DRAWITEM 
  387. message is sent whenever the item needs to be drawn. 
  388.  
  389. Looking at the WM_MEASUREITEM message first, all we need to do here is query 
  390. the font metrics to get the maximum vertical distance from one character 
  391. baseline to the next character baseline, lMaxBaselineExt, for the current 
  392. logical font. Once we have this value we return it to the system. Since we 
  393. don't have a horizontal scroll bar we are not interested in the width so just 
  394. return 0 for its value. However, if you do need to have a horizontal scroll bar 
  395. then you must return the width of the item. You can get this by using 
  396. GpiQueryTextBox. One point worth remembering when you have a horizontal scroll 
  397. bar is that this message is sent every time an item is inserted or deleted for 
  398. each item in the listbox.  This means that when you insert the first 3 items, 
  399. for example, 6 messages are sent (1+2+3).  This is so the system can determine 
  400. the height and width of every item.  For this reason care should be taken not 
  401. to code lengthy calculations here. 
  402.  
  403. We get a WM_DRAWITEM message whenever the listbox needs to be redrawn, for 
  404. example when an item is inserted or selected. On entry the second parameter, 
  405. mp2, is a pointer to an OWNERITEM structure which gives us information about 
  406. the item to be drawn, such as the size of the rectangle it is to be drawn in, 
  407. its select state, a handle to its presentation space and others, but for this 
  408. simple example that's all we are interested in. 
  409.  
  410. If the state is 0 then the item is not selected so we set the normal colours, 
  411. in this case yellow on dark green, if it's 1 then it is selected so we reverse 
  412. the colours. All that needs to be done now is draw the text and exit. The 
  413. important points to note here though are - 
  414.  
  415.   1. Current and old states must be set to 0 else Presentation Manager will 
  416.      take over hilighting and change  what we have done. 
  417.   2. We must return TRUE to prevent Presentation Manager from doing the 
  418.      drawing. If we don't then the text will be left justified and in system 
  419.      colours. 
  420.  
  421.  This is obviously a trivial example but should be sufficient to get you 
  422.  started in this area. 
  423.  
  424.  Note:  If all you want to do with your listbox is change the font or 
  425.  foreground and background colours then there is no need to resort to an 
  426.  ownerdraw listbox as from OS/2 Version 1.2 onwards you can do this with 
  427.  presentation parameters. However, if you do need to use a different font in an 
  428.  ownerdraw listbox then you can use presentation parameters, but you must put 
  429.  the call to WinSetPresParam in your WM_MEASUREITEM statement otherwise the 
  430.  item height will not be set correctly, so if you use a font larger than the 
  431.  system font, it will be clipped. Not only that, but it must only be executed 
  432.  once otherwise the program will get a trap 000C - 
  433.  
  434.   SYS1942  A program attempted to reference storage outside the limits
  435.            of a stack segment.
  436.  
  437.  You therefore need a first-time flag to overcome this. 
  438.  
  439.  Note:  This only really applies if you have horizontal scrolling since the 
  440.  WM_MEASUREITEM message is only sent once. 
  441.  
  442.  
  443. ΓòÉΓòÉΓòÉ 2.7.10. Processing Multiple Items ΓòÉΓòÉΓòÉ
  444.  
  445. To process the selected items in a multiple selection listbox, first send a 
  446. LM_QUERYSELECTION  message with the first parameter set to LIT_FIRST, this will 
  447. return the index of the first selected item.  You can then process this item 
  448. and then send another LM_QUERYSELECTION  message with the first parameter set 
  449. to the index previously returned. Continue this until LIT_NONE is returned. 
  450.  
  451. If this process is going to take some time, and it may well do, since many 
  452. items are going to be processed, then you should consider putting it in another 
  453. thread.  If you don't want the user interacting with your application whilst 
  454. this thread is running then you can disable any relevant controls until the 
  455. thread has completed. 
  456.  
  457. Note:  To deselect items send each one an LM_SELECTITEM message. 
  458.  
  459.  
  460. ΓòÉΓòÉΓòÉ 2.7.11. Removing Scroll Bars ΓòÉΓòÉΓòÉ
  461.  
  462. There is no clean method for removing a scroll bar from a listbox. The best 
  463. that can be done is to get the handle of the scroll bar and use 
  464. WinDestroyWindow to destroy it. However, this leaves a blank space so looks 
  465. untidy. Note that removing a vertical scroll bar does not prevent scrolling up 
  466. and down, whereas removing a horizontal scroll bar does prevent sideways 
  467. scrolling. 
  468.  
  469.  
  470. ΓòÉΓòÉΓòÉ 2.7.12. Retrieving Data Associated with Items ΓòÉΓòÉΓòÉ
  471.  
  472. After saving data in an item handle you can retrieve it again by sending the 
  473. listbox an LM_QUERYITEMHANDLE message. 
  474.  
  475.  
  476. ΓòÉΓòÉΓòÉ 2.7.13. Retrieving the Text of a Selected Item ΓòÉΓòÉΓòÉ
  477.  
  478. To get the text of a selected item you must first send the listbox an 
  479. LM_QUERYSELECTION message to get the index of the selected item, the first 
  480. entry in a listbox having an index of 0. Once you have this value you send it 
  481. an LM_QUERYITEMTEXT message to get the actual text. 
  482.  
  483. Listboxes generate a WM_CONTROL message, so to process it for a listbox check 
  484. the low word of the mp1 parameter using the SHORT1FROMMP macro and then the 
  485. high word of the mp1 parameter using the SHORT2FROMMP macro for the LN_ 
  486. notification code. In this case LN_SELECT. 
  487.  
  488.  
  489. ΓòÉΓòÉΓòÉ 2.7.14. Saving Data Associated with Items ΓòÉΓòÉΓòÉ
  490.  
  491. When inserting items into a listbox it is often useful to save data associated 
  492. with each item, for example, the key field to a database row. To do this, after 
  493. inserting the item send the listbox an LM_SETITEMHANDLE message. At its 
  494. simplest this could be just the key field, but you may need to store more data 
  495. in which case you can define the necessary structure and store a pointer to it 
  496. in the handle. 
  497.  
  498. To retrieve the data send the listbox an LM_QUERYITEMHANDLE. 
  499.  
  500. Note:  Since it is necessary to allocate memory in order to save the data then 
  501. when deleting items you should free any necessary memory, and when removing the 
  502. listbox you should free all memory associated with it.  Another point worth 
  503. mentioning is when allocating memory under OS/2 Version 2 the minimum amount 
  504. allocated will be one page, i.e.  4KB, so you should take this into account 
  505. when allocating memory for your application if it is to run under this version. 
  506.  
  507.  
  508. ΓòÉΓòÉΓòÉ 2.7.15. Selecting Items ΓòÉΓòÉΓòÉ
  509.  
  510. To select an item in a listbox send it an LM_SELECTITEM message. Remember that 
  511. the item's index is zero-based. 
  512.  
  513.  
  514. ΓòÉΓòÉΓòÉ 2.8. Main Window ΓòÉΓòÉΓòÉ
  515.  
  516.  
  517. ΓòÉΓòÉΓòÉ 2.8.1. Dialog Box as a Main Window ΓòÉΓòÉΓòÉ
  518.  
  519. It is sometimes very convenient to use the Dialog Box Editor to create a window 
  520. and have this window your main, or only, window.  The easiest way to do this is 
  521. to create a modal dialog box in your main  routine.  You will not need any 
  522. get/dispatch message loop as this is part of the WinDlgBox  call. When this 
  523. call returns it means your dialog box no longer exists and you can terminate 
  524. your application. 
  525.  
  526. Alternatively, instead of using WinDlgBox you can use WinLoadDlg/WinProcessDlg. 
  527.  
  528.  
  529. ΓòÉΓòÉΓòÉ 2.8.2. Starting Minimized ΓòÉΓòÉΓòÉ
  530.  
  531. To create a dialog in its minimized state use SWP_MINIMIZE in your 
  532. WinSetWindowPos call. 
  533.  
  534.  
  535. ΓòÉΓòÉΓòÉ 2.9. Menus ΓòÉΓòÉΓòÉ
  536.  
  537.  
  538. ΓòÉΓòÉΓòÉ 2.9.1. Pop-up Menus ΓòÉΓòÉΓòÉ
  539.  
  540. This is very similar to pop-ups for client windows, but because a dialog box is 
  541. really just a frame window there are some subtle differences. 
  542.  
  543. In your WM_INITDLG processing you still need to do the WinQuerySysValue and 
  544. WinLoadMenu, but you must be careful where you put it as it is very likely that 
  545. your dialog box will already have a conventional menu. This means you will have 
  546. a WinLoadMenu and a WM_UPDATEFRAME for the action bar, so if you place the 
  547. WinLoadMenu for your pop-up before the WM_UPDATEFRAME then you will find that 
  548. when the menu pops up so will its action bar. As this is undesirable place it 
  549. after. 
  550.  
  551. The WM_BUTTON2DOWN  message processing is identical to that for client windows 
  552. but what must be added is a case for WM_NEXTMENU to prevent your application 
  553. hanging if the pop-up menu is displayed and the user presses button 1 in the 
  554. dialog box area outside the menu. All that's needed is to return FALSE from 
  555. this message. 
  556.  
  557. Unfortunately, another problem exists if you minimize the dialog box. When you 
  558. restore it the system sends the frame a WM_UPDATEFRAME message causing the 
  559. pop-up  menu's action bar to be displayed and any options on the main  action 
  560. bar to disappear.  Now to overcome this you must reload the main menu again 
  561. when the box is restored. This causes the options to reappear on the action bar 
  562. and the desired absence of the pop-up menu's action bar. But obviously you must 
  563. destroy the original action bar, with WinDestroyWindow, when minimizing 
  564. otherwise each time you minimize/restore an extra action bar will be created. 
  565.  
  566.  
  567. ΓòÉΓòÉΓòÉ 2.10. Mnemonics ΓòÉΓòÉΓòÉ
  568.  
  569.  
  570. ΓòÉΓòÉΓòÉ 2.10.1. Mnemonics for Controls ΓòÉΓòÉΓòÉ
  571.  
  572. If you want to use mnemonics in a dialog box then define a static text field 
  573. with the DT_MNEMONIC  style, either manually or by using the Dialog Box Editor, 
  574. and place this immediately before  the control you want the mnemonic to act 
  575. upon.  This creates a mnemonic based on the position of the static text control 
  576. in the resource, and underlines the letter with the tilde. 
  577.  
  578.  
  579. CONTROL "~Single Selection", 101, 10, 155, 71, 8, WC_STATIC, SS_TEXT |
  580.         DT_LEFT | DT_TOP | DT_MNEMONIC | WS_GROUP | WS_VISIBLE
  581. CONTROL "", ID_SLISTBOX, 8, 71, 80, 80, WC_LISTBOX, WS_TABSTOP |
  582.         WS_VISIBLE
  583.  
  584. In the above example when the user presses Alt-S  from anywhere in the dialog, 
  585. or S  from a non-text entry field, it will automatically set the focus to the 
  586. listbox control. 
  587.  
  588.  
  589. ΓòÉΓòÉΓòÉ 2.11. Multi-line Entry Fields ΓòÉΓòÉΓòÉ
  590.  
  591.  
  592. ΓòÉΓòÉΓòÉ 2.11.1. Changing Font ΓòÉΓòÉΓòÉ
  593.  
  594. The simplest method of changing the font, or colour, of a control is to use 
  595. presentation parameters. This method works fine for all controls in a dialog 
  596. box except Multi-line Entry fields (MLE) in which only the following fonts 
  597. appear to work - 
  598.  
  599.  8 point Courier 
  600.  10 point Courier 
  601.  12 point Courier 
  602.  8 point Helvetica 
  603.  10 point Helvetica 
  604.  12 point Helvetica 
  605.  14 point Helvetica 
  606.  18 point Helvetica 
  607.  24 point Helvetica 
  608.  
  609.  To effect this font change use WinSetPresParam. If you need to use a different 
  610.  font in an MLE then you must use the traditional approach, an example of which 
  611.  may be found in the OS/2 Toolkit sample program FONTTEST. 
  612.  
  613.  Note:  The above restriction may change with later levels of OS/2. This is 
  614.  applicable to the initial release of Version 1.3 so if you have a later 
  615.  version then I suggest you try this method first. 
  616.  
  617.  
  618. ΓòÉΓòÉΓòÉ 2.11.2. Clearing the MLE ΓòÉΓòÉΓòÉ
  619.  
  620. To clear the text from an MLE use WinSetDlgItemText or WinSetWindowText. 
  621.  
  622.  
  623. ΓòÉΓòÉΓòÉ 2.11.3. Importing a File ΓòÉΓòÉΓòÉ
  624.  
  625. To import a file to an MLE you must first allocate a buffer into which you read 
  626. the file, or part of the file, and then set this buffer as the current transfer 
  627. buffer for the MLE.  You can then import the file.  If you require the file to 
  628. be inserted at the current cursor position then set the insertion point to -1. 
  629.  
  630. The sample code reads in the CONFIG.SYS file and imports it at the current 
  631. cursor position. 
  632.  
  633.  
  634. ΓòÉΓòÉΓòÉ 2.12. Position ΓòÉΓòÉΓòÉ
  635.  
  636.  
  637. ΓòÉΓòÉΓòÉ 2.12.1. Positioning a Dialog Box on the Desktop ΓòÉΓòÉΓòÉ
  638.  
  639. To position a dialog box on the desktop use WinSetWindowPos without the 
  640. SWP_SIZE option in your WM_INITDLG code. 
  641.  
  642.  
  643. ΓòÉΓòÉΓòÉ 2.13. Push Buttons ΓòÉΓòÉΓòÉ
  644.  
  645.  
  646. ΓòÉΓòÉΓòÉ 2.13.1. Default ΓòÉΓòÉΓòÉ
  647.  
  648. To determine which push button is the default use WinQueryWindowULong. 
  649.  
  650. To remove the default style send the button a BM_SETDEFAULT message set to 
  651. FALSE and to make it the default again send the same message set to TRUE. 
  652.  
  653. Alternatively, to set/remove the default state you can also use 
  654. WinSetWindowBits, but you must call WinInvalidateRect to force a repaint of the 
  655. button afterwards to ensure the default border is added/removed as appropriate. 
  656.  
  657. Note:  From OS/2 Version 1.3 onwards setting another push button to be the 
  658. default will cause the current default button to lose its default state. 
  659.  
  660.  
  661. ΓòÉΓòÉΓòÉ 2.13.2. User Button ΓòÉΓòÉΓòÉ
  662.  
  663. If you need to display a bitmap in a push button, for example the system bitmap 
  664. for a drive, then you must use a push button with the style BS_USERBUTTON. 
  665. Using this causes a BN_PAINT message to be sent to your window procedure. 
  666.  
  667. If you wish to display a non-system bitmap in a push button then you must 
  668. define it in your resource file and load it in your paint procedure prior to 
  669. display. 
  670.  
  671. The user button code shows both methods. It makes use of the DBM_STRETCH option 
  672. so that the bitmap is stretched to the full size of the button. 
  673.  
  674.  
  675. ΓòÉΓòÉΓòÉ 2.14. Radio Buttons ΓòÉΓòÉΓòÉ
  676.  
  677.  
  678. ΓòÉΓòÉΓòÉ 2.14.1. Setting at Initialisation ΓòÉΓòÉΓòÉ
  679.  
  680. This is probably the most common problem of all with radio buttons. If you have 
  681. a group of radio buttons and you want to check one other than the first when 
  682. starting your dialog, then 
  683.  
  684.  
  685. case WM_INITDLG:
  686.   WinSendDlgItemMsg(hwnd, BUTTON_ID, BM_SETCHECK,
  687.                     MPFROM2SHORT(TRUE, 0), NULL);
  688.  
  689. will usually work. 
  690.  
  691. However, if the group of buttons is the first  control in the dialog box then 
  692. the first button will be checked, irrespective of whatever button ID you 
  693. specified on the WinSendDlgItemMsg.  To overcome this, check the required 
  694. button as shown above but make sure you return TRUE  from the WM_INITDLG. 
  695.  
  696.  
  697. ΓòÉΓòÉΓòÉ 2.15. Size ΓòÉΓòÉΓòÉ
  698.  
  699.  
  700. ΓòÉΓòÉΓòÉ 2.15.1. Minimizing a Dialog Box ΓòÉΓòÉΓòÉ
  701.  
  702. The most common problem encountered when minimizing dialog boxes  is the 
  703. disappearance of your icon.  Instead, Presentation Manager paints over the icon 
  704. with the bottom left corner of your dialog box.  To overcome this you must 
  705. first load your icon using WinLoadPointer  and then send a WM_SETICON message 
  706. to the dialog box. You should do this in your WM_INITDLG  code.  You must then 
  707. trap your WM_ADJUSTWINDOWPOS  message and if minimizing, hide the control(s) at 
  708. the bottom left corner of the box.  Conversely, when restoring you must show 
  709. the control(s) again.  Finally, pass control back to the default dialog 
  710. procedure so that it can do any default processing. 
  711.  
  712. You should also add a WinDestroyPointer call during your exit processing. 
  713.  
  714.  
  715. ΓòÉΓòÉΓòÉ 2.16. Status ΓòÉΓòÉΓòÉ
  716.  
  717.  
  718. ΓòÉΓòÉΓòÉ 2.16.1. Status Bar ΓòÉΓòÉΓòÉ
  719.  
  720. If you have ever run the AVIOSAMP sample program from the Toolkit you will have 
  721. noticed that it has a status bar.  This bar gives the user the current 
  722. application status, for example whether he is in insert mode or not. 
  723.  
  724. Here are two ways this can be implemented in dialog boxes, the first makes use 
  725. of the WM_PAINT message and WinDrawText to display the status.  But perhaps the 
  726. easier method is to define a static text field in your dialog box and use 
  727. WinSetPresParam in your WM_INITDLG  to initialise the colours.  In this case 
  728. you use WinSetWindowText to display the status as and when necessary. 
  729.  
  730.  
  731. ΓòÉΓòÉΓòÉ 2.17. Styles ΓòÉΓòÉΓòÉ
  732.  
  733.  
  734. ΓòÉΓòÉΓòÉ 2.17.1. Changing a Control's Style ΓòÉΓòÉΓòÉ
  735.  
  736. To change a control's style, for example, to change an entry field's style of 
  737. left align to centred, use WinSetWindowULong. 
  738.  
  739.  
  740. ΓòÉΓòÉΓòÉ 2.18. Tab Stops ΓòÉΓòÉΓòÉ
  741.  
  742.  
  743. ΓòÉΓòÉΓòÉ 2.18.1. Removing and Adding ΓòÉΓòÉΓòÉ
  744.  
  745. If you need to remove/add the TABSTOP from a dialog box control, a push button 
  746. for example, then use WinSetWindowULong. 
  747.  
  748.  
  749. ΓòÉΓòÉΓòÉ 2.19. Text ΓòÉΓòÉΓòÉ
  750.  
  751.  
  752. ΓòÉΓòÉΓòÉ 2.19.1. Backslash in a Static Text Window ΓòÉΓòÉΓòÉ
  753.  
  754. If you require a \ in a static text window then, like C, you must code a double 
  755. slash, i.e. \\. 
  756.  
  757.  
  758. ΓòÉΓòÉΓòÉ 2.19.2. Changing the Dialog Box Title ΓòÉΓòÉΓòÉ
  759.  
  760. To change the title of the dialog box use WinSetWindowText with the window 
  761. handle set to the actual dialog box handle, i.e. the frame handle. 
  762.  
  763. Alternatively, use WinSetDlgItemText. 
  764.  
  765.  
  766. ΓòÉΓòÉΓòÉ 2.19.3. Changing the Text in a Dialog Box Control ΓòÉΓòÉΓòÉ
  767.  
  768. To change the text in a dialog box control use WinSetWindowText with the window 
  769. handle set to the handle of the control you wish to change. You can use 
  770. WinWindowFromID to get this value. 
  771.  
  772.  
  773. ΓòÉΓòÉΓòÉ 2.19.4. Forcing a Line Break in Static Text Windows ΓòÉΓòÉΓòÉ
  774.  
  775. If you have a static text window with word wrap defined in your dialog box and 
  776. you wish to force a line break, then use \012 at the point you wish to break. 
  777. For example, in your DLG file - 
  778.  
  779.  
  780.       CONTROL "Line one\012Line two\012Line three", ...etc
  781.  
  782. will produce -
  783.  
  784.                       Line one
  785.                       Line two
  786.                       Line three
  787.  
  788. You can do this either by modifying your DLG file manually or by using 
  789. WinSetWindowText within your program. 
  790.  
  791. Unfortunately, if you use the Dialog Box Editor the \012s are replaced by line 
  792. breaks in the DLG file and the Resource Compiler fails with a syntax error. 
  793.  
  794.  
  795. ΓòÉΓòÉΓòÉ 2.20. Window ID ΓòÉΓòÉΓòÉ
  796.  
  797.  
  798. ΓòÉΓòÉΓòÉ 2.20.1. Window ID of a Control ΓòÉΓòÉΓòÉ
  799.  
  800. To retrieve the window identity of a control within a dialog box use 
  801. WinQueryWindowUShort with a value of QWS_ID. 
  802.  
  803.  
  804. ΓòÉΓòÉΓòÉ 2.21. Sample Programs ΓòÉΓòÉΓòÉ
  805.  
  806.  
  807. ΓòÉΓòÉΓòÉ 2.21.1. General Dialog Box ΓòÉΓòÉΓòÉ
  808.  
  809. This sample program does not have any real function but was written to test 
  810. that most of the tips in this section do work. You will find many areas 
  811. commented out, this was done to check that any alternative methods also 
  812. functioned correctly. 
  813.  
  814. If you run the program and press OK most of the features described in this 
  815. section and the section on pop-up menus for dialog boxes are actioned. 
  816. Pressing button 2 causes the pop-up menu to appear. 
  817.  
  818. See the following sample programs for verification of all other tips. 
  819.  
  820.  Listbox 
  821.  MLE and Radio Buttons 
  822.  
  823.  HINTS.C - C source file 
  824.  HINTS.H - Header file 
  825.  HINTS.L - Link control file 
  826.  HINTS.DEF - Module definition file 
  827.  HINTS.RC - Resource file 
  828.  HINTS.DLG - Dialog template 
  829.  HINTS - Make file 
  830.  Run program (Launch doesn't work in 1.3 yet!) 
  831.  
  832.  
  833. ΓòÉΓòÉΓòÉ 2.21.2. MLE and Radio Buttons ΓòÉΓòÉΓòÉ
  834.  
  835. This program was written to verify that the multi-line entry field and radio 
  836. button tips function correctly.  See the following sample programs for 
  837. verification of all other tips. 
  838.  
  839.  General Dialog Box 
  840.  Listbox 
  841.  
  842.  Note:  This program also makes use of Presentation Parameters. 
  843.  
  844.  HINTS.C - C source file 
  845.  HINTS.H - Header file 
  846.  HINTS.L - Link control file 
  847.  HINTS.DEF - Module definition file 
  848.  HINTS.RC - Resource file 
  849.  HINTS.DLG - Dialog template 
  850.  HINTS - Make file 
  851.  Run program (Launch doesn't work in 1.3 yet!) 
  852.  
  853.  
  854. ΓòÉΓòÉΓòÉ 2.21.3. Listbox ΓòÉΓòÉΓòÉ
  855.  
  856. This program was written to verify that the Listbox tips function correctly. 
  857. See the following sample programs for verification of all other tips. 
  858.  
  859.  General Dialog Box 
  860.  MLE and Radio Buttons 
  861.  
  862.  This program displays three listboxes, single and multiple selection, and an 
  863.  ownerdraw, with the first item selected in the single selection box on entry. 
  864.  Items can be deselected from the single and ownerdraw boxes by pressing 
  865.  Deselect, and can be deleted from the single selection box by pressing Delete. 
  866.  If you select items in the multiple selection box and press Process MultSel 
  867.  then each one is processed sequentially and beeps when complete.  Notice that 
  868.  this option uses DosSleep  to do this which is not  recommended.  It is done 
  869.  here merely to slow down the process so that you can see what is happening. 
  870.  The ownerdraw box is a simple implementation of columnar data with Finland 
  871.  non-selectable (I've nothing against Finland, I just happened to pick it at 
  872.  random, my apologies to all those Finns using this package). Finally, pressing 
  873.  Alt-S, Alt-M or Alt-O  will switch focus to the relevant listbox. 
  874.  
  875.  HINTS.C - C source file 
  876.  HINTS.H - Header file 
  877.  HINTS.L - Link control file 
  878.  HINTS.DEF - Module definition file 
  879.  HINTS.RC - Resource file 
  880.  HINTS.DLG - Dialog template 
  881.  HINTS - Make file 
  882.  Run program (Launch doesn't work in 1.3 yet!) 
  883.  
  884.  
  885. ΓòÉΓòÉΓòÉ 3. Fonts ΓòÉΓòÉΓòÉ
  886.  
  887. This section covers the following topics - 
  888.  
  889.  Point Sizes and Face Names 
  890.  
  891.  
  892. ΓòÉΓòÉΓòÉ 3.1. Point Sizes and Face Names ΓòÉΓòÉΓòÉ
  893.  
  894. The following list represents the point sizes and face names of all the 
  895. standard fonts in the system. You may use all of them with WinSetPresParam 
  896. unless you wish to use it for changing the font of a Multi-line Entry field, in 
  897. which case there are limitations. 
  898.  
  899.  8.Courier 
  900.  10.Courier 
  901.  12.Courier 
  902.  8.Helv 
  903.  10.Helv 
  904.  12.Helv 
  905.  14.Helv 
  906.  18.Helv 
  907.  24.Helv 
  908.  10.System Monospaced 
  909.  12.System Monospaced 
  910.  12.System Proportional 
  911.  8.Tms Rmn 
  912.  10.Tms Rmn 
  913.  12.Tms Rmn 
  914.  14.Tms Rmn 
  915.  18.Tms Rmn 
  916.  24.Tms Rmn 
  917.  
  918.  
  919. ΓòÉΓòÉΓòÉ 4. Menus ΓòÉΓòÉΓòÉ
  920.  
  921. This section covers the following topics - 
  922.  
  923.  Add Items to the System Menu 
  924.  Change a Window's Menu 
  925.  Check Menu Item 
  926.  Delete Items from the System Menu 
  927.  Delete Separator from the System Menu 
  928.  Disable Action Bar 
  929.  Disable Items in an Application Menu 
  930.  Disable Items in the System Menu 
  931.  Dismiss 'MIA_NODISMISS' Menu 
  932.  Pop-up Menus for Client Windows 
  933.  Pop-up Menus for Dialog Boxes 
  934.  Pop-up Sample Program (Dialog Box) 
  935.  Sample Program 
  936.  
  937.  
  938. ΓòÉΓòÉΓòÉ 4.1. Add Items to the System Menu ΓòÉΓòÉΓòÉ
  939.  
  940. Perhaps one of the most common queries regarding menus is 'How can I alter the 
  941. system menu?', usually to add an About option, so let's look at how this is 
  942. done. 
  943.  
  944. The first thing to do is get the handle of the system menu by calling 
  945. WinWindowFromID with the identifier FID_SYSMENU. We then send it an 
  946. MM_ITEMIDFROMPOSITION to get the ID of the actual menu list. Once we have this 
  947. we can get the characteristics of the menu by sending it an MM_QUERYITEM 
  948. message. The important item returned in the SysMenu structure is the actual 
  949. handle of the submenu. Armed with this we can insert our items into it by 
  950. sending the submenu an MM_INSERTITEM  message.  If you look at the declaration 
  951. of Item  you will see that we are adding a separator and some text, the actual 
  952. text being defined in Text. 
  953.  
  954. This code would normally be executed at window creation time, i.e. in your 
  955. WM_CREATE statement, so don't forget that you cannot use hwndFrame at this 
  956. point. 
  957.  
  958. Clicking on About... will cause a WM_COMMAND message with the low short of mp1 
  959. set to ID_ABOUT. On receiving this we display a message box giving details 
  960. about the program. This information could alternatively be displayed in a 
  961. dialog box. 
  962.  
  963.  
  964. ΓòÉΓòÉΓòÉ 4.2. Change a Window's Menu ΓòÉΓòÉΓòÉ
  965.  
  966. There may be times when it is convenient for you to have two or more menus 
  967. defined in your resource file for a window, and have any one loaded at any 
  968. given time depending on circumstances.  An easy way to do this is to destroy 
  969. the current menu and use WinLoadMenu to load the next. You must then follow 
  970. this with a WM_UPDATEFRAME message. 
  971.  
  972.  
  973. ΓòÉΓòÉΓòÉ 4.3. Check Menu Item ΓòÉΓòÉΓòÉ
  974.  
  975. Whenever a menu is about to be activated the system sends your application a 
  976. WM_INITMENU message. The purpose being that you can make any changes to the 
  977. submenu before it is displayed. For example, you may need to add a check mark 
  978. to an item, or to toggle the item on/off depending on the current state of the 
  979. application. The sample code shows this by setting up a flag, initially FALSE, 
  980. and sending an MM_SETITEMATTR message to the menu. Because we are sending the 
  981. message to the top-level menu rather than the submenu we must specify TRUE to 
  982. ensure the submenu is searched for the item. Because we want to check an item 
  983. we use the MIA_CHECKED attribute. The data associated with this is dependent on 
  984. the flag, and since it is initially FALSE the item is not checked. However, if 
  985. we now select the item the flag changes state and next time the menu is 
  986. displayed the item will be checked. 
  987.  
  988. Note:  This also applies to disabling items using the MIA_DISABLED attribute. 
  989.  
  990.  
  991. ΓòÉΓòÉΓòÉ 4.4. Delete Items from the System Menu ΓòÉΓòÉΓòÉ
  992.  
  993. To delete items you must first obtain the handle of the system menu and then 
  994. send it an MM_DELETEITEM  message. 
  995.  
  996.  
  997. ΓòÉΓòÉΓòÉ 4.5. Delete Separator from the System Menu ΓòÉΓòÉΓòÉ
  998.  
  999. If you want to remove Close  from the system menu you will also need to remove 
  1000. the separator following it.  The problem with deleting menu separators is that 
  1001. their IDs vary. For example, the first separator will have an ID of -2, and the 
  1002. next -3  etc.  so you cannot supply a fixed value for a separator ID as you 
  1003. don't know its position. 
  1004.  
  1005. To do this then you must first get the handle of the system menu submenu, i.e. 
  1006. the actual menu displaying the items, and send an MM_ITEMPOSITIONFROMID 
  1007. message to get the position of Close in the menu, you can then add 1 to this to 
  1008. get the position of the separator.  Sending an MM_ITEMIDFROMPOSITION message 
  1009. for this value now gives the actual item ID for the separator which can now be 
  1010. used in the MM_DELETEITEM message.  The Close  option can be deleted in the 
  1011. normal manner, i.e.  use (SC_CLOSE, TRUE)  with the system menu  handle. 
  1012.  
  1013.  
  1014. ΓòÉΓòÉΓòÉ 4.6. Disable/Enable Action Bar ΓòÉΓòÉΓòÉ
  1015.  
  1016. To disable the action bar, and thus all its pull-down menus, use 
  1017. WinEnableWindow. 
  1018.  
  1019.  
  1020. ΓòÉΓòÉΓòÉ 4.7. Disable/Enable Items in an Application Menu ΓòÉΓòÉΓòÉ
  1021.  
  1022. To disable, or enable, items in your application menu you must first obtain its 
  1023. handle and then send it an MM_SETITEMATTR  message to change the attribute of 
  1024. the item.  This would normally be done in your WM_INITMENU statement depending 
  1025. on the setting of a flag. See also Check Menu Item. 
  1026.  
  1027.  
  1028. ΓòÉΓòÉΓòÉ 4.8. Disable/Enable Items in the System Menu ΓòÉΓòÉΓòÉ
  1029.  
  1030. To disable, or enable, items you must first obtain the handle of the system 
  1031. menu and then send it an MM_SETITEMATTR  message to change the attribute of the 
  1032. item.  However, you can only disable Close  and Switch to... using this method. 
  1033. If you need to disable Move  then using WinEnableWindow to disable the title 
  1034. bar will cause Move to be greyed as a result. 
  1035.  
  1036. Note:  There are no such restrictions in deleting items from the system menu. 
  1037.  
  1038.  
  1039. ΓòÉΓòÉΓòÉ 4.9. Dismiss 'MIA_NODISMISS' Menu ΓòÉΓòÉΓòÉ
  1040.  
  1041. If you have a menu in which one or more items are defined with the 
  1042. MIA_NODISMISS attribute and you select one of these items, then the menu does 
  1043. not disappear. This may be what you need in your application, but, the problem 
  1044. comes when you want to dismiss it, say by pressing a mouse button. You will not 
  1045. be able to do it by sending an MM_DISMISSMENU  message as the menu is no longer 
  1046. in menu mode. Instead, you must post MM_STARTMENUMODE  and MM_ENDMENUMODE 
  1047. messages.  Notice that the MM_ENDMENUMODE message is posted. The documentation 
  1048. states that this message should be sent.  However, the MM_STARTMENUMODE 
  1049. message MUST  be posted, so if the START was posted, and the END was sent, then 
  1050. the END would be processed first.  This is why both must be posted. 
  1051.  
  1052.  
  1053. ΓòÉΓòÉΓòÉ 4.10. Pop-up ΓòÉΓòÉΓòÉ
  1054.  
  1055.  
  1056. ΓòÉΓòÉΓòÉ 4.10.1. For Client Windows ΓòÉΓòÉΓòÉ
  1057.  
  1058. It can sometimes be useful for your user to be able to pop up a menu by 
  1059. pressing mouse button 2, for example, rather than have to move to the action 
  1060. bar. To do this, first define your menu in the usual way in your resource file, 
  1061. and then trap the WM_CREATE and WM_BUTTON2DOWN messages in your window 
  1062. procedure. 
  1063.  
  1064. In the WM_CREATE case you need to get the handle of the menu by using 
  1065. WinLoadMenu  and the action bar height by using WinQuerySysValue  with 
  1066. SV_CYMENU, i.e.  the height of a single line menu.  This is needed so that you 
  1067. can position the pop-up so that the first menu item lines up with the pointer. 
  1068. Without doing this you will find that the menu items are an action bar's height 
  1069. below the pointer. 
  1070.  
  1071. To complete the implementation you need to get the position of the mouse 
  1072. pointer by using the macro MOUSEMSG, making sure you adjust the Y coordinate by 
  1073. adding the action bar height to it. Finally you must POST an MM_STARTMENUMODE 
  1074. message to the menu handle and position the menu using WinSetWindowPos. You 
  1075. can, of course, use a push button or any other method to initiate the pop-up, 
  1076. but pressing button 2 is probably the best method. 
  1077.  
  1078. You must then add the relevant case statements for the menu items in your 
  1079. WM_COMMAND  message processing. 
  1080.  
  1081.  
  1082. ΓòÉΓòÉΓòÉ 4.10.2. For Dialog Boxes ΓòÉΓòÉΓòÉ
  1083.  
  1084. This is very similar to pop-ups for client windows, but because a dialog box is 
  1085. really just a frame window there are some subtle differences. 
  1086.  
  1087. In your WM_INITDLG processing you still need to do the WinQuerySysValue and 
  1088. WinLoadMenu, but you must be careful where you put it as it is very likely that 
  1089. your dialog box will already have a conventional menu. This means you will have 
  1090. a WinLoadMenu and a WM_UPDATEFRAME for the action bar, so if you place the 
  1091. WinLoadMenu for your pop-up before the WM_UPDATEFRAME then you will find that 
  1092. when the menu pops up so will its action bar. As this is undesirable place it 
  1093. after. 
  1094.  
  1095. The WM_BUTTON2DOWN  message processing is identical to that for client windows 
  1096. but what must be added is a case for WM_NEXTMENU to prevent your application 
  1097. hanging if the pop-up menu is displayed and the user presses button 1 in the 
  1098. dialog box area outside the menu. All that's needed is to return FALSE from 
  1099. this message. 
  1100.  
  1101. Unfortunately, another problem exists if you minimize the dialog box. When you 
  1102. restore it the system sends the frame a WM_UPDATEFRAME message causing the 
  1103. pop-up  menu's action bar to be displayed and any options on the main  action 
  1104. bar to disappear.  Now to overcome this you must reload the main menu again 
  1105. when the box is restored. This causes the options to reappear on the action bar 
  1106. and the desired absence of the pop-up menu's action bar. But obviously you must 
  1107. destroy the original action bar, with WinDestroyWindow, when minimizing 
  1108. otherwise each time you minimize/restore an extra action bar will be created. 
  1109.  
  1110.  
  1111. ΓòÉΓòÉΓòÉ 4.10.3. Sample Program (Dialog Box) ΓòÉΓòÉΓòÉ
  1112.  
  1113. See General Dialog Box sample program. 
  1114.  
  1115.  
  1116. ΓòÉΓòÉΓòÉ 4.11. Sample Program - Menus and Task Manager ΓòÉΓòÉΓòÉ
  1117.  
  1118. This sample program was written to confirm the hints and tips given in the 
  1119. Menus and Task Manager sections and shows the following - 
  1120.  
  1121.  Starting in background 
  1122.  Adding/removing from the task list 
  1123.  Changing the task list 
  1124.  Querying the task list 
  1125.  Disable 'End Task' button in the task list 
  1126.  Disable 'Close' and 'Switch to...' in the system menu 
  1127.  Delete 'Size' and 'Move' from the system menu 
  1128.  Prohibiting exit from the task list and system menu 
  1129.  Adding an 'About...' option to the system menu 
  1130.  Disable all menu items 
  1131.  Make application system modal 
  1132.  Toggle menu item checked/unchecked 
  1133.  Force dismissal of MIA_NODISMISS menu 
  1134.  Delete 'Close' and its separator from the system menu 
  1135.  Changing menus 
  1136.  
  1137.  Initially, 'Close' and 'Switch to...'  in the system menu and 'End Task' in 
  1138.  the task list are greyed out and the action bar is disabled.  Pressing button 
  1139.  1 enables the action bar, 'Close' and 'End Task' but doesn't allow closure 
  1140.  from these options. Exit is via the action bar only. The title is also changed 
  1141.  in the task list. Pressing button 2 removes 'Close' from the system menu. 
  1142.  Pressing 'Switch Menus' causes a different menu to be loaded which has two 
  1143.  options with two items under 'Option 1'. The first is 'checkable' and and the 
  1144.  second is 'NODISMISS', until button 1 is clicked. 
  1145.  
  1146.  HINTS.C - C source file 
  1147.  HINTS.H - Header file 
  1148.  HINTS.L - Link control file 
  1149.  HINTS.DEF - Module definition file 
  1150.  HINTS.RC - Resource file 
  1151.  HINTS - Make file 
  1152.  Run program (Launch doesn't work in 1.3 yet!) 
  1153.  
  1154.  
  1155. ΓòÉΓòÉΓòÉ 5. Mouse and Pointer Control ΓòÉΓòÉΓòÉ
  1156.  
  1157. This section covers the following topics - 
  1158.  
  1159.  Changing the Pointer in a Window 
  1160.  Mouse Pointer Position 
  1161.  Sample Program 
  1162.  
  1163.  
  1164. ΓòÉΓòÉΓòÉ 5.1. Changing the Pointer in a Window ΓòÉΓòÉΓòÉ
  1165.  
  1166. If your application needs to do some lengthy processing in a separate thread, 
  1167. it is a good idea to change the pointer to the hourglass to give the user some 
  1168. visual feedback telling him that he must wait before he is able to continue 
  1169. with the application.  It is also a good idea to change the pointer back to the 
  1170. arrow when it is moved outside your window so that he knows he can continue 
  1171. with another  application.  You will, of course, have to disable all the 
  1172. controls in your application you don't want used whilst the other thread is 
  1173. being processed, as just changing the pointer doesn't stop you using it. So, to 
  1174. do this, trap the WM_CONTROLPOINTER and WM_MOUSEMOVE messages.  Whenever the 
  1175. pointer moves into a new window a WM_CONTROLPOINTER  message is sent to a 
  1176. control's owner window allowing you to change the pointer.  You also need to 
  1177. set the pointer during WM_MOUSEMOVE  messages otherwise it will revert to the 
  1178. system arrow pointer. 
  1179.  
  1180. If you have dialog boxes in your application then you may not need to trap both 
  1181. messages, WM_CONTROLPOINTER  may suffice, so try this first.  If you find that 
  1182. the hourglass reverts to the arrow then you will have to subclass the 
  1183. particular control concerned.  For example, in this section's sample program 
  1184. you will find a dialog box with an entry field and listbox. Without subclassing 
  1185. I found that if the entry field was disabled then the hourglass reverted if it 
  1186. moved over it, and moving the pointer to the listbox scrollbar also caused the 
  1187. same reversion.  Subclassing the entry field and trapping the WM_MOUSEMOVE 
  1188. messages stopped the reversion for the entry field, and subclassing the listbox 
  1189. and trapping the WM_CONTROLPOINTER  messages stopped the scrollbar reverting 
  1190. the pointer.  If you use other controls then you may find similar peculiarities 
  1191. so try subclassing and trapping either, or both messages. 
  1192.  
  1193. Note:  The above technique also works if you wish to change the pointer to an 
  1194. icon, provided you load it first using WinLoadPointer. 
  1195.  
  1196.  
  1197. ΓòÉΓòÉΓòÉ 5.2. Mouse Pointer Position ΓòÉΓòÉΓòÉ
  1198.  
  1199. To retrieve the position of the mouse pointer use WinQueryPointerPos. This will 
  1200. return the co-ordinates in screen units. If you want the co-ordinates relative 
  1201. to your window then use WinMapWindowPoints. 
  1202.  
  1203.  
  1204. ΓòÉΓòÉΓòÉ 5.3. Sample Program ΓòÉΓòÉΓòÉ
  1205.  
  1206. This program shows the following - 
  1207.  
  1208.  Changing the pointer in a window 
  1209.  Mouse pointer position 
  1210.  
  1211.  When the program first starts it is in a busy  state, i.e.  the pointer 
  1212.  changes to the hourglass whenever it moves into the window.  If you click on 
  1213.  the Test DLG button a dialog box is displayed with an entry field and listbox. 
  1214.  The purpose of this is to show that the controls must be subclassed to 
  1215.  maintain the hourglass. In the case of the entry field this is only necessary 
  1216.  if it has been disabled, and in the case of the listbox it is necessary to 
  1217.  maintain the hourglass in the scrollbar region. Try changing the program by 
  1218.  removing the subclassing to see the effect. 
  1219.  
  1220.  If you use other controls, notably MLEs, then you will also have to use 
  1221.  subclassing to maintain the hourglass fully. 
  1222.  
  1223.  To remove the hourglass, i.e. revert to not busy press the Remove Hourglass 
  1224.  button. 
  1225.  
  1226.  You will also notice that the mouse position is displayed in screen 
  1227.  co-ordinates and window co-ordinates whenever the mouse is moved over the 
  1228.  window. If you press, and hold down, button 2 then the mouse will be captured 
  1229.  and its position will be displayed wherever it is on the desktop. Releasing 
  1230.  the button releases the capture. 
  1231.  
  1232.  HINTS.C - C source file 
  1233.  HINTS.H - Header file 
  1234.  HINTS.L - Link control file 
  1235.  HINTS.DEF - Module definition file 
  1236.  HINTS.RC - Resource file 
  1237.  HINTS.DLG - Dialog template 
  1238.  HINTS - Make file 
  1239.  Run program (Launch doesn't work in 1.3 yet!) 
  1240.  
  1241.  
  1242. ΓòÉΓòÉΓòÉ 6. Presentation Parameters ΓòÉΓòÉΓòÉ
  1243.  
  1244. This section covers the following topics - 
  1245.  
  1246.  Changing Colour 
  1247.  Changing Font 
  1248.  Using it on a Frame Window 
  1249.  Sample Program 
  1250.  
  1251.  
  1252. ΓòÉΓòÉΓòÉ 6.1. Changing Colour ΓòÉΓòÉΓòÉ
  1253.  
  1254. To change a control's colour you can either do it at runtime using 
  1255. WinSetPresParam or by presetting it in the DLG file using the PRESPARAMS 
  1256. statement. 
  1257.  
  1258. Note:  If you use the latter approach you must add 
  1259.  
  1260.  
  1261.                      #define  INCL_WINSYS
  1262.  
  1263. to your resource file otherwise you will get the error message Undefined 
  1264. keyword or name from the Resource Compiler. Also, if you subsequently edit the 
  1265. DLG file by using the Dialog Box Editor the CLR_RED etc will be replaced by 
  1266. their numeric values, i.e. 
  1267.  
  1268.  
  1269.         PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
  1270.         PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
  1271.  
  1272. becomes 
  1273.  
  1274.  
  1275.         PRESPARAMS PP_BACKGROUNDCOLORINDEX, 0x00000002L
  1276.         PRESPARAMS PP_FOREGROUNDCOLORINDEX, 0x00000006L
  1277.  
  1278.  
  1279. ΓòÉΓòÉΓòÉ 6.2. Changing Font ΓòÉΓòÉΓòÉ
  1280.  
  1281. To change the font of a dialog control or window you can either do it at 
  1282. runtime using WinSetPresParam  or, for a dialog control, by presetting it in 
  1283. the DLG file using the PRESPARAMS statement. 
  1284.  
  1285. Note:  If you use the latter approach you must add 
  1286.  
  1287.  
  1288.                      #define  INCL_WINSYS
  1289.  
  1290. to your resource file otherwise you will get the error message Undefined 
  1291. keyword or name from the Resource Compiler. Also, if you subsequently edit the 
  1292. DLG file by using the Dialog Box Editor the 10.Courier will be replaced by its 
  1293. meaningless numeric equivalent, i.e. 
  1294.  
  1295.  
  1296.         PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
  1297.  
  1298. becomes 
  1299.  
  1300.  
  1301.         PRESPARAMS PP_FONTNAMESIZE, 0x432E3031L, 0x6972756FL, 0x00007265L
  1302.  
  1303. Although this is a very simple way of changing the font care must be exercised 
  1304. when using this method for Multi-line Entry fields as many fonts cannot be set 
  1305. using WinSetPresParam. 
  1306.  
  1307. Similarly, if you intend to change the font in a listbox at runtime using this 
  1308. method then ensure it has the style LS_NOADJUSTPOS  otherwise the listbox will 
  1309. adjust its size according to what font you use and may render the listbox 
  1310. illegible.  Also, if you are using an ownerdraw listbox care should be taken 
  1311. where you place the WinSetPresParam  call.  See the ownerdraw listbox reference 
  1312. for details. 
  1313.  
  1314. Note:  You cannot use this method to change the font style, e.g. italic or 
  1315. bold. 
  1316.  
  1317.  
  1318. ΓòÉΓòÉΓòÉ 6.3. Using it on a Frame Window ΓòÉΓòÉΓòÉ
  1319.  
  1320. If you use WinSetPresParam on a frame handle then it affects all the controls 
  1321. within that frame, except perhaps the font for any Multi-line Entry fields you 
  1322. may have created. 
  1323.  
  1324.  
  1325. ΓòÉΓòÉΓòÉ 6.4. Sample Program ΓòÉΓòÉΓòÉ
  1326.  
  1327. See the MLE/Radio Button program for sample calls to WinSetPresParam. 
  1328.  
  1329.  
  1330. ΓòÉΓòÉΓòÉ 7. Task Manager ΓòÉΓòÉΓòÉ
  1331.  
  1332. This section covers the following topics - 
  1333.  
  1334.  Add Program Title to the Task List 
  1335.  Change Program Title in the Task List 
  1336.  Disable 'End Task' Button 
  1337.  Prevent Shutdown 
  1338.  Query Program Title in the Task List 
  1339.  SWL_GRAYED 
  1340.  SWL_NONJUMPABLE 
  1341.  Sample Program 
  1342.  
  1343.  
  1344. ΓòÉΓòÉΓòÉ 7.1. Add Program Title to the Task List ΓòÉΓòÉΓòÉ
  1345.  
  1346. If you use the window style FCF_STANDARD, then your program's name will appear 
  1347. in the task list, and your title bar, concatenated with any text you may have 
  1348. defined for your application's title bar.  For example, if your program was 
  1349. called 'XYZ.EXE' and its title was 'Test Program', then in the task list it 
  1350. would appear as 'XYZ.EXETest Program'. 
  1351.  
  1352. To overcome this do not use the style FCF_TASKLIST, which is included in 
  1353. FCF_STANDARD, but manually add it using WinAddSwitchEntry. 
  1354.  
  1355. On exit from the program's message loop use WinRemoveSwitchEntry to remove the 
  1356. entry. Ensure that you declare hwndEntry as static otherwise you will have an 
  1357. invalid handle. Alternatively, use WinQuerySwitchHandle to get the switch list 
  1358. handle first. 
  1359.  
  1360.  
  1361. ΓòÉΓòÉΓòÉ 7.2. Change Program Title in the Task List ΓòÉΓòÉΓòÉ
  1362.  
  1363. To change the title of your application in the task list use 
  1364. WinChangeSwitchEntry. 
  1365.  
  1366. Alternatively, for an easier method use WinSetTitle, but beware, this is 
  1367. undocumented and so should be used with caution. 
  1368.  
  1369.  
  1370. ΓòÉΓòÉΓòÉ 7.3. Disable 'End Task' Button ΓòÉΓòÉΓòÉ
  1371.  
  1372. WARNING - Undocumented, use with caution. 
  1373.  
  1374. If you have a requirement to disable the End Task button on the task list then 
  1375. use WinNoShutdown. 
  1376.  
  1377. See also Prevent Shutdown. 
  1378.  
  1379.  
  1380. ΓòÉΓòÉΓòÉ 7.4. Prevent Shutdown ΓòÉΓòÉΓòÉ
  1381.  
  1382. When the 'End Task' button on the task list is pressed an application receives 
  1383. a WM_QUIT message causing the message loop to end, thus closing the program. 
  1384. However, in this case mp1 contains the frame handle, in all other cases it is 
  1385. NULL. It is therefore possible to use this fact to either ignore shutdown 
  1386. completely, or to put up a message box asking confirmation of closure. This 
  1387. also applies to the Close option on the system menu. To implement this put your 
  1388. message loop in a separate loop and on exit from the message loop test mp1, if 
  1389. not NULL then cancel shutdown. 
  1390.  
  1391.  
  1392. ΓòÉΓòÉΓòÉ 7.5. Query Program Title in the Task List ΓòÉΓòÉΓòÉ
  1393.  
  1394. In order to query the task list for an application use WinQuerySwitchHandle to 
  1395. get the switch list handle followed by WinQuerySwitchEntry. 
  1396.  
  1397.  
  1398. ΓòÉΓòÉΓòÉ 7.6. Task List Options ΓòÉΓòÉΓòÉ
  1399.  
  1400.  
  1401. ΓòÉΓòÉΓòÉ 7.6.1. SWL_GRAYED ΓòÉΓòÉΓòÉ
  1402.  
  1403. Use this value for PgmEntry.uchVisibility when adding your program to the Task 
  1404. List to prohibit switching to it from the Task List. 
  1405.  
  1406.  
  1407. ΓòÉΓòÉΓòÉ 7.6.2. SWL_NONJUMPABLE ΓòÉΓòÉΓòÉ
  1408.  
  1409. Use this value for PgmEntry.fbJump when adding your program to the Task List to 
  1410. prohibit switching to it using the Alt_Esc key sequence. 
  1411.  
  1412.  
  1413. ΓòÉΓòÉΓòÉ 7.7. Sample Program - Menus and Task Manager ΓòÉΓòÉΓòÉ
  1414.  
  1415. This sample program was written to confirm the hints and tips given in the 
  1416. Menus and Task Manager sections and shows the following - 
  1417.  
  1418.  Starting in background 
  1419.  Adding/removing from the task list 
  1420.  Changing the task list 
  1421.  Querying the task list 
  1422.  Disable 'End Task' button in the task list 
  1423.  Disable 'Close' and 'Switch to...' in the system menu 
  1424.  Delete 'Size' and 'Move' from the system menu 
  1425.  Prohibiting exit from the task list and system menu 
  1426.  Adding an 'About...' option to the system menu 
  1427.  Disable all menu items 
  1428.  Make application system modal 
  1429.  Toggle menu item checked/unchecked 
  1430.  Force dismissal of MIA_NODISMISS menu 
  1431.  Delete 'Close' and its separator from the system menu 
  1432.  Changing menus 
  1433.  
  1434.  Initially, 'Close' and 'Switch to...'  in the system menu and 'End Task' in 
  1435.  the task list are greyed out and the action bar is disabled.  Pressing button 
  1436.  1 enables the action bar, 'Close' and 'End Task' but doesn't allow closure 
  1437.  from these options. Exit is via the action bar only. The title is also changed 
  1438.  in the task list. Pressing button 2 removes 'Close' from the system menu. 
  1439.  Pressing 'Switch Menus' causes a different menu to be loaded which has two 
  1440.  options with two items under 'Option 1'. The first is 'checkable' and and the 
  1441.  second is 'NODISMISS', until button 1 is clicked. 
  1442.  
  1443.  HINTS.C - C source file 
  1444.  HINTS.H - Header file 
  1445.  HINTS.L - Link control file 
  1446.  HINTS.DEF - Module definition file 
  1447.  HINTS.RC - Resource file 
  1448.  HINTS - Make file 
  1449.  Run program (Launch doesn't work in 1.3 yet!) 
  1450.  
  1451.  
  1452. ΓòÉΓòÉΓòÉ 8. Windows ΓòÉΓòÉΓòÉ
  1453.  
  1454. This section covers the following topics - 
  1455.  
  1456.  Active 
  1457.  Errors 
  1458.  Modality 
  1459.  Movement 
  1460.  Parent 
  1461.  Position 
  1462.  Saving State 
  1463.  Size 
  1464.  Subclassing 
  1465.  Title 
  1466.  Sample Program 
  1467.  
  1468.  
  1469. ΓòÉΓòÉΓòÉ 8.1. Active ΓòÉΓòÉΓòÉ
  1470.  
  1471.  
  1472. ΓòÉΓòÉΓòÉ 8.1.1. Active Window and its Process ID ΓòÉΓòÉΓòÉ
  1473.  
  1474. To determine the active window and get its process ID, first call 
  1475. WinQueryActiveWindow which returns the handle of the active window, and then 
  1476. call WinQueryWindowProcess to get the process ID of that window.  For a VIO 
  1477. window or full screen icon this will be the process ID of the shell. 
  1478.  
  1479. The sample code gets the active window's process ID and displays it. 
  1480.  
  1481.  
  1482. ΓòÉΓòÉΓòÉ 8.2. Errors ΓòÉΓòÉΓòÉ
  1483.  
  1484.  
  1485. ΓòÉΓòÉΓòÉ 8.2.1. Don't Use hwndFrame During WM_CREATE ΓòÉΓòÉΓòÉ
  1486.  
  1487. Don't use hwndFrame  during WM_CREATE  as it is not assigned until WM_CREATE 
  1488. processing is complete. Instead, use WinQueryWindow to get the client's parent, 
  1489. i.e. the frame handle. 
  1490.  
  1491.  
  1492. ΓòÉΓòÉΓòÉ 8.2.2. Window Not Being Displayed ΓòÉΓòÉΓòÉ
  1493.  
  1494. Sometimes when you attempt to create a window it does not display and the 
  1495. return code from WinCreateStdWindow  is NULL.  The most common cause of this 
  1496. problem is the fact that you have used the frame creation flag of FCF_STANDARD 
  1497. which includes a menu, icon and accelerator resource.  If you have not defined 
  1498. one of these then your window does not get created. 
  1499.  
  1500. You should also check that all resources belonging to a frame have the same 
  1501. ID, so check your RC file to ensure, for example, that your menu does not have 
  1502. a different ID to your icon, else the create will fail. See the RC file 
  1503. extract. 
  1504.  
  1505. One other area to look at is your WM_CREATE message. If you return TRUE from 
  1506. this then window creation is discontinued. 
  1507.  
  1508. If, however, the create does not fail, i.e.  you receive a valid handle, then 
  1509. the most likely cause is that you do not have the WS_VISIBLE  style specified 
  1510. for the window.  The default is, in fact, NOT  visible. It is also possible 
  1511. that if you are not using WinSetWindowPos you may have omitted the frame 
  1512. creation flag FCF_SHELLPOSITION for the window. 
  1513.  
  1514.  
  1515. ΓòÉΓòÉΓòÉ 8.3. Modality ΓòÉΓòÉΓòÉ
  1516.  
  1517.  
  1518. ΓòÉΓòÉΓòÉ 8.3.1. System Modal Window ΓòÉΓòÉΓòÉ
  1519.  
  1520. A simple way to trap Alt-Esc and Ctrl-Esc is to make your window system modal, 
  1521. i.e. the user can only interact with your application. This renders the hot 
  1522. keys unusable until you remove system modality for that window. To do this use 
  1523. WinSetSysModalWindow in your WM_CREATE  statement.  Don't forget that you 
  1524. cannot  use hwndFrame at this point. 
  1525.  
  1526.  
  1527. ΓòÉΓòÉΓòÉ 8.4. Movement ΓòÉΓòÉΓòÉ
  1528.  
  1529.  
  1530. ΓòÉΓòÉΓòÉ 8.4.1. Prohibiting Window Movement ΓòÉΓòÉΓòÉ
  1531.  
  1532. There may be occasions when it is required to prohibit the movement of your 
  1533. main window during the course of your normal processing.  This could be 
  1534. achieved by subclassing the frame window, but an easier way of doing it is to 
  1535. call WinEnableWindow.  This also greys out Move  from the window's system menu. 
  1536.  
  1537. To prohibit movement 
  1538.  
  1539. To restore movement 
  1540.  
  1541.  
  1542. ΓòÉΓòÉΓòÉ 8.5. Parent ΓòÉΓòÉΓòÉ
  1543.  
  1544.  
  1545. ΓòÉΓòÉΓòÉ 8.5.1. Parent Window ΓòÉΓòÉΓòÉ
  1546.  
  1547. To find a window's parent, for example, your client window's parent, i.e. frame 
  1548. window, call WinQueryWindow. 
  1549.  
  1550.  
  1551. ΓòÉΓòÉΓòÉ 8.6. Position ΓòÉΓòÉΓòÉ
  1552.  
  1553.  
  1554. ΓòÉΓòÉΓòÉ 8.6.1. Centralising your Window ΓòÉΓòÉΓòÉ
  1555.  
  1556. To centralise your window use WinQuerySysValue to get the screen resolution, 
  1557. calculate the appropriate co-ordinates and call WinSetWindowPos. However, be 
  1558. aware of the prerequisites for starting with a predetermined size. 
  1559.  
  1560.  
  1561. ΓòÉΓòÉΓòÉ 8.6.2. Keeping your Child Window on Top ΓòÉΓòÉΓòÉ
  1562.  
  1563. If you have a requirement to keep your child window visible whilst you use your 
  1564. main window, maybe in order to keep your application's status in view or for a 
  1565. tool palette, then make the child window's parent HWND_DESKTOP, and then use 
  1566. WinSetOwner  to make the child's owner the application's main window. 
  1567.  
  1568.  
  1569. ΓòÉΓòÉΓòÉ 8.6.3. Keeping your Main Window on Top ΓòÉΓòÉΓòÉ
  1570.  
  1571. Sometimes it may be necessary to keep your window in view at all times, i.e. on 
  1572. top of all other windows.  A very simple way of doing this is to start a timer 
  1573. and in your WM_TIMER  message processing for your client window make a call to 
  1574. WinSetWindowPos using the SWP_ZORDER option. 
  1575.  
  1576. Use WinStopTimer to stop the timer when you close down your application, or 
  1577. before if it is no longer required. 
  1578.  
  1579.  
  1580. ΓòÉΓòÉΓòÉ 8.6.4. Positioning on Screens with Different Resolution ΓòÉΓòÉΓòÉ
  1581.  
  1582. If you use absolute values when initialising the size of your window and then 
  1583. run your application on a machine which has a screen of different resolution, 
  1584. you may find that your window overlaps the screen, or appears in an otherwise 
  1585. unexpected position.  To overcome this you should not use absolute values but 
  1586. ask the system for the screen dimensions first by using WinQuerySysValue.  This 
  1587. will give you back the correct number of pels for the screen you are running 
  1588. under.  You can then use these values in WinSetWindowPos  to set your window's 
  1589. size and position correctly. 
  1590.  
  1591. As an example, if you wanted your window to occupy the entire screen  use the 
  1592. sample code, but make sure you include a frame creation flag of FCF_NOBYTEALIGN 
  1593. when you create your window otherwise it will align on eight pel boundaries and 
  1594. not fit the screen exactly.  If you do not wish your window to be this large 
  1595. then of course you can set the ScrWidth and ScrHeight variables to any suitable 
  1596. values and, if necessary centralise it. 
  1597.  
  1598.  
  1599. ΓòÉΓòÉΓòÉ 8.6.5. Restoring to a Fixed Size or Position ΓòÉΓòÉΓòÉ
  1600.  
  1601. If you always want your window to be set to a particular size and/or position 
  1602. when it is restored then you can use the WinSetWindowUShort  function with the 
  1603. relevant QWS_*RESTORE  value(s) in your WM_MINMAXFRAME case statement. 
  1604.  
  1605.  o QWS_XRESTORE - The X coordinate of the position to which the window is 
  1606.    restored 
  1607.  
  1608.  o QWS_YRESTORE - The Y coordinate of the position to which the window is 
  1609.    restored 
  1610.  
  1611.  o QWS_CXRESTORE - The width to which the window is restored 
  1612.  
  1613.  o QWS_CYRESTORE - The height to which the window is restored 
  1614.  
  1615.  
  1616. ΓòÉΓòÉΓòÉ 8.6.6. Starting in the Background ΓòÉΓòÉΓòÉ
  1617.  
  1618. To start with your window in the background so that it doesn't take the focus 
  1619. away from you use WinSetWindowPos with Behind set to HWND_BOTTOM and SWP_ZORDER 
  1620. as one of the options. 
  1621.  
  1622.  
  1623. ΓòÉΓòÉΓòÉ 8.6.7. Starting with a Predetermined Window Size and Position ΓòÉΓòÉΓòÉ
  1624.  
  1625. If you do not wish your window size and position to be set by Presentation 
  1626. Manager then in your WinCreateStdWindow  call do not specify the style 
  1627. WS_VISIBLE, and do not specify the frame creation flag FCF_SHELLPOSITION. 
  1628. Instead, follow your WinCreateStdWindow call with a call to WinSetWindowPos. 
  1629.  
  1630. Ensure that you always use SWP_SIZE | SWP_MOVE on the WinSetWindowPos call 
  1631. otherwise your size and start position will not be honoured. Also, use 
  1632. SWP_ACTIVATE to give your window the focus. 
  1633.  
  1634. Note:  A common mistake in this area is to use FCF_SHELLPOSITION, which is 
  1635.        included with FCF_STANDARD, and trap the WM_CREATE  message with the aim 
  1636.        of resizing the window.  But, Presentation Manager acts on the 
  1637.        FCF_SHELLPOSITION  after the WM_CREATE message and so your size and 
  1638.        position is overwritten. 
  1639.  
  1640.  
  1641. ΓòÉΓòÉΓòÉ 8.7. Saving State ΓòÉΓòÉΓòÉ
  1642.  
  1643.  
  1644. ΓòÉΓòÉΓòÉ 8.7.1. Saving your Application's Current State ΓòÉΓòÉΓòÉ
  1645.  
  1646. If you have a requirement to save your application's current state of execution 
  1647. then you can make use of the WM_SAVEAPPLICATION  message. This message gets 
  1648. dispatched to your client window procedure when the user requests Save... from 
  1649. the Desktop Manager. You may want to save several different types of data but 
  1650. probably the most common is the window's size and position on the desktop. 
  1651.  
  1652. The sample code shows how to save  the application's size and position in 
  1653. OS2.INI  and restore  next time it starts. 
  1654.  
  1655.  
  1656. ΓòÉΓòÉΓòÉ 8.8. Size ΓòÉΓòÉΓòÉ
  1657.  
  1658.  
  1659. ΓòÉΓòÉΓòÉ 8.8.1. Controlling Window Size ΓòÉΓòÉΓòÉ
  1660.  
  1661. Presentation Manager will not allow the user to size a window smaller than 
  1662. about 3.5 centimetres wide (using 8514/A).  If you have a requirement to do 
  1663. this then you must subclass the frame of the standard window and process the 
  1664. WM_QUERYTRACKINFO message. 
  1665.  
  1666. You can, of course, extend this to ensure that your window is always square, or 
  1667. never smaller or greater than a certain size. 
  1668.  
  1669.  
  1670. ΓòÉΓòÉΓòÉ 8.8.2. Detecting Minimize/Maximize ΓòÉΓòÉΓòÉ
  1671.  
  1672. To check if your window is about to be minimized or maximized then trap your 
  1673. WM_MINMAXFRAME message. 
  1674.  
  1675.  
  1676. ΓòÉΓòÉΓòÉ 8.8.3. Minimizing your Window ΓòÉΓòÉΓòÉ
  1677.  
  1678. If you need to minimize your window automatically from your client's window 
  1679. procedure call WinSetWindowPos. 
  1680.  
  1681.  
  1682. ΓòÉΓòÉΓòÉ 8.8.4. Obtaining Window Size ΓòÉΓòÉΓòÉ
  1683.  
  1684. To obtain the size of a window use the WinQueryWindowRect function. For 
  1685. top-level windows this will return the values in screen coordinates. For child 
  1686. windows the coordinates will be in parent coordinates.  If you need to query 
  1687. the screen coordinates of child windows, which your client area is (child of 
  1688. FRAME), follow the WinQueryWindowRect call with a call to WinMapWindowPoints. 
  1689.  
  1690.  
  1691. ΓòÉΓòÉΓòÉ 8.8.5. Prohibiting Window Minimization/Maximization ΓòÉΓòÉΓòÉ
  1692.  
  1693. To prevent the user from minimizing or maximizing your window, assuming you 
  1694. have FCF_MINMAX defined for the window, use WinEnableWindow with FALSE. To 
  1695. allow it again use TRUE. 
  1696.  
  1697.  
  1698. ΓòÉΓòÉΓòÉ 8.8.6. Prohibiting Window Sizing ΓòÉΓòÉΓòÉ
  1699.  
  1700. There may be occasions when it is required to prohibit the sizing of your main 
  1701. window during the course of your normal processing.  This can be achieved by 
  1702. changing the window's style from FS_SIZEBORDER to FS_DLGBORDER using 
  1703. WinSetWindowULong.  This also greys out Size  from the window's system menu. 
  1704.  
  1705. Another way of doing this is to use WinSetWindowBits. 
  1706.  
  1707. You will also need a call to WinInvalidateRect  to ensure the frame is updated 
  1708. immediately. 
  1709.  
  1710. To prohibit sizing using WinSetWindowULong 
  1711.  
  1712. To restore sizing using WinSetWindowULong 
  1713.  
  1714. To prohibit sizing using WinSetWindowBits 
  1715.  
  1716. To restore sizing using WinSetWindowBits 
  1717.  
  1718.  
  1719. ΓòÉΓòÉΓòÉ 8.8.7. Restoring to a Fixed Size or Position ΓòÉΓòÉΓòÉ
  1720.  
  1721. If you always want your window to be set to a particular size and/or position 
  1722. when it is restored then you can use the WinSetWindowUShort  function with the 
  1723. relevant QWS_*RESTORE  value(s) in your WM_MINMAXFRAME case statement. 
  1724.  
  1725.  o QWS_XRESTORE - The X coordinate of the position to which the window is 
  1726.    restored 
  1727.  
  1728.  o QWS_YRESTORE - The Y coordinate of the position to which the window is 
  1729.    restored 
  1730.  
  1731.  o QWS_CXRESTORE - The width to which the window is restored 
  1732.  
  1733.  o QWS_CYRESTORE - The height to which the window is restored 
  1734.  
  1735.  
  1736. ΓòÉΓòÉΓòÉ 8.8.8. Starting Minimized or Maximized ΓòÉΓòÉΓòÉ
  1737.  
  1738. To create a window in its minimized or maximized state use SWP_MINIMIZE or 
  1739. SWP_MAXIMIZE respectively in your WinSetWindowPos call. 
  1740.  
  1741.  
  1742. ΓòÉΓòÉΓòÉ 8.8.9. Starting with a Predetermined Window Size and Position ΓòÉΓòÉΓòÉ
  1743.  
  1744. If you do not wish your window size and position to be set by Presentation 
  1745. Manager then in your WinCreateStdWindow  call do not specify the style 
  1746. WS_VISIBLE, and do not specify the frame creation flag FCF_SHELLPOSITION. 
  1747. Instead, follow your WinCreateStdWindow call with a call to WinSetWindowPos. 
  1748.  
  1749. Ensure that you always use SWP_SIZE | SWP_MOVE on the WinSetWindowPos call 
  1750. otherwise your size and start position will not be honoured. Also, use 
  1751. SWP_ACTIVATE to give your window the focus. 
  1752.  
  1753. Note:  A common mistake in this area is to use FCF_SHELLPOSITION, which is 
  1754.        included with FCF_STANDARD, and trap the WM_CREATE  message with the aim 
  1755.        of resizing the window.  But, Presentation Manager acts on the 
  1756.        FCF_SHELLPOSITION  after the WM_CREATE message and so your size and 
  1757.        position is overwritten. 
  1758.  
  1759.  
  1760. ΓòÉΓòÉΓòÉ 8.9. Subclassing ΓòÉΓòÉΓòÉ
  1761.  
  1762. For examples of subclassing see - 
  1763.  
  1764.  Controlling Window Size 
  1765.  Numeric Data Only 
  1766.  
  1767.  
  1768. ΓòÉΓòÉΓòÉ 8.10. Title ΓòÉΓòÉΓòÉ
  1769.  
  1770.  
  1771. ΓòÉΓòÉΓòÉ 8.10.1. Changing the Window Title ΓòÉΓòÉΓòÉ
  1772.  
  1773. To change the window title use WinSetWindowText. 
  1774.  
  1775.  
  1776. ΓòÉΓòÉΓòÉ 8.10.2. EXE Name Appearing in Title Bar ΓòÉΓòÉΓòÉ
  1777.  
  1778. This happens because you have specified FCF_TASKLIST for your window. See 
  1779. Adding Program Title to the Task List. 
  1780.  
  1781.  
  1782. ΓòÉΓòÉΓòÉ 8.11. Sample Programs ΓòÉΓòÉΓòÉ
  1783.  
  1784.  
  1785. ΓòÉΓòÉΓòÉ 8.11.1. Skeleton Program ΓòÉΓòÉΓòÉ
  1786.  
  1787. This skeleton program builds a small sizable client window and centralises it 
  1788. on the desktop.  It contains an action bar with an Exit  option, minimize, 
  1789. maximize and the system menu. I have used this as the base for all the other 
  1790. sample programs. 
  1791.  
  1792.  HINTS.C - C source file 
  1793.  HINTS.H - Header file 
  1794.  HINTS.L - Link control file 
  1795.  HINTS.DEF - Module definition file 
  1796.  HINTS.RC - Resource file 
  1797.  HINTS - Make file 
  1798.  Run program (Launch doesn't work in 1.3 yet!) 
  1799.  
  1800.  
  1801. ΓòÉΓòÉΓòÉ 8.11.2. Sample Program - Windows ΓòÉΓòÉΓòÉ
  1802.  
  1803. The sample program does not have any real function but was written just to test 
  1804. that all the tips in this section do work. However, as it currently stands it 
  1805. does not incorporate all the tips as some are obviously mutually exclusive. 
  1806. Having said that though, it does open the main client window at the restored 
  1807. position and the child window to its right.  The main window displays the 
  1808. process ID of the active window and the child window just displays a text 
  1809. string. 
  1810.  
  1811. If you press button 1 in the main window it becomes fixed, i.e. you cannot move 
  1812. or size it, the minimize and maximize buttons are disabled and the title text 
  1813. is changed. Pressing button 2 returns it to its moveable state. 
  1814.  
  1815.  HINTS.C - C source file 
  1816.  HINTS.H - Header file 
  1817.  HINTS.L - Link control file 
  1818.  HINTS.DEF - Module definition file 
  1819.  HINTS.RC - Resource file 
  1820.  HINTS - Make file 
  1821.  Run program (Launch doesn't work in 1.3 yet!) 
  1822.  
  1823.  
  1824. ΓòÉΓòÉΓòÉ 9. Sample Programs ΓòÉΓòÉΓòÉ
  1825.  
  1826. The following programs were written purely to verify all the tips given in this 
  1827. volume. The programs themselves do not have any function other than to perform 
  1828. this verification, usually by pressing a mouse button or push button. 
  1829.  
  1830.  Skeleton Program 
  1831.  General Window Processing 
  1832.  General Dialog Box Processing 
  1833.  MLE and Radio Buttons 
  1834.  Listboxes 
  1835.  Menus and Task Manager 
  1836.  Mouse and Pointer Control 
  1837.  Presentation Parameters 
  1838.  
  1839.  
  1840. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1841.  
  1842. CONTROL "", ID_ENTRY2, 67, 57, 36, 8, WC_ENTRYFIELD, ES_LEFT |
  1843.         ES_MARGIN | WS_TABSTOP | WS_VISIBLE
  1844.         CTLDATA 8, 5, 0, 0
  1845.  
  1846.  
  1847. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1848.  
  1849. /*---------------------------*/
  1850. /* Change focus to ID_ENTRY2 */
  1851. /*---------------------------*/
  1852.  
  1853. WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
  1854.  
  1855. /*------------------------------------------------*/
  1856. /* Position cursor between 1st and 2nd characters */
  1857. /*------------------------------------------------*/
  1858.  
  1859. WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  1860.            MPFROM2SHORT(1, 1), 0L);
  1861.  
  1862. /*------------------------------------------------*/
  1863. /* Position cursor between 1st and 2nd characters */
  1864. /* but mark 2nd and 3rd characters only           */
  1865. /*------------------------------------------------*/
  1866.  
  1867. WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  1868.            MPFROM2SHORT(1, 3), 0L);
  1869.  
  1870. /*---------------------------------------------------------*/
  1871. /* Position cursor at start of field but mark entire field */
  1872. /*---------------------------------------------------------*/
  1873.  
  1874. WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  1875.            MPFROM2SHORT(0, 5), 0L);
  1876.  
  1877.  
  1878. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1879.  
  1880. CONTROL "", ID_PASSWORD, 77, 37, 45, 8, WC_ENTRYFIELD, ES_LEFT |
  1881.         ES_UNREADABLE | ES_MARGIN | WS_TABSTOP | WS_VISIBLE
  1882.  
  1883.  
  1884. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1885.  
  1886. /*-----------------------------------------------*/
  1887. /* This code sets the password length to 8 bytes */
  1888. /*-----------------------------------------------*/
  1889.  
  1890. WinSendMsg(WinWindowFromID(hwndDlg, ID_PASSWORD),
  1891.            EM_SETTEXTLIMIT,
  1892.            MRFROMSHORT(8),
  1893.            NULL);
  1894.  
  1895.  
  1896. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1897.  
  1898. /*---------------------------------------------*/
  1899. /* First define your numeric procedure and a   */
  1900. /* pointer to the public entry field procedure */
  1901. /*---------------------------------------------*/
  1902.  
  1903. typedef struct _CHARMSG *PCHARMSG;  // Not defined in PMWIN.H
  1904.  
  1905. MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  1906.  
  1907. PFNWP   EntryFieldProc;             // Public Entry Field procedure
  1908.  
  1909.  
  1910. /*---------------------------------------------*/
  1911. /* In your WM_INITDLG case statement save the  */
  1912. /* address of the public entry field procedure */
  1913. /*---------------------------------------------*/
  1914.  
  1915. case WM_INITDLG:
  1916.   EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY2),
  1917.                                      NumericProc);
  1918.  
  1919.  
  1920. /*----------------------------------------------*/
  1921. /* The following is the actual window procedure */
  1922. /*----------------------------------------------*/
  1923.  
  1924. MRESULT EXPENTRY  NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  1925. {
  1926.   PCHARMSG  p;
  1927.   if (msg == WM_CHAR)                              // If this is a char msg
  1928.   {
  1929.     p = CHARMSG(&msg);                             // Address char structure
  1930.     if ((p->fs & (KC_KEYUP|KC_CHAR)) == KC_CHAR)   // ONLY key down transitions */
  1931.     {
  1932.       if ((p->chr < 0x30 || p->chr > 0x39) &&      // Not numeric
  1933.           (p->chr != 8) &&                         // Not backspace
  1934.           (p->chr != 9) &&                         // Not tab
  1935.           (p->chr != 0x2D) &&                      // Not -
  1936.           (p->chr != 13))                          // Not enter
  1937.       {
  1938.         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1939.         return (MRESULT)TRUE;
  1940.       }
  1941.     }
  1942.   }
  1943.                                      // Call public entry field procedure
  1944.   return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
  1945. }
  1946.  
  1947.  
  1948. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1949.  
  1950. /*----------------------------------*/
  1951. /* Get password and store in szPswd */
  1952. /*----------------------------------*/
  1953.  
  1954. WinQueryWindowText(WinWindowFromID(hwndDlg, ID_PASSWORD),
  1955.                    sizeof(szPswd), szPswd);
  1956.  
  1957.  
  1958. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1959.  
  1960. /*----------------------------------*/
  1961. /* Get password and store in szPswd */
  1962. /*----------------------------------*/
  1963.  
  1964. WinQueryDlgItemText(hwndDlg, ID_PASSWORD,
  1965.                     sizeof(szPswd), szPswd);
  1966.  
  1967.  
  1968. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1969.  
  1970. /*----------------------------------*/
  1971. /* Get window ID and store in id    */
  1972. /*   FALSE for unsigned value       */
  1973. /*   TRUE for possible signed value */
  1974. /*----------------------------------*/
  1975.  
  1976. WinQueryDlgItemShort(hwndDlg, ID_ENTRY1, &id, FALSE);
  1977.  
  1978.  
  1979. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1980.  
  1981. WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY1),
  1982.            EM_SETREADONLY,
  1983.            (MPARAM)TRUE,
  1984.            NULL);
  1985.  
  1986.  
  1987. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1988.  
  1989. CONTROL "", ID_ENTRY1, 77, 25, 100, 16, WC_ENTRYFIELD, ES_CENTER |
  1990.         ES_AUTOSCROLL | ES_MARGIN | ES_READONLY | WS_VISIBLE
  1991.  
  1992.  
  1993. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  1994.  
  1995. WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "Text");
  1996.  
  1997. /*---------------------------------------------------*/
  1998. /* To clear an entry field write a null string to it */
  1999. /*---------------------------------------------------*/
  2000.  
  2001. WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "");
  2002.  
  2003.  
  2004. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2005.  
  2006. WinSetDlgItemText(hwndDlg, ID_ENTRY1, "Text");
  2007.  
  2008. /*---------------------------------------------------*/
  2009. /* To clear an entry field write a null string to it */
  2010. /*---------------------------------------------------*/
  2011.  
  2012. WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
  2013.  
  2014.  
  2015. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2016.  
  2017. WinSetDlgItemShort(hwndDlg, ID_ENTRY1, id, FALSE);
  2018.  
  2019.  
  2020. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2021.  
  2022. CHAR    *Country,
  2023.         *Capital;
  2024.  
  2025.  
  2026.  
  2027. case WM_CONTROL:
  2028.   switch(SHORT1FROMMP(mp1))
  2029.   {
  2030.     case ID_OLISTBOX:
  2031.       switch(SHORT2FROMMP(mp1))
  2032.       {
  2033.         case LN_SELECT:
  2034.           Oidx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX,
  2035.                                           LM_QUERYSELECTION, 0L, 0L);
  2036.  
  2037.           WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  2038.                             MPFROM2SHORT(Oidx, sizeof(szListBuff)),
  2039.                             MPFROMP(szListBuff));
  2040.  
  2041.           Country = strtok(szListBuff, "\t");
  2042.           Capital = strtok(NULL, "\t");
  2043.  
  2044.           WinSetDlgItemText(hwndDlg, ID_ENTRY1, Capital);
  2045.           WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
  2046.           WinSetDlgItemText(hwndDlg, ID_ENTRY3, Country);
  2047.           break;
  2048.  
  2049.         default:
  2050.           break;
  2051.       }
  2052.       break;
  2053.   }
  2054.  
  2055.  
  2056. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2057.  
  2058. hwndList = WinWindowFromID(hwndDlg, ID_SLISTBOX);
  2059. WinDestroyWindow(WinWindowFromID(hwndList, 0xC001));
  2060.  
  2061.  
  2062. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2063.  
  2064. case WM_MEASUREITEM:
  2065.   if (first)
  2066.   {
  2067.     strcpy(font, "24.Helv");
  2068.     WinSetPresParam(WinWindowFromID(hwndDlg, ID_OLISTBOX),
  2069.                     PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  2070.     first = FALSE;
  2071.   }
  2072.   hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
  2073.   ;
  2074.   ;
  2075.   ;
  2076.   WinReleasePS(hps);
  2077.   return MRFROM2SHORT(cyText, cxText);
  2078.  
  2079.  
  2080. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2081.  
  2082. pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2083.                                       LM_QUERYITEMHANDLE,
  2084.                                       MPFROMSHORT(Idx), NULL);
  2085. DosFreeSeg(SELECTOROF(pDB_Data));
  2086.  
  2087.  
  2088. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2089.  
  2090. /*----------------------------------------------------------*/
  2091. /* By default the start position for drawing in the item    */
  2092. /* rectangle is 1 so if we have been scrolled then xLeft on */
  2093. /* input will be some other value depending on how much we  */
  2094. /* have been scrolled. All we need to do to allow scrolling */
  2095. /* is adjust xLeft by the scrolled amount.                  */
  2096. /*----------------------------------------------------------*/
  2097.  
  2098. if (pOwner->rclItem.xLeft != 1)
  2099.   rc.xLeft = rc.xRight + pOwner->rclItem.xLeft - 1;
  2100. else
  2101.   rc.xLeft = rc.xRight;
  2102.  
  2103.  
  2104. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2105.  
  2106. ULONG  KeyValue;
  2107.  
  2108.  
  2109.  
  2110. /*------------------------------------------------*/
  2111. /* If all we want to do is store the key value... */
  2112. /*------------------------------------------------*/
  2113.  
  2114. for (Idx = 0; Idx < 26; Idx++)
  2115. {
  2116.   WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
  2117.                     MPFROMSHORT(LIT_END),
  2118.                     MPFROMP(szCountry[Idx]));
  2119.  
  2120.                        /*----------------------------------------*/
  2121.                        /* szCountry and KeyValue would normally  */
  2122.   KeyValue = Idx + 1;  /* be obtained from a database.           */
  2123.                        /* In this case give a key value of 1->26 */
  2124.                        /*----------------------------------------*/
  2125.  
  2126.   WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
  2127.                     (MPARAM)Idx, (MPARAM)KeyValue);
  2128. }
  2129.  
  2130.  
  2131.  
  2132. /*------------------------------------------------*/
  2133. /* If we need to save a pointer to a structure... */
  2134. /*------------------------------------------------*/
  2135.  
  2136. SEL  sel;
  2137. typedef struct _DBDATA
  2138. {
  2139.   USHORT Key;
  2140.   CHAR   Capital[20];
  2141. } DBDATA, FAR *PDBDATA;
  2142. PDBDATA pDB_Data;
  2143.  
  2144.  
  2145.  
  2146. for (Idx = 0; Idx < 26; Idx++)
  2147. {
  2148.    WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
  2149.                      MPFROMSHORT(LIT_END),
  2150.                      MPFROMP(szCountry[Idx]));
  2151.    DosAllocSeg(22, &sel, 0);
  2152.    pDB_Data = MAKEP(sel, 0);
  2153.    pDB_Data->Key = Idx + 1;
  2154.    strcpy(pDB_Data->Capital, szCapital[Idx]);
  2155.    WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
  2156.                      (MPARAM)Idx, MPFROMP(pDB_Data));
  2157. }
  2158.  
  2159.  
  2160. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2161.  
  2162. /*--------------------------------------------*/
  2163. /* If we are just retrieving the key value... */
  2164. /*--------------------------------------------*/
  2165.  
  2166. case LN_SELECT:
  2167.   Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2168.                                  LM_QUERYSELECTION, 0L, 0L);
  2169.                                     /*---------------------------------*/
  2170.   if (Idx != LIT_NONE)              /* If nothing selected then ignore */
  2171.   {                                 /*---------------------------------*/
  2172.  
  2173.     KeyValue = (ULONG)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2174.                                         LM_QUERYITEMHANDLE,
  2175.                                         MPFROMSHORT(Idx), NULL);
  2176.     WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)KeyValue, FALSE);
  2177.     ;
  2178.     ;
  2179.     ;
  2180.   }
  2181.   break;
  2182.  
  2183. /*--------------------------------------------------------------*/
  2184. /* Or, to retrieve all data associated with the listbox item... */
  2185. /*--------------------------------------------------------------*/
  2186.  
  2187. case LN_SELECT:
  2188.   Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2189.                                  LM_QUERYSELECTION, 0L, 0L);
  2190.                                     /*---------------------------------*/
  2191.   if (Idx != LIT_NONE)              /* If nothing selected then ignore */
  2192.   {                                 /*---------------------------------*/
  2193.  
  2194.     pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2195.                                           LM_QUERYITEMHANDLE,
  2196.                                           MPFROMSHORT(Idx), NULL);
  2197.     WinSetDlgItemText(hwndDlg, ID_ENTRY1, pDB_Data->Capital);
  2198.     WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)pDB_Data->Key, FALSE);
  2199.     ;
  2200.     ;
  2201.     ;
  2202.   }
  2203.   break;
  2204.  
  2205.  
  2206. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2207.  
  2208. SHORT  Idx;
  2209.  
  2210.  
  2211.  
  2212. /*----------------------*/
  2213. /* Delete selected item */
  2214. /*----------------------*/
  2215.  
  2216. WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEITEM,
  2217.                   MPFROMSHORT(Idx), NULL);
  2218.  
  2219.  
  2220. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2221.  
  2222. /*------------------*/
  2223. /* Delete all items */
  2224. /*------------------*/
  2225.  
  2226. WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEALL, NULL, NULL);
  2227.  
  2228.  
  2229. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2230.  
  2231. /*------------------*/
  2232. /* Deselect an item */
  2233. /*------------------*/
  2234.  
  2235. WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
  2236.                   MPFROMSHORT(Idx), (MPARAM)FALSE);
  2237.  
  2238.  
  2239. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2240.  
  2241. SHORT  Idx;
  2242. static PSZ  szCountry[] = {"Austria",   "Belgium",   "Canada",
  2243.                            "Denmark",   "Egypt",     "Finland",
  2244.                            "Greece",    "Hungary",   "India",
  2245.                            "Japan",     "Kenya",     "Libya",
  2246.                            "Morocco",   "Nigeria",   "Oman",
  2247.                            "Peru",      "Qatar",     "Romania",
  2248.                            "Spain",     "Turkey",    "Uruguay",
  2249.                            "Venezuela", "Wales",     "Xanxere",
  2250.                            "Yemen",     "Zambia"};
  2251.  
  2252.  
  2253. for (Idx = 0; Idx < 26; Idx++)
  2254. {
  2255.    WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
  2256.                      MPFROMSHORT(LIT_END),
  2257.                      MPFROMP(szCountry[Idx]));
  2258. }
  2259.  
  2260.  
  2261. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2262.  
  2263. SHORT  Midx;
  2264.  
  2265.  
  2266.  
  2267.  
  2268. case ID_PROCMULT:
  2269.   Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,        //Get first
  2270.                                   LM_QUERYSELECTION,
  2271.                                   (MPARAM)LIT_FIRST, 0L);
  2272.   while(Midx != LIT_NONE)
  2273.   {
  2274.     WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_QUERYITEMTEXT,  // Get its text
  2275.                       MPFROM2SHORT(Midx, sizeof(szCtry)),
  2276.                       MPFROMP(szCtry));
  2277.     WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry);             // Display it
  2278.     WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_SELECTITEM,     // Deselect it
  2279.                       MPFROMSHORT(Midx), (MPARAM)FALSE);
  2280.  
  2281.                                        /*----------------------------------*/
  2282.                                        /* Slow down so we can see it happen*/
  2283.                                        /*                                  */
  2284.     DosSleep(1000L);                   /* DON'T DO THIS IN PM PROGRAMS     */
  2285.                                        /* AFFECTS PERFORMANCE SEVERELY     */
  2286.                                        /*----------------------------------*/
  2287.  
  2288.     Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,      // Get next
  2289.                                     LM_QUERYSELECTION,
  2290.                                     (MPARAM)Midx, 0L);
  2291.   }
  2292.   WinSetDlgItemText(hwndDlg, ID_ENTRY3, "Done");               // All done
  2293.   return FALSE;
  2294.  
  2295.  
  2296. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2297.  
  2298. /*-------------------*/
  2299. /* Select first item */
  2300. /*-------------------*/
  2301.  
  2302. WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
  2303.                   MPFROMSHORT(0), (MPARAM)TRUE);
  2304.  
  2305.  
  2306. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2307.  
  2308. SHORT Idx;
  2309. CHAR  szCtry[10];
  2310.  
  2311.  
  2312.  
  2313. case WM_CONTROL:
  2314.   switch(SHORT1FROMMP(mp1))
  2315.   {
  2316.     case ID_SLISTBOX:
  2317.       switch(SHORT2FROMMP(mp1))
  2318.       {
  2319.         case LN_SELECT:
  2320.           Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  2321.                                          LM_QUERYSELECTION, 0L, 0L);
  2322.  
  2323.           WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_QUERYITEMTEXT,
  2324.                             MPFROM2SHORT(Idx, sizeof(szCtry)),
  2325.                             MPFROMP(szCtry));
  2326.           ;
  2327.           ;
  2328.           ;
  2329.           break;
  2330.  
  2331.         default:
  2332.           break;
  2333.       }
  2334.       break;
  2335.   }
  2336.  
  2337.  
  2338. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2339.  
  2340. case WM_DRAWITEM:
  2341.   ;
  2342.   ;
  2343.   ;
  2344.   if ((!pOwner->fsState) ||                     // Unselected
  2345.       (pOwner->idItem == 5))                    // Don't allow Finland
  2346.   {
  2347.     GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
  2348.     GpiSetColor(pOwner->hps, CLR_YELLOW);
  2349.   }
  2350.   else                                          // Selected
  2351.   {
  2352.     GpiSetBackColor(pOwner->hps, CLR_YELLOW);
  2353.     GpiSetColor(pOwner->hps, CLR_DARKGREEN);
  2354.   }
  2355.   ;
  2356.   ;
  2357.   ;
  2358.   pOwner->fsStateOld = pOwner->fsState = 0;     // Don't let PM hilite
  2359.   return (MRESULT)TRUE;                         // Don't let PM draw
  2360.  
  2361.  
  2362. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2363.  
  2364. /*-----------------------------------------------------------------*/
  2365. /* The scroll bar ID for a listbox's vertical scroll bar is 0xC001 */
  2366. /* and for a horizontal scroll bar is 0xC002.                      */
  2367. /* This is, however, undocumented so use with caution.             */
  2368. /*-----------------------------------------------------------------*/
  2369.  
  2370. hwndVbar = WinWindowFromID(hwndListbox, 0xC001);
  2371. hwndHbar = WinWindowFromID(hwndListbox, 0xC002);
  2372.  
  2373. /*-----------------------------------------------------------------*/
  2374. /* Alternatively, enumerate the listbox's windows. This way it     */
  2375. /* doesn't matter if the scroll bar IDs change in a later release. */
  2376. /*-----------------------------------------------------------------*/
  2377.  
  2378. hwndListbox = WinWindowFromID(hwndDlg, ID_SLISTBOX);
  2379. hEnum = WinBeginEnumWindows(hwndListbox);
  2380. while (hwndChild = WinGetNextWindow(hEnum))
  2381. {                               /*------------------------------*/
  2382.                                 /* SBS_VERT = 1L, SBS_HORZ = 0L */
  2383.                                 /*------------------------------*/
  2384.   if (WinQueryWindowULong(hwndChild, QWL_STYLE) & SBS_VERT)
  2385.     hwndVbar = hwndChild;
  2386.   else
  2387.     hwndHbar = hwndChild;
  2388. }
  2389. WinEndEnumWindows(hEnum);
  2390.  
  2391.  
  2392. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2393.  
  2394. CHAR    *Country,
  2395.         *Capital;
  2396.  
  2397.  
  2398.  
  2399. case WM_INITDLG:
  2400.   ;
  2401.   ;
  2402.   for (Idx = 0; Idx < 26; Idx++)
  2403.   {
  2404.      strcpy(szListBuff, szCountry[Idx]);
  2405.      strcat(szListBuff, "\t");                // Insert a TAB character
  2406.      strcat(szListBuff, szCapital[Idx]);
  2407.      WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_INSERTITEM,
  2408.                        MPFROMSHORT(LIT_END),
  2409.                        MPFROMP(szListBuff));
  2410.   }
  2411.   ;
  2412.   ;
  2413.   break;
  2414.  
  2415. case WM_DRAWITEM:
  2416.   pOwner = (POWNERITEM)mp2;
  2417.   rc.xRight  = pOwner->rclItem.xRight/2;   // Split into two and draw
  2418.   rc.xLeft   = pOwner->rclItem.xLeft;      // item in left rectangle
  2419.   rc.yTop    = pOwner->rclItem.yTop;
  2420.   rc.yBottom = pOwner->rclItem.yBottom;
  2421.  
  2422.   GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
  2423.  
  2424.   if (!pOwner->fsState)                         // Unselected
  2425.   {
  2426.     GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
  2427.     GpiSetColor(pOwner->hps, CLR_YELLOW);
  2428.   }
  2429.   else                                          // Selected
  2430.   {
  2431.     GpiSetBackColor(pOwner->hps, CLR_YELLOW);
  2432.     GpiSetColor(pOwner->hps, CLR_DARKGREEN);
  2433.   }
  2434.  
  2435.   WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  2436.                     MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
  2437.                     MPFROMP(szListBuff));
  2438.  
  2439.   Country = strtok(szListBuff, "\t");
  2440.   Capital = strtok(NULL, "\t");
  2441.  
  2442.   WinDrawText(pOwner->hps, strlen(Country),
  2443.               Country, &rc, 0L, 0L,
  2444.               DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
  2445.  
  2446.   rc.xLeft  = rc.xRight;                   // Draw next item in right rectangle
  2447.   rc.xRight = pOwner->rclItem.xRight;
  2448.  
  2449.   WinDrawText(pOwner->hps, strlen(Capital),
  2450.               Capital, &rc, 0L, 0L,
  2451.               DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
  2452.  
  2453.   ;
  2454.   ;
  2455.   ;
  2456.   break;
  2457.  
  2458.  
  2459. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2460.  
  2461. POINTL  points[TXTBOX_COUNT];
  2462.  
  2463.  
  2464.  
  2465. case WM_MEASUREITEM:
  2466.   ;
  2467.   ;
  2468.   ;
  2469.   WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  2470.                     MPFROM2SHORT(Idx, sizeof(szListBuff)),
  2471.                     MPFROMP(szListBuff));
  2472.   GpiQueryTextBox(hps, (LONG)strlen(szListBuff), szListBuff,
  2473.                   TXTBOX_COUNT, points);
  2474.                   /*-------------------------------------------------*/
  2475.                   /* May need to add on a bit to cxText to ensure    */
  2476.                   /* the entire item can be read when fully scrolled */
  2477.                   /*-------------------------------------------------*/
  2478.   cxText = (USHORT)points[TXTBOX_TOPRIGHT].x + 20;
  2479.   ;
  2480.   ;
  2481.   ;
  2482.   return MRFROM2SHORT(cyText, cxText);
  2483.  
  2484.  
  2485. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2486.  
  2487. POWNERITEM   pOwner;
  2488. RECTL        rc;
  2489.  
  2490.  
  2491.  
  2492. case WM_DRAWITEM:
  2493.   pOwner = (POWNERITEM)mp2;
  2494.   rc.xRight  = pOwner->rclItem.xRight;
  2495.   rc.xLeft   = pOwner->rclItem.xLeft;
  2496.   rc.yTop    = pOwner->rclItem.yTop;
  2497.   rc.yBottom = pOwner->rclItem.yBottom;
  2498.  
  2499.   GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
  2500.  
  2501.   if (!pOwner->fsState)                         // Unselected
  2502.   {
  2503.     GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
  2504.     GpiSetColor(pOwner->hps, CLR_YELLOW);
  2505.   }
  2506.   else                                          // Selected
  2507.   {
  2508.     GpiSetBackColor(pOwner->hps, CLR_YELLOW);
  2509.     GpiSetColor(pOwner->hps, CLR_DARKGREEN);
  2510.   }
  2511.  
  2512.   WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  2513.                     MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
  2514.                     MPFROMP(szListBuff));
  2515.  
  2516.   WinDrawText(pOwner->hps, strlen(szListBuff),
  2517.               szListBuff, &rc, 0L, 0L,
  2518.               DT_CENTER | DT_TEXTATTRS | DT_ERASERECT);
  2519.  
  2520.   pOwner->fsStateOld = pOwner->fsState = 0;     // Don't let PM hilite
  2521.   return (MRESULT)TRUE;                         // Don't let PM draw
  2522.  
  2523.  
  2524. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2525.  
  2526. HPS          hps;
  2527. FONTMETRICS  fm;
  2528. SHORT        cxText,
  2529.              cyText;
  2530.  
  2531.  
  2532.  
  2533. case WM_MEASUREITEM:
  2534.   hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
  2535.   GpiQueryFontMetrics(hps, (LONG)sizeof(FONTMETRICS), &fm);
  2536.   cyText = (SHORT)fm.lMaxBaselineExt;
  2537.   cxText = 0;
  2538.   WinReleasePS(hps);
  2539.   return MRFROM2SHORT(cyText, cxText);
  2540.  
  2541.  
  2542. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2543.  
  2544. WinSetDlgItemText(hwndDlg, ID_MULTILINE, "");
  2545.  
  2546.  
  2547. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2548.  
  2549. WinSetWindowText(WinWindowFromID(hwndDlg, ID_MULTILINE), "");
  2550.  
  2551.  
  2552. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2553.  
  2554. DosAllocSeg(0, &Selector, SEG_GETTABLE);        // Allocate 64K segment
  2555. Buffer = MAKEP(Selector, 0);                    // Get pointer to segment
  2556.  
  2557. DosOpen("C:\\CONFIG.SYS", &hFile, &Action,
  2558.         (ULONG)NULL,
  2559.         (USHORT)NULL,
  2560.         OPEN_ACTION_OPEN_IF_EXISTS,
  2561.         OPEN_FLAGS_SEQUENTIAL |
  2562.         OPEN_SHARE_DENYNONE   |
  2563.         OPEN_ACCESS_READONLY,
  2564.         (ULONG)NULL);
  2565. DosRead(hFile, Buffer, 65535L, &BytesRead);
  2566. DosClose(hFile);
  2567.  
  2568. WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
  2569.            MLM_SETIMPORTEXPORT, (MPARAM)Buffer,
  2570.            MPFROMLONG(65535L));
  2571.  
  2572. ipt = -1;              // Set insertion point for current cursor position
  2573.  
  2574. WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
  2575.            MLM_IMPORT, (MPARAM)&ipt,
  2576.            MPFROMLONG((LONG)BytesRead));
  2577.  
  2578. DosFreeSeg(Selector);
  2579.  
  2580.  
  2581. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2582.  
  2583. CHAR  font[11];
  2584.  
  2585.  
  2586. /*-------------------------*/
  2587. /* To set 12 point Courier */
  2588. /*-------------------------*/
  2589.  
  2590. strcpy(font, "12.Courier");
  2591. WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  2592.                 PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  2593.  
  2594. /*--------------------------*/
  2595. /* To set 8 point Helvetica */
  2596. /*--------------------------*/
  2597.  
  2598. strcpy(font, "8.Helv");
  2599. WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  2600.                 PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  2601.  
  2602.  
  2603. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2604.  
  2605. BITMAP   ID_LOCK   lock.bmp
  2606.  
  2607.  
  2608. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2609.  
  2610. /*-------------------------------*/
  2611. /* Define button paint procedure */
  2612. /*-------------------------------*/
  2613.  
  2614. VOID  Button_Paint(HWND, HPS, USHORT);
  2615.  
  2616.  
  2617.  
  2618. /*------------------------------------*/
  2619. /* Define pointer to button structure */
  2620. /*------------------------------------*/
  2621.  
  2622.   USERBUTTON      *ubtn;
  2623.  
  2624.  
  2625.  
  2626. /*-----------------------------*/
  2627. /* Handle the BN_PAINT message */
  2628. /*-----------------------------*/
  2629.  
  2630.     case WM_CONTROL:
  2631.       switch(HIUSHORT(mp1))
  2632.       {
  2633.         case BN_PAINT:
  2634.            switch(LOUSHORT(mp1))                       /* Which Button? */
  2635.            {
  2636.              case ID_USERBUTTON:
  2637.                ubtn = (USERBUTTON *)mp2;
  2638.                Button_Paint(ubtn->hwnd, ubtn->hps, ubtn->fsState);
  2639.                return (MRESULT)TRUE;
  2640.              default:
  2641.                 break;
  2642.            }
  2643.       }
  2644.       break;
  2645.  
  2646.  
  2647.  
  2648. /*------------------------*/
  2649. /* Handle the button push */
  2650. /*------------------------*/
  2651.  
  2652.     case WM_COMMAND:
  2653.       switch(SHORT1FROMMP(mp1))
  2654.       {
  2655.         ;
  2656.         ;
  2657.         ;
  2658.         case ID_USERBUTTON:
  2659.           DosBeep(500, 100);
  2660.           return FALSE;
  2661.         ;
  2662.         ;
  2663.         ;
  2664.  
  2665.  
  2666.  
  2667. /*------------------------*/
  2668. /* Button paint procedure */
  2669. /*------------------------*/
  2670.  
  2671. VOID Button_Paint(HWND hwnd, HPS hps, USHORT Status)
  2672. {
  2673.   RECTL   DestPt;
  2674.   HBITMAP hbm;
  2675.  
  2676.   /*------------------------------------------------------------------------*/
  2677.   /*                   Display the disk drive bitmap                        */
  2678.   /*                                                                        */
  2679.   /* hbm = WinGetSysBitmap(HWND_DESKTOP, SBMP_DRIVE);                       */
  2680.   /* WinQueryWindowRect(hwnd, &DestPt);                                     */
  2681.   /* WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, CLR_YELLOW, CLR_BLACK, */
  2682.   /*               (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);       */
  2683.   /*------------------------------------------------------------------------*/
  2684.  
  2685.  
  2686.   /*---------------------------------*/
  2687.   /* Load and display our own bitmap */
  2688.   /*---------------------------------*/
  2689.  
  2690.   hbm = GpiLoadBitmap(hps, NULL, ID_LOCK, 0L, 0L);
  2691.   WinQueryWindowRect(hwnd, &DestPt);
  2692.   WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, 0L, 0L,
  2693.                 (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);
  2694. }
  2695.  
  2696.  
  2697. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2698.  
  2699. ULONG  lStyle;
  2700.  
  2701. lStyle = WinQueryWindowULong(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE);
  2702.  
  2703. if (lStyle & BS_DEFAULT)
  2704. {
  2705.   /*-----------------------*/
  2706.   /* Button is the default */
  2707.   /*-----------------------*/
  2708. }
  2709.  
  2710.  
  2711. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2712.  
  2713. /*----------------------*/
  2714. /* Remove default style */
  2715. /*----------------------*/
  2716.  
  2717. WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT,
  2718.            (MPARAM)FALSE, NULL);
  2719.  
  2720.  
  2721. /*-------------------*/
  2722. /* Set default style */
  2723. /*-------------------*/
  2724.  
  2725. WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT,
  2726.            (MPARAM)TRUE, NULL);
  2727.  
  2728.  
  2729. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2730.  
  2731. /*----------------------*/
  2732. /* Remove default style */
  2733. /*----------------------*/
  2734.  
  2735. WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
  2736.                  0L, BS_DEFAULT);
  2737. WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
  2738.  
  2739.  
  2740. /*-------------------*/
  2741. /* Set default style */
  2742. /*-------------------*/
  2743.  
  2744. WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
  2745.                  BS_DEFAULT, BS_DEFAULT);
  2746. WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
  2747.  
  2748.  
  2749. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2750.  
  2751. /*-----------------------------*/
  2752. /* Change the dialog box title */
  2753. /*-----------------------------*/
  2754.  
  2755. WinSetWindowText(hwndDlg, "New Title");
  2756.  
  2757.  
  2758. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2759.  
  2760. /*-----------------------------*/
  2761. /* Change the dialog box title */
  2762. /*-----------------------------*/
  2763.  
  2764. WinSetDlgItemText(hwndDlg, FID_TITLEBAR, "New Title");
  2765.  
  2766.  
  2767. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2768.  
  2769. /*----------------------------------------*/
  2770. /* Change the text of push button ID_EXIT */
  2771. /*----------------------------------------*/
  2772.  
  2773. WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Quit");
  2774.  
  2775.  
  2776. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2777.  
  2778. /*---------------*/
  2779. /* To disable... */
  2780. /*---------------*/
  2781.  
  2782. WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), FALSE);
  2783.  
  2784. /*--------------*/
  2785. /* To enable... */
  2786. /*--------------*/
  2787.  
  2788. WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), TRUE);
  2789.  
  2790.  
  2791. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2792.  
  2793. USHORT  id;
  2794.  
  2795. /*---------------------------------*/
  2796. /* Find ID of the control ID_ENTRY */
  2797. /*---------------------------------*/
  2798.  
  2799. id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY), QWS_ID);
  2800.  
  2801.  
  2802. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2803.  
  2804. /*-------------------------------------------------------*/
  2805. /* For the information icon (white 'i' in a blue circle) */
  2806. /*-------------------------------------------------------*/
  2807.  
  2808. CONTROL "#11", SPTR_ICONINFORMATION, 5, 35, 22, 16, WC_STATIC,
  2809.         SS_SYSICON | WS_VISIBLE
  2810.  
  2811. /*------------------------------------------------------------------*/
  2812. /* For the warning icon (black exclamation mark in a yellow circle) */
  2813. /*------------------------------------------------------------------*/
  2814.  
  2815. CONTROL "#14", SPTR_ICONWARNING, 5, 35, 22, 16, WC_STATIC,
  2816.         SS_SYSICON | WS_VISIBLE
  2817.  
  2818.  
  2819. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2820.  
  2821. static HWND hABar;
  2822.  
  2823.  
  2824. case WM_INITDLG:
  2825.   ;
  2826.   ;
  2827.   ;
  2828.   hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
  2829.   WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
  2830.   ;
  2831.   return (MRESULT)TRUE;          /* Needed if we have changed focus */
  2832.   break;
  2833.  
  2834.  
  2835. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2836.  
  2837. WinSetWindowText(WinWindowFromID(hwndDlg, ID_LBREAK),
  2838.                  "Line 1\012Line 2\012Line 3");
  2839.  
  2840.  
  2841. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2842.  
  2843. hDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL,
  2844.                   DLG_HINTS, NULL);
  2845.  
  2846. WinProcessDlg(hDlg);
  2847.  
  2848.  
  2849. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2850.  
  2851. hab = WinInitialize(NULL);
  2852. hmq = WinCreateMsgQueue(hab, 0);
  2853.  
  2854. WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
  2855.  
  2856. WinDestroyMsgQueue(hmq);
  2857. WinTerminate(hab);
  2858.  
  2859.  
  2860. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2861.  
  2862. static  HWND  hDlgBoxIcon;
  2863.  
  2864.  
  2865. case WM_INITDLG:
  2866.   hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
  2867.   WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
  2868.   ;
  2869.   ;
  2870.   ;
  2871.   return (MRESULT)TRUE;          /* Needed if we have changed focus */
  2872.   break;
  2873.  
  2874.  
  2875. case WM_ADJUSTWINDOWPOS:
  2876.   if (((PSWP)mp1)->fs & SWP_MINIMIZE)       // Being minimized
  2877.   {
  2878.     WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
  2879.   }
  2880.   else
  2881.     if (((PSWP)mp1)->fs & SWP_RESTORE)      // Being restored
  2882.     {
  2883.       WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
  2884.     }
  2885.  
  2886.   return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  2887.   break;
  2888.  
  2889.  
  2890. case ID_EXIT:
  2891.   WinDestroyPointer(hDlgBoxIcon);
  2892.   ;
  2893.   ;
  2894.   ;
  2895.   break;
  2896.  
  2897.  
  2898. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2899.  
  2900. SHORT X_Left,
  2901.       Y_Bot;
  2902. LONG  ScreenHeight,
  2903.       ScreenWidth;
  2904.  
  2905.  
  2906.  
  2907. case WM_INITDLG:
  2908.           /*----------------------------------------*/
  2909.           /* This code will ensure that your dialog */
  2910.           /* box is centred on the desktop.         */
  2911.           /*----------------------------------------*/
  2912.  
  2913.   ScreenWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  2914.   ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  2915.  
  2916.   WinQueryWindowRect(hwndDlg, &rc);
  2917.   X_Left = (SHORT)(ScreenWidth  - rc.xRight)  / 2;
  2918.   Y_Bot  = (SHORT)(ScreenHeight - rc.yTop) / 2;
  2919.  
  2920.   WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
  2921.                   SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  2922.  
  2923.   /*---------------------------------------------------------------------*/
  2924.   /* If you want to start minimized, then use the following              */
  2925.   /*                                                                     */
  2926.   /* WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,             */
  2927.   /*                 SWP_MOVE | SWP_SHOW | SWP_ACTIVATE | SWP_MINIMIZE); */
  2928.   /*---------------------------------------------------------------------*/
  2929.   ;
  2930.   ;
  2931.   return (MRESULT)TRUE;          /* Needed if we have changed focus */
  2932.   break;
  2933.  
  2934.  
  2935. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2936.  
  2937. MENU  ID_MENU  PRELOAD
  2938. BEGIN
  2939.   SUBMENU   "~Options",   ID_OPTIONS
  2940.   BEGIN
  2941.       MENUITEM   "Test ~1", ID_TEST1
  2942.       MENUITEM   "Test ~2", ID_TEST2
  2943.       MENUITEM   "Test ~3", ID_TEST3
  2944.   END
  2945. END
  2946.  
  2947.  
  2948. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2949.  
  2950. /*---------------------------------------*/
  2951. /* Set the focus to entry field ID_ENTRY */
  2952. /*---------------------------------------*/
  2953.  
  2954. case WM_INITDLG:
  2955.   WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY));
  2956.   ;
  2957.   ;
  2958.   ;
  2959.   return (MRESULT)TRUE;          /* Needed if we have changed focus */
  2960.   break;
  2961.  
  2962.  
  2963. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2964.  
  2965. CONTROL "This is a status line", ID_STATUS, 0, 0, 185, 8, WC_STATIC,
  2966.         SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
  2967.  
  2968.  
  2969. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2970.  
  2971. WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), szNewStatus);
  2972.  
  2973.  
  2974. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2975.  
  2976. HPS    hps;
  2977. RECTL  rc;
  2978.  
  2979.  
  2980.  
  2981. case WM_PAINT:
  2982.   WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  2983.   hps = WinGetPS(hwndDlg);
  2984.   WinQueryWindowRect(hwndDlg, &rc);
  2985.   WinCalcFrameRect(hwndDlg, &rc, TRUE);
  2986.   rc.yTop = rc.yBottom + WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  2987.   WinDrawText(hps, -1, "Status = OK", &rc, CLR_YELLOW, CLR_DARKGREEN,
  2988.               DT_CENTER | DT_VCENTER | DT_ERASERECT);
  2989.   WinReleasePS(hps);
  2990.   break;
  2991.  
  2992.  
  2993. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  2994.  
  2995. ULONG  Colour;
  2996.  
  2997.  
  2998.  
  2999. case WM_INITDLG:
  3000.   Colour = CLR_DARKGREEN;
  3001.   WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
  3002.                   PP_BACKGROUNDCOLORINDEX,
  3003.                   (ULONG)sizeof(Colour), &Colour);
  3004.  
  3005.   Colour = CLR_YELLOW;
  3006.   WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
  3007.                   PP_FOREGROUNDCOLORINDEX,
  3008.                   (ULONG)sizeof(Colour), &Colour);
  3009.   ;
  3010.   ;
  3011.   ;
  3012.   return (MRESULT)TRUE;  /* If changing focus during initialisation */
  3013.   break;
  3014.  
  3015.  
  3016. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3017.  
  3018. /*---------------------------*/
  3019. /* Get handle of entry field */
  3020. /*---------------------------*/
  3021.  
  3022. hEntry = WinWindowFromID(hwndDlg, ID_ENTRY2);
  3023.  
  3024. /*-----------------------------*/
  3025. /* Change its style to centred */
  3026. /*-----------------------------*/
  3027.  
  3028. WinSetWindowULong(hEntry, QWL_STYLE,
  3029.                   WinQueryWindowULong(hEntry, QWL_STYLE ) | ES_CENTER);
  3030.  
  3031.  
  3032. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3033.  
  3034. /*----------------------*/
  3035. /* To remove WS_TABSTOP */
  3036. /*----------------------*/
  3037.  
  3038. hButton = WinWindowFromID(hwndDlg, ID_EXIT);
  3039.  
  3040. WinSetWindowULong(hButton, QWL_STYLE,
  3041.                   WinQueryWindowULong(hButton, QWL_STYLE ) & ~WS_TABSTOP);
  3042.  
  3043.  
  3044.  
  3045. /*-------------------*/
  3046. /* To add WS_TABSTOP */
  3047. /*-------------------*/
  3048.  
  3049. hButton = WinWindowFromID(hwndDlg, ID_EXIT);
  3050.  
  3051. WinSetWindowULong(hButton, QWL_STYLE,
  3052.                   WinQueryWindowULong(hButton, QWL_STYLE ) | WS_TABSTOP);
  3053.  
  3054.  
  3055. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3056.  
  3057. #define INCL_WIN
  3058.  
  3059. #include <os2.h>
  3060. #include <string.h>
  3061. #include "hints.h"
  3062.  
  3063. typedef struct _CHARMSG *PCHARMSG;
  3064.  
  3065. MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
  3066. MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  3067. VOID             Button_Paint(HWND, HPS, USHORT);
  3068.  
  3069. PFNWP   EntryFieldProc;             // Public Entry Field procedure
  3070.  
  3071. /******************************************************************************/
  3072.  
  3073. VOID cdecl main()
  3074. {
  3075.   HAB    hab;
  3076.   HMQ    hmq;
  3077.   HWND   hDlg;
  3078.  
  3079.  
  3080.   hab = WinInitialize(NULL);
  3081.   hmq = WinCreateMsgQueue(hab, 0);
  3082.  
  3083.   WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
  3084.  
  3085.   /*--------------------------------------------------------------*/
  3086.   /* hDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, */
  3087.   /*                   DLG_HINTS, NULL);                          */
  3088.   /* WinProcessDlg(hDlg);                                         */
  3089.   /*--------------------------------------------------------------*/
  3090.  
  3091.   WinDestroyMsgQueue(hmq);
  3092.   WinTerminate(hab);
  3093. }
  3094.  
  3095. /******************************************************************************/
  3096.  
  3097. MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
  3098. {
  3099.   static  HWND    hDlgBoxIcon,
  3100.                   hwndEntry,
  3101.                   hABar,
  3102.                   hMenu;
  3103.   HWND            hButton,
  3104.                   hEntry,
  3105.                   hPwd;
  3106.   static  BOOL    NewTitle = FALSE;
  3107.   static  ULONG   MenuHt;
  3108.   ULONG           Colour,
  3109.                   val,
  3110.                   lStyle;
  3111.   SWCNTRL         PgmEntry;
  3112.   POINTL          Pt;
  3113.   USHORT          id;
  3114.   HPS             hps;
  3115.   RECTL           rc;
  3116.   SHORT           X_Left,
  3117.                   Y_Bot;
  3118.   LONG            ScreenHeight,
  3119.                   ScreenWidth;
  3120.   CHAR            szPswd[9];
  3121.   USERBUTTON      *ubtn;
  3122.  
  3123. //=============================================================================
  3124.  
  3125.   switch (msg)
  3126.   {
  3127.     case WM_INITDLG:
  3128.       EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY2),
  3129.                                          NumericProc);
  3130.       WinSendMsg(WinWindowFromID(hwndDlg, ID_PASSWORD),
  3131.                  EM_SETTEXTLIMIT,
  3132.                  MRFROMSHORT(8),
  3133.                  NULL);
  3134.       WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3135.                  EM_SETREADONLY,
  3136.                  (MPARAM)TRUE,
  3137.                  NULL);
  3138.       hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
  3139.       WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
  3140.       WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
  3141.  
  3142.       hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
  3143.       WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
  3144.       hMenu = WinLoadMenu(hwndDlg, NULL, ID_MENU2);
  3145.  
  3146.       MenuHt  = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  3147.  
  3148.       Colour = CLR_DARKGREEN;
  3149.       WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
  3150.                       PP_BACKGROUNDCOLORINDEX,
  3151.                       (ULONG)sizeof(Colour), &Colour);
  3152.       Colour = CLR_YELLOW;
  3153.       WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
  3154.                       PP_FOREGROUNDCOLORINDEX,
  3155.                       (ULONG)sizeof(Colour), &Colour);
  3156.  
  3157.       ScreenWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  3158.       ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  3159.  
  3160.       WinQueryWindowRect(hwndDlg, &rc);                  /*---------------*/
  3161.       X_Left = (SHORT)(ScreenWidth  - rc.xRight)  / 2;   /* Centre window */
  3162.       Y_Bot  = (SHORT)(ScreenHeight - rc.yTop) / 2;      /*---------------*/
  3163.  
  3164.       WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
  3165.                       SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  3166.  
  3167.       PgmEntry.hwnd          = hwndDlg;
  3168.       PgmEntry.hwndIcon      = hDlgBoxIcon;
  3169.       PgmEntry.hprog         = NULL;
  3170.       PgmEntry.idProcess     = NULL;
  3171.       PgmEntry.idSession     = NULL;
  3172.       PgmEntry.uchVisibility = SWL_VISIBLE;
  3173.       PgmEntry.fbJump        = SWL_JUMPABLE;
  3174.       strcpy(PgmEntry.szSwtitle, "Hints & Tips");
  3175.       hwndEntry = WinAddSwitchEntry(&PgmEntry);
  3176.       return (MRESULT)TRUE;
  3177.       break;
  3178.  
  3179.     /*-----------------------------------------------------------------------*/
  3180.     /* case WM_PAINT:                                                        */
  3181.     /*   WinDefDlgProc(hwndDlg, msg, mp1, mp2);                              */
  3182.     /*   hps = WinGetPS(hwndDlg);                                            */
  3183.     /*   WinQueryWindowRect(hwndDlg, &rc);                                   */
  3184.     /*   WinCalcFrameRect(hwndDlg, &rc, TRUE);                               */
  3185.     /*   rc.yTop = rc.yBottom + WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);   */
  3186.     /*   WinDrawText(hps, -1, "Status = OK", &rc, CLR_YELLOW, CLR_DARKGREEN, */
  3187.     /*               DT_CENTER | DT_VCENTER | DT_ERASERECT);                 */
  3188.     /*   WinReleasePS(hps);                                                  */
  3189.     /*   break;                                                              */
  3190.     /*-----------------------------------------------------------------------*/
  3191.  
  3192.     case WM_BUTTON2DOWN:
  3193.       Pt.x = MOUSEMSG(&msg)->x;
  3194.       Pt.y = MOUSEMSG(&msg)->y + MenuHt;
  3195.       WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
  3196.       WinSetWindowPos(hMenu, HWND_TOP, (USHORT)Pt.x, (USHORT)Pt.y, 0, 0,
  3197.                       SWP_MOVE | SWP_SHOW);
  3198.       break;
  3199.  
  3200.     case WM_NEXTMENU:
  3201.       return (MRESULT)NULL;
  3202.  
  3203.     case WM_ADJUSTWINDOWPOS:
  3204.       if (((PSWP)mp1)->fs & SWP_MINIMIZE)
  3205.       {
  3206.         WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
  3207.         WinShowWindow(WinWindowFromID(hwndDlg, ID_STATUS), FALSE);
  3208.         WinDestroyWindow(hABar);
  3209.       }
  3210.       else
  3211.         if (((PSWP)mp1)->fs & SWP_RESTORE)
  3212.         {
  3213.           WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
  3214.           WinShowWindow(WinWindowFromID(hwndDlg, ID_STATUS), TRUE);
  3215.           hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
  3216.           WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
  3217.         }
  3218.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  3219.       break;
  3220.  
  3221.     case WM_CONTROL:
  3222.       switch(HIUSHORT(mp1))
  3223.       {
  3224.         case BN_PAINT:
  3225.            switch(LOUSHORT(mp1))                       /* Which Button? */
  3226.            {
  3227.              case ID_USERBUTTON:
  3228.                ubtn = (USERBUTTON *)mp2;
  3229.                Button_Paint(ubtn->hwnd, ubtn->hps, ubtn->fsState);
  3230.                return (MRESULT)TRUE;
  3231.  
  3232.              default:
  3233.                 break;
  3234.            }
  3235.       }
  3236.       break;
  3237.  
  3238.     case WM_COMMAND:
  3239.       switch(SHORT1FROMMP(mp1))
  3240.       {
  3241.         case ID_TEST1:
  3242.           DosBeep(500, 100);
  3243.           return FALSE;
  3244.  
  3245.         case ID_TEST2:
  3246.           DosBeep(1000, 100);
  3247.           return FALSE;
  3248.  
  3249.         case ID_TEST3:
  3250.           DosBeep(1500, 100);
  3251.           return FALSE;
  3252.  
  3253.         case ID_ITEM1:
  3254.           DosBeep(500, 100);
  3255.           return FALSE;
  3256.  
  3257.         case ID_ITEM2:
  3258.           DosBeep(1000, 100);
  3259.           return FALSE;
  3260.  
  3261.         case ID_ITEM3:
  3262.           DosBeep(1500, 100);
  3263.           return FALSE;
  3264.  
  3265.         case ID_ITEM4:
  3266.           DosBeep(2000, 100);
  3267.           return FALSE;
  3268.  
  3269.         case ID_ITEM5:
  3270.           DosBeep(2500, 100);
  3271.           return FALSE;
  3272.  
  3273.         case ID_USERBUTTON:
  3274.           DosBeep(1000, 100);
  3275.           DosBeep(500, 100);
  3276.           return FALSE;
  3277.  
  3278.         case ID_OK:
  3279.           WinSetWindowText(WinWindowFromID(hwndDlg, ID_LBREAK),
  3280.                            "Line 1\012Line 2\012Line 3");
  3281.           if (NewTitle)
  3282.             NewTitle = FALSE;
  3283.           else
  3284.             NewTitle = TRUE;
  3285.  
  3286.           if (NewTitle)
  3287.           {
  3288.             WinSetWindowText(hwndDlg, "Sample Dialog Box with New Title");
  3289.             /*--------------------------------------------------------*/
  3290.             /* WinSetDlgItemText(hwndDlg, FID_TITLEBAR, "New Title"); */
  3291.             /*--------------------------------------------------------*/
  3292.             WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Quit");
  3293.             WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), "New Status");
  3294.             hButton = WinWindowFromID(hwndDlg, ID_EXIT);
  3295.             WinSetWindowULong(hButton, QWL_STYLE,
  3296.                               WinQueryWindowULong(hButton, QWL_STYLE ) &
  3297.                               ~WS_TABSTOP);
  3298.           }
  3299.           else
  3300.           {
  3301.             WinSetWindowText(hwndDlg, "Sample Dialog Box");
  3302.             WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Exit");
  3303.             WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), "Old Status");
  3304.             hButton = WinWindowFromID(hwndDlg, ID_EXIT);
  3305.             WinSetWindowULong(hButton, QWL_STYLE,
  3306.                               WinQueryWindowULong(hButton, QWL_STYLE ) |
  3307.                               WS_TABSTOP);
  3308.           }
  3309.  
  3310.           hEntry = WinWindowFromID(hwndDlg, ID_ENTRY2);
  3311.           WinSetWindowULong(hEntry, QWL_STYLE,
  3312.                             WinQueryWindowULong(hEntry, QWL_STYLE ) |
  3313.                             ES_CENTER);
  3314.  
  3315.           id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3316.                                     QWS_ID);
  3317.           WinSetDlgItemShort(hwndDlg, ID_ENTRY1, id, FALSE);
  3318.           id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY2),
  3319.                                     QWS_ID);
  3320.           WinSetDlgItemShort(hwndDlg, ID_ENTRY2, id, FALSE);
  3321.  
  3322.           WinQueryWindowText(WinWindowFromID(hwndDlg, ID_PASSWORD),
  3323.                               sizeof(szPswd), szPswd);
  3324.           WinQueryDlgItemText(hwndDlg, ID_PASSWORD,
  3325.                               sizeof(szPswd), szPswd);
  3326.  
  3327.           WinQueryDlgItemShort(hwndDlg, ID_ENTRY1, &id, FALSE);   // Unsigned
  3328.  
  3329.           WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
  3330.           /*------------------------------------------------*/
  3331.           /* Position cursor between 1st and 2nd characters */
  3332.           /*------------------------------------------------*/
  3333.           WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  3334.                      MPFROM2SHORT(1, 1), 0L);
  3335.           /*------------------------------------------------*/
  3336.           /* Position cursor between 1st and 2nd characters */
  3337.           /* and mark 2nd and 3rd                           */
  3338.           /*------------------------------------------------*/
  3339.           WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  3340.                      MPFROM2SHORT(1, 3), 0L);
  3341.           /*---------------------------------------------------------*/
  3342.           /* Position cursor at start of field and mark entire field */
  3343.           /*---------------------------------------------------------*/
  3344.           WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
  3345.                      MPFROM2SHORT(0, 5), 0L);
  3346.  
  3347.           lStyle = WinQueryWindowULong(WinWindowFromID(hwndDlg, ID_OK),
  3348.                                        QWL_STYLE);
  3349.           if (lStyle & BS_DEFAULT)                     // Default
  3350.           {
  3351.             DosBeep(100, 200);
  3352.             /*------------------------------------------------------------*/
  3353.             /* WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT, */
  3354.             /*           (MPARAM)FALSE, NULL);                            */
  3355.             /*------------------------------------------------------------*/
  3356.             /*--------------------------------------------------------------*/
  3357.             /* WinSendMsg(WinWindowFromID(hwndDlg, ID_EXIT), BM_SETDEFAULT, */
  3358.             /*           (MPARAM)TRUE, NULL);                               */
  3359.             /*--------------------------------------------------------------*/
  3360.             WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
  3361.                              0L, BS_DEFAULT);
  3362.             WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
  3363.           }
  3364.           else                                         // Not default
  3365.           {
  3366.             DosBeep(1000, 200);
  3367.             /*-----------------------------------------------------------*/
  3368.             /*WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT, */
  3369.             /*           (MPARAM)TRUE, NULL);                            */
  3370.             /*-----------------------------------------------------------*/
  3371.             WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
  3372.                              BS_DEFAULT, BS_DEFAULT);
  3373.             WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
  3374.           }
  3375.           return FALSE;
  3376.  
  3377.         case ID_EXIT:
  3378.           WinDestroyPointer(hDlgBoxIcon);
  3379.           WinRemoveSwitchEntry(hwndEntry);
  3380.           WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
  3381.           break;
  3382.  
  3383.         default:
  3384.           return FALSE;
  3385.       }
  3386.       WinDismissDlg(hwndDlg, TRUE);                 /* Removes the dialog box */
  3387.       break;
  3388.  
  3389.     default:
  3390.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  3391.   }
  3392.   return FALSE;
  3393. }
  3394.  
  3395. MRESULT EXPENTRY  NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  3396. {
  3397.   PCHARMSG  p;
  3398.  
  3399.   if (msg == WM_CHAR)                              // If this is a char msg
  3400.   {
  3401.     p = CHARMSG(&msg);                             // Address char structure
  3402.     if ((p->fs & (KC_KEYUP|KC_CHAR)) == KC_CHAR)   // ONLY key down transitions */
  3403.     {
  3404.       if ((p->chr < 0x30 || p->chr > 0x39) &&      // Not numeric
  3405.           (p->chr != 8) &&                         // Not backspace
  3406.           (p->chr != 9) &&                         // Not tab
  3407.           (p->chr != 0x2D) &&                      // Not -
  3408.           (p->chr != 13))                          // Not enter
  3409.       {
  3410.         WinAlarm(HWND_DESKTOP, WA_WARNING);
  3411.         return (MRESULT)TRUE;
  3412.       }
  3413.     }
  3414.   }                                  /* Call public entry field procedure */
  3415.   return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
  3416. }
  3417.  
  3418. VOID Button_Paint(HWND hwnd, HPS hps, USHORT Status)
  3419. {
  3420.   RECTL   DestPt;
  3421.   HBITMAP hbm;
  3422.  
  3423.   /*------------------------------------------------------------------------*/
  3424.   /* hbm = WinGetSysBitmap(HWND_DESKTOP, SBMP_DRIVE);                       */
  3425.   /* WinQueryWindowRect(hwnd, &DestPt);                                     */
  3426.   /* WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, CLR_YELLOW, CLR_BLACK, */
  3427.   /*               (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);       */
  3428.   /*------------------------------------------------------------------------*/
  3429.  
  3430.   hbm = GpiLoadBitmap(hps, NULL, ID_LOCK, 0L, 0L);
  3431.   WinQueryWindowRect(hwnd, &DestPt);
  3432.   WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, 0L, 0L,
  3433.                 (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);
  3434. }
  3435.  
  3436.  
  3437. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3438.  
  3439. #define ID_LOCK         279
  3440. #define ID_USERBUTTON   278
  3441. #define ID_PASSWORD     277
  3442. #define ID_LBREAK       276
  3443. #define ID_DLGICON      275
  3444. #define ID_STATUS       274
  3445. #define ID_OPTIONS2     273
  3446. #define ID_ITEM5        272
  3447. #define ID_ITEM4        271
  3448. #define ID_ITEM3        270
  3449. #define ID_ITEM2        269
  3450. #define ID_ITEM1        268
  3451. #define ID_MENU2        267
  3452. #define ID_TEST3        266
  3453. #define ID_TEST2        265
  3454. #define ID_TEST1        264
  3455. #define ID_OPTIONS      263
  3456. #define ID_MENU         262
  3457. #define ID_ENTRY2       261
  3458. #define ID_ENTRY1       260
  3459. #define ID_ICON         259
  3460. #define ID_EXIT         258
  3461. #define ID_OK           257
  3462. #define DLG_HINTS       256
  3463.  
  3464.  
  3465. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3466.  
  3467. hints +
  3468. /A:16 /CO
  3469. hints.exe
  3470. hints.map  /NOD
  3471. llibce.lib+
  3472. os2.lib
  3473. hints.def
  3474.  
  3475.  
  3476. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3477.  
  3478. NAME    Hints WINDOWAPI
  3479.  
  3480. DESCRIPTION 'Test program for OS/2 Hints and Tips'
  3481.  
  3482. STUB    'OS2STUB.EXE'
  3483.  
  3484. DATA    MULTIPLE
  3485.  
  3486. HEAPSIZE    8192
  3487. STACKSIZE   8192
  3488.  
  3489. PROTMODE
  3490.  
  3491.  
  3492. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3493.  
  3494. #include <os2.h>
  3495. #include "hints.h"
  3496.  
  3497. ICON   ID_ICON     hints.ico
  3498. ICON   ID_DLGICON  hints.ico
  3499. BITMAP ID_LOCK     lock.bmp
  3500.  
  3501. MENU  ID_MENU  PRELOAD
  3502. BEGIN
  3503.   SUBMENU   "~Options",   ID_OPTIONS
  3504.   BEGIN
  3505.       MENUITEM   "Test ~1", ID_TEST1
  3506.       MENUITEM   "Test ~2", ID_TEST2
  3507.       MENUITEM   "Test ~3", ID_TEST3
  3508.   END
  3509. END
  3510.  
  3511. MENU  ID_MENU2  PRELOAD
  3512. BEGIN
  3513.   SUBMENU "", ID_OPTIONS2
  3514.   BEGIN
  3515.     MENUITEM  "Menu Item ~1", ID_ITEM1
  3516.     MENUITEM  "Menu Item ~2", ID_ITEM2
  3517.     MENUITEM  "Menu Item ~3", ID_ITEM3
  3518.     MENUITEM  SEPARATOR
  3519.     MENUITEM  "Menu Item ~4", ID_ITEM4
  3520.     MENUITEM  "Menu Item ~5", ID_ITEM5
  3521.   END
  3522. END
  3523.  
  3524. rcinclude hints.dlg
  3525.  
  3526.  
  3527. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3528.  
  3529. DLGINCLUDE 1 "HINTS.H"
  3530.  
  3531. DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
  3532. BEGIN
  3533.     DIALOG "Sample Dialog Box", DLG_HINTS, 105, 56, 195, 101, FS_NOBYTEALIGN |
  3534.                 FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  3535.                 FCF_SYSMENU | FCF_TITLEBAR | FCF_MINBUTTON
  3536.     BEGIN
  3537.         CONTROL "", ID_ENTRY1, 67, 72, 36, 8, WC_ENTRYFIELD, ES_LEFT |
  3538.                 ES_MARGIN | WS_TABSTOP | WS_VISIBLE
  3539.         CONTROL "", ID_ENTRY2, 67, 57, 36, 8, WC_ENTRYFIELD, ES_LEFT |
  3540.                 ES_MARGIN | WS_TABSTOP | WS_VISIBLE
  3541.                 CTLDATA 8, 5, 0, 0
  3542.         CONTROL "", ID_PASSWORD, 77, 37, 45, 8, WC_ENTRYFIELD, ES_LEFT |
  3543.                 ES_MARGIN | ES_UNREADABLE | WS_TABSTOP | WS_VISIBLE
  3544.         CONTROL "OK", ID_OK, 5, 15, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
  3545.                 BS_DEFAULT | WS_TABSTOP | WS_VISIBLE
  3546.         CONTROL "Exit", ID_EXIT, 45, 15, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
  3547.                 WS_TABSTOP | WS_VISIBLE
  3548.         CONTROL "", ID_USERBUTTON, 150, 12, 32, 25, WC_BUTTON, BS_USERBUTTON |
  3549.                 WS_TABSTOP | WS_VISIBLE
  3550.         CONTROL "Entry Field 1", 100, 5, 70, 55, 8, WC_STATIC, SS_TEXT |
  3551.                 DT_LEFT | DT_TOP | WS_GROUP | WS_VISIBLE
  3552.         CONTROL "Entry Field 2", 101, 5, 55, 55, 8, WC_STATIC, SS_TEXT |
  3553.                 DT_LEFT | DT_TOP | WS_GROUP | WS_VISIBLE
  3554.         CONTROL "This is a status line", ID_STATUS, 0, 0, 195, 8, WC_STATIC,
  3555.                 SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
  3556.         CONTROL ID_DLGICON, ID_DLGICON, 5, 35, 20, 16, WC_STATIC, SS_ICON |
  3557.                 WS_GROUP | WS_VISIBLE
  3558.         CONTROL "Line one\012Line two\012Line three", ID_LBREAK, 115, 53, 70, 28, WC_STATIC, SS_TEXT |
  3559.                 DT_LEFT | DT_TOP | DT_WORDBREAK | WS_GROUP | WS_VISIBLE
  3560.         CONTROL "Password", 102, 30, 35, 44, 8, WC_STATIC, SS_TEXT | DT_LEFT |
  3561.                 DT_TOP | WS_GROUP | WS_VISIBLE
  3562.     END
  3563. END
  3564.  
  3565.  
  3566. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3567.  
  3568. hints.exe: hints.obj \
  3569.           hints.def hints.res
  3570.  link @hints.l
  3571.  rc hints.res
  3572.  
  3573. hints.obj: hints.c hints.h
  3574.  cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
  3575.  
  3576. hints.res: hints.h hints.rc hints.dlg hints.ico
  3577.  rc -r hints.rc
  3578.  
  3579.  
  3580. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3581.  
  3582. #define INCL_WIN
  3583.  
  3584. #include <os2.h>
  3585. #include <string.h>
  3586. #include "hints.h"
  3587.  
  3588. MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
  3589.  
  3590. /******************************************************************************/
  3591.  
  3592. VOID cdecl main()
  3593. {
  3594.   HAB    hab;
  3595.   HMQ    hmq;
  3596.   HWND   hDlg;
  3597.  
  3598.  
  3599.   hab = WinInitialize(NULL);
  3600.   hmq = WinCreateMsgQueue(hab, 0);
  3601.  
  3602.   WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
  3603.  
  3604.   WinDestroyMsgQueue(hmq);
  3605.   WinTerminate(hab);
  3606. }
  3607.  
  3608. /******************************************************************************/
  3609.  
  3610. MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
  3611. {
  3612.   static  HWND    hDlgBoxIcon,
  3613.                   hwndEntry;
  3614.   SWCNTRL         PgmEntry;
  3615.   RECTL           rc;
  3616.   SHORT           X_Left,
  3617.                   Y_Bot;
  3618.   LONG            ScreenHeight,
  3619.                   ScreenWidth;
  3620.   CHAR            font[25];
  3621.   SEL             Selector;
  3622.   PBYTE           Buffer;
  3623.   IPT             ipt;
  3624.   HFILE           hFile;
  3625.   USHORT          Action,
  3626.                   BytesRead;
  3627.   ULONG           Colour;
  3628.   static SHORT    Idx = 0;
  3629.   static PSZ      Columns[] = {
  3630.                                "001  002  003  004  005  006",
  3631.                                "010  011  012  013  014  015",
  3632.                                "101  102  103  104  105  106"};
  3633.   static PSZ      FontTable[] = {
  3634.                                "8.Courier",
  3635.                                "10.Courier",
  3636.                                "12.Courier",
  3637.                                "8.Helv",
  3638.                                "10.Helv",
  3639.                                "12.Helv",
  3640.                                "14.Helv",
  3641.                                "18.Helv",
  3642.                                "24.Helv",
  3643.                                "10.System Monospaced",
  3644.                                "12.System Monospaced",
  3645.                                "12.System Proportional",
  3646.                                "8.Tms Rmn",
  3647.                                "10.Tms Rmn",
  3648.                                "12.Tms Rmn",
  3649.                                "14.Tms Rmn",
  3650.                                "18.Tms Rmn",
  3651.                                "24.Tms Rmn"};
  3652.  
  3653.  
  3654. //=============================================================================
  3655.  
  3656.   switch (msg)
  3657.   {
  3658.     case WM_INITDLG:
  3659.       hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
  3660.       WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
  3661.  
  3662.       ScreenWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  3663.       ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  3664.       WinQueryWindowRect(hwndDlg, &rc);                  /*---------------*/
  3665.       X_Left = (SHORT)(ScreenWidth  - rc.xRight)  / 2;   /* Centre window */
  3666.       Y_Bot  = (SHORT)(ScreenHeight - rc.yTop) / 2;      /*---------------*/
  3667.       WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
  3668.                       SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  3669.  
  3670.       PgmEntry.hwnd          = hwndDlg;
  3671.       PgmEntry.hwndIcon      = hDlgBoxIcon;
  3672.       PgmEntry.hprog         = NULL;
  3673.       PgmEntry.idProcess     = NULL;
  3674.       PgmEntry.idSession     = NULL;
  3675.       PgmEntry.uchVisibility = SWL_VISIBLE;
  3676.       PgmEntry.fbJump        = SWL_JUMPABLE;
  3677.       strcpy(PgmEntry.szSwtitle, "Hints & Tips");
  3678.       hwndEntry = WinAddSwitchEntry(&PgmEntry);
  3679.  
  3680.       WinSendDlgItemMsg(hwndDlg, ID_RADIO3, BM_SETCHECK,
  3681.                         MPFROM2SHORT(TRUE, 0), NULL);
  3682.  
  3683.       strcpy(font, "12.Courier");
  3684.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3685.                       PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3686.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3687.                       PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3688.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3689.                       PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3690.       WinSetDlgItemText(hwndDlg, ID_ENTRY1, "12.Courier");
  3691.       WinSetDlgItemText(hwndDlg, ID_MULTILINE, "12.Courier");
  3692.       for (Idx = 0; Idx < 3; Idx++)
  3693.       {
  3694.          WinSendMsg(WinWindowFromID(hwndDlg, ID_LISTBOX), LM_INSERTITEM,
  3695.                                     MRFROMSHORT(LIT_END),
  3696.                                     MRFROMP(Columns[Idx]));
  3697.       }
  3698.  
  3699.       for (Idx = 0; Idx < 18; Idx++)
  3700.       {
  3701.          WinSendMsg(WinWindowFromID(hwndDlg, ID_LISTBOX), LM_INSERTITEM,
  3702.                                     MRFROMSHORT(LIT_END),
  3703.                                     MRFROMP(FontTable[Idx]));
  3704.       }
  3705.       Idx = 0;
  3706.  
  3707.       return (MRESULT)TRUE;
  3708.       break;
  3709.  
  3710.     case WM_ADJUSTWINDOWPOS:
  3711.       if (((PSWP)mp1)->fs & SWP_MINIMIZE)
  3712.       {
  3713.         WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
  3714.       }
  3715.       else
  3716.         if (((PSWP)mp1)->fs & SWP_RESTORE)
  3717.         {
  3718.           WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
  3719.         }
  3720.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  3721.       break;
  3722.  
  3723.     case WM_CONTROL:
  3724.       switch( SHORT1FROMMP( mp1 ) )
  3725.       {
  3726.         case ID_RADIO1:
  3727.           switch( SHORT2FROMMP( mp1 ) )
  3728.           {
  3729.             case BN_CLICKED:
  3730.               strcpy(font, "8.Courier");
  3731.               WinSetDlgItemText(hwndDlg, ID_ENTRY1, "8.Courier");
  3732.               WinSetDlgItemText(hwndDlg, ID_MULTILINE, "8.Courier");
  3733.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3734.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3735.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3736.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3737.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3738.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3739.               Colour = CLR_RED;
  3740.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3741.                               PP_BACKGROUNDCOLORINDEX,
  3742.                               (ULONG)sizeof(Colour), &Colour);
  3743.               Colour = CLR_YELLOW;
  3744.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3745.                               PP_FOREGROUNDCOLORINDEX,
  3746.                               (ULONG)sizeof(Colour), &Colour);
  3747.               break;
  3748.  
  3749.             default:
  3750.               break;
  3751.           }
  3752.           break;
  3753.  
  3754.         case ID_RADIO2:
  3755.           switch( SHORT2FROMMP( mp1 ) )
  3756.           {
  3757.             case BN_CLICKED:
  3758.               strcpy(font, "10.Courier");
  3759.               WinSetDlgItemText(hwndDlg, ID_ENTRY1, "10.Courier");
  3760.               WinSetDlgItemText(hwndDlg, ID_MULTILINE, "10.Courier");
  3761.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3762.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3763.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3764.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3765.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3766.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3767.               break;
  3768.  
  3769.             default:
  3770.               break;
  3771.           }
  3772.           break;
  3773.  
  3774.         case ID_RADIO3:
  3775.           switch( SHORT2FROMMP( mp1 ) )
  3776.           {
  3777.             case BN_CLICKED:
  3778.               strcpy(font, "12.Courier");
  3779.               WinSetDlgItemText(hwndDlg, ID_ENTRY1, "12.Courier");
  3780.               WinSetDlgItemText(hwndDlg, ID_MULTILINE, "12.Courier");
  3781.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3782.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3783.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3784.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3785.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3786.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3787.               break;
  3788.  
  3789.             default:
  3790.               break;
  3791.           }
  3792.           break;
  3793.  
  3794.         case ID_RADIO4:
  3795.           switch( SHORT2FROMMP( mp1 ) )
  3796.           {
  3797.             case BN_CLICKED:
  3798.               strcpy(font, "8.Helv");
  3799.               WinSetDlgItemText(hwndDlg, ID_ENTRY1, "8.Helv");
  3800.               WinSetDlgItemText(hwndDlg, ID_MULTILINE, "8.Helv");
  3801.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3802.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3803.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3804.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3805.               WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3806.                               PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3807.               break;
  3808.  
  3809.             default:
  3810.               break;
  3811.           }
  3812.           break;
  3813.       }
  3814.  
  3815.     case WM_COMMAND:
  3816.       switch(SHORT1FROMMP(mp1))
  3817.       {
  3818.         case ID_OK:
  3819.           DosAllocSeg(0, &Selector, SEG_GETTABLE);    // Allocate 64K segment
  3820.           Buffer = MAKEP(Selector, 0);                // Get pointer to segment
  3821.           DosOpen("C:\\CONFIG.SYS", &hFile, &Action,
  3822.                   (ULONG)NULL,
  3823.                   (USHORT)NULL,
  3824.                   OPEN_ACTION_OPEN_IF_EXISTS,
  3825.                   OPEN_FLAGS_SEQUENTIAL |
  3826.                   OPEN_SHARE_DENYNONE   |
  3827.                   OPEN_ACCESS_READONLY,
  3828.                   (ULONG)NULL);
  3829.           DosRead(hFile, Buffer, 65535L, &BytesRead);
  3830.           DosClose(hFile);
  3831.           WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3832.                      MLM_SETIMPORTEXPORT, (MPARAM)Buffer,
  3833.                      MPFROMLONG(65535L));
  3834.           ipt = -1;
  3835.           WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3836.                      MLM_IMPORT, (MPARAM)&ipt,
  3837.                      MPFROMLONG((LONG)BytesRead));
  3838.           DosFreeSeg(Selector);
  3839.           return FALSE;
  3840.  
  3841.         case ID_CLEAR:
  3842.           /*-----------------------------------------------*/
  3843.           /* WinSetDlgItemText(hwndDlg, ID_MULTILINE, ""); */
  3844.           /*-----------------------------------------------*/
  3845.           WinSetWindowText(WinWindowFromID(hwndDlg, ID_MULTILINE), "");
  3846.           return FALSE;
  3847.  
  3848.         case ID_FONT:
  3849.           strcpy(font, FontTable[Idx]);
  3850.           WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
  3851.                           PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3852.           WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3853.                           PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3854.           WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
  3855.                           PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  3856.           WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "");
  3857.           WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1),
  3858.                            FontTable[Idx++]);
  3859.           if (Idx == 18)
  3860.             Idx = 0;
  3861.           return FALSE;
  3862.  
  3863.         case ID_EXIT:
  3864.           WinDestroyPointer(hDlgBoxIcon);
  3865.           WinRemoveSwitchEntry(hwndEntry);
  3866.           WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
  3867.           break;
  3868.  
  3869.         default:
  3870.           return FALSE;
  3871.       }
  3872.       WinDismissDlg(hwndDlg, TRUE);                 /* Removes the dialog box */
  3873.       break;
  3874.  
  3875.     default:
  3876.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  3877.   }
  3878.   return FALSE;
  3879. }
  3880.  
  3881.  
  3882. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3883.  
  3884. #define DLG_HINTS      256
  3885. #define ID_OK          257
  3886. #define ID_EXIT        258
  3887. #define ID_ICON        259
  3888. #define ID_MULTILINE   260
  3889. #define ID_RADIO1      261
  3890. #define ID_RADIO2      262
  3891. #define ID_RADIO3      263
  3892. #define ID_ENTRY1      264
  3893. #define ID_RADIO4      265
  3894. #define ID_CLEAR       266
  3895. #define ID_FONT        267
  3896. #define ID_LISTBOX     268
  3897.  
  3898.  
  3899. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3900.  
  3901. #define INCL_WINSYS
  3902.  
  3903. #include <os2.h>
  3904. #include "hints.h"
  3905.  
  3906. ICON   ID_ICON     hints.ico
  3907.  
  3908. rcinclude hints.dlg
  3909.  
  3910.  
  3911. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3912.  
  3913. DLGINCLUDE 1 "HINTS.H"
  3914.  
  3915. DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
  3916. BEGIN
  3917.     DIALOG "Sample Dialog Box", DLG_HINTS, 68, 30, 276, 159, FS_NOBYTEALIGN |
  3918.                 FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  3919.                 FCF_SYSMENU | FCF_TITLEBAR | FCF_MINBUTTON
  3920.     BEGIN
  3921.         CONTROL "Group 1", 100, 8, 76, 84, 77, WC_STATIC, SS_GROUPBOX |
  3922.                 WS_GROUP | WS_VISIBLE
  3923.         CONTROL "8.Courier", ID_RADIO1, 16, 128, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
  3924.                 WS_TABSTOP | WS_VISIBLE
  3925.         CONTROL "10.Courier", ID_RADIO2, 16, 113, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
  3926.                 WS_TABSTOP | WS_VISIBLE
  3927.         CONTROL "12.Courier", ID_RADIO3, 16, 98, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
  3928.                 WS_TABSTOP | WS_VISIBLE
  3929.         CONTROL "8.Helv", ID_RADIO4, 16, 83, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
  3930.                 WS_TABSTOP | WS_VISIBLE
  3931.         CONTROL "", ID_ENTRY1, 105, 119, 158, 28, WC_ENTRYFIELD, ES_CENTER |
  3932.                 ES_MARGIN | WS_GROUP | WS_TABSTOP | WS_VISIBLE
  3933.         CONTROL "", ID_LISTBOX, 103, 80, 162, 32, WC_LISTBOX, LS_NOADJUSTPOS |
  3934.                 WS_TABSTOP | WS_VISIBLE
  3935.         CONTROL "", ID_MULTILINE, 8, 20, 259, 54, WC_MLE, MLS_BORDER |
  3936.                 MLS_HSCROLL | MLS_VSCROLL | WS_TABSTOP | WS_VISIBLE
  3937.         CONTROL "Read File", ID_OK, 6, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
  3938.                 WS_TABSTOP | WS_VISIBLE
  3939.         CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
  3940.                 WS_TABSTOP | WS_VISIBLE
  3941.         PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
  3942.         PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
  3943.         PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
  3944.         CONTROL "Change Font", ID_FONT, 167, 5, 62, 13, WC_BUTTON, BS_PUSHBUTTON |
  3945.                 WS_TABSTOP | WS_VISIBLE
  3946.         CONTROL "Exit", ID_EXIT, 240, 5, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
  3947.                 WS_TABSTOP | WS_VISIBLE
  3948.     END
  3949. END
  3950.  
  3951.  
  3952. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  3953.  
  3954. #define INCL_WIN
  3955. #define INCL_GPILCIDS
  3956. #define INCL_GPIPRIMITIVES
  3957. #define INCL_DOS
  3958.  
  3959. #include <os2.h>
  3960. #include <string.h>
  3961. #include "hints.h"
  3962.  
  3963. MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
  3964.  
  3965. /******************************************************************************/
  3966.  
  3967. VOID cdecl main()
  3968. {
  3969.   HAB    hab;
  3970.   HMQ    hmq;
  3971.   HWND   hDlg;
  3972.  
  3973.  
  3974.   hab = WinInitialize(NULL);
  3975.   hmq = WinCreateMsgQueue(hab, 0);
  3976.  
  3977.   WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
  3978.  
  3979.   WinDestroyMsgQueue(hmq);
  3980.   WinTerminate(hab);
  3981. }
  3982.  
  3983. /******************************************************************************/
  3984.  
  3985. MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
  3986. {
  3987.   static  HWND    hwndEntry;
  3988.   HWND            hwndItem;
  3989.   SWCNTRL         PgmEntry;
  3990.   RECTL           rc;
  3991.   SHORT           X_Left,
  3992.                   Y_Bot,
  3993.                   Midx;
  3994.   static SHORT    Idx,
  3995.                   Oidx;
  3996.   LONG            ScreenHeight,
  3997.                   ScreenWidth;
  3998.   CHAR            font[15];
  3999.   ULONG           Colour;
  4000.   SEL             sel;
  4001.  
  4002.   typedef struct _DBDATA
  4003.   {
  4004.     USHORT Key;
  4005.     CHAR   Capital[20];
  4006.   } DBDATA, FAR *PDBDATA;
  4007.  
  4008.   PDBDATA         pDB_Data;
  4009.  
  4010.   static PSZ      szCountry[] = {"Austria",   "Belgium",   "Canada",
  4011.                                  "Denmark",   "Egypt",     "Finland",
  4012.                                  "Greece",    "Hungary",   "India",
  4013.                                  "Japan",     "Kenya",     "Libya",
  4014.                                  "Morocco",   "Nigeria",   "Oman",
  4015.                                  "Peru",      "Qatar",     "Romania",
  4016.                                  "Spain",     "Turkey",    "Uruguay",
  4017.                                  "Venezuela", "Wales",     "Xanxere",
  4018.                                  "Yemen",     "Zambia"};
  4019.  
  4020.   static PSZ      szCapital[] = {"Vienna",     "Brussels",  "Ottawa",
  4021.                                  "Copenhagen", "Cairo",     "Helsinki",
  4022.                                  "Athens",     "Budapest",  "Delhi",
  4023.                                  "Tokyo",      "Nairobi",   "Tripoli",
  4024.                                  "Rabat",      "Lagos",     "Muscat",
  4025.                                  "Lima",       "Doha",      "Bucharest",
  4026.                                  "Madrid",     "Ankara",    "Montevideo",
  4027.                                  "Caracas",    "Cardiff",   "None",
  4028.                                  "Sana",       "Lusaka"};
  4029.  
  4030.   CHAR            szCtry[10],
  4031.                   szCap[12],
  4032.                   szListBuff[50];
  4033.   CHAR            *Country,
  4034.                   *Capital;
  4035.   ULONG           KeyValue;
  4036.   POWNERITEM      pOwner;
  4037.   SHORT           cxText,
  4038.                   cyText;
  4039.   HPS             hps;
  4040.   FONTMETRICS     fm;
  4041.   POINTL          points[TXTBOX_COUNT],
  4042.                   pt;
  4043.  
  4044.  
  4045. //=============================================================================
  4046.  
  4047.   switch (msg)
  4048.   {
  4049.     case WM_INITDLG:
  4050.       WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), FALSE);
  4051.       strcpy(font, "18.Helv");
  4052.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  4053.                       PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  4054.       Colour = CLR_RED;
  4055.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  4056.                       PP_BACKGROUNDCOLORINDEX,
  4057.                       (ULONG)sizeof(Colour), &Colour);
  4058.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY3),
  4059.                       PP_BACKGROUNDCOLORINDEX,
  4060.                       (ULONG)sizeof(Colour), &Colour);
  4061.  
  4062.       Colour = CLR_YELLOW;
  4063.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
  4064.                       PP_FOREGROUNDCOLORINDEX,
  4065.                       (ULONG)sizeof(Colour), &Colour);
  4066.       WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY3),
  4067.                       PP_FOREGROUNDCOLORINDEX,
  4068.                       (ULONG)sizeof(Colour), &Colour);
  4069.  
  4070.       ScreenWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  4071.       ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  4072.       WinQueryWindowRect(hwndDlg, &rc);                  /*---------------*/
  4073.       X_Left = (SHORT)(ScreenWidth  - rc.xRight)  / 2;   /* Centre window */
  4074.       Y_Bot  = (SHORT)(ScreenHeight - rc.yTop) / 2;      /*---------------*/
  4075.       WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
  4076.                       SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  4077.  
  4078.       PgmEntry.hwnd          = hwndDlg;
  4079.       PgmEntry.hwndIcon      = NULL;
  4080.       PgmEntry.hprog         = NULL;
  4081.       PgmEntry.idProcess     = NULL;
  4082.       PgmEntry.idSession     = NULL;
  4083.       PgmEntry.uchVisibility = SWL_VISIBLE;
  4084.       PgmEntry.fbJump        = SWL_JUMPABLE;
  4085.       strcpy(PgmEntry.szSwtitle, "Hints & Tips");
  4086.       hwndEntry = WinAddSwitchEntry(&PgmEntry);
  4087.  
  4088.       for (Idx = 0; Idx < 26; Idx++)
  4089.       {
  4090.          /*--------------------------------------------------------------*/
  4091.          /* If all we want to do is store the key value...               */
  4092.          /*                                                              */
  4093.          /* WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,       */
  4094.          /*                   MPFROMSHORT(LIT_END),                      */
  4095.          /*                   MPFROMP(szCountry[Idx]));                  */
  4096.          /* KeyValue = Idx + 1;                                          */
  4097.          /* WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,    */
  4098.          /*                   (MPARAM)Idx, (MPARAM)KeyValue);            */
  4099.          /*--------------------------------------------------------------*/
  4100.  
  4101.          /*--------------------------------------------------------------*/
  4102.          /* Otherwise we need to save a pointer to our structure...      */
  4103.          /*                                                              */
  4104.          /*--------------------------------------------------------------*/
  4105.  
  4106.          WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
  4107.                            MPFROMSHORT(LIT_END),
  4108.                            MPFROMP(szCountry[Idx]));
  4109.          DosAllocSeg(22, &sel, 0);
  4110.          pDB_Data = MAKEP(sel, 0);
  4111.          pDB_Data->Key = Idx + 1;
  4112.          strcpy(pDB_Data->Capital, szCapital[Idx]);
  4113.          WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
  4114.                            (MPARAM)Idx, MPFROMP(pDB_Data));
  4115.  
  4116.          WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_INSERTITEM,
  4117.                            MPFROMSHORT(LIT_END),
  4118.                            MPFROMP(szCountry[Idx]));
  4119.  
  4120.          strcpy(szListBuff, szCountry[Idx]);
  4121.          strcat(szListBuff, "\t");
  4122.          strcat(szListBuff, szCapital[Idx]);
  4123.          WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_INSERTITEM,
  4124.                            MPFROMSHORT(LIT_END),
  4125.                            MPFROMP(szListBuff));
  4126.       }
  4127.       WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
  4128.                         MPFROMSHORT(0), (MPARAM)TRUE);
  4129.       break;
  4130.  
  4131.     case WM_MEASUREITEM:
  4132.       hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
  4133.       WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  4134.                         MPFROM2SHORT(Idx, sizeof(szListBuff)),
  4135.                         MPFROMP(szListBuff));
  4136.       GpiQueryFontMetrics(hps, (LONG)sizeof(FONTMETRICS), &fm);
  4137.       cyText = (SHORT)fm.lMaxBaselineExt;
  4138.       GpiQueryTextBox(hps, (LONG)strlen(szListBuff), szListBuff,
  4139.                       TXTBOX_COUNT, points);
  4140.                       /*-------------------------------------------------*/
  4141.                       /* May need to add on a bit to cxText to ensure    */
  4142.                       /* the entire item can be read when fully scrolled */
  4143.                       /*-------------------------------------------------*/
  4144.       cxText = (USHORT)points[TXTBOX_TOPRIGHT].x + 20;
  4145.       WinReleasePS(hps);
  4146.       return MRFROM2SHORT(cyText, cxText);
  4147.  
  4148.     case WM_DRAWITEM:
  4149.       pOwner = (POWNERITEM)mp2;
  4150.       rc.xRight  = pOwner->rclItem.xRight/3*2;
  4151.       rc.xLeft   = pOwner->rclItem.xLeft;
  4152.       rc.yTop    = pOwner->rclItem.yTop;
  4153.       rc.yBottom = pOwner->rclItem.yBottom;
  4154.  
  4155.       GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
  4156.  
  4157.       if ((!pOwner->fsState) ||                     // Unselected
  4158.           (pOwner->idItem == 5))                    // Don't allow Finland
  4159.       {
  4160.         GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
  4161.         GpiSetColor(pOwner->hps, CLR_YELLOW);
  4162.       }
  4163.       else                                          // Selected
  4164.       {
  4165.         GpiSetBackColor(pOwner->hps, CLR_YELLOW);
  4166.         GpiSetColor(pOwner->hps, CLR_DARKGREEN);
  4167.       }
  4168.  
  4169.       WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  4170.                         MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
  4171.                         MPFROMP(szListBuff));
  4172.  
  4173.       Country = strtok(szListBuff, "\t");
  4174.       Capital = strtok(NULL, "\t");
  4175.  
  4176.       WinDrawText(pOwner->hps, strlen(Country),
  4177.                   Country, &rc, 0L, 0L,
  4178.                   DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
  4179.  
  4180.                                       /*-----------------------------------*/
  4181.                                       /* Draw next item in right rectangle */
  4182.                                       /* allowing for horiz scrolling      */
  4183.                                       /*-----------------------------------*/
  4184.  
  4185.       if (pOwner->rclItem.xLeft != 1)           // i.e. we have been scrolled
  4186.         rc.xLeft = rc.xRight + pOwner->rclItem.xLeft - 1;
  4187.       else
  4188.         rc.xLeft = rc.xRight;
  4189.  
  4190.       rc.xRight = pOwner->rclItem.xRight;
  4191.  
  4192.       WinDrawText(pOwner->hps, strlen(Capital),
  4193.                   Capital, &rc, 0L, 0L,
  4194.                   DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
  4195.  
  4196.       pOwner->fsStateOld = pOwner->fsState = 0;     // Don't let PM hilite
  4197.       return (MRESULT)TRUE;                         // Don't let PM draw
  4198.  
  4199.     case WM_CONTROL:
  4200.       switch(SHORT1FROMMP(mp1))
  4201.       {
  4202.         case ID_SLISTBOX:
  4203.           switch(SHORT2FROMMP(mp1))
  4204.           {
  4205.             case LN_SELECT:
  4206.               Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  4207.                                              LM_QUERYSELECTION, 0L, 0L);
  4208.               if (Idx != LIT_NONE)
  4209.               {
  4210.                 WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), TRUE);
  4211.                 WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_QUERYITEMTEXT,
  4212.                                   MPFROM2SHORT(Idx, sizeof(szCtry)),
  4213.                                   MPFROMP(szCtry));
  4214.                 WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry);
  4215.  
  4216.                 /*-----------------------------------------------------------------*/
  4217.                 /* Retrieve the key value...                                       */
  4218.                 /*                                                                 */
  4219.                 /* KeyValue = (ULONG)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,       */
  4220.                 /*                                     LM_QUERYITEMHANDLE,         */
  4221.                 /*                                     MPFROMSHORT(Idx), NULL);    */
  4222.                 /* WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)KeyValue, FALSE); */
  4223.                 /*-----------------------------------------------------------------*/
  4224.  
  4225.                 /*-------------------------------------------------------------*/
  4226.                 /* Or, retrieve all data associated with the listbox item...   */
  4227.                 /*                                                             */
  4228.                 /*-------------------------------------------------------------*/
  4229.  
  4230.                 pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  4231.                                                       LM_QUERYITEMHANDLE,
  4232.                                                       MPFROMSHORT(Idx), NULL);
  4233.                 WinSetDlgItemText(hwndDlg, ID_ENTRY1, pDB_Data->Capital);
  4234.                 WinSetDlgItemShort(hwndDlg, ID_ENTRY2,
  4235.                                    (SHORT)pDB_Data->Key, FALSE);
  4236.               }
  4237.               break;
  4238.  
  4239.             default:
  4240.               break;
  4241.           }
  4242.           break;
  4243.  
  4244.         case ID_MLISTBOX:
  4245.           switch(SHORT2FROMMP(mp1))
  4246.           {
  4247.             case LN_SELECT:
  4248.               WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), TRUE);
  4249.               break;
  4250.  
  4251.             default:
  4252.               break;
  4253.           }
  4254.           break;
  4255.  
  4256.         case ID_OLISTBOX:
  4257.           switch(SHORT2FROMMP(mp1))
  4258.           {
  4259.             case LN_SELECT:
  4260.               Oidx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX,
  4261.                                               LM_QUERYSELECTION, 0L, 0L);
  4262.  
  4263.               if (Oidx == 5)                  // Don't allow Finland
  4264.               {
  4265.                 DosBeep(1000, 100);
  4266.                 break;
  4267.               }
  4268.  
  4269.               WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
  4270.                                 MPFROM2SHORT(Oidx, sizeof(szListBuff)),
  4271.                                 MPFROMP(szListBuff));
  4272.  
  4273.               Country = strtok(szListBuff, "\t");
  4274.               Capital = strtok(NULL, "\t");
  4275.  
  4276.               WinSetDlgItemText(hwndDlg, ID_ENTRY1, Capital);
  4277.               WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
  4278.               WinSetDlgItemText(hwndDlg, ID_ENTRY3, Country);
  4279.               break;
  4280.  
  4281.             default:
  4282.               break;
  4283.           }
  4284.           break;
  4285.       }
  4286.  
  4287.     case WM_COMMAND:
  4288.       switch(SHORT1FROMMP(mp1))
  4289.       {
  4290.         case ID_DESELECT:
  4291.           WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
  4292.                             MPFROMSHORT(Idx), (MPARAM)FALSE);
  4293.           WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_SELECTITEM,
  4294.                             MPFROMSHORT(Oidx), (MPARAM)FALSE);
  4295.           WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), FALSE);
  4296.           WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
  4297.           WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
  4298.           WinSetDlgItemText(hwndDlg, ID_ENTRY3, "");
  4299.           return FALSE;
  4300.  
  4301.         case ID_DELETE:
  4302.           pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
  4303.                                                 LM_QUERYITEMHANDLE,
  4304.                                                 MPFROMSHORT(Idx), NULL);
  4305.           DosFreeSeg(SELECTOROF(pDB_Data));
  4306.           WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEITEM,
  4307.                             MPFROMSHORT(Idx), NULL);
  4308.           WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
  4309.           WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
  4310.           WinSetDlgItemText(hwndDlg, ID_ENTRY3, "");
  4311.           WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
  4312.                             MPFROMSHORT(0), (MPARAM)TRUE);
  4313.           return FALSE;
  4314.  
  4315.         case ID_PROCMULT:
  4316.           WinSendMsg(hwndDlg, WM_COMMAND, MPFROMSHORT(ID_DESELECT), 0L);
  4317.           Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,
  4318.                                           LM_QUERYSELECTION,
  4319.                                           (MPARAM)LIT_FIRST, 0L);
  4320.           while(Midx != LIT_NONE)
  4321.           {
  4322.             WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_QUERYITEMTEXT,
  4323.                               MPFROM2SHORT(Midx, sizeof(szCtry)),
  4324.                               MPFROMP(szCtry));
  4325.             WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry);
  4326.  
  4327.             WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_SELECTITEM,
  4328.                               MPFROMSHORT(Midx), (MPARAM)FALSE);
  4329.  
  4330.                               /*------------------------------*/
  4331.             DosSleep(1000L);  /* DON'T DO THIS IN PM PROGRAMS */
  4332.                               /* AFFECTS PERFORMANCE SEVERELY */
  4333.                               /*------------------------------*/
  4334.  
  4335.             Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,
  4336.                                             LM_QUERYSELECTION,
  4337.                                             (MPARAM)Midx, 0L);
  4338.           }
  4339.           WinSetDlgItemText(hwndDlg, ID_ENTRY3, "Done");
  4340.           DosBeep(500, 200);
  4341.           WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), FALSE);
  4342.           return FALSE;
  4343.  
  4344.         case ID_EXIT:
  4345.           WinRemoveSwitchEntry(hwndEntry);
  4346.           WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
  4347.           break;
  4348.  
  4349.         default:
  4350.           return FALSE;
  4351.       }
  4352.       WinDismissDlg(hwndDlg, TRUE);                 /* Removes the dialog box */
  4353.       break;
  4354.  
  4355.     default:
  4356.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  4357.   }
  4358.   return FALSE;
  4359. }
  4360.  
  4361.  
  4362. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4363.  
  4364. #define ID_PROCMULT   266
  4365. #define ID_ENTRY3     265
  4366. #define ID_ENTRY2     264
  4367. #define ID_DELETE     263
  4368. #define ID_ENTRY1     262
  4369. #define ID_OLISTBOX   261
  4370. #define ID_MLISTBOX   260
  4371. #define ID_SLISTBOX   259
  4372. #define ID_EXIT       258
  4373. #define ID_DESELECT   257
  4374. #define DLG_HINTS     256
  4375.  
  4376.  
  4377. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4378.  
  4379. #include <os2.h>
  4380. #include "hints.h"
  4381.  
  4382. rcinclude hints.dlg
  4383.  
  4384.  
  4385. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4386.  
  4387. DLGINCLUDE 1 "HINTS.H"
  4388.  
  4389. DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
  4390. BEGIN
  4391.     DIALOG "Listbox Sample", DLG_HINTS, 30, 24, 317, 172, FS_NOBYTEALIGN |
  4392.                 FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  4393.                 FCF_SYSMENU | FCF_TITLEBAR
  4394.     BEGIN
  4395.         CONTROL "~Single Selection", 101, 8, 155, 80, 8, WC_STATIC, SS_TEXT |
  4396.                 DT_CENTER | DT_TOP | DT_MNEMONIC | WS_GROUP | WS_VISIBLE
  4397.         CONTROL "", ID_SLISTBOX, 8, 71, 80, 80, WC_LISTBOX, WS_TABSTOP |
  4398.                 WS_VISIBLE
  4399.         CONTROL "~Multiple Selection", 102, 115, 155, 80, 8, WC_STATIC,
  4400.                 SS_TEXT | DT_CENTER | DT_TOP | DT_MNEMONIC | WS_VISIBLE
  4401.         CONTROL "", ID_MLISTBOX, 115, 71, 80, 80, WC_LISTBOX, LS_MULTIPLESEL |
  4402.                 WS_TABSTOP | WS_VISIBLE
  4403.         CONTROL "~Ownerdraw", 103, 216, 155, 91, 8, WC_STATIC, SS_TEXT |
  4404.                 DT_CENTER | DT_TOP | DT_MNEMONIC | WS_VISIBLE
  4405.         CONTROL "", ID_OLISTBOX, 216, 71, 91, 83, WC_LISTBOX, LS_OWNERDRAW |
  4406.                 LS_HORZSCROLL | WS_TABSTOP | WS_VISIBLE
  4407.         CONTROL "Deselect", ID_DESELECT, 5, 5, 49, 13, WC_BUTTON, BS_PUSHBUTTON |
  4408.                 WS_TABSTOP | WS_VISIBLE
  4409.         CONTROL "Delete", ID_DELETE, 65, 5, 40, 13, WC_BUTTON, BS_PUSHBUTTON |
  4410.                 WS_TABSTOP | WS_VISIBLE
  4411.         CONTROL "Process MultSel", ID_PROCMULT, 115, 5, 79, 13, WC_BUTTON,
  4412.                 BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE
  4413.         CONTROL "Exit", ID_EXIT, 205, 5, 40, 13, WC_BUTTON, BS_PUSHBUTTON |
  4414.                 WS_TABSTOP | WS_VISIBLE
  4415.         CONTROL "", ID_ENTRY1, 77, 25, 100, 16, WC_ENTRYFIELD, ES_CENTER |
  4416.                 ES_AUTOSCROLL | ES_MARGIN | ES_READONLY | WS_GROUP | WS_VISIBLE
  4417.         CONTROL "Capital City", 104, 9, 28, 54, 8, WC_STATIC, SS_TEXT |
  4418.                 DT_LEFT | DT_TOP | WS_VISIBLE
  4419.         CONTROL "Key", 105, 200, 28, 21, 8, WC_STATIC, SS_TEXT | DT_LEFT |
  4420.                 DT_TOP | WS_VISIBLE
  4421.         CONTROL "", ID_ENTRY2, 232, 30, 39, 8, WC_ENTRYFIELD, ES_CENTER |
  4422.                 ES_MARGIN | ES_READONLY | WS_VISIBLE
  4423.         CONTROL "Country", 106, 9, 50, 48, 8, WC_STATIC, SS_TEXT | DT_LEFT |
  4424.                 DT_TOP | WS_VISIBLE
  4425.         CONTROL "", ID_ENTRY3, 77, 51, 100, 8, WC_ENTRYFIELD, ES_CENTER |
  4426.                 ES_MARGIN | ES_READONLY | WS_VISIBLE
  4427.     END
  4428. END
  4429.  
  4430.  
  4431. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4432.  
  4433. VOID  AddMenuItem(HWND hwnd)
  4434. {
  4435.   HWND        hSysMenu,
  4436.               hSysSubMenu;
  4437.   MENUITEM    SysMenu;
  4438.   SHORT       I,
  4439.               idSysMenu;
  4440.  
  4441.   static MENUITEM Item[2] = {MIT_END, MIS_SEPARATOR, 0, 0,        NULL, NULL,
  4442.                              MIT_END, MIS_TEXT,      0, ID_ABOUT, NULL, NULL};
  4443.  
  4444.   static CHAR    *Text[2] = {NULL, "~About..."};
  4445.  
  4446.  
  4447.   hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
  4448.                              FID_SYSMENU);
  4449.  
  4450.   idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
  4451.                            NULL, NULL));
  4452.  
  4453.   WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
  4454.              MPFROMP(&SysMenu));
  4455.  
  4456.   hSysSubMenu = SysMenu.hwndSubMenu;
  4457.  
  4458.   for (I = 0; I < 2; I++)
  4459.     WinSendMsg(hSysSubMenu, MM_INSERTITEM, MPFROMP(Item+I), MPFROMP(Text[I]));
  4460. }
  4461.  
  4462.  
  4463. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4464.  
  4465. case WM_INITMENU:
  4466.   switch (SHORT1FROMMP(mp1))
  4467.   {
  4468.     case IDM_TWO:
  4469.       /*---------------------------*/
  4470.       /* Toggle menu item 1 on/off */
  4471.       /*---------------------------*/
  4472.  
  4473.       hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4474.       hMenu  = WinWindowFromID(hFrame, FID_MENU);
  4475.       WinSendMsg(hMenu, MM_SETITEMATTR,
  4476.                  MPFROM2SHORT(MI_ITEM1, TRUE),
  4477.                  MPFROM2SHORT(MIA_CHECKED,
  4478.                               fbChecked ? MIA_CHECKED : 0));
  4479.       break;
  4480.   }
  4481.   break;
  4482.  
  4483. case WM_COMMAND:
  4484.   switch (SHORT1FROMMP(mp1))
  4485.     {
  4486.       case MI_ITEM1:
  4487.         fbChecked = (fbChecked ? FALSE : TRUE);
  4488.         break;
  4489.       ;
  4490.       ;
  4491.       ;
  4492.     }
  4493.   break;
  4494.  
  4495.  
  4496. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4497.  
  4498. /*-------------------------------------------*/
  4499. /* Delete 'Size' and 'Move' from system menu */
  4500. /*-------------------------------------------*/
  4501.  
  4502. hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
  4503.  
  4504. WinSendMsg(hwndSysMenu, MM_DELETEITEM,
  4505.            MPFROM2SHORT(SC_SIZE, TRUE),
  4506.            MPFROMSHORT(NULL));
  4507.  
  4508. WinSendMsg(hwndSysMenu, MM_DELETEITEM,
  4509.            MPFROM2SHORT(SC_MOVE, TRUE),
  4510.            MPFROMSHORT(NULL));
  4511.  
  4512.  
  4513. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4514.  
  4515. /*------------------------*/
  4516. /* Disable all menu items */
  4517. /*------------------------*/
  4518.  
  4519. hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4520. WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), FALSE);
  4521.  
  4522. /*-----------------------*/
  4523. /* Enable all menu items */
  4524. /*-----------------------*/
  4525.  
  4526. hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4527. WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), TRUE);
  4528.  
  4529.  
  4530. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4531.  
  4532. /*-------------------------------------*/
  4533. /* To disable CLOSE in the system menu */
  4534. /*-------------------------------------*/
  4535.  
  4536. hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
  4537.  
  4538. WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
  4539.            MPFROM2SHORT(SC_CLOSE, TRUE),
  4540.            MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  4541.  
  4542. /*--------------------*/
  4543. /* To enable it again */
  4544. /*--------------------*/
  4545.  
  4546. WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
  4547.            MPFROM2SHORT(SC_CLOSE, TRUE),
  4548.            MPFROM2SHORT(MIA_DISABLED, 0));
  4549.  
  4550.  
  4551. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4552.  
  4553. hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4554.  
  4555. WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
  4556. WinLoadMenu(hFrame, NULL, ID_MENU2);
  4557. WinSendMsg(hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)NULL);
  4558.  
  4559.  
  4560. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4561.  
  4562. case ID_ABOUT:
  4563.   WinMessageBox(HWND_DESKTOP, hwnd,
  4564.                 "Version 1\n24 April 1991\nWritten by Bryan Goodyer",
  4565.                 "PM Hints and Tips",
  4566.                 0,
  4567.                 MB_INFORMATION | MB_OK | MB_MOVEABLE );
  4568.   break;
  4569.  
  4570.  
  4571. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4572.  
  4573. case WM_BUTTON2DOWN:
  4574.   Pt.x = MOUSEMSG(&msg)->x;
  4575.   Pt.y = MOUSEMSG(&msg)->y + MenuHt;
  4576.   WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
  4577.   WinSetWindowPos(hMenu, HWND_TOP, (USHORT)Pt.x, (USHORT)Pt.y, 0, 0,
  4578.                   SWP_MOVE | SWP_SHOW);
  4579.   break;
  4580.  
  4581. case WM_NEXTMENU:
  4582.   return (MRESULT)NULL;
  4583.  
  4584.  
  4585. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4586.  
  4587. BEGIN
  4588.   MENUITEM "Menu Item ~1", MI_ITEM1, MIS_TEXT
  4589.   MENUITEM "Menu Item ~2", MI_ITEM2, MIS_TEXT, MIA_NODISMISS
  4590. END
  4591.  
  4592.  
  4593. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4594.  
  4595. static HWND hABar;
  4596.  
  4597.  
  4598. case WM_INITDLG:
  4599.   ;
  4600.   ;
  4601.   hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
  4602.   WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
  4603.   MenuHt = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  4604.   hMenu  = WinLoadMenu(hwndDlg, NULL, ID_MENU2);
  4605.   ;
  4606.   ;
  4607.   break
  4608.  
  4609.  
  4610. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4611.  
  4612. static HWND    hMenu;
  4613. static ULONG   MenuHt;
  4614. POINTL         Pt;
  4615.  
  4616.  
  4617. case WM_CREATE:
  4618.   hMenu  = WinLoadMenu(hwnd, NULL, ID_MENU2);
  4619.   MenuHt = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  4620.   break;
  4621.  
  4622. case WM_BUTTON2DOWN:
  4623.   Pt.x = MOUSEMSG(&msg)->x;
  4624.   Pt.y = MOUSEMSG(&msg)->y + MenuHt;
  4625.   WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
  4626.   WinSetWindowPos(hMenu, HWND_TOP, (SHORT)Pt.x, (SHORT)Pt.y, 0, 0,
  4627.                   SWP_MOVE | SWP_SHOW);
  4628.   break;
  4629.  
  4630.  
  4631. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4632.  
  4633. MENU  ID_MENU2  PRELOAD
  4634. BEGIN
  4635.   SUBMENU "", ID_OPTIONS2
  4636.   BEGIN
  4637.     MENUITEM  "Menu Item ~1", ID_ITEM1
  4638.     MENUITEM  "Menu Item ~2", ID_ITEM2
  4639.     MENUITEM  "Menu Item ~3", ID_ITEM3
  4640.     MENUITEM  SEPARATOR
  4641.     MENUITEM  "Menu Item ~4", ID_ITEM4
  4642.     MENUITEM  "Menu Item ~5", ID_ITEM5
  4643.   END
  4644. END
  4645.  
  4646.  
  4647. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4648.  
  4649. VOID  DelClose(HWND hwnd)
  4650. {
  4651.   HWND        hSysMenu,
  4652.               hSysSubMenu;
  4653.   MENUITEM    SysMenu;
  4654.   SHORT       idItem,
  4655.               idSep,
  4656.               idSysMenu;
  4657.  
  4658.   hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
  4659.                              FID_SYSMENU);
  4660.  
  4661.   idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
  4662.                            NULL, NULL));
  4663.  
  4664.   WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
  4665.              MPFROMP(&SysMenu));
  4666.  
  4667.   hSysSubMenu = SysMenu.hwndSubMenu;
  4668.  
  4669.   idItem = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMPOSITIONFROMID,
  4670.                                    MPFROM2SHORT(SC_CLOSE, FALSE), NULL));
  4671.   if (idItem != MIT_ERROR)
  4672.   {
  4673.     idSep = idItem + 1;                                  // Get separator ID
  4674.  
  4675.     idSep  = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMIDFROMPOSITION,
  4676.                                      MPFROMSHORT(idSep), NULL));
  4677.  
  4678.     WinSendMsg(hSysMenu, MM_DELETEITEM, MPFROM2SHORT(SC_CLOSE, TRUE),
  4679.                MPFROMSHORT(NULL));
  4680.  
  4681.     WinSendMsg(hSysSubMenu, MM_DELETEITEM, MPFROM2SHORT(idSep, FALSE), NULL);
  4682.   }
  4683. }
  4684.  
  4685.  
  4686. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4687.  
  4688. case WM_ADJUSTWINDOWPOS:
  4689.   if (((PSWP)mp1)->fs & SWP_MINIMIZE)
  4690.   {
  4691.     WinDestroyWindow(hABar);
  4692.   }
  4693.   else
  4694.     if (((PSWP)mp1)->fs & SWP_RESTORE)
  4695.     {
  4696.       ;
  4697.       ;
  4698.       hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
  4699.       WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
  4700.       ;
  4701.       ;
  4702.     }
  4703.   return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  4704.   break;
  4705.  
  4706.  
  4707. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4708.  
  4709. case WM_BUTTON1DOWN:
  4710.   /*-----------------------*/
  4711.   /* Force menu to dismiss */
  4712.   /*-----------------------*/
  4713.  
  4714.   hMenu = WinWindowFromID(hFrame, FID_MENU);
  4715.  
  4716.   WinPostMsg(hMenu, MM_STARTMENUMODE,
  4717.              MPFROM2SHORT(FALSE, TRUE), (MPARAM)NULL);
  4718.  
  4719.   WinPostMsg(hMenu, MM_ENDMENUMODE,
  4720.              MPFROMSHORT(TRUE), (MPARAM)NULL);
  4721.   ;
  4722.   ;
  4723.   ;
  4724.   break;
  4725.  
  4726.  
  4727. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4728.  
  4729. MENU       ID_MAINWND PRELOAD
  4730. BEGIN
  4731.   SUBMENU "E~xit",                     IDM_ONE
  4732.   BEGIN
  4733.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  4734.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  4735.   END
  4736. END
  4737.  
  4738. MENU       ID_MENU2
  4739. BEGIN
  4740.   SUBMENU "~Option 1",                 IDM_TWO
  4741.   BEGIN
  4742.     MENUITEM "Menu Item ~1",           MI_ITEM1,       MIS_TEXT
  4743.     MENUITEM "Menu Item ~2",           MI_ITEM2,       MIS_TEXT
  4744.   END
  4745.   SUBMENU "E~xit",                     IDM_THREE
  4746.   BEGIN
  4747.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  4748.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  4749.   END
  4750. END
  4751.  
  4752.  
  4753. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  4754.  
  4755. #define  INCL_WIN
  4756.  
  4757. #include <os2.h>
  4758. #include <string.h>
  4759. #include <stdlib.h>
  4760. #include "hints.h"
  4761.  
  4762.  
  4763. MRESULT EXPENTRY MainWndProc  (HWND, USHORT, MPARAM, MPARAM);
  4764. VOID    APIENTRY WinSetTitle  (PSZ);
  4765. BOOL    APIENTRY WinNoShutdown(USHORT, BOOL);
  4766. VOID             AddMenuItem  (HWND);
  4767. VOID             DelClose     (HWND);
  4768.  
  4769.  
  4770.  
  4771. /****************************************************************************/
  4772.  
  4773. VOID    cdecl main (void)
  4774. {
  4775.   HAB     hab;
  4776.   HMQ     hmq;
  4777.  
  4778.   HWND    hwndFrame,
  4779.           hwndEntry,
  4780.           hwndClient,
  4781.           hwndSysMenu;
  4782.   QMSG    qmsg;
  4783.   ULONG   flFrameFlags;
  4784.   CHAR    Title[80];
  4785.   SWCNTRL PgmEntry;
  4786.   SHORT   X_Left,
  4787.           Y_Bot,
  4788.           Height,
  4789.           Width;
  4790.   LONG    ScrHeight,
  4791.           ScrWidth;
  4792.  
  4793. /****************************************************************************/
  4794.  
  4795.   hab = WinInitialize(0);
  4796.   hmq = WinCreateMsgQueue(hab, 0);
  4797.  
  4798.   WinRegisterClass(hab,
  4799.                    "Hints",
  4800.                    MainWndProc,
  4801.                    CS_SIZEREDRAW,
  4802.                    0);
  4803.  
  4804.   WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
  4805.  
  4806.   flFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU    | FCF_MENU       |
  4807.                   FCF_SIZEBORDER | FCF_MINMAX     | FCF_ACCELTABLE |
  4808.                   FCF_ICON       | FCF_NOBYTEALIGN;
  4809.  
  4810.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  4811.                                  0L,
  4812.                                  &flFrameFlags,
  4813.                                  "Hints",
  4814.                                  (PSZ)Title,
  4815.                                  0L,
  4816.                                  NULL,
  4817.                                  ID_MAINWND,
  4818.                                  &hwndClient);
  4819.  
  4820.   WinCreateWindow(hwndClient,
  4821.                   WC_BUTTON,
  4822.                   "Switch Menus",
  4823.                   WS_VISIBLE,
  4824.                   10,
  4825.                   10,
  4826.                   120,
  4827.                   30,
  4828.                   hwndClient,
  4829.                   HWND_TOP,
  4830.                   ID_SWITCH,
  4831.                   0,
  4832.                   0);
  4833.  
  4834.   ScrWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  4835.   ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  4836.  
  4837.  
  4838.   Width  = 400;
  4839.   Height = 300;
  4840.  
  4841.   X_Left = ((SHORT)ScrWidth  - Width)  / 2;
  4842.   Y_Bot  = ((SHORT)ScrHeight - Height) / 2;
  4843.  
  4844.   /*-----------------------------------------------------------------------*/
  4845.   /* Startup in background                                                 */
  4846.   /*                                                                       */
  4847.   /* WinSetWindowPos(hwndFrame, HWND_BOTTOM, X_Left, Y_Bot, Width, Height, */
  4848.   /*                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER);         */
  4849.   /*-----------------------------------------------------------------------*/
  4850.  
  4851.   /*-----------------------*/
  4852.   /* Startup in foreground */
  4853.   /*-----------------------*/
  4854.  
  4855.   WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
  4856.                   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  4857.  
  4858.   /*------------------*/
  4859.   /* Add to task list */
  4860.   /*------------------*/
  4861.  
  4862.   PgmEntry.hwnd          = hwndFrame;
  4863.   PgmEntry.hwndIcon      = NULL;
  4864.   PgmEntry.hprog         = NULL;
  4865.   PgmEntry.idProcess     = NULL;
  4866.   PgmEntry.idSession     = NULL;
  4867.   PgmEntry.uchVisibility = SWL_VISIBLE;
  4868.   PgmEntry.fbJump        = SWL_JUMPABLE;
  4869.   strcpy(PgmEntry.szSwtitle, Title);
  4870.  
  4871.   hwndEntry = WinAddSwitchEntry(&PgmEntry);
  4872.  
  4873.   /*---------------------------------*/
  4874.   /* Disable 'End Task' in task list */
  4875.   /*---------------------------------*/
  4876.  
  4877.   WinNoShutdown(0, TRUE);
  4878.  
  4879.   /*--------------------------------*/
  4880.   /* Disable 'Close' in system menu */
  4881.   /*--------------------------------*/
  4882.  
  4883.   hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
  4884.   WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
  4885.              MPFROM2SHORT(SC_CLOSE, TRUE),
  4886.              MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  4887.  
  4888.   /*---------------------------------------*/
  4889.   /* Disable 'Switch to...' in system menu */
  4890.   /*---------------------------------------*/
  4891.  
  4892.   WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
  4893.              MPFROM2SHORT(SC_TASKMANAGER, TRUE),
  4894.              MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  4895.  
  4896.   /*-------------------------------------------*/
  4897.   /* Delete 'Size' and 'Move' from system menu */
  4898.   /*-------------------------------------------*/
  4899.  
  4900.   WinSendMsg(hwndSysMenu, MM_DELETEITEM,
  4901.              MPFROM2SHORT(SC_SIZE, TRUE),
  4902.              MPFROMSHORT(NULL));
  4903.  
  4904.   WinSendMsg(hwndSysMenu, MM_DELETEITEM,
  4905.              MPFROM2SHORT(SC_MOVE, TRUE),
  4906.              MPFROMSHORT(NULL));
  4907.  
  4908.   while (TRUE)
  4909.   {
  4910.     while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  4911.       WinDispatchMsg(hab, &qmsg);
  4912.  
  4913.       /*---------------------------------*/
  4914.       /* Don't allow exit from task list */
  4915.       /*---------------------------------*/
  4916.  
  4917.       if (qmsg.mp1 == NULL)
  4918.         break;
  4919.       else
  4920.       {
  4921.         DosBeep(100, 200);
  4922.         WinCancelShutdown(hmq, FALSE);
  4923.       }
  4924.   }
  4925.  
  4926.   /*------------------------------------*/
  4927.   /* Remove from task list and clean up */
  4928.   /*------------------------------------*/
  4929.  
  4930.   WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
  4931.   WinDestroyWindow(hwndFrame);
  4932.   WinDestroyMsgQueue(hmq);
  4933.   WinTerminate(hab);
  4934. }
  4935.  
  4936. /****************************************************************************/
  4937.  
  4938. MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  4939. {
  4940.   SWCNTRL PgmEntry;
  4941.   HWND    hFrame,
  4942.           hMenu,
  4943.           hSwL,
  4944.           hSysMenu;
  4945.  
  4946.   static  BOOL fbSwitched = FALSE,
  4947.                fbChecked  = FALSE;
  4948.  
  4949.  
  4950.   switch (msg)
  4951.     {
  4952.       case WM_CREATE:
  4953.         /*----------------------------*/
  4954.         /* Add 'About' to system menu */
  4955.         /*----------------------------*/
  4956.  
  4957.         AddMenuItem(hwnd);
  4958.  
  4959.         /*------------------------*/
  4960.         /* Disable all menu items */
  4961.         /*------------------------*/
  4962.  
  4963.         hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4964.         WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), FALSE);
  4965.  
  4966.         /*---------------------------------------------*/
  4967.         /*             Make system modal               */
  4968.         /*                                             */
  4969.         /* WinSetSysModalWindow(HWND_DESKTOP, hFrame); */
  4970.         /*---------------------------------------------*/
  4971.         break;
  4972.  
  4973.       case WM_INITMENU:
  4974.         switch (SHORT1FROMMP(mp1))
  4975.         {
  4976.           case IDM_TWO:
  4977.             /*---------------------------*/
  4978.             /* Toggle menu item 1 on/off */
  4979.             /*---------------------------*/
  4980.  
  4981.             hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  4982.             hMenu  = WinWindowFromID(hFrame, FID_MENU);
  4983.             WinSendMsg(hMenu, MM_SETITEMATTR,
  4984.                        MPFROM2SHORT(MI_ITEM1, TRUE),
  4985.                        MPFROM2SHORT(MIA_CHECKED,
  4986.                                     fbChecked ? MIA_CHECKED : 0));
  4987.             break;
  4988.         }
  4989.         break;
  4990.  
  4991.       case WM_BUTTON1DOWN:
  4992.         /*--------------------------------*/
  4993.         /* Enable 'End Task' in task list */
  4994.         /*--------------------------------*/
  4995.  
  4996.         WinNoShutdown(0, FALSE);
  4997.  
  4998.         /*-------------------------------*/
  4999.         /* Enable 'Close' in system menu */
  5000.         /*-------------------------------*/
  5001.  
  5002.         hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
  5003.                                    FID_SYSMENU);
  5004.         WinSendMsg(hSysMenu, MM_SETITEMATTR,
  5005.                    MPFROM2SHORT(SC_CLOSE, TRUE),
  5006.                    MPFROM2SHORT(MIA_DISABLED, 0));
  5007.  
  5008.         /*-----------------------*/
  5009.         /* Enable all menu items */
  5010.         /*-----------------------*/
  5011.  
  5012.         hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  5013.         WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), TRUE);
  5014.  
  5015.         /*-----------------------*/
  5016.         /* Force menu to dismiss */
  5017.         /*-----------------------*/
  5018.  
  5019.         hMenu = WinWindowFromID(hFrame, FID_MENU);
  5020.         WinPostMsg(hMenu, MM_STARTMENUMODE,
  5021.                    MPFROM2SHORT(FALSE, TRUE), (MPARAM)NULL);
  5022.         WinPostMsg(hMenu, MM_ENDMENUMODE,
  5023.                    MPFROMSHORT(TRUE), (MPARAM)NULL);
  5024.  
  5025.         /*------------------------*/
  5026.         /* Change task list entry */
  5027.         /*------------------------*/
  5028.  
  5029.         PgmEntry.hwnd          = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  5030.         PgmEntry.hwndIcon      = NULL;
  5031.         PgmEntry.hprog         = NULL;
  5032.         PgmEntry.idProcess     = NULL;
  5033.         PgmEntry.idSession     = NULL;
  5034.         PgmEntry.uchVisibility = SWL_VISIBLE;
  5035.         PgmEntry.fbJump        = SWL_JUMPABLE;
  5036.         strcpy(PgmEntry.szSwtitle, "Tips and Hints");
  5037.  
  5038.         WinChangeSwitchEntry(WinQuerySwitchHandle(PgmEntry.hwnd, 0), &PgmEntry);
  5039.  
  5040.         /*-----------------------*/
  5041.         /* Query task list entry */
  5042.         /*-----------------------*/
  5043.  
  5044.         hSwL = WinQuerySwitchHandle(WinQueryWindow(hwnd, QW_PARENT, FALSE), 0);
  5045.         WinQuerySwitchEntry(hSwL, &PgmEntry);
  5046.  
  5047.         /*-------------------------------------------*/
  5048.         /*         Remove system modality            */
  5049.         /*                                           */
  5050.         /* WinSetSysModalWindow(HWND_DESKTOP, NULL); */
  5051.         /*-------------------------------------------*/
  5052.         break;
  5053.  
  5054.       case WM_BUTTON2DOWN:
  5055.         /*----------------------------------*/
  5056.         /* Delete 'Close' and its Separator */
  5057.         /*----------------------------------*/
  5058.  
  5059.         DelClose(hwnd);
  5060.         break;
  5061.  
  5062.       case WM_COMMAND:
  5063.         switch (SHORT1FROMMP(mp1))
  5064.           {
  5065.             case ID_SWITCH:
  5066.               /*--------------*/
  5067.               /* Switch menus */
  5068.               /*--------------*/
  5069.  
  5070.               hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  5071.               if (!fbSwitched)
  5072.               {
  5073.                 WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
  5074.                 WinLoadMenu(hFrame, NULL, ID_MENU2);
  5075.                 WinSendMsg(hFrame, WM_UPDATEFRAME,
  5076.                            (MPARAM)FCF_MENU, (MPARAM)NULL);
  5077.                 fbSwitched = TRUE;
  5078.               }
  5079.               else
  5080.               {
  5081.                 WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
  5082.                 WinLoadMenu(hFrame, NULL, ID_MAINWND);
  5083.                 WinSendMsg(hFrame, WM_UPDATEFRAME,
  5084.                            (MPARAM)FCF_MENU, (MPARAM)NULL);
  5085.                 fbSwitched = FALSE;
  5086.               }
  5087.               break;
  5088.  
  5089.             case ID_ABOUT:
  5090.               /*-------------------*/
  5091.               /* Display About box */
  5092.               /*-------------------*/
  5093.  
  5094.               WinMessageBox(HWND_DESKTOP, hwnd,
  5095.                             "Version 1\n24 April 1991\nWritten by Bryan Goodyer",
  5096.                             "PM Hints and Tips",
  5097.                             0,
  5098.                             MB_INFORMATION | MB_OK | MB_MOVEABLE );
  5099.               break;
  5100.  
  5101.             case MI_ITEM1:
  5102.               fbChecked = (fbChecked ? FALSE : TRUE);
  5103.               break;
  5104.  
  5105.             case MI_EXIT:
  5106.               WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  5107.               break;
  5108.  
  5109.             default:
  5110.               break;
  5111.           }
  5112.         break;
  5113.  
  5114.       case WM_ERASEBACKGROUND:
  5115.         return (MRESULT)TRUE;
  5116.     }
  5117.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  5118. }
  5119.  
  5120. VOID  AddMenuItem(HWND hwnd)
  5121. {
  5122.   HWND        hSysMenu,
  5123.               hSysSubMenu;
  5124.   MENUITEM    SysMenu;
  5125.   SHORT       I,
  5126.               idSysMenu;
  5127.  
  5128.   static MENUITEM Item[2] = {MIT_END, MIS_SEPARATOR, 0, 0,        NULL, NULL,
  5129.                              MIT_END, MIS_TEXT,      0, ID_ABOUT, NULL, NULL};
  5130.  
  5131.   static CHAR    *Text[2] = {NULL, "~About..."};
  5132.  
  5133.  
  5134.   hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
  5135.                              FID_SYSMENU);
  5136.  
  5137.   idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
  5138.                            NULL, NULL));
  5139.  
  5140.   WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
  5141.              MPFROMP(&SysMenu));
  5142.  
  5143.   hSysSubMenu = SysMenu.hwndSubMenu;
  5144.  
  5145.   for (I = 0; I < 2; I++)
  5146.     WinSendMsg(hSysSubMenu, MM_INSERTITEM, MPFROMP(Item+I), MPFROMP(Text[I]));
  5147. }
  5148.  
  5149. VOID  DelClose(HWND hwnd)
  5150. {
  5151.   HWND        hSysMenu,
  5152.               hSysSubMenu;
  5153.   MENUITEM    SysMenu;
  5154.   SHORT       idItem,
  5155.               idSep,
  5156.               idSysMenu;
  5157.  
  5158.   hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
  5159.                              FID_SYSMENU);
  5160.  
  5161.   idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
  5162.                            NULL, NULL));
  5163.  
  5164.   WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
  5165.              MPFROMP(&SysMenu));
  5166.  
  5167.   hSysSubMenu = SysMenu.hwndSubMenu;
  5168.  
  5169.   idItem = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMPOSITIONFROMID,
  5170.                                    MPFROM2SHORT(SC_CLOSE, FALSE), NULL));
  5171.   if (idItem != MIT_ERROR)
  5172.   {
  5173.     idSep = idItem + 1;                                  // Get separator ID
  5174.  
  5175.     idSep  = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMIDFROMPOSITION,
  5176.                                      MPFROMSHORT(idSep), NULL));
  5177.  
  5178.     WinSendMsg(hSysMenu, MM_DELETEITEM, MPFROM2SHORT(SC_CLOSE, TRUE),
  5179.                MPFROMSHORT(NULL));
  5180.  
  5181.     WinSendMsg(hSysSubMenu, MM_DELETEITEM, MPFROM2SHORT(idSep, FALSE), NULL);
  5182.   }
  5183. }
  5184.  
  5185.  
  5186. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5187.  
  5188. #define   ID_MAINWND    200
  5189. #define   ID_TITLE      201
  5190. #define   ID_ABOUT      202
  5191. #define   MI_EXIT       203
  5192. #define   MI_RESUME     204
  5193. #define   ID_MENU2      205
  5194. #define   MI_ITEM1      206
  5195. #define   MI_ITEM2      207
  5196. #define   ID_SWITCH     208
  5197. #define   IDM_ONE       209
  5198. #define   IDM_TWO       210
  5199. #define   IDM_THREE     211
  5200.  
  5201.  
  5202. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5203.  
  5204. #include <os2.h>
  5205. #include "hints.h"
  5206.  
  5207. STRINGTABLE PRELOAD
  5208. BEGIN
  5209.  ID_TITLE,  "PM Hints and Tips"
  5210. END
  5211.  
  5212. ICON       ID_MAINWND  hints.ico
  5213.  
  5214. ACCELTABLE ID_MAINWND
  5215. BEGIN
  5216.   VK_F3,   MI_EXIT,        VIRTUALKEY
  5217. END
  5218.  
  5219. MENU       ID_MAINWND PRELOAD
  5220. BEGIN
  5221.   SUBMENU "E~xit",                     IDM_ONE
  5222.   BEGIN
  5223.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  5224.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  5225.   END
  5226. END
  5227.  
  5228. MENU       ID_MENU2
  5229. BEGIN
  5230.   SUBMENU "~Option 1",                 IDM_TWO
  5231.   BEGIN
  5232.     MENUITEM "Menu Item ~1",           MI_ITEM1,       MIS_TEXT
  5233.     MENUITEM "Menu Item ~2",           MI_ITEM2,       MIS_TEXT, MIA_NODISMISS
  5234.   END
  5235.   SUBMENU "E~xit",                     IDM_THREE
  5236.   BEGIN
  5237.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  5238.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  5239.   END
  5240. END
  5241.  
  5242.  
  5243. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5244.  
  5245. hints.exe: hints.obj \
  5246.           hints.def hints.res
  5247.  link @hints.l
  5248.  rc hints.res
  5249.  
  5250. hints.obj: hints.c hints.h
  5251.  cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
  5252.  
  5253. hints.res: hints.h hints.rc hints.ico
  5254.  rc -r hints.rc
  5255.  
  5256.  
  5257. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5258.  
  5259. HPOINTER hptr;
  5260.  
  5261.  
  5262.  
  5263. case WM_CONTROLPOINTER:
  5264.   hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5265.   WinSetPointer(HWND_DESKTOP, hptr);
  5266.   return(hptr);
  5267.  
  5268. case WM_MOUSEMOVE:
  5269.   hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5270.   WinSetPointer(HWND_DESKTOP, hptr);
  5271.   return (MPARAM)TRUE;
  5272.  
  5273.  
  5274. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5275.  
  5276. WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
  5277.  
  5278.  
  5279. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5280.  
  5281. POINTL   ptl;
  5282.  
  5283.  
  5284.  
  5285. WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
  5286.  
  5287.  
  5288. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5289.  
  5290. POINTL   ptl;
  5291.  
  5292.  
  5293.  
  5294. WinQueryPointerPos(HWND_DESKTOP, &ptl);
  5295.  
  5296.  
  5297. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5298.  
  5299. /*------------------------*/
  5300. /* In your main procedure */
  5301. /*------------------------*/
  5302.  
  5303. MRESULT EXPENTRY EntryProc(HWND, USHORT, MPARAM, MPARAM);
  5304.  
  5305. PFNWP   EntryFieldProc;             // Public Entry Field procedure
  5306.  
  5307.  
  5308. /*------------------------------*/
  5309. /* In your dialog box procedure */
  5310. /*------------------------------*/
  5311.  
  5312. case WM_INITDLG:
  5313.   EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY),
  5314.                                      EntryProc);
  5315.   ;
  5316.   ;
  5317.   ;
  5318.   break;
  5319.  
  5320.  
  5321. /*--------------------*/
  5322. /* Subclass procedure */
  5323. /*--------------------*/
  5324.  
  5325. MRESULT EXPENTRY  EntryProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  5326. {
  5327.   HPOINTER hptr;
  5328.  
  5329.  
  5330.   switch (msg)
  5331.   {
  5332.     case WM_MOUSEMOVE:
  5333.       hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5334.       WinSetPointer(HWND_DESKTOP, hptr);
  5335.       return (MPARAM)TRUE;
  5336.   }
  5337.                                      // Call public entry field procedure
  5338.   return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
  5339. }
  5340.  
  5341.  
  5342. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5343.  
  5344. /*------------------------*/
  5345. /* In your main procedure */
  5346. /*------------------------*/
  5347.  
  5348. MRESULT EXPENTRY ListProc(HWND, USHORT, MPARAM, MPARAM);
  5349.  
  5350. PFNWP   ListboxProc;                // Public Listbox procedure
  5351.  
  5352.  
  5353. /*------------------------------*/
  5354. /* In your dialog box procedure */
  5355. /*------------------------------*/
  5356.  
  5357. case WM_INITDLG:
  5358.   ListboxProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_LISTBOX),
  5359.                                   ListProc);
  5360.   ;
  5361.   ;
  5362.   ;
  5363.   break;
  5364.  
  5365.  
  5366. /*--------------------*/
  5367. /* Subclass procedure */
  5368. /*--------------------*/
  5369.  
  5370. MRESULT EXPENTRY  ListProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  5371. {
  5372.   HPOINTER hptr;
  5373.  
  5374.  
  5375.   switch (msg)
  5376.   {
  5377.     case WM_CONTROLPOINTER:
  5378.       hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5379.       WinSetPointer(HWND_DESKTOP, hptr);
  5380.       return(hptr);
  5381.   }
  5382.                                      // Call public listbox procedure
  5383.   return ((*ListboxProc)(hwnd, msg, mp1, mp2));
  5384. }
  5385.  
  5386.  
  5387. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5388.  
  5389.  
  5390. #define  INCL_WIN
  5391.  
  5392. #include <os2.h>
  5393. #include <string.h>
  5394. #include <stdlib.h>
  5395. #include "hints.h"
  5396.  
  5397.  
  5398. MRESULT EXPENTRY MainWndProc  (HWND, USHORT, MPARAM, MPARAM);
  5399. MRESULT EXPENTRY TestDlgProc  (HWND, USHORT, MPARAM, MPARAM);
  5400. MRESULT EXPENTRY EntryProc    (HWND, USHORT, MPARAM, MPARAM);
  5401. MRESULT EXPENTRY ListProc     (HWND, USHORT, MPARAM, MPARAM);
  5402.  
  5403. PFNWP   EntryFieldProc;             // Public Entry Field procedure
  5404. PFNWP   ListboxProc;                // Public Listbox procedure
  5405.  
  5406. BOOL    fbBusy = TRUE;
  5407.  
  5408. /****************************************************************************/
  5409.  
  5410. VOID    cdecl main (void)
  5411. {
  5412.   HAB     hab;
  5413.   HMQ     hmq;
  5414.  
  5415.   HWND    hwndFrame,
  5416.           hwndEntry,
  5417.           hwndClient,
  5418.           hstatic;
  5419.   QMSG    qmsg;
  5420.   ULONG   flFrameFlags;
  5421.   CHAR    Title[80];
  5422.   SWCNTRL PgmEntry;
  5423.   SHORT   X_Left,
  5424.           Y_Bot,
  5425.           Height,
  5426.           Width;
  5427.   LONG    ScrHeight,
  5428.           ScrWidth;
  5429.  
  5430. /****************************************************************************/
  5431.  
  5432.   hab = WinInitialize(0);
  5433.   hmq = WinCreateMsgQueue(hab, 0);
  5434.  
  5435.   WinRegisterClass(hab,
  5436.                    "Hints",
  5437.                    MainWndProc,
  5438.                    CS_SIZEREDRAW,
  5439.                    0);
  5440.  
  5441.   WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
  5442.  
  5443.   flFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU    | FCF_MENU       |
  5444.                   FCF_SIZEBORDER | FCF_MINMAX     | FCF_ACCELTABLE |
  5445.                   FCF_ICON       | FCF_NOBYTEALIGN;
  5446.  
  5447.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  5448.                                  0L,
  5449.                                  &flFrameFlags,
  5450.                                  "Hints",
  5451.                                  (PSZ)Title,
  5452.                                  0L,
  5453.                                  NULL,
  5454.                                  ID_MAINWND,
  5455.                                  &hwndClient);
  5456.  
  5457.   WinCreateWindow(hwndClient, WC_BUTTON, "Test DLG", WS_VISIBLE,
  5458.                   10, 10, 150, 30, hwndClient, HWND_TOP, ID_DLG, 0, 0);
  5459.  
  5460.   WinCreateWindow(hwndClient, WC_BUTTON, "Remove Hourglass", WS_VISIBLE,
  5461.                   175, 10, 200, 30, hwndClient, HWND_TOP, ID_REMOVE, 0, 0);
  5462.  
  5463.   WinCreateWindow(hwndClient, WC_STATIC, "", WS_VISIBLE | SS_TEXT,
  5464.                   10, 125, 400, 30, hwndClient, HWND_TOP, ID_PTRTEXT1, 0, 0);
  5465.  
  5466.   WinCreateWindow(hwndClient, WC_STATIC, "", WS_VISIBLE | SS_TEXT,
  5467.                   10, 75, 400, 30, hwndClient, HWND_TOP, ID_PTRTEXT2, 0, 0);
  5468.  
  5469.   ScrWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  5470.   ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  5471.  
  5472.  
  5473.   Width  = 450;
  5474.   Height = 300;
  5475.  
  5476.   X_Left = ((SHORT)ScrWidth  - Width)  / 2;
  5477.   Y_Bot  = ((SHORT)ScrHeight - Height) / 2;
  5478.  
  5479.   /*-----------------------*/
  5480.   /* Startup in foreground */
  5481.   /*-----------------------*/
  5482.  
  5483.   WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
  5484.                   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  5485.  
  5486.   /*------------------*/
  5487.   /* Add to task list */
  5488.   /*------------------*/
  5489.  
  5490.   PgmEntry.hwnd          = hwndFrame;
  5491.   PgmEntry.hwndIcon      = NULL;
  5492.   PgmEntry.hprog         = NULL;
  5493.   PgmEntry.idProcess     = NULL;
  5494.   PgmEntry.idSession     = NULL;
  5495.   PgmEntry.uchVisibility = SWL_VISIBLE;
  5496.   PgmEntry.fbJump        = SWL_JUMPABLE;
  5497.   strcpy(PgmEntry.szSwtitle, Title);
  5498.  
  5499.   hwndEntry = WinAddSwitchEntry(&PgmEntry);
  5500.  
  5501.   while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  5502.     WinDispatchMsg(hab, &qmsg);
  5503.  
  5504.   /*------------------------------------*/
  5505.   /* Remove from task list and clean up */
  5506.   /*------------------------------------*/
  5507.  
  5508.   WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
  5509.   WinDestroyWindow(hwndFrame);
  5510.   WinDestroyMsgQueue(hmq);
  5511.   WinTerminate(hab);
  5512. }
  5513.  
  5514. /****************************************************************************/
  5515.  
  5516. MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  5517. {
  5518.   HPOINTER hptr;
  5519.   POINTL   ptl;
  5520.   CHAR     szText[100],
  5521.            szCoord[10];
  5522.  
  5523.  
  5524.   switch (msg)
  5525.     {
  5526.       case WM_PAINT:
  5527.         WinQueryPointerPos(HWND_DESKTOP, &ptl);
  5528.         strcpy(szText, "(Screen Coords) Mouse X = ");
  5529.         ltoa(ptl.x, szCoord, 10);
  5530.         strcat(szText, szCoord);
  5531.         strcat(szText, "  Mouse Y = ");
  5532.         ltoa(ptl.y, szCoord, 10);
  5533.         strcat(szText, szCoord);
  5534.         WinSetWindowText(WinWindowFromID(hwnd, ID_PTRTEXT1), szText);
  5535.  
  5536.         WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
  5537.         strcpy(szText, "(Window Coords) Mouse X = ");
  5538.         ltoa(ptl.x, szCoord, 10);
  5539.         strcat(szText, szCoord);
  5540.         strcat(szText, "  Mouse Y = ");
  5541.         ltoa(ptl.y, szCoord, 10);
  5542.         strcat(szText, szCoord);
  5543.         WinSetWindowText(WinWindowFromID(hwnd, ID_PTRTEXT2), szText);
  5544.         break;
  5545.  
  5546.       case WM_CONTROLPOINTER:
  5547.         if (!fbBusy)
  5548.           break;
  5549.  
  5550.         /*-----------------------------------------------------*/
  5551.         /*                    Load icon                        */
  5552.         /* hptr = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON); */
  5553.         /*-----------------------------------------------------*/
  5554.  
  5555.         /*-----------------------------*/
  5556.         /* Change pointer to hourglass */
  5557.         /*-----------------------------*/
  5558.         hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5559.         WinSetPointer(HWND_DESKTOP, hptr);
  5560.         return(hptr);
  5561.  
  5562.       case WM_BUTTON2DOWN:
  5563.         WinSetCapture(HWND_DESKTOP, hwnd);
  5564.         break;
  5565.  
  5566.       case WM_BUTTON2UP:
  5567.         WinSetCapture(HWND_DESKTOP, NULL);
  5568.         break;
  5569.  
  5570.       case WM_MOUSEMOVE:
  5571.         WinInvalidateRect(hwnd, NULL, FALSE);
  5572.         if (!fbBusy)
  5573.           break;
  5574.  
  5575.         /*-----------------------------------------------------*/
  5576.         /*                    Load icon                        */
  5577.         /* hptr = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON); */
  5578.         /*-----------------------------------------------------*/
  5579.  
  5580.         /*-----------------------------*/
  5581.         /* Change pointer to hourglass */
  5582.         /*-----------------------------*/
  5583.         hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5584.         WinSetPointer(HWND_DESKTOP, hptr);
  5585.         return (MPARAM)TRUE;
  5586.  
  5587.       case WM_COMMAND:
  5588.         switch (SHORT1FROMMP(mp1))
  5589.           {
  5590.             case ID_DLG:
  5591.               WinDlgBox(HWND_DESKTOP, hwnd, TestDlgProc, NULL,
  5592.                         DLG_HINTS, NULL );
  5593.               break;
  5594.  
  5595.             case ID_REMOVE:
  5596.               fbBusy = FALSE;
  5597.               WinEnableWindow(WinWindowFromID(hwnd, ID_REMOVE), FALSE);
  5598.               break;
  5599.  
  5600.             case MI_EXIT:
  5601.               WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  5602.               break;
  5603.  
  5604.             default:
  5605.               break;
  5606.           }
  5607.         break;
  5608.  
  5609.       case WM_ERASEBACKGROUND:
  5610.         return (MRESULT)TRUE;
  5611.     }
  5612.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  5613. }
  5614.  
  5615. MRESULT EXPENTRY TestDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
  5616. {
  5617.   HPOINTER hptr;
  5618.  
  5619.  
  5620.   switch (msg)
  5621.   {
  5622.     case WM_INITDLG:
  5623.       if (!fbBusy)
  5624.         break;
  5625.  
  5626.       EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY),
  5627.                                          EntryProc);
  5628.       ListboxProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_LISTBOX),
  5629.                                       ListProc);
  5630.       WinEnableWindow(WinWindowFromID(hwndDlg, ID_ENTRY), FALSE);
  5631.       break;
  5632.  
  5633.     case WM_CONTROLPOINTER:
  5634.       if (!fbBusy)
  5635.         return (WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
  5636.  
  5637.       hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5638.       WinSetPointer(HWND_DESKTOP, hptr);
  5639.       return(hptr);
  5640.  
  5641.     case WM_COMMAND:
  5642.       switch(SHORT1FROMMP(mp1))
  5643.       {
  5644.         case ID_OK:
  5645.           WinDismissDlg(hwndDlg, TRUE);
  5646.           break;
  5647.  
  5648.         default:
  5649.           return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  5650.       }
  5651.  
  5652.       WinDismissDlg(hwndDlg, TRUE);
  5653.       break;
  5654.  
  5655.     default:
  5656.       return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  5657.   }
  5658.   return FALSE;
  5659. }
  5660.  
  5661. MRESULT EXPENTRY  EntryProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  5662. {
  5663.   HPOINTER hptr;
  5664.  
  5665.  
  5666.   switch (msg)
  5667.   {
  5668.     case WM_MOUSEMOVE:
  5669.       hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5670.       WinSetPointer(HWND_DESKTOP, hptr);
  5671.       return (MPARAM)TRUE;
  5672.   }
  5673.                                      // Call public entry field procedure
  5674.   return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
  5675. }
  5676.  
  5677. MRESULT EXPENTRY  ListProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  5678. {
  5679.   HPOINTER hptr;
  5680.  
  5681.  
  5682.   switch (msg)
  5683.   {
  5684.     case WM_CONTROLPOINTER:
  5685.       hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  5686.       WinSetPointer(HWND_DESKTOP, hptr);
  5687.       return(hptr);
  5688.   }
  5689.                                      // Call public listbox procedure
  5690.   return ((*ListboxProc)(hwnd, msg, mp1, mp2));
  5691. }
  5692.  
  5693.  
  5694. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5695.  
  5696. #define ID_PTRTEXT2  262
  5697. #define ID_PTRTEXT1  261
  5698. #define ID_REMOVE    260
  5699. #define ID_DLG       259
  5700. #define ID_LISTBOX   258
  5701. #define ID_OK        257
  5702. #define DLG_HINTS    256
  5703. #define ID_ICON      206
  5704. #define ID_ENTRY     205
  5705. #define MI_RESUME    204
  5706. #define MI_EXIT      203
  5707. #define IDM_ONE      202
  5708. #define ID_TITLE     201
  5709. #define ID_MAINWND   200
  5710.  
  5711.  
  5712. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5713.  
  5714. #include <os2.h>
  5715. #include "hints.h"
  5716.  
  5717. STRINGTABLE PRELOAD
  5718. BEGIN
  5719.  ID_TITLE,  "PM Hints and Tips"
  5720. END
  5721.  
  5722. ICON       ID_MAINWND  hints.ico
  5723. ICON       ID_ICON     wait.ico
  5724.  
  5725. ACCELTABLE ID_MAINWND
  5726. BEGIN
  5727.   VK_F3,   MI_EXIT,        VIRTUALKEY
  5728. END
  5729.  
  5730. MENU       ID_MAINWND PRELOAD
  5731. BEGIN
  5732.   SUBMENU "E~xit",                     IDM_ONE
  5733.   BEGIN
  5734.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  5735.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  5736.   END
  5737. END
  5738.  
  5739. rcinclude hints.dlg
  5740.  
  5741.  
  5742. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5743.  
  5744. DLGINCLUDE 1 "HINTS.H"
  5745.  
  5746. DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
  5747. BEGIN
  5748.     DIALOG "Test Dialog Box", DLG_HINTS, 22, 20, 114, 101, FS_NOBYTEALIGN |
  5749.                 FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  5750.                 FCF_TITLEBAR
  5751.     BEGIN
  5752.         CONTROL "OK", ID_OK, 5, 5, 29, 13, WC_BUTTON, BS_PUSHBUTTON | BS_DEFAULT |
  5753.                 WS_TABSTOP | WS_VISIBLE
  5754.         CONTROL "", ID_ENTRY, 7, 84, 100, 8, WC_ENTRYFIELD, ES_LEFT | ES_MARGIN |
  5755.                 WS_TABSTOP | WS_VISIBLE
  5756.         CONTROL "", ID_LISTBOX, 5, 21, 104, 56, WC_LISTBOX, WS_TABSTOP |
  5757.                 WS_VISIBLE
  5758.     END
  5759. END
  5760.  
  5761.  
  5762. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5763.  
  5764. hints.exe: hints.obj \
  5765.           hints.def hints.res
  5766.  link @hints.l
  5767.  rc hints.res
  5768.  
  5769. hints.obj: hints.c hints.h
  5770.  cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
  5771.  
  5772. hints.res: hints.h hints.rc hints.ico hints.dlg wait.ico
  5773.  rc -r hints.rc
  5774.  
  5775.  
  5776. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5777.  
  5778. ULONG  Colour;
  5779.  
  5780.  
  5781.  
  5782. Colour = CLR_RED;
  5783. WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
  5784.                 PP_BACKGROUNDCOLORINDEX,
  5785.                 (ULONG)sizeof(Colour), &Colour);
  5786.  
  5787. Colour = CLR_YELLOW;
  5788. WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
  5789.                 PP_FOREGROUNDCOLORINDEX,
  5790.                 (ULONG)sizeof(Colour), &Colour);
  5791.  
  5792.  
  5793. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5794.  
  5795. CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
  5796.         WS_TABSTOP | WS_VISIBLE
  5797.         PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
  5798.         PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
  5799.  
  5800.  
  5801. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5802.  
  5803. CHAR  font[11];
  5804.  
  5805.  
  5806. /*------------------------------------------------*/
  5807. /* Length parameter must include NULL terminator, */
  5808. /* so use SIZEOF and not STRLEN                   */
  5809. /*------------------------------------------------*/
  5810.  
  5811. strcpy(font, "10.Courier");
  5812. WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
  5813.                 PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
  5814.  
  5815.  
  5816. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5817.  
  5818. CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
  5819.         WS_TABSTOP | WS_VISIBLE
  5820.         PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
  5821.  
  5822.  
  5823. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5824.  
  5825. static  HWND  hwndEntry;
  5826.  
  5827. SWCNTRL PgmEntry;
  5828.  
  5829.  
  5830.  
  5831. PgmEntry.hwnd          = hwndFrame;
  5832. PgmEntry.hwndIcon      = NULL;
  5833. PgmEntry.hprog         = NULL;
  5834. PgmEntry.idProcess     = NULL;
  5835. PgmEntry.idSession     = NULL;
  5836. PgmEntry.uchVisibility = SWL_VISIBLE;
  5837. PgmEntry.fbJump        = SWL_JUMPABLE;
  5838. strcpy(PgmEntry.szSwtitle, Title);
  5839.  
  5840. hwndEntry = WinAddSwitchEntry(&PgmEntry);
  5841.  
  5842. while(WinGetMsg(hab, &qmsg, NULL, 0, 0))
  5843.   WinDispatchMsg(hab, &qmsg);
  5844.  
  5845. WinRemoveSwitchEntry(hwndEntry);
  5846.  
  5847.  
  5848. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5849.  
  5850. SWCNTRL PgmEntry;
  5851.  
  5852.  
  5853.  
  5854. case WM_xxx:
  5855.   ;
  5856.   ;
  5857.   PgmEntry.hwnd          = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  5858.   PgmEntry.hwndIcon      = NULL;
  5859.   PgmEntry.hprog         = NULL;
  5860.   PgmEntry.idProcess     = NULL;
  5861.   PgmEntry.idSession     = NULL;
  5862.   PgmEntry.uchVisibility = SWL_VISIBLE;
  5863.   PgmEntry.fbJump        = SWL_JUMPABLE;
  5864.   strcpy(PgmEntry.szSwtitle, "Tips and Hints");
  5865.  
  5866.   WinChangeSwitchEntry(WinQuerySwitchHandle(PgmEntry.hwnd, 0), &PgmEntry);
  5867.   break;
  5868.  
  5869.  
  5870. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5871.  
  5872. VOID APIENTRY WinSetTitle(PSZ);
  5873.  
  5874.  
  5875.  
  5876.  
  5877. case WM_xxx:
  5878.   ;
  5879.   ;
  5880.   WinSetTitle("Tips and Hints");
  5881.   break;
  5882.  
  5883.  
  5884. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5885.  
  5886. while (TRUE)
  5887. {
  5888.   while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  5889.     WinDispatchMsg(hab, &qmsg);
  5890.  
  5891.     if (qmsg.mp1 == NULL)
  5892.       break;
  5893.     else
  5894.       WinCancelShutdown(hmq, FALSE);
  5895. }
  5896.  
  5897.  
  5898. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5899.  
  5900. BOOL APIENTRY WinNoShutdown(USHORT sessionid, BOOL fNoShutdown);
  5901.  
  5902.  
  5903.  
  5904. WinNoShutdown(0, TRUE);    // To disable
  5905. WinNoShutdown(0, FALSE);   // To enable
  5906.  
  5907.  
  5908. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5909.  
  5910. hSwL = WinQuerySwitchHandle(hwndFrame, 0);
  5911.  
  5912.  
  5913. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5914.  
  5915. hSwL = WinQuerySwitchHandle(WinQueryWindow(hwnd, QW_PARENT, FALSE), 0);
  5916. WinQuerySwitchEntry(hSwL, &PgmEntry);
  5917.  
  5918.  
  5919. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  5920.  
  5921. #define  INCL_WIN
  5922.  
  5923. #include <os2.h>
  5924. #include <string.h>
  5925. #include <stdlib.h>
  5926. #include "hints.h"
  5927.  
  5928.  
  5929. MRESULT EXPENTRY MainWndProc  (HWND, USHORT, MPARAM, MPARAM);
  5930.  
  5931.  
  5932.  
  5933. /****************************************************************************/
  5934.  
  5935. VOID    cdecl main (void)
  5936. {
  5937.   HAB     hab;
  5938.   HMQ     hmq;
  5939.  
  5940.   HWND    hwndFrame,
  5941.           hwndClient;
  5942.   QMSG    qmsg;
  5943.   ULONG   flFrameFlags;
  5944.   CHAR    Title[80];
  5945.   SWCNTRL PgmEntry;
  5946.   SHORT   X_Left,
  5947.           Y_Bot,
  5948.           Height,
  5949.           Width;
  5950.   LONG    ScrHeight,
  5951.           ScrWidth;
  5952.  
  5953. /****************************************************************************/
  5954.  
  5955.   hab = WinInitialize(0);
  5956.   hmq = WinCreateMsgQueue(hab, 0);
  5957.  
  5958.   WinRegisterClass(hab,
  5959.                    "Hints",
  5960.                    MainWndProc,
  5961.                    CS_SIZEREDRAW,
  5962.                    0);
  5963.  
  5964.   WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
  5965.  
  5966.   flFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU    | FCF_MENU       |
  5967.                   FCF_SIZEBORDER | FCF_MINMAX     | FCF_ACCELTABLE |
  5968.                   FCF_ICON;
  5969.  
  5970.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  5971.                                  0L,
  5972.                                  &flFrameFlags,
  5973.                                  "Hints",
  5974.                                  (PSZ)Title,
  5975.                                  0L,
  5976.                                  NULL,
  5977.                                  ID_MAINWND,
  5978.                                  &hwndClient);
  5979.  
  5980.   ScrWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  5981.   ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  5982.  
  5983.  
  5984.   Width  = 400;
  5985.   Height = 300;
  5986.  
  5987.   X_Left = ((SHORT)ScrWidth  - Width)  / 2;
  5988.   Y_Bot  = ((SHORT)ScrHeight - Height) / 2;
  5989.  
  5990.   /*-----------------------*/
  5991.   /* Startup in foreground */
  5992.   /*-----------------------*/
  5993.  
  5994.   WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
  5995.                   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  5996.  
  5997.   /*------------------*/
  5998.   /* Add to task list */
  5999.   /*------------------*/
  6000.  
  6001.   PgmEntry.hwnd          = hwndFrame;
  6002.   PgmEntry.hwndIcon      = NULL;
  6003.   PgmEntry.hprog         = NULL;
  6004.   PgmEntry.idProcess     = NULL;
  6005.   PgmEntry.idSession     = NULL;
  6006.   PgmEntry.uchVisibility = SWL_VISIBLE;
  6007.   PgmEntry.fbJump        = SWL_JUMPABLE;
  6008.   strcpy(PgmEntry.szSwtitle, Title);
  6009.  
  6010.   WinAddSwitchEntry(&PgmEntry);
  6011.  
  6012.   while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  6013.     WinDispatchMsg(hab, &qmsg);
  6014.  
  6015.   /*------------------------------------*/
  6016.   /* Remove from task list and clean up */
  6017.   /*------------------------------------*/
  6018.  
  6019.   WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
  6020.   WinDestroyWindow(hwndFrame);
  6021.   WinDestroyMsgQueue(hmq);
  6022.   WinTerminate(hab);
  6023. }
  6024.  
  6025. /****************************************************************************/
  6026.  
  6027. MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  6028. {
  6029.   switch (msg)
  6030.     {
  6031.       case WM_COMMAND:
  6032.         switch (SHORT1FROMMP(mp1))
  6033.           {
  6034.             case MI_EXIT:
  6035.               WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  6036.               break;
  6037.  
  6038.             default:
  6039.               break;
  6040.           }
  6041.         break;
  6042.  
  6043.       case WM_ERASEBACKGROUND:
  6044.         return (MRESULT)TRUE;
  6045.     }
  6046.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  6047. }
  6048.  
  6049.  
  6050. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6051.  
  6052. #define   ID_MAINWND    200
  6053. #define   ID_TITLE      201
  6054. #define   IDM_ONE       202
  6055. #define   MI_EXIT       203
  6056. #define   MI_RESUME     204
  6057.  
  6058.  
  6059. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6060.  
  6061. #include <os2.h>
  6062. #include "hints.h"
  6063.  
  6064. STRINGTABLE PRELOAD
  6065. BEGIN
  6066.  ID_TITLE,  "PM Hints and Tips"
  6067. END
  6068.  
  6069. ICON       ID_MAINWND  hints.ico
  6070.  
  6071. ACCELTABLE ID_MAINWND
  6072. BEGIN
  6073.   VK_F3,   MI_EXIT,        VIRTUALKEY
  6074. END
  6075.  
  6076. MENU       ID_MAINWND PRELOAD
  6077. BEGIN
  6078.   SUBMENU "E~xit",                     IDM_ONE
  6079.   BEGIN
  6080.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  6081.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  6082.   END
  6083. END
  6084.  
  6085.  
  6086. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6087.  
  6088. hints.exe: hints.obj \
  6089.           hints.def hints.res
  6090.  link @hints.l
  6091.  rc hints.res
  6092.  
  6093. hints.obj: hints.c hints.h
  6094.  cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
  6095.  
  6096. hints.res: hints.h hints.rc hints.ico
  6097.  rc -r hints.rc
  6098.  
  6099.  
  6100. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6101.  
  6102. SHORT  X_Left,
  6103.        Y_Bot,
  6104.        Height,
  6105.        Width;
  6106. LONG   ScrHeight,
  6107.        ScrWidth;
  6108.  
  6109.  
  6110.  
  6111. ScrWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  6112. ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  6113.  
  6114.                 /*-----------------------------------------------*/
  6115. Width  = 400;   /* Or set as a percentage of screen size         */
  6116. Height = 300;   /* eg. Width = ScrWidth/2; Height = ScrHeight/2; */
  6117.                 /*-----------------------------------------------*/
  6118. X_Left = ((SHORT)ScrWidth  - Width)  / 2;
  6119. Y_Bot  = ((SHORT)ScrHeight - Height) / 2;
  6120.  
  6121. WinSetWindowPos(hwndFrame, HWND_TOP, X_Left, Y_Bot, Width, Height,
  6122.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6123.  
  6124.  
  6125. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6126.  
  6127. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6128.  
  6129. WinSetWindowText(hwndFrame, "Hints - Size and Position Fixed");
  6130.  
  6131.  
  6132. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6133.  
  6134. FCF_STANDARD includes the following flags - 
  6135.  
  6136.  o FCF_TITLEBAR 
  6137.  o FCF_SYSMENU 
  6138.  o FCF_MINMAX 
  6139.  o FCF_SIZEBORDER 
  6140.  o FCF_TASKLIST 
  6141.  o FCF_MENU 
  6142.  o FCF_ACCELTABLE 
  6143.  o FCF_SHELLPOSITION 
  6144.  o FCF_ICON 
  6145.  
  6146.  If you required all these flags except FCF_ACCELTABLE then you could set up 
  6147.  your own identifier as follows - 
  6148.  
  6149.  
  6150.   #define FCF_NOACCEL  FCF_STANDARD & ~FCF_ACCELTABLE
  6151.  
  6152.  
  6153. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6154.  
  6155. WinMapWindowPoints(hwnd, WinQueryWindow(hwnd, QW_PARENT, FALSE),
  6156.                   (PPOINTL)&WinRect, 2);
  6157.  
  6158.  
  6159. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6160.  
  6161. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6162.  
  6163. WinSetWindowPos(hwndFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE);
  6164.  
  6165.  
  6166. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6167.  
  6168. case WM_MINMAXFRAME:
  6169.    if (((PSWP)mp1)->fs & SWP_MINIMIZE)
  6170.    {
  6171.          /*-----------------------*/
  6172.          /* About to be minimized */
  6173.          /*-----------------------*/
  6174.    }
  6175.    else
  6176.      if (((PSWP)mp1)->fs & SWP_MAXIMIZE)
  6177.      {
  6178.            /*-----------------------*/
  6179.            /* About to be maximized */
  6180.            /*-----------------------*/
  6181.      }
  6182.      else
  6183.        if (((PSWP)mp1)->fs & SWP_RESTORE)
  6184.        {
  6185.              /*----------------------*/
  6186.              /* About to be restored */
  6187.              /*----------------------*/
  6188.        }
  6189.    break;
  6190.  
  6191.  
  6192. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6193.  
  6194. WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), FALSE);
  6195.  
  6196.  
  6197. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6198.  
  6199. flCFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU | FCF_NOBYTEALIGN |
  6200.                  FCF_SIZEBORDER | FCF_MINMAX;
  6201.  
  6202.  
  6203. hwndChildFrame = WinCreateStdWindow(HWND_DESKTOP,
  6204.                                     0L,
  6205.                                     &flCFrameFlags,
  6206.                                     "Hints2",
  6207.                                     (PSZ)CTitle,
  6208.                                     0L,
  6209.                                     NULL,
  6210.                                     0,
  6211.                                     &hwndChild);
  6212.  
  6213. WinSetOwner(hwndChildFrame, hwndFrame);
  6214.  
  6215. WinSetWindowPos(hwndChildFrame, HWND_TOP, 350, 100, 200, 200,
  6216.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6217.  
  6218.  
  6219. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6220.  
  6221. RECTL  rc;
  6222. HPS    hps;
  6223. HWND   hwndActiveWin;
  6224. PID    pid;
  6225. TID    tid;
  6226. CHAR   szText[20],
  6227.        szPid[6];
  6228.  
  6229. case WM_PAINT:
  6230.   hwndActiveWin = WinQueryActiveWindow(HWND_DESKTOP, FALSE);
  6231.   WinQueryWindowProcess(hwndActiveWin, &pid, &tid);
  6232.   strcpy(szText, "Process ID = ");
  6233.   strcat(szText, itoa(pid, szPid, 10));
  6234.   WinQueryWindowRect(hwnd, &rc);
  6235.   hps = WinBeginPaint(hwnd, NULL, &rc);
  6236.   WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
  6237.                SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
  6238.   WinEndPaint(hps);
  6239.   break;
  6240.  
  6241. case WM_TIMER:
  6242.   hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6243.   WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
  6244.   WinInvalidateRect(hwnd, NULL, TRUE);  /* Cause PID to be displayed */
  6245.   break;
  6246.  
  6247.  
  6248. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6249.  
  6250. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6251.  
  6252.  
  6253. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6254.  
  6255. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6256.  
  6257. WinEnableWindow(WinWindowFromID(hwndFrame, FID_TITLEBAR), FALSE);
  6258.  
  6259.  
  6260. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6261.  
  6262. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6263.  
  6264. WinEnableWindow(WinWindowFromID(hwndFrame, FID_TITLEBAR), TRUE);
  6265.  
  6266.  
  6267. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6268.  
  6269. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6270.  
  6271. WinSetWindowULong(hwndFrame, QWL_STYLE,
  6272.                   (WinQueryWindowULong(hwndFrame, QWL_STYLE) &
  6273.                    ~FS_SIZEBORDER | FS_DLGBORDER));
  6274.  
  6275. WinInvalidateRect(hwndFrame, NULL, TRUE);
  6276.  
  6277.  
  6278. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6279.  
  6280. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6281.  
  6282. WinSetWindowULong(hwndFrame, QWL_STYLE,
  6283.                   (WinQueryWindowULong(hwndFrame, QWL_STYLE) &
  6284.                    ~FS_DLGBORDER | FS_SIZEBORDER));
  6285.  
  6286. WinInvalidateRect(hwndFrame, NULL, TRUE);
  6287.  
  6288.  
  6289. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6290.  
  6291. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6292.  
  6293. WinSetWindowBits(hwndFrame, QWL_STYLE,
  6294.                  (~FS_SIZEBORDER | FS_DLGBORDER),
  6295.                  ( FS_SIZEBORDER | FS_DLGBORDER));
  6296.  
  6297. WinInvalidateRect(hwndFrame, NULL, TRUE);
  6298.  
  6299.  
  6300. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6301.  
  6302. hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6303.  
  6304. WinSetWindowBits(hwndFrame, QWL_STYLE,
  6305.                  (FS_SIZEBORDER | ~FS_DLGBORDER),
  6306.                  (FS_SIZEBORDER |  FS_DLGBORDER));
  6307.  
  6308. WinInvalidateRect(hwndFrame, NULL, TRUE);
  6309.  
  6310.  
  6311. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6312.  
  6313. WinQueryWindowRect(hwnd, (PRECTL)&WinRect);
  6314.  
  6315.  
  6316. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6317.  
  6318. case WM_MINMAXFRAME:
  6319.   hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6320.  
  6321.   WinSetWindowUShort(hwndFrame, QWS_XRESTORE, 100);
  6322.   WinSetWindowUShort(hwndFrame, QWS_YRESTORE, 100);
  6323.   WinSetWindowUShort(hwndFrame, QWS_CXRESTORE, 200);
  6324.   WinSetWindowUShort(hwndFrame, QWS_CYRESTORE, 200);
  6325.   break;
  6326.  
  6327.  
  6328. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6329.  
  6330.  
  6331. ACCELTABLE ID_MAINWND
  6332. BEGIN
  6333.   VK_F3,   MI_EXIT,  VIRTUALKEY
  6334. END
  6335.  
  6336. ICON       ID_MAINWND hints.ico
  6337.  
  6338. MENU       ID_MAINWND PRELOAD
  6339. BEGIN
  6340.    .
  6341.    .
  6342.    .
  6343. END
  6344.  
  6345.  
  6346. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6347.  
  6348. case WM_SAVEAPPLICATION:
  6349.   WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT, FALSE), &swp);
  6350.   PrfWriteProfileData(HINI_USERPROFILE, "Hints", "Size",
  6351.                       &swp, (ULONG)sizeof(swp));
  6352.   return NULL;
  6353.  
  6354.  
  6355. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6356.  
  6357. /*--------------------------------------------------------------*/
  6358. /* This should probably go just after your WinCreate... call    */
  6359. /*--------------------------------------------------------------*/
  6360.  
  6361. ULONG   DataLength;
  6362.  
  6363. DataLength = sizeof(swp);
  6364. if (!PrfQueryProfileData(HINI_USERPROFILE, "Hints", "Size",
  6365.                          &swp, &DataLength))
  6366. {
  6367.   swp.x  = 100;            /*-----------------------------------*/
  6368.   swp.y  = 100;            /* Profile not found so use defaults */
  6369.   swp.cx = 200;            /*-----------------------------------*/
  6370.   swp.cy = 200;
  6371. }
  6372. WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
  6373.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6374.  
  6375.  
  6376. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6377.  
  6378. SHORT  X_Left,
  6379.        Y_Bot,
  6380.        Height,
  6381.        Width;
  6382.  
  6383.  
  6384.  
  6385. X_Left = 100;
  6386. Y_Bot  = 100;
  6387. Width  = 400;
  6388. Height = 300;
  6389.  
  6390. WinSetWindowPos(hwndFrame, HWND_TOP, X_Left, Y_Bot, Width, Height,
  6391.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6392.  
  6393.  
  6394. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6395.  
  6396. WinSetWindowPos(hwndFrame, HWND_BOTTOM, X_Left, Y_Bot, Width, Height,
  6397.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER);
  6398.  
  6399.  
  6400. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6401.  
  6402. swp.x  = 100;            /*----------------------------*/
  6403. swp.y  = 100;            /* Set restored size/position */
  6404. swp.cx = 200;            /*----------------------------*/
  6405. swp.cy = 200;
  6406.  
  6407. WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
  6408.                 SWP_SIZE | SWP_MOVE | SWP_SHOW |
  6409.                 SWP_ACTIVATE | SWP_MINIMIZE);
  6410.  
  6411.  
  6412. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6413.  
  6414. swp.x  = 100;            /*----------------------------*/
  6415. swp.y  = 100;            /* Set restored size/position */
  6416. swp.cx = 200;            /*----------------------------*/
  6417. swp.cy = 200;
  6418.  
  6419. WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
  6420.                 SWP_SIZE | SWP_MOVE | SWP_SHOW |
  6421.                 SWP_ACTIVATE | SWP_MAXIMIZE);
  6422.  
  6423.  
  6424. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6425.  
  6426. /*-------------------------------------------------------------*/
  6427. /* Declare your subclassed window procedure and pointer to the */
  6428. /* default frame window procedure                              */
  6429. /*-------------------------------------------------------------*/
  6430.  
  6431. MRESULT EXPENTRY SubFrameProc(HWND, USHORT, MPARAM, MPARAM);
  6432. PFNWP   OldFrameProc;
  6433.  
  6434. /*-------------------------------------------------------------*/
  6435. /* Immediately after creating your main window store the       */
  6436. /* address of the default frame window procedure               */
  6437. /*-------------------------------------------------------------*/
  6438.  
  6439. OldFrameProc = WinSubclassWindow(hwndFrame, (PFNWP)SubFrameProc);
  6440.  
  6441. /*-------------------------------------------------------------*/
  6442. /* The following example procedure allows your window to be    */
  6443. /* reduced in size to 25x25 pels.                              */
  6444. /*-------------------------------------------------------------*/
  6445.  
  6446. MRESULT EXPENTRY SubFrameProc(HWND hwnd,
  6447.                               USHORT msg,
  6448.                               MPARAM mp1,
  6449.                               MPARAM mp2)
  6450. {
  6451.   PTRACKINFO  ptrack;
  6452.  
  6453.   switch(msg)
  6454.   {
  6455.     case WM_QUERYTRACKINFO:
  6456.       /*----------------------------------------------------------*/
  6457.       /* Invoke the default frame window procedure first in order */
  6458.       /* to update the tracking rectangle to the new position.    */
  6459.       /*----------------------------------------------------------*/
  6460.       OldFrameProc(hwnd, msg, mp1, mp2);
  6461.  
  6462.       ptrack = (PTRACKINFO)mp2;
  6463.       ptrack->ptlMinTrackSize.x = 25;
  6464.       ptrack->ptlMinTrackSize.y = 25;
  6465.  
  6466.       return((MRESULT)TRUE);
  6467.       break;
  6468.  
  6469.     default:
  6470.       return(OldFrameProc(hwnd, msg, mp1, mp2));
  6471.       break;
  6472.   }
  6473.   return((MRESULT)NULL);
  6474. }
  6475.  
  6476.  
  6477. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6478.  
  6479. ScrWidth  = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  6480. ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  6481.  
  6482. WinSetWindowPos(hwndFrame, HWND_TOP,
  6483.                 0, 0, (SHORT)ScrWidth, (SHORT)ScrHeight,
  6484.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6485.  
  6486.  
  6487. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6488.  
  6489. /*----------------------------------*/
  6490. /* To start a 500 millisecond timer */
  6491. /*----------------------------------*/
  6492.  
  6493. WinStartTimer(hab, hwndClient, TimerID, 500);
  6494.  
  6495.  
  6496. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6497.  
  6498. WinStopTimer(hab, hwndClient, TimerID);
  6499.  
  6500.  
  6501. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6502.  
  6503. case WM_TIMER:
  6504.   hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6505.   WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
  6506.   break;
  6507.  
  6508.  
  6509. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6510.  
  6511. case WM_CREATE:
  6512.   ;
  6513.   ;
  6514.   /*-------------------*/
  6515.   /* Make system modal */
  6516.   /*-------------------*/
  6517.  
  6518.   hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6519.   WinSetSysModalWindow(HWND_DESKTOP, hFrame);
  6520.   break;
  6521.  
  6522.  
  6523.  
  6524. case WM_xxx:
  6525.   /*------------------------*/
  6526.   /* Remove system modality */
  6527.   /*------------------------*/
  6528.  
  6529.   WinSetSysModalWindow(HWND_DESKTOP, NULL);
  6530.   break;
  6531.  
  6532.  
  6533. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6534.  
  6535. #define  INCL_WIN
  6536.  
  6537. #include <os2.h>
  6538. #include <string.h>
  6539. #include <stdlib.h>
  6540. #include "hints.h"
  6541.  
  6542.  
  6543. PFNWP   OldFrameProc;
  6544.  
  6545. MRESULT EXPENTRY MainWndProc  (HWND, USHORT, MPARAM, MPARAM);
  6546. MRESULT EXPENTRY ChildWndProc (HWND, USHORT, MPARAM, MPARAM);
  6547. MRESULT EXPENTRY NewFrame     (HWND, USHORT, MPARAM, MPARAM);
  6548.  
  6549. /****************************************************************************/
  6550.  
  6551. VOID    cdecl main (void)
  6552. {
  6553.   HAB     hab;
  6554.   HMQ     hmq;
  6555.  
  6556.   static  HWND   hwndEntry,
  6557.                  hwndClient,
  6558.                  hwndChild,
  6559.                  hwndFrame,
  6560.                  hwndChildFrame;
  6561.  
  6562.   QMSG    qmsg;
  6563.  
  6564.   ULONG   flFrameFlags,
  6565.           flCFrameFlags,
  6566.           DataLength;
  6567.  
  6568.   CHAR    Title[80],
  6569.           CTitle[80];
  6570.  
  6571.   SWCNTRL PgmEntry;
  6572.  
  6573.   SWP     swp;
  6574.  
  6575. /****************************************************************************/
  6576.  
  6577.   hab = WinInitialize(0);
  6578.   hmq = WinCreateMsgQueue(hab, 0);
  6579.  
  6580.   WinRegisterClass(hab,
  6581.                    "Hints",
  6582.                    MainWndProc,
  6583.                    CS_SIZEREDRAW,
  6584.                    0);
  6585.  
  6586.   WinRegisterClass(hab,
  6587.                    "Hints2",
  6588.                    ChildWndProc,
  6589.                    CS_SIZEREDRAW,
  6590.                    0);
  6591.  
  6592.   WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
  6593.   WinLoadString( hab, NULL, ID_CTITLE, sizeof(CTitle), CTitle );
  6594.  
  6595.   flCFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU | FCF_NOBYTEALIGN |
  6596.                    FCF_SIZEBORDER | FCF_MINMAX;
  6597.  
  6598.   flFrameFlags  = FCF_TITLEBAR   | FCF_SYSMENU    | FCF_MENU       |
  6599.                   FCF_SIZEBORDER | FCF_MINMAX     | FCF_ACCELTABLE |
  6600.                   FCF_NOBYTEALIGN;
  6601.  
  6602.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  6603.                                  0L,
  6604.                                  &flFrameFlags,
  6605.                                  "Hints",
  6606.                                  (PSZ)Title,
  6607.                                  0L,
  6608.                                  NULL,
  6609.                                  ID_MAINWND,
  6610.                                  &hwndClient);
  6611.  
  6612.   OldFrameProc = WinSubclassWindow(hwndFrame, (PFNWP)NewFrame);
  6613.  
  6614.   DataLength = sizeof(swp);
  6615.   if (!PrfQueryProfileData(HINI_USERPROFILE, "Hints", "Size",
  6616.                            &swp, &DataLength))
  6617.   {
  6618.     swp.x  = 100;
  6619.     swp.y  = 100;
  6620.     swp.cx = 200;
  6621.     swp.cy = 200;
  6622.     /*-------------------------------------------------------------*/
  6623.     /* For full screen -                                           */
  6624.     /*                                                             */
  6625.     /*  swp.cx = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);      */
  6626.     /*  swp.cy = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);      */
  6627.     /*-------------------------------------------------------------*/
  6628.   }
  6629.   WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
  6630.                   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6631.  
  6632.   hwndChildFrame = WinCreateStdWindow(HWND_DESKTOP,
  6633.                                       0L,
  6634.                                       &flCFrameFlags,
  6635.                                       "Hints2",
  6636.                                       (PSZ)CTitle,
  6637.                                       0L,
  6638.                                       NULL,
  6639.                                       0,
  6640.                                       &hwndChild);
  6641.  
  6642.   WinSetOwner(hwndChildFrame, hwndFrame);
  6643.  
  6644.   WinSetWindowPos(hwndChildFrame, HWND_TOP, 350, 100, 200, 200,
  6645.                   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  6646.  
  6647.   PgmEntry.hwnd          = hwndFrame;
  6648.   PgmEntry.hwndIcon      = NULL;
  6649.   PgmEntry.hprog         = NULL;
  6650.   PgmEntry.idProcess     = NULL;
  6651.   PgmEntry.idSession     = NULL;
  6652.   PgmEntry.uchVisibility = SWL_VISIBLE;
  6653.   PgmEntry.fbJump        = SWL_JUMPABLE;
  6654.  
  6655.   strcpy(PgmEntry.szSwtitle, Title);
  6656.  
  6657.   hwndEntry = WinAddSwitchEntry(&PgmEntry);
  6658.  
  6659.   WinStartTimer( hab, hwndClient, 1, 500 );
  6660.  
  6661.   WinSendMsg(hwndFrame, WM_SETICON,
  6662.              WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE), NULL);
  6663.   WinSendMsg(hwndChildFrame, WM_SETICON,
  6664.              WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE), NULL);
  6665.  
  6666.   while(WinGetMsg(hab, &qmsg, NULL, 0, 0))
  6667.     WinDispatchMsg(hab, &qmsg);
  6668.  
  6669.   WinStopTimer( hab, hwndClient, 1);
  6670.   WinDestroyWindow(hwndFrame);
  6671.   WinRemoveSwitchEntry(hwndEntry);
  6672.   WinDestroyMsgQueue(hmq);
  6673.   WinTerminate(hab);
  6674. }
  6675.  
  6676. /****************************************************************************/
  6677.  
  6678. MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  6679. {
  6680.   RECTL  rc;
  6681.   SWP    swp;
  6682.   HPS    hps;
  6683.   HWND   hwndActiveWin,
  6684.          hwndFrame;
  6685.   PID    pid;
  6686.   TID    tid;
  6687.   CHAR   szText[20],
  6688.          szPid[6];
  6689.  
  6690.   switch (msg)
  6691.     {
  6692.       case WM_PAINT:
  6693.         hwndActiveWin = WinQueryActiveWindow(HWND_DESKTOP, FALSE);
  6694.         WinQueryWindowProcess(hwndActiveWin, &pid, &tid);
  6695.         strcpy(szText, "Process ID = ");
  6696.         strcat(szText, itoa(pid, szPid, 10));
  6697.  
  6698.         WinQueryWindowRect(hwnd, &rc);
  6699.  
  6700.         /*------------------------------------------------------------------*/
  6701.         /* WinMapWindowPoints(hwnd, WinQueryWindow(hwnd, QW_PARENT, FALSE), */
  6702.         /*                    (PPOINTL)&rc, 2);                             */
  6703.         /*------------------------------------------------------------------*/
  6704.  
  6705.         hps = WinBeginPaint(hwnd, NULL, &rc);
  6706.         WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
  6707.                       SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
  6708.         WinEndPaint(hps);
  6709.         break;
  6710.  
  6711.       case WM_TIMER:
  6712.         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6713.         WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
  6714.         WinInvalidateRect(hwnd, NULL, TRUE);  /* Cause PID to be displayed */
  6715.         break;
  6716.  
  6717.       case WM_BUTTON1DOWN:
  6718.         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6719.         WinSetWindowText(hwndFrame, "Hints - Size and Position Fixed");
  6720.         WinEnableWindow (WinWindowFromID (hwndFrame, FID_TITLEBAR), FALSE);
  6721.         WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), FALSE);
  6722.  
  6723.         WinSetWindowBits(hwndFrame, QWL_STYLE,
  6724.                          (~FS_SIZEBORDER | FS_DLGBORDER),
  6725.                          ( FS_SIZEBORDER | FS_DLGBORDER));
  6726.  
  6727.         /*-----------------------------------------------------------------*/
  6728.         /* WinSetWindowULong(hwndFrame, QWL_STYLE,                         */
  6729.         /*                   (WinQueryWindowULong(hwndFrame, QWL_STYLE) &  */
  6730.         /*                    ~FS_SIZEBORDER | FS_DLGBORDER));             */
  6731.         /*-----------------------------------------------------------------*/
  6732.  
  6733.         WinInvalidateRect(hwndFrame, NULL, TRUE);
  6734.         break;
  6735.  
  6736.       case WM_BUTTON2DOWN:
  6737.         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6738.         WinSetWindowText(hwndFrame, "Hints");
  6739.         WinEnableWindow (WinWindowFromID (hwndFrame, FID_TITLEBAR), TRUE);
  6740.         WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), TRUE);
  6741.  
  6742.         WinSetWindowBits(hwndFrame, QWL_STYLE,
  6743.                          (FS_SIZEBORDER | ~FS_DLGBORDER),
  6744.                          (FS_SIZEBORDER |  FS_DLGBORDER));
  6745.  
  6746.         /*-----------------------------------------------------------------*/
  6747.         /* WinSetWindowULong(hwndFrame, QWL_STYLE,                         */
  6748.         /*                   (WinQueryWindowULong(hwndFrame, QWL_STYLE) &  */
  6749.         /*                    ~FS_DLGBORDER | FS_SIZEBORDER));             */
  6750.         /*-----------------------------------------------------------------*/
  6751.  
  6752.         WinInvalidateRect(hwndFrame, NULL, TRUE);
  6753.         break;
  6754.  
  6755.       case WM_MINMAXFRAME:
  6756.         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6757.         if (((PSWP)mp1)->fs & SWP_MINIMIZE)
  6758.         {
  6759.           DosBeep(100, 100);
  6760.         }
  6761.         else
  6762.           if (((PSWP)mp1)->fs & SWP_MAXIMIZE)
  6763.           {
  6764.             DosBeep(1000, 100);
  6765.           }
  6766.           else
  6767.             if (((PSWP)mp1)->fs & SWP_RESTORE)
  6768.             {
  6769.               DosBeep(500, 100);
  6770.             }
  6771.  
  6772.         WinSetWindowUShort(hwndFrame, QWS_XRESTORE, 100);
  6773.         WinSetWindowUShort(hwndFrame, QWS_YRESTORE, 100);
  6774.         WinSetWindowUShort(hwndFrame, QWS_CXRESTORE, 200);
  6775.         WinSetWindowUShort(hwndFrame, QWS_CYRESTORE, 200);
  6776.         break;
  6777.  
  6778.       case WM_SAVEAPPLICATION:
  6779.         WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT, FALSE), &swp);
  6780.         PrfWriteProfileData(HINI_USERPROFILE, "Hints", "Size",
  6781.                             &swp, (ULONG)sizeof(swp));
  6782.         return NULL;
  6783.  
  6784.       case WM_COMMAND:
  6785.         switch (SHORT1FROMMP(mp1))
  6786.           {
  6787.             case MI_MIN:
  6788.               hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6789.               WinSetWindowPos(hwndFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE);
  6790.               break;
  6791.  
  6792.             case MI_EXIT:
  6793.               WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  6794.               break;
  6795.           }
  6796.  
  6797.       case WM_ERASEBACKGROUND:
  6798.         return (MRESULT)TRUE;
  6799.     }
  6800.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  6801. }
  6802.  
  6803. /****************************************************************************/
  6804.  
  6805. MRESULT EXPENTRY NewFrame(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  6806. {
  6807.   PTRACKINFO  ptrack;
  6808.  
  6809.   switch(msg)
  6810.   {
  6811.     case WM_QUERYTRACKINFO:
  6812.       /*----------------------------------------------------------*/
  6813.       /* Invoke the default frame window procedure first in order */
  6814.       /* to update the tracking rectangle to the new position.    */
  6815.       /*----------------------------------------------------------*/
  6816.       OldFrameProc(hwnd, msg, mp1, mp2);
  6817.  
  6818.       ptrack = (PTRACKINFO)mp2;
  6819.       ptrack->ptlMinTrackSize.x = 25;
  6820.       ptrack->ptlMinTrackSize.y = 25;
  6821.  
  6822.       return((MRESULT)TRUE);
  6823.       break;
  6824.  
  6825.     default:
  6826.       return(OldFrameProc(hwnd, msg, mp1, mp2));
  6827.       break;
  6828.   }
  6829.   return((MRESULT)NULL);
  6830. }
  6831.  
  6832. /****************************************************************************/
  6833.  
  6834. MRESULT EXPENTRY ChildWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  6835. {
  6836.   RECTL  rc;
  6837.   HPS    hps;
  6838.   CHAR   szText[22];
  6839.   HWND   hwndChildFrame;
  6840.  
  6841.  
  6842.   switch(msg)
  6843.     {
  6844.       case WM_PAINT:
  6845.         strcpy(szText, "I am a child of Hints");
  6846.         WinQueryWindowRect(hwnd, &rc);
  6847.         hps = WinBeginPaint(hwnd, NULL, &rc);
  6848.         WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
  6849.                       SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
  6850.         WinEndPaint(hps);
  6851.         break;
  6852.  
  6853.       case WM_ERASEBACKGROUND:
  6854.         return (MRESULT)TRUE;
  6855.  
  6856.       case WM_CLOSE:
  6857.         hwndChildFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  6858.         WinDestroyWindow(hwndChildFrame);
  6859.         break;
  6860.     }
  6861.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  6862. }
  6863.  
  6864.  
  6865. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6866.  
  6867. #define   ID_MAINWND    200
  6868. #define   ID_CHILDWND   201
  6869. #define   ID_TITLE      202
  6870. #define   ID_CTITLE     203
  6871. #define   MI_EXIT       100
  6872. #define   MI_RESUME     101
  6873. #define   MI_MIN        102
  6874.  
  6875.  
  6876. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6877.  
  6878. hints +
  6879. /A:16 /CO
  6880. hints.exe
  6881. hints.map  /NOD
  6882. llibce.lib+
  6883. os2.lib
  6884. hints.def
  6885.  
  6886.  
  6887. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6888.  
  6889. NAME    Hints WINDOWAPI
  6890.  
  6891. DESCRIPTION 'Test program for OS/2 Hints and Tips'
  6892.  
  6893. STUB    'OS2STUB.EXE'
  6894.  
  6895. DATA    MULTIPLE
  6896.  
  6897. HEAPSIZE    8192
  6898. STACKSIZE   8192
  6899.  
  6900. PROTMODE
  6901.  
  6902.  
  6903. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6904.  
  6905. #include <os2.h>
  6906. #include "hints.h"
  6907.  
  6908. STRINGTABLE PRELOAD
  6909. BEGIN
  6910.  ID_TITLE,  "Hints"
  6911.  ID_CTITLE, "Child Window of Hints"
  6912. END
  6913.  
  6914. ACCELTABLE ID_MAINWND
  6915. BEGIN
  6916.   VK_F3,   MI_EXIT,        VIRTUALKEY
  6917. END
  6918.  
  6919. MENU       ID_MAINWND PRELOAD
  6920. BEGIN
  6921.   MENUITEM "~Minimize",                MI_MIN,         MIS_TEXT
  6922.   SUBMENU "E~xit",                     1
  6923.   BEGIN
  6924.     MENUITEM "~Exit Program\tF3",      MI_EXIT,        MIS_TEXT
  6925.     MENUITEM "~Resume Program",        MI_RESUME,      MIS_TEXT
  6926.   END
  6927. END
  6928.  
  6929.  
  6930. ΓòÉΓòÉΓòÉ <hidden>  ΓòÉΓòÉΓòÉ
  6931.  
  6932. hints.exe: hints.obj \
  6933.           hints.def hints.res
  6934.  link @hints.l
  6935.  rc hints.res
  6936.  
  6937. hints.obj: hints.c hints.h
  6938.  cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
  6939.  
  6940. hints.res: hints.h hints.rc
  6941.  rc -r hints.rc
  6942.