home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pwr16.zip / POWER.C < prev    next >
Text File  |  1994-11-07  |  34KB  |  648 lines

  1. /*______________________________________________________________________
  2. |                PowerThread  (c) 1994 Greg Ratajik                     |
  3. |-----------------------------------------------------------------------|
  4. |               You may use this code in your programs under the        |
  5. |               following conditions:                                   |
  6. |                                                                       |
  7. |               o  You keep this module seperate, with all comments     |
  8. |                  copyright notices intact (You can, of course add to  |
  9. |                  or change to fit your needs, I just ask that you     |
  10. |                  keep the main banners/info intact.)                  |
  11. |                                                                       |
  12. |               o  If you sell a product that uses this, I ask that     |
  13. |                  you put my name and contact info in it,  and what    |
  14. |                  you got out of it.  (This doesn't need to be in a    |
  15. |                  about box, but it would be nice at the end of the    |
  16. |                  credits of the .INF file, or DOC's.)                 |
  17. |                                                                       |
  18. |               Beyond that, go for it!  You're free to hack this up    |
  19. |               in any way that you need.  I'm not asking for any return|
  20. |               on this code, except (mabye?) to provide a quick and    |
  21. |               easy way for fellow OS/2 developers to thread their     |
  22. |               programs.                                               |
  23. |                                                                       |
  24. |                ---------------------------------------------------    |
  25. |               | Special Thanks to Ron Finlayson, for part of the  |   |
  26. |               | initial concept work on this.  It really helps to |   |
  27. |               | have someone to brain storm with! :)              |   |
  28. |                ---------------------------------------------------    |
  29. |                                                                       |
  30. |   *****************************************************************   |
  31. |   *DISCLAIMER OF WARRANTIES.  The following  code is              *   |
  32. |   *sample code created by Greg Ratajik.  The code is provided     *   |
  33. |   *"AS IS", without warranty of any kind.  Greg Ratatjik shall not*   |
  34. |   *be liable for any damages arising out of your use of the sample*   |
  35. |   *code.                                                          *   |
  36. |   *****************************************************************   |
  37. |                                                                       |
  38. |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  39. | Description:  This module has two main functions in it, PowerCall and |
  40. |               PowerHABCall.  Both of them let an application call a   |
  41. |               function, while processing a PM message, without locking|
  42. |               up PM. The function calls can be treated like  normal   |
  43. |               function that runs consecutively to other function calls|
  44. |               (instead of posting messages back to the parent, or     |
  45. |               having a worker thread processing requests)             |
  46. |                                                                       |
  47. |               The basic flow of this program is:                      |
  48. |                                                                       |
  49. |               PowerHABCall():                                         |
  50. |                                                                       |
  51. |                  Get PM Message                                       |
  52. |                        |                                              |
  53. |                       \|/                                             |
  54. |                   Start Thread --------------                         |
  55. |                        |                    |                         |
  56. |                        |                    |                         |
  57. |                       \|/                  \|/                        |
  58. |                   Process Queue         Call Function                 |
  59. |                        |                    |                         |
  60. |                        |                    |                         |
  61. |                       \|/                  \|/                        |
  62. |                      Return <---------- Notify Function Done          |
  63. |                        |                                              |
  64. |                        |                                              |
  65. |                       \|/                                             |
  66. |                Continue Processing                                    |
  67. |                     Message                                           |
  68. |                                                                       |
  69. |               ======================================================= |
  70. |                                                                       |
  71. |               PowerCall():                                            |
  72. |                                                                       |
  73. |                  Get PM Message                                       |
  74. |                        |                                              |
  75. |                       \|/                                             |
  76. |                   Start Thread --------------                         |
  77. |                        |                    |                         |
  78. |                        |                    |                         |
  79. |                       \|/                  \|/                        |
  80. |                   Start DLG             Call Function                 |
  81. |             (Will process messages)         |                         |
  82. |                        |                    |                         |
  83. |                        |                    |                         |
  84. |                       \|/                  \|/                        |
  85. |                      Return <---------- Post Message To DLG           |
  86. |                        |                                              |
  87. |                        |                                              |
  88. |                       \|/                                             |
  89. |                Continue Processing                                    |
  90. |                     Message                                           |
  91. |                                                                       |
  92. |                                                                       |
  93. |               PowerHABCall is the most staight forward way, but you   |
  94. |               have to pass the HAB.  PowerCall is a little more       |
  95. |               complex, but if you want to display somthing to the user|
  96. |               while the thread is running (i.e. do a timer,and animate|
  97. |               the pointer while the thread is running...) or if you   |
  98. |               don't want to worry about getting the HAB, use          |
  99. |               it.                                                     |
  100. |                                                                       |
  101. |               For more information, and some thoughts on how to use   |
  102. |               this technique, see POWER.DOC                           |
  103. |                                                                       |
  104. |               If you have any questions and comments about this       |
  105. |               technique, you can get in touch with me at:             |
  106. |                                                                       |
  107. |               CompuServe          : 74555,542                         |
  108. |               Internet            : 74555.542@compuserve.com          |
  109. |               Voice               : (305)/340-7985                    |
  110. |               OS/2 ShareWare BBS  : (703)/385-4325                    |
  111. |                                                                       |
  112. | Version    Date       Change                    |
  113. | ------------    ---------  ----------------------------------------    |
  114. | 1.00          09-01-1994 Initial Development                          |
  115. |_____________________________________________________________________*/
  116. #define INCL_PM             /*  PM Support                           */
  117. #define INCL_DOSPROCESS     /*  Process and thread support           */
  118.  
  119. /*______________________________________________________________________
  120. |                                                                       |
  121. |                         System Includes                               |
  122. |_____________________________________________________________________*/
  123. #define _MT
  124.  
  125. #include <os2.h>            /* Base OS/2 Include                     */
  126. #include <stdlib.h>         /* malloc and free                       */
  127. #include <process.h>        /* _beginthread support                  */
  128.  
  129. /*______________________________________________________________________
  130. |                                                                       |
  131. |             Application Specific Includes & Defines                   |
  132. |_____________________________________________________________________*/
  133. #include "power.h"        /* Prototypes for PowerCalls              */
  134. #include "test.rch"       /* RC info for the DLG                    */
  135.  
  136. /*______________________________________________________________________
  137. |                                                                       |
  138. |  Gobal Local Variables                        |
  139. |_____________________________________________________________________*/
  140. #define STACK_SIZE   15000
  141.  
  142. BOOL  g_bDone = FALSE;  /* Used to tell message loop that thread is done  */
  143.  
  144. /*______________________________________________________________________
  145. |                                                                       |
  146. |  Gobal Local Structures                        |
  147. |_____________________________________________________________________*/
  148. /*____________________________________
  149. |                                     |
  150. | pfnFunctionAddr and hWnd            |
  151. | should be kept in the structure.    |
  152. | pUserParm should be whatever parm   |
  153. | needs to be passed to the user      |
  154. | function.  Any number of user parms |
  155. | can be added, but you must modify   |
  156. | the functions that use the structure|
  157. |____________________________________*/
  158. /*____________________________________
  159. |                                     |
  160. | The primary use of this structure   |
  161. | is to isolate the information that  |
  162. | needs to be passed to the thread.   |
  163. | (You can only pass ONE parm to a    |
  164. | thread) If you don't want to use a  |
  165. | structure, you can use globals.     |
  166. |____________________________________*/
  167. typedef struct _THREAD_CALL_INFO     /* Process Linkage Structure      */
  168.         {
  169.          void far *pfnFunctionAddr;  /* Address of Function to call    */
  170.          HWND      hWnd;             /* HWND of processing DLG.        */
  171.  
  172.          PVOID pUserParm;            /* User parm(s)...                */
  173.  
  174.         } THREAD_CALL_INFO, *PTHREAD_CALL_INFO;
  175.  
  176. /*____________________________________________________________________
  177. |                                      |
  178. |  Function Prototypes.                           |
  179. |____________________________________________________________________*/
  180. MRESULT EXPENTRY PowerCallWndProc  (HWND hWndDlg, USHORT ulMsg, MPARAM mp1, MPARAM mp2);
  181. MRESULT EXPENTRY FrameWindowMsgProc(HWND hWndDlg, USHORT ulMsg, MPARAM mp1, MPARAM mp2);
  182.  
  183. VOID CallFunction    ( PTHREAD_CALL_INFO);  /* Loader for PowerCall        */
  184. VOID CallHABFunction ( PTHREAD_CALL_INFO);  /* Loader for PowerHABCall     */
  185.  
  186. /*__________________________________________________________________________
  187. |                                                                           |
  188. |    Function: PowerHABCall                                                 |
  189. |                                                                           |
  190. | Description: This function calls the passed function with the passed parm,|
  191. |              and then processes the message queue until the thread is done|
  192. |                                                                           |
  193. |              The result is that you can make the call to your function,   |
  194. |              and wait for it to return, without locking PM up.            |
  195. |                                                                           |
  196. |              This is Solution #1, which requires that HAB is passed.      |
  197. |              It should be possible to either have HAB as a global, or     |
  198. |              to ask the system what the HAB is for the process.           |
  199. |                                                                           |
  200. |      Return: BOOL  - You can use the structure to pass back your own      |
  201. |                      return value.  See CallHABFunction for more info.    |
  202. |                                                                           |
  203. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  204. |                            C H A N G E    L O G                           |
  205. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  206. |                                                                           |
  207. |  PRG.    DATE       DESCRIPTION                                           |
  208. |  ----    ---------- ---------------------------------------------------   |
  209. |  RATAJIK 11-01-1994 Initial Developement                                  |
  210. |__________________________________________________________________________*/
  211. BOOL PowerHABCall(HAB    hAB            ,
  212.                   PFN    pfnFunctionAddr,
  213.                   PVOID  pUserParm      )
  214. {
  215. PTHREAD_CALL_INFO ptciData = malloc(sizeof(THREAD_CALL_INFO));
  216. QMSG              qmsg;
  217. INT               pid;
  218.  
  219.  /*____________________________________
  220.  |                                     |
  221.  | Copy the call info to the comm.     |
  222.  | structure.                          |
  223.  |____________________________________*/
  224.  ptciData->pfnFunctionAddr = (void far *)pfnFunctionAddr;
  225.  ptciData->pUserParm       = pUserParm;
  226.  
  227.  g_bDone = FALSE;
  228.  
  229.  /*____________________________________
  230.  |                                     |
  231.  | Start the Loader thread.  It will   |
  232.  | call the function passed in         |
  233.  | pfnFunctionAddr.                    |
  234.  |____________________________________*/
  235.  pid=_beginthread(CallHABFunction,   /* Address of the Loader Function     */
  236.                   NULL,              /* Use the programs stack             */
  237.                   STACK_SIZE,        /* Amount of the stack we want to use */
  238.                   (PVOID)ptciData);  /* Info for the Loader Function       */
  239.  
  240.  /*____________________________________
  241.  |                                     |
  242.  | Process messages until g_bDone is   |
  243.  | TRUE.  This, in effect, prevents PM |
  244.  | from locking up while we process the|
  245.  | message that called this function.  |
  246.  |____________________________________*/
  247.  while(WinGetMsg(hAB, (PQMSG)&qmsg, (HWND)NULL, 0, 0) && !g_bDone)
  248.      WinDispatchMsg(hAB, (PQMSG)&qmsg);
  249.  
  250.  /*____________________________________
  251.  |                                     |
  252.  | Free up the Data, and return.  If   |
  253.  | you want to return with another     |
  254.  | type/value, you can use the comm    |
  255.  | structure to pass it.               |
  256.  |____________________________________*/
  257.  free(ptciData);
  258.  return(TRUE);
  259. }
  260.  
  261. /*__________________________________________________________________________
  262. |                                                                           |
  263. |    Function: CallHABunction                                               |
  264. |                                                                           |
  265. | Description: This function is used to call the user function, with any    |
  266. |              parms needed.  When it is done, it will set g_bDone to TRUE, |
  267. |              which will tell the message processing loop to finish. If you|
  268. |              don't want to use a global, you can use another BOOL in the  |
  269. |              passed structure, or a semaphore.                            |
  270. |                                                                           |
  271. |      Return: VOID                                                         |
  272. |                                                                           |
  273. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  274. |                            C H A N G E    L O G                           |
  275. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  276. |                                                                           |
  277. |  PRG.    DATE       DESCRIPTION                                           |
  278. |  ----    ---------- ---------------------------------------------------   |
  279. |  RATAJIK 11-01-1994 Initial Developement                                  |
  280. |__________________________________________________________________________*/
  281. VOID CallHABFunction(PTHREAD_CALL_INFO ptciData)
  282. {
  283.  PFN pfnAddr;
  284.  
  285.  /*____________________________________
  286.  |                                     |
  287.  | Resolve the function address.       |
  288.  |                                     |
  289.  |____________________________________*/
  290.  pfnAddr = (PFN) ptciData->pfnFunctionAddr;
  291.  
  292.  /*____________________________________
  293.  |                                     |
  294.  | Call the function with the parm list|
  295.  | Add vars to the parm list as needed.|
  296.  |____________________________________*/
  297.  pfnAddr(ptciData->pUserParm);
  298.  
  299.  /*____________________________________
  300.  |                                     |
  301.  | Tell the while loop for the queue   |
  302.  | that we are done.                   |
  303.  |____________________________________*/
  304.  g_bDone = TRUE;
  305. }
  306.  
  307. /*__________________________________________________________________________
  308. |                                                                           |
  309. |    Function: PowerCall                                                    |
  310. |                                                                           |
  311. | Description: This function calls the passed function with the passed parm.|
  312. |              It will then do a WinDlgBox.  This will process any message  |
  313. |              untill the thread is done.  The WinDlgBox can also be used to|
  314. |              display a message to the user, while the thead is processing.|
  315. |                                                                           |
  316. |      Return: BOOL  - You can use the structure to pass back your own      |
  317. |                      return value.  See CallHABFunction for more info.    |
  318. |                                                                           |
  319. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  320. |                            C H A N G E    L O G                           |
  321. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  322. |                                                                           |
  323. |  PRG.    DATE       DESCRIPTION                                           |
  324. |  ----    ---------- ---------------------------------------------------   |
  325. |  RATAJIK 11-01-1994 Initial Developement                                  |
  326. |__________________________________________________________________________*/
  327. BOOL PowerCall(PFN   pfnFunctionAddr,
  328.                PVOID pUserParm      )
  329. {
  330. PTHREAD_CALL_INFO ptciData = malloc(sizeof(THREAD_CALL_INFO));
  331. INT               pid;
  332.  
  333.  /*____________________________________
  334.  |                                     |
  335.  | Copy the call info to the comm.     |
  336.  | structure.                          |
  337.  |____________________________________*/
  338.  ptciData->pfnFunctionAddr = (void far *)pfnFunctionAddr;
  339.  ptciData->pUserParm       = pUserParm;
  340.  ptciData->hWnd            = NULL;    /* The DLG will fill this out for us */
  341.  
  342.  /*____________________________________
  343.  |                                     |
  344.  | Start up the Loader thread.  It will|
  345.  | call the function passed in         |
  346.  | pfnFunctionAddr                     |
  347.  |____________________________________*/
  348.  pid=_beginthread(CallFunction,      /* Address of the Loader Function     */
  349.                   NULL,              /* Use the programs stack             */
  350.                   STACK_SIZE,        /* Amount of the stack we want to use */
  351.                   (PVOID)ptciData);  /* Info for the Loader Function       */
  352.  
  353.  /*____________________________________
  354.  |                                     |
  355.  | Run the DLG.  This has the same     |
  356.  | results as the message loop in      |
  357.  | PowerHABCall.                       |
  358.  |                                     |
  359.  | It will return when the thread posts|
  360.  | a message to it.                    |
  361.  |                                     |
  362.  | You could also do a WinCreateWindow,|
  363.  | and process message, but this way   |
  364.  | you can show somthing to the user.  |
  365.  |____________________________________*/
  366.  WinDlgBox(HWND_DESKTOP,
  367.            HWND_DESKTOP,
  368.            PowerCallWndProc,
  369.            0,
  370.            DLG_THREAD,
  371.            (PVOID)ptciData);    /* Pass this so DLG can get to hwnd   */
  372.  
  373.  /*____________________________________
  374.  |                                     |
  375.  | Free up the Data, and return.  If   |
  376.  | you want to return with another     |
  377.  | type/value, you can use the comm    |
  378.  | structure to pass it.               |
  379.  |____________________________________*/
  380.  free(ptciData);
  381.  return(TRUE);
  382. }
  383.  
  384. /*__________________________________________________________________________
  385. |                                                                           |
  386. |    Function: CallFunction                                                 |
  387. |                                                                           |
  388. | Description: This function is used to call the user function, with any    |
  389. |              parms needed.  When it is done, it will post a message back  |
  390. |              to the DLG to let it know it should dismiss itself.          |
  391. |                                                                           |
  392. |      Return: VOID                                                         |
  393. |                                                                           |
  394. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  395. |                            C H A N G E    L O G                           |
  396. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  397. |                                                                           |
  398. |  PRG.    DATE       DESCRIPTION                                           |
  399. |  ----    ---------- ---------------------------------------------------   |
  400. |  RATAJIK 11-01-1994 Initial Developement                                  |
  401. |__________________________________________________________________________*/
  402. VOID CallFunction(PTHREAD_CALL_INFO ptciData)
  403. {
  404.  PFN pfnAddr;
  405.  
  406.  /*____________________________________
  407.  |                                     |
  408.  | Resolve the function address.       |
  409.  |                                     |
  410.  |____________________________________*/
  411.  pfnAddr = (PFN)ptciData->pfnFunctionAddr;
  412.  
  413.  /*____________________________________
  414.  |                                     |
  415.  | Call the function with the parm list|
  416.  | Add vars to the parm list as needed.|
  417.  |____________________________________*/
  418.  pfnAddr(ptciData->pUserParm);
  419.  
  420.  /*____________________________________
  421.  |                                     |
  422.  | Tell the DLG that we are done.      |
  423.  |                                     |
  424.  |____________________________________*/
  425.  if(ptciData->hWnd)
  426.      WinPostMsg(ptciData->hWnd, WM_INITDLG, (MPARAM)7985, 0);
  427. }
  428.  
  429. /*__________________________________________________________________________
  430. |                                                                           |
  431. |    Function: PowerCallWndProc                                             |
  432. |                                                                           |
  433. | Description: This function acts as a message processor for the message    |
  434. |              queue.  When the thread is done, it will post a message to   |
  435. |              this DLG, which will cause the DLG to finish.                |
  436. |                                                                           |
  437. |              A semaphore might work better here, as it's possible the     |
  438. |              thread could finish before the DLG started. I've never       |
  439. |              had it happen yet, as beginthread general takes a while to   |
  440. |              start up.                                                    |
  441. |                                                                           |
  442. |      Return: MRESULT                                                      |
  443. |                                                                           |
  444. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  445. |                            C H A N G E    L O G                           |
  446. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  447. |                                                                           |
  448. |  PRG.    DATE       DESCRIPTION                                           |
  449. |  ----    ---------- ---------------------------------------------------   |
  450. |  RATAJIK 11-01-1994 Initial Developement                                  |
  451. |__________________________________________________________________________*/
  452. MRESULT EXPENTRY PowerCallWndProc(HWND hWndDlg, USHORT msg,MPARAM mp1, MPARAM mp2)
  453.  
  454. {
  455.    static PTHREAD_CALL_INFO ptciData;
  456.  
  457.    switch (msg)
  458.       {
  459.        /*____________________________________
  460.        |                                     |
  461.        | I'm using WM_INITDLG and 7985 to    |
  462.        | make this very simple.  You can add |
  463.        | your own message ID's if you like.  |
  464.        |____________________________________*/
  465.        case  WM_INITDLG:
  466.              {
  467.               /*____________________________________
  468.               |                                     |
  469.               | The thread will post this message to|
  470.               | us when it is done                  |
  471.               |____________________________________*/
  472.               if(mp1 == (MPARAM)7985)
  473.                  {
  474.                   WinDismissDlg(hWndDlg, TRUE);
  475.                  }
  476.               else
  477.                  {
  478.                   /*____________________________________
  479.                   |                                     |
  480.                   | mp2 will contain the comm structure.|
  481.                   | Put the current HWND in to it, so   |
  482.                   | the thread will know where to post  |
  483.                   | the "finished" message.             |
  484.                   |____________________________________*/
  485.                   ptciData = (MPARAM)mp2;
  486.  
  487.                   ptciData->hWnd = hWndDlg;
  488.  
  489.                   /*____________________________________
  490.                   |                                     |
  491.                   | Provide the Running/Wait animation. |
  492.                   |                                     |
  493.                   |____________________________________*/
  494.           WinSubclassWindow(WinWindowFromID(hWndDlg, FRAME_WAIT), FrameWindowMsgProc);
  495.  
  496.                   WinSendMsg( WinWindowFromID(hWndDlg, FRAME_WAIT),
  497.                               WM_CREATE,
  498.                               0, 0);
  499.  
  500.                   /*____________________________________
  501.                   |                                     |
  502.                   | If you don't want the DLG to display|
  503.                   | info to the user, do this (Makes    |
  504.                   | the DLG invisible)                  |
  505.                   |____________________________________*/
  506.           //WinSetWindowPos(hWndDlg, 0,
  507.           //           0, 0, 0, 0, SWP_HIDE|SWP_MOVE|SWP_SIZE );
  508.                  }
  509.              }
  510.           break;
  511.  
  512.        default:
  513.            return(WinDefDlgProc(hWndDlg, msg, mp1, mp2));
  514.            break;
  515.  
  516.       }
  517.  
  518. return(FALSE);
  519. }
  520.  
  521. /*__________________________________________________________________________
  522. |                                                                           |
  523. |    Function: FrameWindowMsgProc                                           |
  524. |                                                                           |
  525. | Description: This function does a little animation in a frame.  It will   |
  526. |              cycle through the array of bitmaps.  You can replace these   |
  527. |              bitmaps with anything you like.  You may note that the       |
  528. |              this takes a fair amount of CPU time.  If you want to        |
  529. |              lessen the amount of CPU activity used for the animation,    |
  530. |              you can slow it down by increasing the WinStartTimer value.  |
  531. |                                                                           |
  532. |              (This was a last minute hack to show what you could do       |
  533. |               using the DLG version of PowerCall.  Feel free to improve   |
  534. |               it...)                                                      |
  535. |                                                                           |
  536. |      Return: MRESULT                                                      |
  537. |                                                                           |
  538. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  539. |                            C H A N G E    L O G                           |
  540. | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
  541. |                                                                           |
  542. |  PRG.    DATE       DESCRIPTION                                           |
  543. |  ----    ---------- ---------------------------------------------------   |
  544. |  RATAJIK 11-05-1994 Initial Developement                                  |
  545. |__________________________________________________________________________*/
  546. MRESULT EXPENTRY FrameWindowMsgProc(HWND hWndDlg, USHORT ulMsg, MPARAM mp1, MPARAM mp2)
  547. {
  548.  static HBITMAP hbBMP[BMP_RUN10]; /* Array of Bitmaps to display           */
  549.  static SHORT   sCur = 0;         /* Current Bitmap to display             */
  550.  static SHORT   sDir = 1;         /* Move foward or backwards in the array */
  551.  static BOOL    bFirst = TRUE;
  552.         INT     j;
  553.         HPS     hPS;
  554.         RECTL   rClient;
  555.  
  556.  /*_________________________________________
  557.  |                                          |
  558.  | Process messages from subclassed field.  |
  559.  |_________________________________________*/
  560.  switch(ulMsg)
  561.    {
  562.     case WM_CREATE:
  563.          /*____________________________________
  564.          |                                     |
  565.          | We want to start moving foward in   |
  566.          | the array.                          |
  567.          |____________________________________*/
  568.          sCur = -1;
  569.          sDir = 1;
  570.  
  571.          /*____________________________________
  572.          |                                     |
  573.          | The timer is used to force a re-    |
  574.          | paint the window ever x ms.  The    |
  575.          | actual calculations will be in      |
  576.          | WM_PAINT                            |
  577.          |____________________________________*/
  578.          WinStartTimer(0, hWndDlg, 0, 150);
  579.      break;
  580.  
  581.     case WM_TIMER:
  582.          /*____________________________________
  583.          |                                     |
  584.          | This will generate a WM_PAINT       |
  585.          |                                     |
  586.          |____________________________________*/
  587.          WinInvalidateRect(hWndDlg, NULL, TRUE);
  588.          break;
  589.  
  590.     case WM_PAINT:
  591.          /*____________________________________
  592.          |                                     |
  593.          | Get ready to paint..                |
  594.          |                                     |
  595.          |____________________________________*/
  596.          hPS = WinBeginPaint(hWndDlg, 0, 0);
  597.  
  598.          GpiSetBackColor(hPS, CLR_YELLOW);
  599.  
  600.          if(bFirst)
  601.             {
  602.              bFirst = FALSE;
  603.  
  604.              /*____________________________________
  605.              |                                     |
  606.              | Load the bitmaps into the array.    |
  607.              |                                     |
  608.              |____________________________________*/
  609.              for(j = BMP_RUN1; j < BMP_RUN10; j++)
  610.                {
  611.                 hbBMP[j-BMP_RUN1] = GpiLoadBitmap(hPS, 0, j, 0, 0);
  612.                }
  613.             }
  614.  
  615.          /*____________________________________
  616.          |                                     |
  617.          | Move the current index in the       |
  618.          | current direction.                  |
  619.          |____________________________________*/
  620.          sCur += sDir;
  621.  
  622.          /*____________________________________
  623.          |                                     |
  624.          | If we've gone beyond a boundry,     |
  625.          | start moving in the next direction. |
  626.          |____________________________________*/
  627.          if(sCur >= (BMP_RUN10 - BMP_RUN1))
  628.             sDir = -1;
  629.  
  630.          if(sCur <= 0)
  631.             sDir = 1;
  632.  
  633.          WinQueryWindowRect(hWndDlg, &rClient);
  634.  
  635.          /*____________________________________
  636.          |                                     |
  637.          | Display the bitmap, stretching to   |
  638.          | the frame.                          |
  639.          |____________________________________*/
  640.          WinDrawBitmap(hPS, hbBMP[sCur], NULL, (POINTL *)&rClient, (LONG)1, (LONG)2, DBM_IMAGEATTRS|DBM_STRETCH);
  641.      WinEndPaint(hPS);
  642.  
  643.          break; /* End of WM_PAINT */
  644.    }
  645.  
  646.  return WinDefDlgProc(hWndDlg, ulMsg, mp1, mp2);
  647. }
  648.