home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol04 / 01b / macsl / mpmmsg.c < prev    next >
C/C++ Source or Header  |  1988-10-03  |  14KB  |  467 lines

  1. /*-----------------------------------------------------------------*/
  2. /* MpmMsg.c                                                        */
  3. /* Messaging functions                                             */
  4. /*-----------------------------------------------------------------*/
  5.  
  6. #include "MacPM.h"
  7.  
  8. /*-----------------------------------------------------------------*/
  9.  
  10. LOCAL BOOL      MpmMsgActivate( PQMSG pqmsg, EventRecord *pEvent,
  11.                                 USHORT fs );
  12. LOCAL BOOL      MpmMsgKey( PQMSG pqmsg, EventRecord *pEvent,
  13.                            USHORT usCode );
  14. LOCAL BOOL      MpmMsgFindChild( PQMSG pqmsg, PPOINTL pptl );
  15. LOCAL BOOL      MpmMsgMouse( PQMSG pqmsg, EventRecord *pEvent,
  16.                              USHORT msg );
  17. LOCAL BOOL      MpmMsgPaint( PQMSG pqmsg, EventRecord *pEvent,
  18.                              USHORT fsPeek );
  19. LOCAL BOOL      MpmMsgPosted( PQMSG pqmsg, EventRecord *pEvent );
  20. LOCAL BOOL      MpmPeekEvent( SHORT sEventMask, EventRecord *pEvent,
  21.                               USHORT fs );
  22.  
  23. /*-----------------------------------------------------------------*/
  24. /* Dispatch a message to its destination window.                   */
  25. /*-----------------------------------------------------------------*/
  26.  
  27. ULONG APIENTRY WinDispatchMsg( hab, pqmsg )
  28.     HAB         hab;
  29.     PQMSG       pqmsg;
  30. {
  31.     if( ! pqmsg->hwnd  ||  ! MpmValidateWindow(pqmsg->hwnd) )
  32.       return 0L;
  33.  
  34.     return
  35.       (ULONG)( *MYWNDOF(pqmsg->hwnd).pfnwp )(
  36.         pqmsg->hwnd, pqmsg->msg, pqmsg->mp1, pqmsg->mp2
  37.      );
  38. }
  39.  
  40. /*-----------------------------------------------------------------*/
  41. /* Get the next message, waiting for one if necessary.             */
  42. /*-----------------------------------------------------------------*/
  43.  
  44. BOOL APIENTRY WinGetMsg( hab, pqmsg, hwnd, msgMin, msgMax )
  45.     HAB         hab;
  46.     PQMSG       pqmsg;
  47.     HWND        hwnd;
  48.     USHORT      msgMin;
  49.     USHORT      msgMax;
  50. {
  51.     while( ! WinPeekMsg( hab, pqmsg, hwnd,
  52.                          msgMin, msgMax, PM_REMOVE ) )
  53.       WinWaitMsg( hab, msgMin, msgMax );
  54.  
  55.     return pqmsg->msg != WM_QUIT;
  56. }
  57.  
  58. /*-----------------------------------------------------------------*/
  59. /* See if a message is available and pass it back in *pqmsg if so. */
  60. /* This function does the dirty work of converting from Mac events */
  61. /* to PM messages.                                                 */
  62. /*-----------------------------------------------------------------*/
  63.  
  64. BOOL APIENTRY WinPeekMsg( hab, pqmsg, hwnd, msgMin, msgMax, fs )
  65.     HAB         hab;
  66.     PQMSG       pqmsg;
  67.     HWND        hwnd;
  68.     USHORT      msgMin;
  69.     USHORT      msgMax;
  70.     USHORT      fs;
  71. {
  72.     EventRecord event;
  73.     SHORT       sEventMask;
  74.     BOOL        fMine;
  75.     static Point  pointMouse = { -999, -999 };
  76.  
  77.     sEventMask = everyEvent;
  78.     if( msgMin == WM_ACTIVATE  &&  msgMax == WM_ACTIVATE )
  79.       sEventMask = activMask;
  80.     else
  81.       ASSERT( ! hwnd && ! msgMin && ! msgMax,
  82.               "WinPeekMsg: hwnd, msgMin, and msgMax must be NULL" );
  83.  
  84.     /* Let desk accessories run */
  85.  
  86.     SystemTask();
  87.  
  88.     /* Peek at the next Mac event.  If it's a null event, check
  89.        for mouse movement. */
  90.  
  91.     fMine = MpmPeekEvent( sEventMask, &event, fs );
  92.  
  93.     if( event.what == nullEvent )
  94.       if( event.where.v != pointMouse.v ||
  95.           event.where.h != pointMouse.h )
  96.       {
  97.         if( fs & PM_REMOVE )
  98.           pointMouse = event.where;
  99.         pqmsg->ptl.x = event.where.h;
  100.         pqmsg->ptl.y = screenBits.bounds.bottom - event.where.v;
  101.         pqmsg->time = event.when * 100 / 6;  /* hack? */
  102.         return MpmMsgMouse( pqmsg, &event, WM_MOUSEMOVE );
  103.       }
  104.  
  105.     if( ! fMine )
  106.       return FALSE;
  107.  
  108.     /* Set up *pqmsg and process the specific type of event */
  109.  
  110.     pqmsg->ptl.x = event.where.h;
  111.     pqmsg->ptl.y = screenBits.bounds.bottom - event.where.v;
  112.     pqmsg->time = event.when * 100 / 6;  /* hack? */
  113.  
  114.     switch( event.what )
  115.     {
  116.       case mouseDown:
  117.         return MpmMsgMouse( pqmsg, &event, WM_BUTTON1DOWN );
  118.  
  119.       case mouseUp:
  120.         return MpmMsgMouse( pqmsg, &event, WM_BUTTON1UP );
  121.  
  122.       case keyDown:
  123.         return MpmMsgKey( pqmsg, &event, 0 );
  124.  
  125.       case keyUp:
  126.         return MpmMsgKey( pqmsg, &event, KC_KEYUP | KC_PREVDOWN );
  127.  
  128.       case autoKey:
  129.         return MpmMsgKey( pqmsg, &event, KC_PREVDOWN );
  130.  
  131.       case updateEvt:
  132.         return MpmMsgPaint( pqmsg, &event, fs );
  133.  
  134.       case activateEvt:
  135.         return MpmMsgActivate( pqmsg, &event, fs );
  136.  
  137.       case postedEvt:
  138.         return MpmMsgPosted( pqmsg, &event );
  139.     }
  140.  
  141.     return FALSE;
  142. }
  143.  
  144. /*-----------------------------------------------------------------*/
  145. /* Post a message to a window or the application queue.  This uses */
  146. /* the Mac's event queue to do the actual posting.  Since there    */
  147. /* isn't room in the Mac's event record to carry all the           */
  148. /* information we need, allocate a QMSG structure.  This structure */
  149. /* had better get freed up when the message is pulled from the     */
  150. /* queue!!                                                         */
  151. /*-----------------------------------------------------------------*/
  152.  
  153. BOOL APIENTRY WinPostMsg( hwnd, msg, mp1, mp2 )
  154.     HWND        hwnd;
  155.     USHORT      msg;
  156.     MPARAM      mp1, mp2;
  157. {
  158.     PQMSG       pqmsg;
  159.     Handle      hqmsg;
  160.  
  161.     if( hwnd && ! MpmValidateWindow(hwnd) )
  162.       return FALSE;
  163.  
  164.     hqmsg = MpmNewHandleZ( sizeof(QMSG) );
  165.     if( ! hqmsg )
  166.       return FALSE;
  167.  
  168.     pqmsg = (PQMSG)*hqmsg;
  169.     pqmsg->hwnd = hwnd;
  170.     pqmsg->msg  = msg;
  171.     pqmsg->mp1  = mp1;
  172.     pqmsg->mp2  = mp2;
  173.  
  174.     return PostEvent( postedEvt, (LONG)hqmsg ) == 0;
  175. }
  176.  
  177. /*-----------------------------------------------------------------*/
  178. /* Post a message to the application queue.                        */
  179. /*-----------------------------------------------------------------*/
  180.  
  181. BOOL APIENTRY WinPostQueueMsg( hmq, msg, mp1, mp2 )
  182.     HMQ         hmq;
  183.     USHORT      msg;
  184.     MPARAM      mp1, mp2;
  185. {
  186.     return WinPostMsg( NULL, msg, mp1, mp2 );
  187. }
  188.  
  189. /*-----------------------------------------------------------------*/
  190. /* Send a message to hwnd's window function.                       */
  191. /*-----------------------------------------------------------------*/
  192.  
  193. MRESULT APIENTRY WinSendMsg( hwnd, msg, mp1, mp2 )
  194.     HWND        hwnd;
  195.     USHORT      msg;
  196.     MPARAM      mp1;
  197.     MPARAM      mp2;
  198. {
  199.     if( ! MpmValidateWindow(hwnd) )
  200.       return FALSE;
  201.  
  202.     return ( *MYWNDOF(hwnd).pfnwp )( hwnd, msg, mp1, mp2 );
  203. }
  204.  
  205. /*-----------------------------------------------------------------*/
  206. /* Wait for the next message; don't remove it from the queue.      */
  207. /*-----------------------------------------------------------------*/
  208.  
  209. BOOL APIENTRY WinWaitMsg( hab, msgMin, msgMax )
  210.     HAB         hab;
  211.     USHORT      msgMin;
  212.     USHORT      msgMax;
  213. {
  214.     QMSG        qmsg;
  215.  
  216.     while( ! WinPeekMsg( hab, &qmsg, NULL,
  217.                          msgMin, msgMax, PM_NOREMOVE ) )
  218.       ;
  219.  
  220.     return TRUE;
  221. }
  222.  
  223. /*-----------------------------------------------------------------*/
  224. /* Handle an activate event.  Redraw the size box and scroll bars  */
  225. /* as is the practice on the Mac, and generate a WM_ACTIVATE       */
  226. /* message.                                                        */
  227. /*-----------------------------------------------------------------*/
  228.  
  229. LOCAL BOOL MpmMsgActivate( pqmsg, pEvent, fs )
  230.     PQMSG       pqmsg;
  231.     EventRecord *pEvent;
  232.     USHORT      fs;
  233. {
  234.     WindowPeek  pwin;
  235.     BOOL        fActive;
  236.     HWND        hwnd;
  237.  
  238.     fActive = pEvent->modifiers & activeFlag;
  239.     pwin = (WindowPeek)pEvent->message;
  240.  
  241.     pqmsg->hwnd = hwnd = HWNDOFPWIN(pwin);
  242.     pqmsg->msg = WM_ACTIVATE;
  243.     pqmsg->mp1 = MPFROM2SHORT( fActive, TRUE );
  244.     pqmsg->mp2 = MPFROMSHORT( ! _sSetFocusDepth );
  245.  
  246.     if( ! ( fs & PM_REMOVE ) )
  247.       return TRUE;
  248.  
  249.     MpmDrawGrowIcon( hwnd );
  250.     MpmActivateScrollBars( pqmsg->hwnd, fActive );
  251.  
  252.     if( fActive )
  253.       _hwndActive = pqmsg->hwnd;
  254.     else
  255.       WinSetFocus( NULL, NULL );
  256.  
  257.     return TRUE;
  258. }
  259.  
  260. /*-----------------------------------------------------------------*/
  261. /* Find the child window of pqmsg->hwnd that contains the point    */
  262. /* *pptl.  If there is such a child, change pqmsg->hwnd to that    */
  263. /* window and also adjust *pptl to that window's coordinates.      */
  264. /*-----------------------------------------------------------------*/
  265.  
  266. LOCAL BOOL MpmMsgFindChild( pqmsg, pptl )
  267.     PQMSG       pqmsg;
  268.     PPOINTL     pptl;
  269. {
  270.     HWND        hwnd;
  271.     PMYWND      pwnd;
  272.  
  273.     for( hwnd = MYWNDOF(pqmsg->hwnd).hwndTopChild;
  274.          hwnd;
  275.          hwnd = MYWNDOF(hwnd).hwndNextSibling )
  276.     {
  277.       pwnd = PMYWNDOF(hwnd);
  278.       if( pptl->x >= pwnd->x  &&  pptl->x < pwnd->x + pwnd->cx  &&
  279.           pptl->y >= pwnd->y  &&  pptl->y < pwnd->y + pwnd->cy )
  280.       {
  281.         pptl->x -= pwnd->x;
  282.         pptl->y -= pwnd->y;
  283.         pqmsg->hwnd = hwnd;
  284.         MpmMsgFindChild( pqmsg, pptl );
  285.         return TRUE;
  286.       }
  287.     }
  288.  
  289.     return FALSE;
  290. }
  291.  
  292. /*-----------------------------------------------------------------*/
  293. /* Handle a keyboard event by generating a WM_CHAR message.        */
  294. /*-----------------------------------------------------------------*/
  295.  
  296. LOCAL BOOL MpmMsgKey( pqmsg, pEvent, usCode )
  297.     PQMSG       pqmsg;
  298.     EventRecord *pEvent;
  299.     USHORT      usCode;
  300. {
  301.     if( _hwndFocus )
  302.       pqmsg->hwnd = _hwndFocus;
  303.     else
  304.       pqmsg->hwnd = _hwndActive;
  305.  
  306.     pqmsg->msg = WM_CHAR;
  307.     pqmsg->mp1 = 0;
  308.     pqmsg->mp2 = 0;
  309.  
  310.     /* THIS FUNCTION IS OBVIOUSLY VERY INCOMPLETE!!! */
  311.  
  312.     return TRUE;
  313. }
  314.  
  315. /*-----------------------------------------------------------------*/
  316. /* Handle a mouse event, either mouseDown, mouseUp, or our         */
  317. /* synthesized mouseMove event.  Figure out who should get the     */
  318. /* event and generate the WM_BUTTON1DOWN, WM_BUTTON1UP, or         */
  319. /* WM_MOUSEMOVE message.  DOESN'T YET HANDLE DOUBLE-CLICKS!!       */
  320. /*-----------------------------------------------------------------*/
  321.  
  322. LOCAL BOOL MpmMsgMouse( pqmsg, pEvent, msg )
  323.     PQMSG       pqmsg;
  324.     EventRecord *pEvent;
  325.     USHORT      msg;
  326. {
  327.     SHORT       sArea;
  328.     POINTL      ptl;
  329.     WindowPeek  pwin;
  330.     USHORT      fid, usHitHi;
  331.     HWND        hwnd;
  332.  
  333.     sArea = FindWindow( pEvent->where, &pwin );
  334.  
  335.     fid = usHitHi = 0;
  336.     ptl = pqmsg->ptl;
  337.     pqmsg->hwnd = hwnd = ( pwin ? HWNDOFPWIN(pwin) : _hwndDesktop );
  338.  
  339.     switch( sArea )
  340.     {
  341.       case inContent:
  342.         WinMapWindowPoints( _hwndDesktop, hwnd, &ptl, 1 );
  343.         MpmMsgFindChild( pqmsg, &ptl );
  344.         hwnd = pqmsg->hwnd;
  345.         break;
  346.  
  347.       case inDesk:
  348.         break;
  349.  
  350.       case inDrag:
  351.         fid = FID_TITLEBAR;
  352.         break;
  353.  
  354.       case inGoAway:
  355.         fid = FID_SYSMENU;
  356.         break;
  357.  
  358.       case inGrow:
  359.         fid = FID_SIZEBORDER;
  360.         break;
  361.  
  362.       case inMenuBar:
  363.         hwnd = _hwndMenu;
  364.         if( ! hwnd )
  365.           return FALSE;
  366.         break;
  367.  
  368.       case inSysWindow:
  369.         SystemClick( pEvent, pwin );
  370.         return FALSE;
  371.  
  372.       case inZoomIn:
  373.       case inZoomOut:
  374.         usHitHi = sArea;
  375.         fid = FID_MINMAX;
  376.         break;
  377.  
  378.       default:
  379.         return FALSE;
  380.     }
  381.  
  382.     if( fid )
  383.     {
  384.       hwnd = WinWindowFromID( hwnd, fid );
  385.       ASSERT( hwnd,
  386.               "MpmMsgMouse: missing frame control" );
  387.     }
  388.  
  389.     if( MYWNDOF(hwnd).flStyle & WS_DISABLED )
  390.       return FALSE;
  391.  
  392.     pqmsg->hwnd = hwnd;
  393.     pqmsg->msg  = msg;
  394.     pqmsg->mp1  = MPFROM2SHORT( ptl.x, ptl.y );
  395.     pqmsg->mp2  = MPFROM2SHORT( HT_NORMAL, usHitHi );
  396.  
  397.     return TRUE;
  398. }
  399.  
  400. /*-----------------------------------------------------------------*/
  401. /* Handle an update event by generating WM_PAINT messages to the   */
  402. /* window and its children.                                        */
  403. /*-----------------------------------------------------------------*/
  404.  
  405. LOCAL BOOL MpmMsgPaint( pqmsg, pEvent, fsPeek )
  406.     PQMSG       pqmsg;
  407.     EventRecord *pEvent;
  408.     USHORT      fsPeek;
  409. {
  410.     WindowPeek  pwin;
  411.  
  412.     pwin = (WindowPeek)pEvent->message;
  413.     pqmsg->hwnd = HWNDOFPWIN(pwin);
  414.     ASSERT( MpmValidateWindow(pqmsg->hwnd),
  415.             "MpmMsgPaint: bad hwnd" );
  416.  
  417.     pqmsg->msg = WM_PAINT;
  418.     pqmsg->mp1 = 0;
  419.     pqmsg->mp2 = 0;
  420.  
  421.     if( ! (fsPeek & PM_REMOVE) )
  422.       return TRUE;
  423.  
  424.     WinUpdateWindow( pqmsg->hwnd );
  425.  
  426.     return FALSE;
  427. }
  428.  
  429. /*-----------------------------------------------------------------*/
  430. /* Handle a posted message.                                        */
  431. /*-----------------------------------------------------------------*/
  432.  
  433. LOCAL BOOL MpmMsgPosted( pqmsg, pEvent )
  434.     PQMSG       pqmsg;
  435.     EventRecord *pEvent;
  436. {
  437.     PQMSG       pqmsgPosted;
  438.  
  439.     pqmsgPosted = (PQMSG)*(Handle)pEvent->message;
  440.  
  441.     pqmsg->hwnd = pqmsgPosted->hwnd;
  442.     pqmsg->msg  = pqmsgPosted->msg;
  443.     pqmsg->mp1  = pqmsgPosted->mp1;
  444.     pqmsg->mp2  = pqmsgPosted->mp2;
  445.  
  446.     DisposHandle( (Handle)pEvent->message );
  447.  
  448.     return TRUE;
  449. }
  450.  
  451. /*-----------------------------------------------------------------*/
  452. /* Peek at a Mac event, either pulling it from the queue or not.   */
  453. /*-----------------------------------------------------------------*/
  454.  
  455. LOCAL BOOL MpmPeekEvent( sEventMask, pEvent, fs )
  456.     SHORT       sEventMask;
  457.     EventRecord *pEvent;
  458.     USHORT      fs;
  459. {
  460.     if( fs & PM_REMOVE )
  461.       return GetNextEvent( sEventMask, pEvent );
  462.     else
  463.       return EventAvail( sEventMask, pEvent );
  464. }
  465.  
  466. /*-----------------------------------------------------------------*/
  467.