예제 #1
0
BOOL APIENTRY WprogressBar(HWND hParent, HWND hOwner, PPROGRESSDLG ppd) {
   QMSG  qmsg;
   HWND hwnd;
   PPRGSAPPDATA pad;
   BOOL rc = FALSE;
   
   // allocate storage for application data
   if (!(pad = (PPRGSAPPDATA)malloc(sizeof(PRGSAPPDATA)))) return FALSE;
   memset(pad, 0, sizeof(PRGSAPPDATA));
   pad->ppd = ppd;
   // ottiene tempo di inizio
   pad->start = WinGetCurrentTime(pad->hab = WinQueryAnchorBlock(hOwner))
                / 1000;
   // window handles
   if (ppd->fl & PRGSS_BITMAP) {
      SIZEL szl;
      WqueryBitmapSize(pad->ppd->hbmp, &szl);
      pad->cxbmp = szl.cx;
   } /* endif */
   if (NULLHANDLE != (hwnd = WinLoadDlg(hParent, hOwner, ProgressDlgProc,
                                     hmod, DLG_PROGRESS, pad))) {
      if (!ppd->pszPrgrss) ppd->pszPrgrss = SZ_PROGRESS;
      if (!ppd->pszTime) ppd->pszTime = SZ_ELAPSTIME;
      if (ppd->pszStop) WinSetDlgItemText(hwnd, BTN_STOP, ppd->pszStop);
      pad->hOwner = WinQueryWindow(hwnd, QW_OWNER);
      WinEnableWindow(pad->hOwner, FALSE);
      for(;;) {
         if (WinGetMsg(pad->hab, &qmsg, NULLHANDLE, 0, 0)) {    // loop standard
            if (qmsg.msg == PRGSM_END && qmsg.hwnd == hwnd) {
               if (pad->qQuit.msg)
                  WinPostMsg(pad->qQuit.hwnd, pad->qQuit.msg,
                             pad->qQuit.mp1, pad->qQuit.mp2);
               break;
            } // end if   
            WinDispatchMsg(pad->hab, &qmsg);
         } else {                   // WM_QUIT
            pad->qQuit = qmsg;
            if(qmsg.hwnd == NULLHANDLE)                       // SHUTDOWN
               WinPostMsg(hwnd, WM_CLOSE, MPFROMLONG(TRUE), NULL);
            else if(qmsg.hwnd == HWNDFROMMP(qmsg.mp2))        // TASKLIST
               WinPostMsg(hwnd, WM_CLOSE, 0L, 0L);
            else                            // chiusura regolare: termina
               break;
         } // end if
      } // end forever
      WinSetFocus(HWND_DESKTOP, hOwner);
      WinDestroyWindow(hwnd);
      WinEnableWindow(pad->hOwner, TRUE);
      rc = TRUE;
   } // end if
   free(pad);
   return rc;
}
예제 #2
0
MRESULT EXPENTRY ProgressDlgProc(HWND hwnd,
                                 ULONG msg,
                                 MPARAM mp1,
                                 MPARAM mp2) {
   switch (msg) {
   // init -----------------------------------------------------------------
      case WM_INITDLG: {
         PPRGSAPPDATA pad = (PPRGSAPPDATA)mp2;
         ULONG ul;
         POINTL aptl[] = {{1, 36}, {220, 24}}; 
         WinSetWindowPtr(hwnd, 0L, (PVOID)mp2);
         WinSetWindowText(hwnd, pad->ppd->pszTitle);
         // dimensioni-coordinate varie
         pad->cyTitle = uGetSval(SV_CYTITLEBAR);
         pad->hButton = WinWindowFromID(hwnd, BTN_STOP);
         WinQueryWindowPos(pad->hButton, &pad->swp);
         WinQueryWindowRect(hwnd, &pad->rcl);
         WinMapDlgPoints(hwnd, aptl, 2, TRUE);
         pad->sldd.cbSize = sizeof(SLDCDATA);
         pad->sldd.usScale1Increments = 11;
         pad->sldd.usScale1Spacing = (pad->rcl.xRight - 2 * pad->cyTitle) / 10 - 1;
         pad->hProgress = WinCreateWindow(hwnd, WC_SLIDER, (PSZ)NULL,
                                          SLS_BOTTOM | SLS_OWNERDRAW |
                                          SLS_READONLY | SLS_RIBBONSTRIP |
                                          WS_VISIBLE, 3, aptl[0].y,
                                          pad->rcl.xRight - 6, aptl[1].y,
                                          hwnd, HWND_TOP, SLDR_PROGRESS,
                                          (PVOID)&pad->sldd, NULL);
         // controlla versione S.O. e setta font slider e bottone
         DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_MINOR,
                         &ul, sizeof(ULONG));
         if (ul < 40) {
            WinSetPresParam(pad->hProgress, PP_FONTNAMESIZE, 7, "8.Helv");
            WinSetPresParam(pad->hButton, PP_FONTNAMESIZE, 7, "8.Helv");
         } else {
            WinSetPresParam(pad->hProgress, PP_FONTNAMESIZE, 11, "9.WarpSans");
         } /* endif */
         // rileva larghezza progress bar
         pad->cxPrgs = LOUSHORT((ULONG)WinSendMsg(pad->hProgress,
                                                 SLM_QUERYSLIDERINFO,
                                         MPFROM2SHORT(SMA_SHAFTDIMENSIONS, 0),
                                         MPVOID)) - 6;
         // setta altezza barra pari a altezza barra titolo
         WinSendMsg(pad->hProgress, SLM_SETSLIDERINFO,
                    MPFROM2SHORT(SMA_SHAFTDIMENSIONS, 0), (MPARAM)pad->cyTitle);
         // setta testo e altezza barra graduata
         WinSendMsg(pad->hProgress, SLM_SETTICKSIZE,
                    MPFROM2SHORT(SMA_SETALLTICKS, pad->cyTitle / 3), MPVOID);
         WinSendMsg(pad->hProgress, SLM_SETSCALETEXT, (MPARAM)0, (MPARAM)"0%");
         WinSendMsg(pad->hProgress, SLM_SETSCALETEXT, (MPARAM)5, (MPARAM)"50%");
         WinSendMsg(pad->hProgress, SLM_SETSCALETEXT, (MPARAM)10, (MPARAM)"100%");
         // testo iniziale progesso e elapsed time:
         sprintf(pad->achElapsed, "%s: 00:00:00", pad->ppd->pszTime);
         WinSetDlgItemText(hwnd, TXT_TIME, pad->achElapsed);
         sprintf(pad->achCurPrg, "%s:   0%%", pad->ppd->pszPrgrss);
         WinSetDlgItemText(hwnd, TXT_PERCENT, pad->achCurPrg);
         // se specificato setta nuovo font dialogo
         if (pad->ppd->fl & PRGSS_FONT)
            WsetDlgFonts(hwnd, NULLHANDLE, pad->ppd->FontNameSize);
         // posiziona finestra al centro Parent window
         if (pad->ppd->fl & PRGSS_CENTER) {
            WcenterInWindow(hwnd, pad->ppd->hPos);
         } else {
            SWP swp;
            swp.hwnd = pad->ppd->hPos;
            swp.x = pad->ppd->ptl.x;
            swp.y = pad->ppd->ptl.y;
            swp.cx = swp.cy = 0;
            swp.fl = SWP_MOVE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER;
            swp.hwndInsertBehind = HWND_TOP;
            WsetRelativePos(hwnd, &swp);
         } // end if
         // notifica creazione dialogo
         WinPostMsg(pad->ppd->hNotify, WM_PRGRSREADY, (MPARAM)hwnd, (MPARAM)0);
         break;
      } // end case WM_INITDLG
      case WM_DRAWITEM:
         if (((POWNERITEM)mp2)->idItem == SDA_RIBBONSTRIP) {
            PPRGSAPPDATA pad = GetData(hwnd);
            if (pad->ppd->fl & PRGSS_BITMAP) {   // se deve disegnare la bitmap
               RECTL rcl = {0, 0, ((POWNERITEM)mp2)->rclItem.xRight -
                            ((POWNERITEM)mp2)->rclItem.xLeft, pad->cyTitle};
               POINTL ptl = {((POWNERITEM)mp2)->rclItem.xLeft,
                             ((POWNERITEM)mp2)->rclItem.yBottom};
               while (ptl.x < ((POWNERITEM)mp2)->rclItem.xRight) {
                  WinDrawBitmap(((POWNERITEM)mp2)->hps, pad->ppd->hbmp, &rcl,
                                &ptl, 0L, 0L, DBM_NORMAL);
                  ptl.x += pad->cxbmp;
                  rcl.xRight = ((POWNERITEM)mp2)->rclItem.xRight - ptl.x;
               } /* endwhile */
            } else {                       // colore
               GpiCreateLogColorTable(((POWNERITEM)mp2)->hps,
                                      0, LCOLF_RGB, 0, 0, NULL);
               WinFillRect(((POWNERITEM)mp2)->hps,
                           &((POWNERITEM)mp2)->rclItem, pad->ppd->color);
            } /* endif */
            return (MRESULT)TRUE;
         } // end if
         break;
      case PRGSM_INCREMENT: { // notifica incremento
         PPRGSAPPDATA pad = GetData(hwnd);
         ULONG ul;
         pad->incr = (ULONG)mp1;
         WinSendMsg(pad->hProgress,
                    SLM_SETSLIDERINFO,
                    MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
                    (MPARAM)((pad->incr * pad->cxPrgs) / 1000));
         ul = WinGetCurrentTime(pad->hab) / 1000;
         if (pad->current != ul) {
            pad->current = ul;
            pad->elapsed = pad->current - pad->start;
            sprintf(pad->achElapsed, "%s: %02d:%02d:%02d", pad->ppd->pszTime,
                    pad->elapsed / 3600, (pad->elapsed % 3600) / 60,
                    pad->elapsed % 60);
            WinSetDlgItemText(hwnd, TXT_TIME, pad->achElapsed);
         } // end if
         if (pad->ulCurPrg != (ul = (ULONG)mp1 / 10)) {
            pad->ulCurPrg = ul;
            sprintf(pad->achCurPrg, "%s: %3d %%",
                    pad->ppd->pszPrgrss, pad->ulCurPrg);
            WinSetDlgItemText(hwnd, TXT_PERCENT, pad->achCurPrg);
         } // end if
         return (MRESULT)pad->flStop;
      } // end case PRGSM_INCREMENT
      case PRGSM_MSG:
         return (MRESULT)Wprint(hwnd, (PSZ)mp1, (ULONG)mp2);
      case WM_COMMAND:
         if ((ULONG)mp1 == BTN_STOP) {
            PPRGSAPPDATA pad = GetData(hwnd);
            pad->flStop = TRUE;
            WinEnableWindow(pad->hButton, FALSE);
         } /* endif */
         break;
      case WM_CLOSE: {
         PPRGSAPPDATA pad = GetData(hwnd);
         // se elaborazione ancora in corso mostra messaggio
         if (pad->incr > 0 && pad->incr < 1000) {
            PSZ psz;
            if (!(psz = (PSZ)malloc(1024)) ||
            // se la notify window restituisce NULL
                (BOOL)WinSendMsg(pad->ppd->hNotify, WM_PRGRSQUIT,
                                 (MPARAM)psz, MPVOID) ||
            // o se la chiusura Š confermata
                Wprint(hwnd, psz, PMPRNT_QUERY)) {
               WinPostMsg(hwnd, PRGSM_END, MPVOID, MPVOID);
               WinPostMsg(pad->hOwner, WM_CLOSE, MPVOID, MPVOID);
            // se nel frattempo Š terminato
            } else {
               pad->qQuit.msg = 0;
               if (!pad->incr || pad->incr >= 1000) {
                  WinPostMsg(hwnd, PRGSM_END, MPVOID, MPVOID);
               } else if ((BOOL)mp1) {
                  WinCancelShutdown((HMQ)WinQueryWindowULong(hwnd, QWL_HMQ),
                                    FALSE);
               } // end if
            } // end if
            free (psz);
         } /* endif */
      }  break;
      default:
         return WinDefDlgProc(hwnd, msg, mp1, mp2);
   } /* endswitch */
   return (MRESULT)FALSE;
}
예제 #3
0
MRESULT Window::stdWndProc( HWND hWnd, ULONG iMessage, MPARAM mParam1,
                            MPARAM mParam2, BOOL *returned )
{
  switch( iMessage )
  {
//    case WM_FOCUSCHANGE :
    case WM_SETSELECTION :
    case WM_ACTIVATE :
    {
      if( type != Window::LISTBOX &&
          type != Window::COMBOLISTBOX )
      {
        focus( (BOOL)mParam1 );//SHORT1FROMMP( mParam2 ) );
      }
      break;
    }
    case WM_SETFOCUS :
    {
      if( type != Window::LISTBOX &&
          type != Window::COMBOLISTBOX )
        focusSet( (BOOL)mParam2 );
      break;
    }
    case WM_BUTTON1DOWN :
    {
      if( type == SCROLLBAR )
        setFocus();
      HWND hwnd = WinQueryFocus( HWND_DESKTOP );
      if( mouseListener.getSize() != 0 )
      {
        mouseButtonDown = TRUE;
        WinSetCapture( HWND_DESKTOP, hWnd );
	  		WinStartTimer( Application::hab, hWndClient, 1, 50 );
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::DOWN );
      }
      if( hwnd != WinQueryFocus( HWND_DESKTOP ) ) return (MRESULT)TRUE;
      break;
    }
    case WM_BUTTON1UP :
    {
      if( type == LISTBOX ||
          type == COMBOLISTBOX )
      {
        performFocusEvent(
          (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) );
      }
      else
      if( mouseListener.getSize() != 0 )
      {
        mouseButtonDown = FALSE;
        WinStopTimer( Application::hab, hWndClient, 1 );
        WinSetCapture( HWND_DESKTOP, NULLHANDLE );
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::RELEASE );
//        return (MPARAM)TRUE;
      }
      break;
    }
    case WM_BUTTON2DOWN :
    {
      if( mouseListener.getSize() != 0 )
      {
        WinSetCapture( HWND_DESKTOP, hWnd );
	  		WinStartTimer( Application::hab, hWndClient, 1, 50 );
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::DOWN );
      }
      break;
    }
    case WM_BUTTON2UP :
    {
      if( mouseListener.getSize() != 0 )
      {
        WinStopTimer( Application::hab, hWndClient, 1 );
        WinSetCapture( HWND_DESKTOP, NULLHANDLE );
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::RELEASE );
      }
      break;
    }
    case WM_BUTTON1CLICK :
    {
      if( mouseListener.getSize() != 0 )
      {
				// Check if triple click

				int newTick = WinGetCurrentTime( Application::hab );
				if( newTick - lastTick <= 
            WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) )
				{
	        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
		      performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::TRIPLECLICK );
				}
				else
        {
        	Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        	performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::CLICK );
				}
      }
      break;
    }
    case WM_BUTTON2CLICK :
    {
      if( mouseListener.getSize() != 0 )
      {
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::CLICK );
      }
      break;
    }
    case WM_BUTTON1DBLCLK :
    {
      if( mouseListener.getSize() != 0 )
      {
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::DOUBLECLICK );
      }
			lastTick = WinGetCurrentTime( Application::hab );
      break;
    }
    case WM_BUTTON2DBLCLK :
    {
      if( mouseListener.getSize() != 0 )
      {
        Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::DOUBLECLICK );
      }
      break;
    }
    case WM_MOUSEMOVE :
    {
      if( currentPointer != NULLHANDLE )
        WinSetPointer( HWND_DESKTOP, currentPointer );
      if( mouseListener.getSize() != 0 )
      {
        Point pos( (SHORT)SHORT1FROMMP(mParam1), (SHORT)SHORT2FROMMP(mParam1) );
        performMouseEvent( &pos, 0, AMouseEvent::MOVE );
      }
      if( currentPointer != NULLHANDLE )
       	return (MPARAM)TRUE;
      break;
    }
    case WM_TIMER :
    {
      if( mouseButtonDown )
      {
        POINTL ptl;
        WinQueryPointerPos( HWND_DESKTOP, &ptl );
        WinMapWindowPoints( HWND_DESKTOP, hWnd, &ptl, 1 );

        if( ptl.y < 0 || ptl.y > height )
        {
          Point pos( ptl.x, ptl.y );
          performMouseEvent( &pos, 0, AMouseEvent::MOVE );
        }
      }
      break;
    }
    case WM_SIZE :
    {
      int oldWidth = width, oldHeight = height;
      SWP swp;

      WinQueryWindowPos( hWndFrame, &swp );

      width = swp.cx;
      height = swp.cy;
      size( oldWidth, oldHeight );
      break;
    }
    case WM_HSCROLL :
    {
      int pos = SHORT1FROMMP( mParam2 ), id = SHORT1FROMMP( mParam1 );
      switch( SHORT2FROMMP( mParam2 ) )
      {
        case SB_PAGERIGHT :
        {
          performScrollbarEvent( id, Scrollbar::PAGERIGHT, pos );
          break;
        }
        case SB_PAGELEFT :
        {
          performScrollbarEvent( id, Scrollbar::PAGELEFT, pos );
          break;
        }
        case SB_LINERIGHT :
        {
          performScrollbarEvent( id, Scrollbar::LINERIGHT, pos );
          break;
        }
        case SB_LINELEFT :
        {
          performScrollbarEvent( id, Scrollbar::LINELEFT, pos );
          break;
        }
        case SB_SLIDERTRACK :
        {
          performScrollbarEvent( id, Scrollbar::HORZTRACK, pos );
          break;
        }
        case SB_SLIDERPOSITION :
        {
          performScrollbarEvent( id, Scrollbar::HORZRELEASED, pos );
          break;
        }
      }
      break;
    }
    case WM_SYSCOMMAND :
    {
      // Check if the parent is a dialog, then chain the WM_SYSCOMMAND

      if( parent->getType() == DIALOG )
        WinSendMsg( ((Window *)parent)->getHWND(), WM_SYSCOMMAND, mParam1, mParam2 );
      break;
    }
    case WM_VSCROLL :
    {
      int id = SHORT1FROMMP( mParam1 );
      Scrollbar *scrollbar = (Scrollbar *)getControl( id );
      int pos;
      if( scrollbar )
        pos = scrollbar->convertScrollPosToReal( SHORT1FROMMP( mParam2 ) );
      else
        pos = SHORT1FROMMP( mParam2 );

      switch( SHORT2FROMMP( mParam2 ) )
      {
        case SB_PAGEDOWN :
        {
          performScrollbarEvent( id, Scrollbar::PAGEDOWN, pos );
          break;
        }
        case SB_PAGEUP :
        {
          performScrollbarEvent( id, Scrollbar::PAGEUP, pos );
          break;
        }
        case SB_LINEDOWN :
        {
          performScrollbarEvent( id, Scrollbar::LINEDOWN, pos );
          break;
        }
        case SB_LINEUP :
        {
          performScrollbarEvent( id, Scrollbar::LINEUP, pos );
          break;
        }
        case SB_SLIDERTRACK :
        {
          performScrollbarEvent( id, Scrollbar::VERTTRACK, pos );
          break;
        }
        case SB_SLIDERPOSITION :
        {
          performScrollbarEvent( id, Scrollbar::VERTRELEASED, pos );
          break;
        }
      }
      break;
    }
    case WM_MOVE :
    {
      SWP swp;

      WinQueryWindowPos( hWndFrame, &swp );

      x = swp.x;
      y = swp.y;
      move();
      break;
    }
    case WM_CLOSE :
    {
      if( close() )
        break;
      else
        return (MPARAM)FALSE;
    }
    case WM_COMMAND :
    {
      if( SHORT1FROMMP( mParam2 ) == CMDSRC_PUSHBUTTON )
      {
        Window *control = (Window *)getControl( SHORT1FROMMP(mParam1));
        if( control != NULL )
        {
          if( control->type == PUSHBUTTON )
          {
            control->performButtonEvent( control, control->id );
            return FALSE;
          }
        }
        else
          return FALSE; // In case ESC would close the dialog
      }
      break;
    }
    case WM_CHAR :
    {
      if( type == LISTBOX )
      {
        performFocusEvent(
          (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) );
      }

      if( (SHORT1FROMMP( mParam1 ) & KC_KEYUP) ||
          (SHORT1FROMMP( mParam1 ) & KC_DEADKEY) ||
          (SHORT1FROMMP( mParam1 ) & KC_INVALIDCOMP) )
        break;

/*			if( SHORT1FROMMP( mParam1 ) & KC_COMPOSITE )
				mParam1 = MPFROM2SHORT( SHORT1FROMMP( mParam1 ) & ~KC_VIRTUALKEY,
																SHORT2FROMMP( mParam1 ) );*/

      int modifiers = 0;

      if( SHORT1FROMMP( mParam1 ) & KC_SHIFT )
        modifiers |= KeyDef::SHIFT;

      if( SHORT1FROMMP( mParam1 ) & KC_ALT )
        modifiers |= KeyDef::kALT;

      if( SHORT1FROMMP( mParam1 ) & KC_CTRL)
        modifiers |= KeyDef::CTRL;

      if( SHORT1FROMMP( mParam1 ) & KC_VIRTUALKEY )
      {
        int key = 0, vKey = SHORT2FROMMP( mParam2 );

       // Maybe NumLock is on

        if( SHORT1FROMMP(mParam1) & KC_CHAR &&
            !(vKey == VK_ENTER || vKey == VK_NEWLINE || vKey == VK_TAB ||
              vKey == VK_BACKSPACE ))
          key = SHORT1FROMMP( mParam2 );
        else
        if( vKey == VK_UP )
          key = KeyDef::UP;
        else
        if( vKey == VK_DOWN )
          key = KeyDef::DOWN;
        else
        if( vKey == VK_LEFT )
          key = KeyDef::LEFT;
        else
        if( vKey == VK_RIGHT )
          key = KeyDef::RIGHT;
        else
        if( vKey == VK_PAGEUP )
          key = KeyDef::PAGEUP;
        else
        if( vKey == VK_PAGEDOWN )
          key = KeyDef::PAGEDOWN;
        else
        if( vKey == VK_INSERT )
          key = KeyDef::INSERT;
        else
        if( vKey == VK_DELETE )
          key = KeyDef::kDELETE;
        else
        if( vKey == VK_HOME )
          key = KeyDef::HOME;
        else
        if( vKey == VK_END )
          key = KeyDef::END;
        else
        if( vKey == VK_ESC )
          key = KeyDef::ESCAPE;
        else
        if( vKey == VK_F1 )
          key = KeyDef::F1;
        else
        if( vKey == VK_F2 )
          key = KeyDef::F2;
        else
        if( vKey == VK_F3 )
          key = KeyDef::F3;
        else
        if( vKey == VK_F4 )
          key = KeyDef::F4;
        else
        if( vKey == VK_F5 )
          key = KeyDef::F5;
        else
        if( vKey == VK_F6 )
          key = KeyDef::F6;
        else
        if( vKey == VK_F7 )
          key = KeyDef::F7;
        else
        if( vKey == VK_F8 )
          key = KeyDef::F8;
        else
        if( vKey == VK_F9 )
          key = KeyDef::F9;
        else
        if( vKey == VK_F10 )
          key = KeyDef::F10;
        else
        if( vKey == VK_F11 )
          key = KeyDef::F11;
        else
        if( vKey == VK_F12 )
          key = KeyDef::F12;
        else
        if( vKey == VK_ENTER )
          key = KeyDef::ENTER;
        else
        if( vKey == VK_NEWLINE )
          key = KeyDef::RETURN;
        else
        if( vKey == VK_BACKSPACE )
          key = KeyDef::BACKSPACE;
        else
        if( vKey == VK_TAB )
          key = KeyDef::TAB;
        else
        if( vKey == VK_BACKTAB )
        {
          key = KeyDef::TAB;
          modifiers |= KeyDef::SHIFT;
        }
        else
        if( vKey == VK_SPACE )
          key = KeyDef::SPACE;

	      if( parent->getType() == DIALOG )
  	    	((Dialog *)parent)->focusHotkey( key );

        if( key != 0 )
          if( performKeyEvent( this, modifiers, key ) ) return MPARAM(TRUE);

        // Do not pass up and down key to dialog if this is a combobox (would
        // move focus)

/*        if( getFilterDialogArrows() &&
            (vKey == VK_UP || vKey == VK_DOWN) )
          return (MPARAM)TRUE;*/
      }
      else
      {
        int key = SHORT1FROMMP( mParam2 );
        if( performKeyEvent( this, modifiers, key ) ) return MPARAM(TRUE);
      }
      break;
    }
    case WM_CONTROL :
    {
      Window *control = (Window *)getControl( SHORT1FROMMP(mParam1));
      if( control != NULL )
      {
        if( control->type == Window::LISTBOX ||
            control->type == Window::COMBOLISTBOX )
        {
          switch( SHORT2FROMMP(mParam1) )
          {
            case LN_KILLFOCUS : control->focus( FALSE ); break;
            case LN_SETFOCUS : control->focus( TRUE );break;
            case LN_ENTER :
              control->performSelectionEvent(
                (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) );
              break;
          }
        }
        else
        if( control->type == Window::SCROLLBAR )
        {
          switch( SHORT2FROMMP(mParam1) )
          {
            case SLN_KILLFOCUS : control->focus( FALSE ); break;
            case SLN_SETFOCUS : control->setFocus(); break;
          }
        }
        else
        if( control->type == Window::RADIOBUTTON ||
            control->type == Window::CHECKBOX )
        {
          switch( SHORT2FROMMP( mParam1) )
          {
            case BN_CLICKED :
            case BN_DBLCLICKED :
              control->performButtonEvent( control, control->id );
              break;
          }
        }
      }
      break;
    }
		case DM_DRAGOVER:
		{
			PDRAGINFO pDInfo;
			PDRAGITEM pDItem;
  
	  	if( !acceptDropFiles )
				return MRFROM2SHORT(DOR_NODROPOP, 0);

			pDInfo = (PDRAGINFO)mParam1;
			DrgAccessDraginfo(pDInfo);
			pDItem = DrgQueryDragitemPtr(pDInfo, 0);
			USHORT   usOp = 0, usDrop = DOR_NEVERDROP;

			/* Inspect each item to see if it is acceptable */
			ULONG  ulItems = DrgQueryDragitemCount (pDInfo);
      for (INT i = 0; i < ulItems; i++)
			{
				pDItem = DrgQueryDragitemPtr(pDInfo, i);

				/* The item is acceptable only if it is copyable and the     */
				/* operation is a copy, or it is moveable and the operation  */
				/* is a move, and it can render <DRM_OS2FILE, NULL>          */
				if (pDItem->fsSupportedOps & DO_COPYABLE)
				{
					usOp = DO_COPY;
					/* Only check files, all types */
					if (DrgVerifyRMF(pDItem, "DRM_OS2FILE", 0))
						usDrop = DOR_DROP;
					else
					{
						usDrop = DOR_NEVERDROP;
						break;
					}
				}
				else
				{
					/* Must be a file but not droppable in type op */
					usDrop = DOR_NODROPOP;
          usOp = 0;
					break;
				}
			} /* end for all items dragged  */

			DrgFreeDraginfo(pDInfo);

			return MRFROM2SHORT(usDrop, usOp);
		}
		case DM_DROP:
		{
			PDRAGINFO pDInfo;
			PDRAGITEM pDItem;
			pDInfo = (PDRAGINFO)mParam1;
			DrgAccessDraginfo(pDInfo);
			pDItem = DrgQueryDragitemPtr(pDInfo, 0);
			ULONG  ulItems = DrgQueryDragitemCount (pDInfo);
			ULONG  p;
			char **files;

			files = (char **)malloc( sizeof( char * ) * ulItems );

			for (INT i=0; i < ulItems; i++)
			{
				CHAR    DragSrcPath[CCHMAXPATH], DragSrcName[CCHMAXPATH];
				pDItem = DrgQueryDragitemPtr(pDInfo, i);
				DrgQueryStrName(pDItem->hstrContainerName, sizeof(DragSrcPath), (PSZ)DragSrcPath);
				if (!(PSZ)DragSrcPath)
					break;
				if (DragSrcPath[(strlen(DragSrcPath)-1)] != '\\')
					strcat((PSZ)DragSrcPath, "\\");

				/* Use the dragitem source name, it's the real name */
				DrgQueryStrName(pDItem->hstrSourceName, sizeof(DragSrcName),
																									(PSZ)DragSrcName);
				if (!((PSZ)DragSrcName))
					break;
				strcat((PSZ)DragSrcPath, (PSZ)DragSrcName);
				FILESTATUS3  fsFile;
				DosError(FERR_DISABLEHARDERR);
				APIRET rc = DosQueryPathInfo(DragSrcPath, FIL_STANDARD, &fsFile,
																									sizeof(FILESTATUS3));
				DosError(FERR_ENABLEHARDERR);

				if (!rc && !(fsFile.attrFile & FILE_DIRECTORY))
				{
					files[i] = (char *)malloc( strlen(DragSrcPath) + 1 );
          strcpy( files[i], DragSrcPath );
					DrgSendTransferMsg(pDItem->hwndItem, DM_ENDCONVERSATION,
																			MPFROMLONG(pDItem->ulItemID),
																			MPFROMLONG(DMFL_TARGETSUCCESSFUL));
				}
				else
				{
					DosBeep(100,10);
//					EditorDisplay[BufNum]->DisplayMessage( pszDropNoFile );
				}
			}

			filesDropped( files, ulItems );

			for( i = 0; i < ulItems; i++ )
	      free( (void *)files[i] );

      free( (void *)files );

			DrgFreeDraginfo(pDInfo);
			break;
		}
    case WM_USER + 1 :
    {
      return (MPARAM)execFromMainThread( (int)mParam1, (void *)mParam2 );
    }
    case WM_USER + 2 :
    {
      setFocus();
      break;
    }
  }
  *returned = FALSE;
  return (MRESULT)NULL;
}
예제 #4
0
MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
//	static POINTS DragStartPtrPos;
    POINTL ptl;
    static char Row, Col;
    static BOOL HasMoved = FALSE;
    static BOOL IntroSoundPlayed = FALSE;
    static BOOL RealPaint = TRUE;           // indicates whether the board
				// has to be repainted or just copied
    INT aktscan;
    CHAR msgtext[256];
    ULONG ulResponse;
//	ERRORID errId;

	
    switch( msg ){
    case WM_CREATE:
	if( !InfoData.LoadHigh() ){	// get previously saved highscores
	    InfoData.ResetHigh();
	    WinMessageBox( HWND_DESKTOP, hwndMain,
			   "The file scores.dat " \
			   "(which is in the current directory) was somehow corrupted." \
			   " All Highscores will be reset to Zero.",
			   "Error when loading Highscores",
			   0, MB_OK | MB_INFORMATION );
	}

	// allocate memory for global variables; see GLOBALS struct in tgraph.h
	pg = new GLOBALS;
	// initialize globals to zero
	memset( pg, 0, sizeof( GLOBALS ));
	// store globals pointer into client window words; see WinRegisterClass
//    WinSetWindowULong( hwnd, QWL_USER, (ULONG) pg );

    wcprintf("1: %x", WinGetLastError( hab ) );
	DosCreateEventSem( NULL, &hevWaitAfterScan, 0, FALSE );
				// Sem is created in reset state
	DosCreateEventSem( NULL, &hevHiScoreWin, 0, FALSE );
	DosCreateEventSem( NULL, &hevWaitAfterSound, 0, FALSE );
	DosCreateEventSem( NULL, &hevWaitSoundReady, 0, TRUE );
				// Sem is created in posted state
	// hevWaitAfterScan and hewWaitAfterSound are used to indicate
	// when the respective WM_CREATE routines are done.
	// after that they are in posted state, as desired
            
	// initialize globals with important data
	pg->hab          = hab;
	pg->hwndClient   = hwnd;
	pg->hwndFrame    = WinQueryWindow( hwnd, QW_PARENT );
	pg->hwndTitlebar = WinWindowFromID( pg->hwndFrame, FID_TITLEBAR );
	pg->hwndMenubar  = WinWindowFromID( pg->hwndFrame, FID_MENU );
	// create graphics and sound threads
	pg->tidTSound = _beginthread( &threadsound, NULL, LEN_STACK, NULL );
	pg->tidTGraph = _beginthread( &threadgraph, NULL, LEN_STACK, NULL );
	DosWaitEventSem( hevWaitAfterSound, SEM_INDEFINITE_WAIT );
	WinPostMsg( pg->hwndTSound, WM_SOUND_INTRO, MPFROMHWND(hwnd), 0 );
	// wait for the sound's WM_CREATE
	DosWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
	// wait for the graphics' WM_CREATE
	InfoData.ShipsNotFound = GBoard.GetShipNumber();
	wcprintf("create: %x", WinGetLastError( hab ) );
	return (MRESULT)0;
			
    case WM_CONTROL:
	break;
    case WM_QUIT:
	break;
			
    case WM_CLOSE:	// this message is sent before WM_QUIT
	InfoData.SaveHigh( WinGetCurrentTime(hab) );
				// save the highscores and provide a random seed
	// get pointer to globals from window words
//    pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
	// tell object windows to quit, then exit their threads
//			WinSendMsg( pg->hwndTGraph, WM_DESTROY, mp1, mp2 );
	WinPostMsg( pg->hwndTGraph, WM_QUIT, mp1, mp2 );
//			WinSendMsg( pg->hwndTSound, WM_DESTROY, mp1, mp2 );
	WinPostMsg( pg->hwndTSound, WM_QUIT, mp1, mp2 );
	DosCloseEventSem( hevWaitAfterScan );
	DosCloseEventSem( hevHiScoreWin );
	DosCloseEventSem( hevWaitAfterSound );
	DosCloseEventSem( hevWaitSoundReady );
	WriteProfile( hab );
	delete pg;
	return (MRESULT) 0;
	
    case WM_ERASEBACKGROUND:
	wcprintf("erasebackground");        
//	return (MRESULT) FALSE;
	return (MRESULT) TRUE;

    case WM_PAINT:
///////////////////////////////////
	    {
		RECTL rectl;
		WinQueryWindowRect( pg->hwndClient, &rectl );
wcprintf("Linienrechteck: Breite: %d H”he: %d", rectl.xRight, rectl.yTop );
		// test size:
		GpiSetColor( hpsGlob, CLR_RED );
		ptl.x = rectl.xLeft; ptl.y = rectl.yBottom;
		GpiMove( hpsGlob, &ptl );
		ptl.x = rectl.xRight; ptl.y = rectl.yTop;
		GpiLine( hpsGlob, &ptl );
	    }
///////////////////////////
	break;

    case WM_SIZE:
	wcprintf("main wnd function wm-size");
	RealPaint = TRUE;
	GBoard.SetPMBoardValues( SHORT1FROMMP( mp2 ), SHORT2FROMMP( mp2 ) );
	WndResize( hwnd );
	wcprintf("size: %x", WinGetLastError( hab ) );
	break;
			
    case WM_BEGINDRAG:
	WinSetCapture( HWND_DESKTOP, hwnd );	// capture the mouse pointer
	GBoard.SetfDrag( TRUE );	// indicate that mouse is being dragged
	GBoard.ResetFirstDraw();	// for initialization of drag op.
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
//			GBoard.ShowPointerPos( hwnd, 0, 0 ); // removes the square
	ptl.x = SHORT1FROMMP(mp1);
	ptl.y = SHORT2FROMMP(mp1);
	Row = GBoard.GetBoardRow( ptl.y );	// starting point of drag
	Col = GBoard.GetBoardCol( ptl.x );	// operation; static!
	return (MRESULT)TRUE;
			
    case WM_MOUSEMOVE:
	if( GBoard.GetfDrag() ){	// if mouse is being dragged
	    WinSendMsg( pg->hwndTGraph, WM_DRAWDRAGLINE, mp1,
			MPFROM2SHORT( Row, Col ) );
	    HasMoved = TRUE;
	} else {		// mouse is moved normally
	    if( !fHideSquare )
		WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
			    mp1 );
//					GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1),
//														  SHORT2FROMMP(mp1));
	}
	break;	
    case WM_ENDDRAG:
	WinSetCapture( HWND_DESKTOP, NULLHANDLE ); // release the captured
				// mouse pointer
	if( HasMoved ){	// mousemove has actually been moved
	    WinSendMsg( pg->hwndTGraph, WM_MARKDRAGLINE,
			MPFROM2SHORT( Row, Col ), 0 );
	    HasMoved = FALSE;
	}
	GBoard.SetfDrag( FALSE );
	GBoard.ClearDrawPoint();	// because no square is drawn right now
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    mp1 );
//			GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
				// draws square at the current ptr pos
	break;
			
    case WM_CHAR:	// key was pressed
	if( SHORT2FROMMP( mp2 ) != VK_SPACE ) break;	// only space is interesting
	if( GBoard.GetfDrag() ) break;	// do nothing while dragging
	if( !GBoard.GetfShowLines() ){	// lines not visible yet
	    GBoard.SetfShowLines( TRUE );
	    WinSendMsg( pg->hwndTGraph, WM_DISPLAYLINES, 0, 0 );
	}
	break;
			
    case WM_BUTTON1CLICK:
	if( !InfoData.ShipsNotFound ) break;	// game is finished
	ptl.x = (LONG)SHORT1FROMMP( mp1 );
	ptl.y = (LONG)SHORT2FROMMP( mp1 );
	Row = GBoard.GetBoardRow( ptl.y );
	Col = GBoard.GetBoardCol( ptl.x );
	if( !Row || !Col ) break;
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
//			GBoard.ShowPointerPos( hwnd, 0, 0 );	// hides pointer square
	if(( aktscan = GBoard.GetDiscovered( Row, Col )) != -1 ){
	    WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd),
			MPFROMSH2CH( MAKESHORT(Row, Col),
				     (CHAR)aktscan,(CHAR)TRUE));
// umstricken auf WinPostMsg												 
				// toggle Place display
	} else {	// scan Place
	    DosResetEventSem( hevWaitAfterScan, &ulResponse );
// DosBeep(500, 150 );				
	    WinPostMsg( pg->hwndTGraph, WM_GRAPH_SCAN, MPFROMHWND(hwnd),
			MPFROM2SHORT( Row, Col ) );
// DosBeep( 800, 150 );								
	    WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
// DosBeep( 1000, 150 );				
				// first the scanning sounds must be played (and finished)
	    aktscan = GBoard.Scan( Row, Col );
	    if( aktscan == GBoard.GetShipNumber() + 10 ){
		InfoData.ShipsNotFound--;
		WinPostMsg( pg->hwndTSound, WM_SOUND_FOUNDSHIP, MPFROMHWND(hwnd), 0 );
	    } else {
		if( aktscan )
		    WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND,
				MPFROMHWND(hwnd), MPFROMLONG( aktscan ) );
		else	
		    WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND0, MPFROMHWND(hwnd), 0 );
	    }
	    WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
				// waits until scanning is done, and only then displays the
				// field icon
//				hps = WinGetPS( hwnd );
	    WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd),
			MPFROMSH2CH( MAKESHORT(Row, Col),
				     (CHAR)aktscan,(CHAR)TRUE));
// umstricken auf WinPostMsg
	    WinPostMsg( pg->hwndTGraph, WM_SHOWSTATUSLINE, 0, 0 );
				
//				ShowStatusLine( hps, GBoard.MovesNeeded(), InfoData.ShipsNotFound,
//									 GBoard.GetWinWidth(), GBoard.GetWinHeight() );
//				WinReleasePS( hps );
	    if( !InfoData.ShipsNotFound ){	// game is finished, all ships found
		Score = GBoard.MovesNeeded();
		if	( !InfoData.ReturnLastHigh()	// still space in the hiscore table
		|| Score < InfoData.ReturnLastHigh() ){	// player kicks last one out
				// player enters highscore table
		    WinPostMsg( pg->hwndTSound, WM_SOUND_NEWHISCORE, MPFROMHWND(hwnd), 0 );
		    WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT );
				// waits until the NEWHISCORE sound is actually played
		    WinDlgBox( HWND_DESKTOP, hwnd, HighScoreDlgProc, (HMODULE)0,
			       IDR_HIGHSCOREDLG, NULL );
		    WinPostMsg( hwnd, WM_COMMAND,
				MPFROMSHORT(IDM_GAMEHIGH), (MPARAM)0 );
				// show highscore-table
		    DosResetEventSem( hevHiScoreWin, &ulResponse ); // resets the sem again
		} else {
		    WinPostMsg( pg->hwndTSound, WM_SOUND_LOST, MPFROMHWND(hwnd), 0 );
		    WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT );
				// waits until the NEWHISCORE sound is actually played
		    sprintf( msgtext,
			     "You needed %d moves to find the lost ships. " \
			     "To enter the highscore list you need %d moves." \
			     " So try again!", Score, InfoData.ReturnLastHigh() - 1 );
		    WinMessageBox( HWND_DESKTOP, hwnd, msgtext, "Oh, Shit!", 0,
				   MB_OK | MB_INFORMATION | MB_HELP );
		}
	    }
	}
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( ptl.x, ptl.y ) );
//			GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y ); // redisplay ptr square
	break;
			
    case WM_BUTTON2CLICK:
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
	ptl.x = (LONG)SHORT1FROMMP( mp1 );
	ptl.y = (LONG)SHORT2FROMMP( mp1 );
	Row = GBoard.GetBoardRow( ptl.y );
	Col = GBoard.GetBoardCol( ptl.x );
	WinSendMsg( pg->hwndTGraph, WM_DRAWPMMARK, MPFROMHWND(hwnd),
		    MPFROM2SHORT( Row, Col ) );
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( ptl.x, ptl.y ) );
	break;
			
    case WM_COMMAND:
	switch( SHORT1FROMMP( mp1 ) ){
	case IDM_GAMENEW:
	    GBoard.NewGame();
	    InfoData.ShipsNotFound = GBoard.GetShipNumber();
	    RealPaint = TRUE;
	    WinInvalidateRect( hwnd, NULL, TRUE );
	    break;
	case IDM_GAMESETTINGS:
	    if( WinDlgBox( HWND_DESKTOP, hwndFrame,
			   GameSettingsDlgProc, (HMODULE)0,
			   IDR_GAMESETTINGSDLG, NULL ) ){
				// screen must be repainted
		RealPaint = TRUE;
		WinInvalidateRect( hwnd, NULL, TRUE );
	    }
	    break;
	case IDM_GAMEHIGH:
	    if( !WinDlgBox( HWND_DESKTOP, hwndFrame,
			    ShowHighDlgProc, (HMODULE)0,
			    IDR_SHOWHIGHDLG, NULL ) ){	// user requested "Clear"
		if( WinMessageBox( HWND_DESKTOP, hwndMain,
				   "Do you really want to eradicate all those " \
				   "arduously achieved highscores?",
				   "Clear Highscores",
				   0, MB_OKCANCEL | MB_WARNING ) == MBID_OK )
		    InfoData.ResetHigh();
	    }
	    break;
					
	case IDM_HELPINDEX:	// help index
	    WinSendMsg( hwndHelp, HM_HELP_INDEX, 0, 0 );
	    break;
					
	case IDM_HELPGENERAL:	// general help
	    WinSendMsg( hwndHelp, HM_EXT_HELP, 0, 0 );
	    break;
					
	case IDM_HELPEXTENDED:	// help on help (system page)
	    WinSendMsg( hwndHelp, HM_DISPLAY_HELP, 0, 0 );
	    break;
					
	case IDM_HELPKEYS:	// keys help
	    WinSendMsg( hwndHelp, HM_KEYS_HELP, 0, 0 );
	    break;
					
	
	case IDM_HELPPRODUCTINFO:
	    ulResponse = WinDlgBox( HWND_DESKTOP, hwndFrame,
				    ProdInfoDlgProc, (HMODULE)0,
				    IDR_PRODINFODLG, NULL );
	    break;		
	}
	break;

    case HM_QUERY_KEYS_HELP:                // system asks which page to display
	return MRFROMSHORT( PANEL_HELPKEYS );
	      
    case HM_HELPSUBITEM_NOT_FOUND:
	return (MRESULT)FALSE;
			
    case WM_USER_ACK:	// graphics task finished its work
//         DosBeep( 1000, 150 );
	switch( (ULONG)mp1 ){
	case WM_USER_PAINT:
	    WinQueryPointerPos( HWND_DESKTOP, &ptl );
	    WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1);
	    fHideSquare = FALSE;
	    WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
			MPFROM2SHORT( ptl.x, ptl.y ) );
//					GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y );
				// painting has finished, square can be displayed now
	    break;
	}
	break;	
    case WM_SOUND_ACK:
	switch( (ULONG)mp1 ){
	case WM_SOUND_INTRO:
	    break;
	}
	break;

			
    default:
	return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 );
    }		// end switch( msg )
    return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 );
}		// end MRESULT EXPENTRY WndProc()
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static BOOL   fContinueCalc = FALSE ;
     static HAB    hab ;
     static HWND   hwndMenu ;
     static INT    iStatus = STATUS_READY ;
     static INT    iCurrentRep = IDM_10 ;
     static LONG   lCalcRep, lRepAmts [] = { 10, 100, 1000, 10000, 100000 } ;
     static ULONG  ulElapsedTime ;
     double        A ;
     LONG          lRep ;
     QMSG          qmsg ;

     switch (msg)
          {
          case WM_CREATE:
               hab = WinQueryAnchorBlock (hwnd) ;

               hwndMenu = WinWindowFromID (
                               WinQueryWindow (hwnd, QW_PARENT),
                               FID_MENU) ;
               return 0 ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                    case IDM_10:
                    case IDM_100:
                    case IDM_1000:
                    case IDM_10000:
                    case IDM_100000:
                         WinCheckMenuItem (hwndMenu, iCurrentRep, FALSE) ;
                         iCurrentRep = COMMANDMSG(&msg)->cmd ;
                         WinCheckMenuItem (hwndMenu, iCurrentRep, TRUE) ;
                         return 0 ;

                    case IDM_START:
                         WinEnableMenuItem (hwndMenu, IDM_START, FALSE) ;
                         WinEnableMenuItem (hwndMenu, IDM_ABORT, TRUE) ;

                         iStatus = STATUS_WORKING ;
                         WinInvalidateRect (hwnd, NULL, FALSE) ;

                         lCalcRep = lRepAmts [iCurrentRep - IDM_10] ;
                         fContinueCalc = TRUE ;
                         ulElapsedTime = WinGetCurrentTime (hab) ;

                         qmsg.msg = WM_NULL ;

                         for (A = 1.0, lRep = 0 ; lRep < lCalcRep ; lRep++)
                              {
                              A = Savage (A) ;

                              while (WinPeekMsg (hab, &qmsg, NULLHANDLE,
                                                 0, 0, PM_NOREMOVE))
                                   {
                                   if (qmsg.msg == WM_QUIT)
                                        break ;

                                   WinGetMsg (hab, &qmsg, NULLHANDLE, 0, 0) ;
                                   WinDispatchMsg (hab, &qmsg) ;

                                   if (!fContinueCalc)
                                        break ;
                                   }
                              if (!fContinueCalc || qmsg.msg == WM_QUIT)
                                   break ;
                              }
                         ulElapsedTime = WinGetCurrentTime (hab) - 
                                                  ulElapsedTime ;

                         if (!fContinueCalc || qmsg.msg == WM_QUIT)
                              iStatus = STATUS_READY ;
                         else
                              iStatus = STATUS_DONE ;

                         WinInvalidateRect (hwnd, NULL, FALSE) ;

                         WinEnableMenuItem (hwndMenu, IDM_START, TRUE) ;
                         WinEnableMenuItem (hwndMenu, IDM_ABORT, FALSE) ;
                         return 0 ;

                    case IDM_ABORT:
                         fContinueCalc = FALSE ;
                         return 0 ;
                    }
               break ;

          case WM_PAINT:
               PaintWindow (hwnd, iStatus, lCalcRep, ulElapsedTime) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
예제 #6
0
void	draw_thread(void *args)
{
   static long          b,b2,index;
	static int           distance;
   static RECTL         ScreenSize;
   static long          Color;
   static DATETIME	   DateTime;
   static POINTL        p1,p2,op1,op2;
   static POINTL        ptl[3];
   static long          width,height;
   static long          starcount,whiteStars,redStars,blueStars,yellowStars;
   static POINTL        *whitesegs,*redsegs,*bluesegs,*yellowsegs;  
   static POINTL        *whitesegs_o,*redsegs_o,*bluesegs_o,*yellowsegs_o;  
   static long          x[500],y[500];
   static float         realX[500],realY[500],realZ[500],sx[500],sy[500],sz[500],size[500];
   static float         ss,dfx,dfy,dfz,dd,f;
   static long          whitecount,redcount,bluecount,yellowcount;
   static long          whitecount_o,redcount_o,bluecount_o,yellowcount_o;
   static long          wc,rc,bc,yc;
   static long          gravity;
   static float         middleX,middleY,middleZ;

   int first;


   POINTL whitesegsAr[200]; 
   POINTL redsegsAr[200];
   POINTL bluesegsAr[200];
   POINTL yellowsegsAr[200];
   POINTL whitesegsAr_o[200]; 
   POINTL redsegsAr_o[200];
   POINTL bluesegsAr_o[200];
   POINTL yellowsegsAr_o[200];

   long gridX,gridY;
   long gridX_o,gridY_o;
   int isGrid;

   int inside;

   long searchNearX;
   long searchNearY;

   float dsx;
   float dsy;
   float ds;
   float minds;

   char starName[MAX_NAMESIZE];
   char starName_o[MAX_NAMESIZE];

   BOOL tracename;

   BOOL trid;

   float sinA;
   float cosA;

   float yAxis1Mx,yAxis1My,yAxis1Mz;
   float yAxis2Mx,yAxis2My,yAxis2Mz;
   float xAxis1Mx,xAxis1My,xAxis1Mz;
   float xAxis2Mx,xAxis2My,xAxis2Mz;
   float zAxis1Mx,zAxis1My,zAxis1Mz;
   float zAxis2Mx,zAxis2My,zAxis2Mz;

   float yAr1x,yAr1y,yAr1z;
   float yAr2x,yAr2y,yAr2z;
   float xAr1x,xAr1y,xAr1z;
   float xAr2x,xAr2y,xAr2z;
   float zAr1x,zAr1y,zAr1z;
   float zAr2x,zAr2y,zAr2z;


   long yAxis12Dx,yAxis12Dy;
   long yAxis22Dx,yAxis22Dy;
   long xAxis12Dx,xAxis12Dy;
   long xAxis22Dx,xAxis22Dy;
   long zAxis12Dx,zAxis12Dy;
   long zAxis22Dx,zAxis22Dy;

   long yAr12Dx,yAr12Dy;
   long yAr22Dx,yAr22Dy;
   long xAr12Dx,xAr12Dy;
   long xAr22Dx,xAr22Dy;
   long zAr12Dx,zAr12Dy;
   long zAr22Dx,zAr22Dy;

   HAB	   drawingthread_hab = WinInitialize(0);
   HMQ	   drawingthread_hmq = WinCreateMsgQueue(drawingthread_hab, 0);

   /* Settings galaxy parameter. */

   setTNGfont(hps); /* Setzen der Schriftart */


   whiteStars=configuration_data.whitestar_count;
   redStars=configuration_data.redstar_count;
   blueStars=configuration_data.bluestar_count;
   yellowStars=configuration_data.yellowstar_count;

   tracename=configuration_data.tracename;

   gravity=configuration_data.gravity;

   starcount=whiteStars+redStars+blueStars+yellowStars;

   width    = screenSizeX;
   height   = screenSizeY;

   trid=configuration_data.show3d;
   sinA=sin(-0.03f);
   cosA=cos(-0.03f);


   if ( trid )
   {
       yAxis1Mx=   0;
       yAxis1My=AXISMY;
       yAxis1Mz=   0;
       yAxis2Mx=   0;
       yAxis2My=AXISMY+AXISL;
       yAxis2Mz=   0;

       yAr1x=   ARROWW;
       yAr1y=   AXISMY+AXISL-ARROWL;
       yAr1z=      0;
       yAr2x=   -ARROWW;
       yAr2y=   AXISMY+AXISL-ARROWL;
       yAr2z=      0;

       xAxis1Mx=-AXISL2;
       xAxis1My=AXISMY;
       xAxis1Mz=   0;
       xAxis2Mx=AXISL2;
       xAxis2My=AXISMY;
       xAxis2Mz=   0;

       xAr1x=   AXISL2-ARROWL;
       xAr1y=   AXISMY;
       xAr1z=   ARROWW;
       xAr2x=   AXISL2-ARROWL;
       xAr2y=   AXISMY;
       xAr2z=   -ARROWW;


       zAxis1Mx=   0;
       zAxis1My=AXISMY;
       zAxis1Mz=-AXISL2;
       zAxis2Mx=   0;
       zAxis2My=AXISMY;
       zAxis2Mz=AXISL2;

       zAr1x=   ARROWW;
       zAr1y=   AXISMY;
       zAr1z=   AXISL2-ARROWL;
       zAr2x=   -ARROWW;
       zAr2y=   AXISMY;
       zAr2z=   AXISL2-ARROWL;

       convertTo2D(yAxis1Mx,yAxis1My,yAxis1Mz,&yAxis12Dx,&yAxis12Dy);
       convertTo2D(yAxis2Mx,yAxis2My,yAxis2Mz,&yAxis22Dx,&yAxis22Dy);
   }

   /* random seed (needed for each thread) */
	srand(WinGetCurrentTime(hab));


   /* Clear the background. */
   WinQueryWindowRect( hwndSaver, &ScreenSize );
   WinFillRect( hps, &ScreenSize, CLR_BLACK );


   /* Allocate memory. */
/*
   whitesegs = (POINTL *) ( malloc ( sizeof ( POINTL ) * starcount * 4 ) );
   redsegs = (POINTL *) ( malloc ( sizeof ( POINTL ) * starcount * 4 ) );
   bluesegs = (POINTL *) ( malloc ( sizeof ( POINTL ) * starcount * 4 ) );
   yellowsegs = (POINTL *) ( malloc ( sizeof ( POINTL ) * starcount * 4 ) );
*/   

   whitesegs = (POINTL *) &whitesegsAr;
   redsegs =   (POINTL *) &redsegsAr;
   bluesegs =  (POINTL *) &bluesegsAr;
   yellowsegs =(POINTL *) &yellowsegsAr;

   whitesegs_o = (POINTL *) &whitesegsAr_o;
   redsegs_o =   (POINTL *) &redsegsAr_o;
   bluesegs_o =  (POINTL *) &bluesegsAr_o;
   yellowsegs_o =(POINTL *) &yellowsegsAr_o;


  
   /* Init stars */
   for (b = 0; b < starcount; b++)
   {

      if (trid)
      {
          realX[b] = (rand()%(4000))-2000;
          realY[b] = (rand()%(2000))-1000;
          realZ[b] = (rand()%(4000))-2000;
      }
      else
      {
          realX[b] = (rand()%(4000))-2000;
          realY[b] = (rand()%(4000))-2000;
          realZ[b] = 0;
      }

      size[b]=1;
      if ( rand()%(10)>7 )
      {
         size[b]=4;
      }

      sx[b]=0;
      sy[b]=0; 
      sz[b]=0;

      x[b]=-1;
      y[b]=-1;
   }
 
   first=1;

   searchNearX=screenSizeX/2;
   searchNearY=screenSizeY/2;

   while(!stop_draw_thread)
   {
      DosGetDateTime ( &DateTime );
      srand ( DateTime.hundredths * 320 );

      if (trid )
      {
         turn2D(&xAxis1Mx,&xAxis1Mz,sinA,cosA);
         turn2D(&xAxis2Mx,&xAxis2Mz,sinA,cosA);
         turn2D(&zAxis1Mx,&zAxis1Mz,sinA,cosA);
         turn2D(&zAxis2Mx,&zAxis2Mz,sinA,cosA);

         turn2D(&yAr1x,&yAr1z,sinA,cosA);
         turn2D(&yAr2x,&yAr2z,sinA,cosA);

         turn2D(&xAr1x,&xAr1z,sinA,cosA);
         turn2D(&xAr2x,&xAr2z,sinA,cosA);

         turn2D(&zAr1x,&zAr1z,sinA,cosA);
         turn2D(&zAr2x,&zAr2z,sinA,cosA);
      }

      if (!first)
      {
         memcpy(whitesegs_o,whitesegs,sizeof ( POINTL ) * whitecount * 4);
         memcpy(redsegs_o,redsegs,sizeof ( POINTL ) * redcount * 4);
         memcpy(bluesegs_o,bluesegs,sizeof ( POINTL ) * bluecount * 4);
         memcpy(yellowsegs_o,yellowsegs,sizeof ( POINTL ) * yellowcount * 4);

         whitecount_o= whitecount;
         redcount_o=   redcount;
         bluecount_o=  bluecount;
         yellowcount_o=yellowcount;

         if (isGrid)
         {
            gridX_o=gridX;
            gridY_o=gridY;
            strcpy(starName_o,starName);
         }
      }
     
      
      /* <=- Stars -=> */

      whitecount=0;
      redcount=0;
      bluecount=0;
      yellowcount=0;

      wc=0;
      rc=0;
      bc=0;
      yc=0;


      middleX=0;
      middleY=0;
      middleZ=0;

      for (b = 0; b < starcount; b++)
      {
          if (trid )
          {
             turn2D(&realX[b],&realZ[b],sinA,cosA);
          }

          middleX+=realX[b];
          middleY+=realY[b];
          middleZ+=realZ[b];
      }
      middleX=middleX/starcount;
      middleY=middleY/starcount;
      middleZ=middleZ/starcount;
      for (b = 0; b < starcount; b++)
      {
          realX[b]-=middleX;
          if (!trid)
              realY[b]-=middleY;
          realZ[b]-=middleZ;
      }

      isGrid=0;

      minds=1e9;


      for (b = 0; b < starcount; b++)
      {
         for (b2=b+1 ;b2<starcount ;b2++)
         {
              if (trid)
              {
                  dfx=realX[b]-realX[b2];
                  dfy=realY[b]-realY[b2];
                  dfz=realZ[b]-realZ[b2];

                  dd=gravity*size[b2]/((dfx*dfx)+(dfy*dfy)+(dfz*dfz));           
                  dfx=dfx*dd;
                  dfy=dfy*dd;
                  dfz=dfz*dd;
                  sx[b]=sx[b]-dfx;
                  sy[b]=sy[b]-dfy;
                  sz[b]=sz[b]-dfz;

                  sx[b2]=sx[b2]+dfx;
                  sy[b2]=sy[b2]+dfy;
                  sz[b2]=sz[b2]+dfz;
              }
              else {
                  dfx=realX[b]-realX[b2];
                  dfy=realY[b]-realY[b2];

                  dd=gravity*size[b2]/((dfx*dfx)+(dfy*dfy));           
                  dfx=dfx*dd;
                  dfy=dfy*dd;
                  sx[b]=sx[b]-dfx;
                  sy[b]=sy[b]-dfy;

                  sx[b2]=sx[b2]+dfx;
                  sy[b2]=sy[b2]+dfy;
              }

         }
         realX[b]=realX[b]+sx[b];
         realY[b]=realY[b]+sy[b];
         realZ[b]=realZ[b]+sz[b];

         convertTo2D(realX[b],realY[b],realZ[b],&x[b],&y[b]);

         inside=isInside(x[b],y[b]);

         if ( wc<whiteStars )
         {
            wc++;
            if (inside)
            {
                index = whitecount*4;
                whitesegs[index].x = x[b];
                whitesegs[index].y = y[b];
                whitesegs[index+1].x = x[b]+2;
                whitesegs[index+1].y = y[b];
                whitesegs[index+2].x = x[b];
                whitesegs[index+2].y = y[b]+1;
                whitesegs[index+3].x = x[b]+2;
                whitesegs[index+3].y = y[b]+1;
                whitecount++;
            }
         }
         else {
            if (rc<redStars )
            {
                rc++;
                if (inside)
                {
                   index = redcount*4;
                   redsegs[index].x = x[b];
                   redsegs[index].y = y[b];
                   redsegs[index+1].x = x[b]+2;
                   redsegs[index+1].y = y[b];
                   redsegs[index+2].x = x[b];
                   redsegs[index+2].y = y[b]+1;
                   redsegs[index+3].x = x[b]+2;
                   redsegs[index+3].y = y[b]+1;
                   redcount++;
                }
            }
            else {
               if (bc<blueStars )
               {
                    bc++;
                    if (inside)
                    {
                       index = bluecount*4;
                       bluesegs[index].x = x[b];
                       bluesegs[index].y = y[b];
                       bluesegs[index+1].x = x[b]+2;
                       bluesegs[index+1].y = y[b];
                       bluesegs[index+2].x = x[b];
                       bluesegs[index+2].y = y[b]+1;
                       bluesegs[index+3].x = x[b]+2;
                       bluesegs[index+3].y = y[b]+1;
                       bluecount++;
                    }
               }
               else {
                    yc++;
                    if (inside)
                    {
                       index = yellowcount*4;
                       yellowsegs[index].x = x[b];
                       yellowsegs[index].y = y[b];
                       yellowsegs[index+1].x = x[b]+2;
                       yellowsegs[index+1].y = y[b];
                       yellowsegs[index+2].x = x[b];
                       yellowsegs[index+2].y = y[b]+1;
                       yellowsegs[index+3].x = x[b]+2;
                       yellowsegs[index+3].y = y[b]+1;
                       yellowcount++;
                    }
               }
             }
         }

         if (inside)
         {
             isGrid=1;
             dsx=(searchNearX-x[b]);
             dsy=(searchNearY-y[b]);
             ds=dsx*dsx+dsy*dsy;
             if (ds<minds)
             {
                 minds=ds;
                 gridX=x[b];
                 gridY=y[b];

                 strcpy(starName,starNames[b % CNT_STARS]);
             }
         }
      }

      if (!first)
      {
           drawGrid(hps,gridX_o,gridY_o,0,starName_o,tracename);

           if ( trid )
           {
               drawAxis(hps,yAxis12Dx,yAxis12Dy,yAxis22Dx,yAxis22Dy,xAxis12Dx,xAxis12Dy,xAxis22Dx,xAxis22Dy,zAxis12Dx,zAxis12Dy,zAxis22Dx,zAxis22Dy,0);
               drawArrows(hps,yAxis22Dx,yAxis22Dy,yAr12Dx,yAr12Dy,yAr22Dx,yAr22Dy,0);
               drawArrows(hps,xAxis22Dx,xAxis22Dy,xAr12Dx,xAr12Dy,xAr22Dx,xAr22Dy,0);
               drawArrows(hps,zAxis22Dx,zAxis22Dy,zAr12Dx,zAr12Dy,zAr22Dx,zAr22Dy,0);

           }

      }

      if (!first)
      {

          Color=CLR_BLACK;
          GpiSetColor ( hps , Color );
          GpiPolyLineDisjoint ( hps ,whitecount_o * 4 , whitesegs_o );
      }
      Color=CLR_WHITE;
      GpiSetColor ( hps , Color );
      GpiPolyLineDisjoint ( hps ,whitecount * 4 , whitesegs );

      if (!first)
      {
          Color=CLR_BLACK;
          GpiSetColor ( hps , Color );
          GpiPolyLineDisjoint ( hps ,redcount_o * 4 , redsegs_o );
      }
      Color=CLR_RED;
      GpiSetColor ( hps , Color );
      GpiPolyLineDisjoint ( hps ,redcount * 4 , redsegs );

      if (!first)
      {
          Color=CLR_BLACK;
          GpiSetColor ( hps , Color );
          GpiPolyLineDisjoint ( hps ,bluecount_o * 4 , bluesegs_o );
      }
      Color=CLR_BLUE;
      GpiSetColor ( hps , Color );
      GpiPolyLineDisjoint ( hps ,bluecount * 4 , bluesegs );

      if (!first)
      {
          Color=CLR_BLACK;
          GpiSetColor ( hps , Color );
          GpiPolyLineDisjoint ( hps ,yellowcount_o * 4 , yellowsegs_o );
      }
      Color=CLR_YELLOW;
      GpiSetColor ( hps , Color );
      GpiPolyLineDisjoint ( hps ,yellowcount * 4 , yellowsegs );

      if (isGrid)
      {
          drawGrid(hps,gridX,gridY,1,starName,tracename);
          searchNearX=gridX+(rand()%(4))-2;
          searchNearY=gridY+(rand()%(4))-2;
      }
      else {
           for (b = 0; b < starcount; b++)
           {
                if (trid)
                {
                    realX[b] = (rand()%(4000))-2000;
                    realY[b] = (rand()%(2000))-1000;
                    realZ[b] = (rand()%(4000))-2000;
                }
                else
                {
                    realX[b] = (rand()%(4000))-2000;
                    realY[b] = (rand()%(4000))-2000;
                    realZ[b] = 0;
                }
           }
      }

      if ( trid )
      {

         convertTo2D(xAxis1Mx,xAxis1My,xAxis1Mz,&xAxis12Dx,&xAxis12Dy);
         convertTo2D(xAxis2Mx,xAxis2My,xAxis2Mz,&xAxis22Dx,&xAxis22Dy);

         convertTo2D(zAxis1Mx,zAxis1My,zAxis1Mz,&zAxis12Dx,&zAxis12Dy);
         convertTo2D(zAxis2Mx,zAxis2My,zAxis2Mz,&zAxis22Dx,&zAxis22Dy);

         convertTo2D(yAr1x,yAr1y,yAr1z,&yAr12Dx,&yAr12Dy);
         convertTo2D(yAr2x,yAr2y,yAr2z,&yAr22Dx,&yAr22Dy);

         convertTo2D(xAr1x,xAr1y,xAr1z,&xAr12Dx,&xAr12Dy);
         convertTo2D(xAr2x,xAr2y,xAr2z,&xAr22Dx,&xAr22Dy);

         convertTo2D(zAr1x,zAr1y,zAr1z,&zAr12Dx,&zAr12Dy);
         convertTo2D(zAr2x,zAr2y,zAr2z,&zAr22Dx,&zAr22Dy);


         drawAxis(hps,yAxis12Dx,yAxis12Dy,yAxis22Dx,yAxis22Dy,xAxis12Dx,xAxis12Dy,xAxis22Dx,xAxis22Dy,zAxis12Dx,zAxis12Dy,zAxis22Dx,zAxis22Dy,1);

         drawArrows(hps,yAxis22Dx,yAxis22Dy,yAr12Dx,yAr12Dy,yAr22Dx,yAr22Dy,1);
         drawArrows(hps,xAxis22Dx,xAxis22Dy,xAr12Dx,xAr12Dy,xAr22Dx,xAr22Dy,1);
         drawArrows(hps,zAxis22Dx,zAxis22Dy,zAr12Dx,zAr12Dy,zAr22Dx,zAr22Dy,1);
      }


      first=0;
     
      /* sleep a while if necessary */
	   if(low_priority == TRUE)
          DosSleep(10);
      else
          DosSleep(2);
      }
/*   
   free ( whitesegs );
   free ( redsegs );
*/
   WinDestroyMsgQueue(drawingthread_hmq);
   WinTerminate(drawingthread_hab);

   _endthread();
}
예제 #7
0
/*
	draw_thread
	This is the drawing-thread.
	You have a valid presentation space handle (hps), a valid window
	handle (hwndSaver) and the configuration_data structure is loaded.
	The screen size is stored in "screenSizeX" and "screenSizeY".
	IMPORTANT NOTE 1:
	You must check the "stop_draw_thread" flag regularly. If it is set,
	free all resources you have allocated and call _endthread (or just
	return) to end the drawing-thread.
	IMPORTANT NOTE 2:
	If the "low_priority" flag is NOT set (that means you run with
	regular priority, sharing CPU usage with other programs), you should
	call DosSleep(x) with "x" set at least to 1 as often as possible, to
	allow other programs to do their work. A screen saver should not eat
	up other program's CPU time!
	IMPORTANT NOTE 3:
	For some of the PM calls to work properly, your thread needs an
	own HAB and maybe even a message queue. You have to get and release
	both of them here if you use such PM calls.

	The following sample code is from the "Pyramids" module that comes
	with the ScreenSaver distribution.
	It selects a random color and a random point on the screen, then
	draws lines in the selected color from each corner of the screen
	to the selected point (looks somewhat like a pyramid).
	It remembers a number of points (this number can be set in the
	configuration dialog). Having filled the point memory, it redraws
	the "oldest" visible pyramid in black. This has the effect that more
	and more pixels on the screen get black, only a few constantly
	changing colored lines remain.
*/
void draw_thread(void *args)
    {
	int i, j;
	const RECTL ScreenRect = { 0, 0, screenSizeX, screenSizeY };
	int color_count = 0;
	ULONG color;
	int pushleftx = 11, pushlefty = 11, pushrightx = 11, pushrighty = 11;
	BOOL	point_buffer_filled;
	BOOL first_paint = TRUE;
	POINTL	*ptleft, *ptright;
	EXCEPTIONREGISTRATIONRECORD xcpthand = { 
	    (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler };

	DosSetExceptionHandler(&xcpthand) ;

	i = 0;
	point_buffer_filled = FALSE;
	/* allocate memory for circular point buffer	*/
	ptleft = malloc(configuration_data.count * sizeof(POINTL));
	ptright = malloc(configuration_data.count * sizeof(POINTL));
	if( (ptleft == NULL) || (ptright == NULL) ) goto end;
	GpiSetLineWidth( hps, LINEWIDTH_THICK );

	srand(WinGetCurrentTime(hab));
	
	do{
	    color = ((unsigned)rand()) % 17 - 2;
	}while ( color == -1 || color == 0 || color == 7 || color == 8 );
	/* blank screen if requested	*/
	if( configuration_data.blank_screen )
	    WinFillRect( hps, &ScreenRect, CLR_BLACK );

	while(!stop_draw_thread){

	    if(point_buffer_filled){
		/* redraw old line in black	*/
		GpiSetColor(hps, CLR_BLACK);
		GpiMove(hps, &ptleft[i]);
		GpiLine(hps, &ptright[i]);
	    }
	    if( color_count == configuration_data.colors ){
		/* select random color	*/
		do{
		    color = ((unsigned)rand()) % 17 - 2;
		}while ( color == -1 || color == 0 || color == 7 || color == 8 );
		color_count = 0;
	    }
	    GpiSetColor(hps, color);
	    color_count++;	
	    if (first_paint ){		
		/* set the start coordinates	*/
		ptleft[0].x = rand() % screenSizeX;
		ptleft[0].y = rand() % screenSizeY;
		ptright[0].x = rand() % screenSizeX;
		ptright[0].y = rand() % screenSizeY;
		first_paint = FALSE;
	    } else {
		/* calculate new line points	*/
		j = i==0 ? configuration_data.count - 1 : i - 1;
		ptleft[i].x = ptleft[j].x + pushleftx; 
		ptleft[i].y = ptleft[j].y + pushlefty; 
		ptright[i].x = ptright[j].x + pushrightx;
		ptright[i].y = ptright[j].y + pushrighty; 
	    }

	    /* adjust lines if they hit a screen border */
	    if( ptleft[i].x >= screenSizeX ) {
		ptleft[i].x = 2 * screenSizeX - ptleft[i].x;
		pushleftx = - pushleftx + (rand() % 2);
	    }	
	    if( ptleft[i].y >= screenSizeY ) {
		ptleft[i].y = 2 * screenSizeY - ptleft[i].y;
		pushlefty = - pushlefty + (rand() % 2);
	    }	
	    if( ptright[i].x >= screenSizeX ) {
		ptright[i].x = 2 * screenSizeX - ptright[i].x;
		pushrightx = - pushrightx + ( rand() % 2);
	    }	
	    if( ptright[i].y >= screenSizeY ) {
		ptright[i].y = 2 * screenSizeY - ptright[i].y;
		pushrighty = - pushrighty + ( rand() % 2);
	    }
	    if( ptleft[i].x < 0 ) {	
		ptleft[i].x *= -1;
		pushleftx = - pushleftx + (rand() % 2);
	    }	
	    if( ptleft[i].y < 0 ) {
		ptleft[i].y *= -1;
		pushlefty = - pushlefty + (rand() % 2);
	    }	
	    if( ptright[i].x < 0 ) {
		ptright[i].x *= -1;
		pushrightx = - pushrightx + (rand() % 2);
	    }	
	    if( ptright[i].y < 0 ) {
		ptright[i].y *= -1;
		pushrighty = - pushrighty + (rand() % 2);
	    }	
		
	    /* draw line	*/
	    GpiMove(hps, &ptleft[i]);
	    GpiLine(hps, &ptright[i]);

	    /* sleep if necessary	*/
	    if(low_priority == FALSE)
		DosSleep(1);

	    // sleep if user requests slower animation
				 switch(configuration_data.animation_speed){
				 case 4: break;
				 case 3: DosSleep(10); break;
				 case 2: DosSleep(30); break;
				 case 1: DosSleep(50); break;
				 case 0: DosSleep(70); break;
				 }
	    i++;
	    /* move circular buffer index	*/
	    if(i == configuration_data.count){
		point_buffer_filled = TRUE;
		i = 0;
	    }	
	}
	/* free resources	*/
      end:  // goto from memory allocation
	free( ptleft );
	free( ptright );
	DosUnsetExceptionHandler(&xcpthand);
	_endthread();
    }
// Message определяет пришедшее сообщение.
VOID Clipper_ClipperMessageProcessing( PQMSG Message )
{
 // Устанавливаем приоритет потока.
 if( Message->msg == SM_PRIORITY )
  {
   // Устанавливаем приоритет.
   LONG Class = (LONG) Message->mp1;
   LONG Delta = (LONG) Message->mp2;
   DosSetPriority( PRTYS_THREAD, Class, Delta, 0 );

   // Запоминаем приоритет.
   Enhancer.Modules.Clipper->Priority = MAKELONG( Class, Delta );
  }

 // Включаем выделение в текстовом окне.
 if( Message->msg == SM_BEGIN_VIO_MARKING || Message->msg == SM_END_VIO_MARKING )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Включаем и выключаем выделение.
   if( Message->msg == SM_BEGIN_VIO_MARKING ) Clipper_BeginVIOMarking( Frame_window );
   if( Message->msg == SM_END_VIO_MARKING ) Clipper_EndVIOMarkingAndCopyText( Frame_window );
  }

 // Запоминаем выделенный текст.
 if( Message->msg == SM_COPY_VIO_TEXT )
  {
   // Если в текстовых окнах не надо запоминать текст - возврат.
   if( !Clipper.Settings.Mouse_in_VIO ) return;

   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Если выделение текста еще не начато - начинаем его.
   if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_BeginVIOMarking( Frame_window );
   // Иначе - завершаем выделение и запоминаем текст.
   else Clipper_EndVIOMarkingAndCopyText( Frame_window );
  }

 // Вставляем текст в окно.
 if( Message->msg == SM_PASTE_VIO_TEXT )
  {
   // Если в текстовых окнах не надо запоминать текст - возврат.
   if( !Clipper.Settings.Mouse_in_VIO ) return;

   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Если в окне не идет выделение текста - вставляем текст.
   if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_PasteTextToVIOWindow( Frame_window );
  }

 // Запоминаем текст при нажатии средней кнопки мыши.
 if( Message->msg == SM_MB_CLICK )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Узнаем окно рабочего стола.
   HWND Desktop = QueryDesktopWindow();

   // Узнаем время, достаточное для двойного нажатия на кнопку мыши.
   LONG DblClk_delta = WinQuerySysValue( Desktop, SV_DBLCLKTIME );

   // Выполняем задержку, чтобы избежать двойного нажатия.
   while( 1 )
    {
     // Если время последнего нажатия на среднюю кнопку мыши неизвестно - произошло двойное нажатие, возврат.
     // В это время в очереди потока уже лежит следующее сообщение - SM_MB_DOUBLECLICK.
     if( WMMBDownTime() == 0 )
      {
       // Освобождаем указатель мыши.
       ResetPointer();

       // Возврат.
       return;
      }

     // Узнаем текущее время.
     LONG Current_time = WinGetCurrentTime( Enhancer.Application );

     // Если прошло достаточно много времени - все в порядке.
     if( Current_time > WMMBDownTime() )
      if( Current_time - WMMBDownTime() > DblClk_delta )
       break;

     // Если время прошло через ноль - возврат.
     if( Current_time < WMMBDownTime() )
      {
       // Освобождаем указатель мыши.
       ResetPointer();

       // Возврат.
       return;
      }

     // Через некоторое время - устанавливаем указатель мыши "прозрачная стрелка".
     if( Current_time - WMMBDownTime() > ( DblClk_delta / 2 ) )
      if( Resources.Pointer_for_CopyPaste != NULLHANDLE )
       WinSetPointer( QueryDesktopWindow(), Resources.Pointer_for_CopyPaste );

     // Выполняем задержку.
     Retard();
    }

   // Освобождаем указатель мыши.
   ResetPointer();

   // Время последнего нажатия на среднюю кнопку мыши - неизвестно.
   DiscardWMMBDownTime();

   // Узнаем ускоритель для этого окна.
   LONG Accelerator = (LONG) Message->mp2;

   // Запоминаем текст в окне.
   ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_COPY, Accelerator );
  }

 // Вставляем текст в окно при нажатии средней кнопки мыши.
 if( Message->msg == SM_MB_DOUBLECLICK )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Если кнопка мыши снова была нажата - возврат.
   if( WMMBDownTime() ) return;

   // Узнаем ускоритель для этого окна.
   LONG Accelerator = (LONG) Message->mp2;

   // Вставляем текст в окно.
   ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_PASTE, Accelerator );
  }

 // Вставляем текст в окно Mozilla при нажатии FireFox-клавиши.
 if( Message->msg >= SM_FFX_PASTE_FIRST && Message->msg <= SM_FFX_PASTE_LAST )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Вставляем текст в окно.
   Clipper_PasteFireFoxCharacters( Input_window, Message->msg );
  }

 // Восстанавливаем содержимое Clipboard.
 if( Message->msg == SM_RESTORE_CLIPBOARD ) Clipper_RestoreClipboard();

 // Возврат.
 return;
}
예제 #9
0
/*
	draw_thread
	This is the drawing-thread.
	You have a valid presentation space handle (hps), a valid window
	handle (hwndSaver) and the configuration_data structure is loaded.
	The screen size is stored in "screenSizeX" and "screenSizeY".
	IMPORTANT NOTE 1:
	You must check the "stop_draw_thread" flag regularly. If it is set,
	free all resources you have allocated and call _endthread (or just
	return) to end the drawing-thread.
	IMPORTANT NOTE 2:
	If the "low_priority" flag is NOT set (that means you run with
	regular priority, sharing CPU usage with other programs), you should
	call DosSleep(x) with "x" set at least to 1 as often as possible, to
	allow other programs to do their work. A screen saver should not eat
	up other program's CPU time!
	IMPORTANT NOTE 3:
	For some of the PM calls to work properly, your thread needs an
	own HAB and maybe even a message queue. You have to get and release
	both of them here if you use such PM calls.

	The following sample code is from the "Pyramids" module that comes
	with the ScreenSaver distribution.
	It selects a random color and a random point on the screen, then
	draws lines in the selected color from each corner of the screen
	to the selected point (looks somewhat like a pyramid).
	It remembers a number of points (this number can be set in the
	configuration dialog). Having filled the point memory, it redraws
	the "oldest" visible pyramid in black. This has the effect that more
	and more pixels on the screen get black, only a few constantly
	changing colored lines remain.
*/
void	draw_thread(void *args)
{
    INT	i, j;
    typedef struct {
	INT x;
	INT y;
	float dx;
	float dy;
	INT step;
    } STAR;
    STAR *star;
    RECTL rect;
    BOOL point_buffer_filled;
    BOOL free_star_field = TRUE;
    float norm;
    EXCEPTIONREGISTRATIONRECORD	xcpthand = { (PEXCEPTIONREGISTRATIONRECORD)0, 
					     GPFHandler };
    DosSetExceptionHandler(&xcpthand) ;

    /* random seed (needed for each thread) */
    srand(WinGetCurrentTime(hab));

    i = 0;
    point_buffer_filled = FALSE;
    /* allocate stack memory for circular point buffer */
    star = malloc(configuration_data.count * sizeof(STAR));
    if( star == NULL ) stop_draw_thread = TRUE;

    /* blank Screen */
    rect.xLeft = 0;
    rect.xRight = screenSizeX;
    rect.yBottom = 0;
    rect.yTop = screenSizeY;
    WinFillRect( hps, &rect, CLR_BLACK );

    while(!stop_draw_thread){
	if( free_star_field ){
	    /* create a new star */
	    star[i].x = rand() % screenSizeX/10 + screenSizeX * 9 / 20;
	    star[i].y = rand() % screenSizeY / 10 + screenSizeY * 9 / 20;
	    /* distance from screen center: */
	    star[i].dx = star[i].x - screenSizeX / 2;
	    star[i].dy = star[i].y - screenSizeY / 2;
	    /* it was created right in the middle: move it a little */
	    if( !star[i].dx && !star[i].dy) star[i].dx = 1;
	    /* half the distance to the center: */
	    norm = sqrt( star[i].dx * star[i].dx + 
			 star[i].dy * star[i].dy ) / 2;
	    if( norm < 1 ) norm = 1;
	    /* Offsets normieren */
	    star[i].dx /= norm;
	    star[i].dy /= norm;
	    /* step counter for increasing star size: */
	    star[i].step = 1;
	    rect.xLeft = star[i].x;
	    rect.xRight = star[i].x + star[i].step / 22 + 1;
	    rect.yBottom = star[i].y;
	    rect.yTop = star[i].y  + star[i].step / 22 + 1;
	    WinFillRect( hps, &rect, CLR_WHITE );
	}
	for( j = 0; 
	    j < (point_buffer_filled ? configuration_data.count : i + 1);
	    j++){	/* move all stars */
	    rect.xLeft = star[j].x;
	    rect.xRight = star[j].x  + star[j].step / 22 + 1;
	    rect.yBottom = star[j].y;
	    rect.yTop = star[j].y  + star[j].step / 22 + 1;
	    WinFillRect( hps, &rect, CLR_BLACK );
	    star[j].step++;
	    star[j].x += star[j].dx * star[j].step / 4;	/* neu */
	    star[j].y += star[j].dy * star[j].step / 4;
	    rect.xLeft = star[j].x;
	    rect.xRight = star[j].x  + star[j].step / 22 + 1;
	    rect.yBottom = star[j].y;
	    rect.yTop = star[j].y  + star[j].step / 22 + 1;
	    WinFillRect( hps, &rect, CLR_WHITE );
	}
	i++;
	if( i==configuration_data.count ){
	    /* index wrap */
	    i = 0;
	    point_buffer_filled = TRUE;
	    free_star_field = FALSE;
	}
	if( point_buffer_filled ){
	    for( j = 0; j < configuration_data.count; j++){	
		/* check all stars whether they are still on screen */
		if( star[j].x < - 10 || star[j].x > screenSizeX
		    || star[j].y < -10 || star[j].y > screenSizeY ) {
		    free_star_field = TRUE;
		    i = j;
		    break;
		} else {
		    free_star_field = FALSE;
		}
	    }
	}

	/* sleep if necessary */
	if(low_priority == FALSE)
	    DosSleep(1);

	/* sleep if user requests slower animation */
	switch(configuration_data.animation_speed){
	case 4: break;
	case 3: DosSleep(10); break;
	case 2: DosSleep(30); break;
	case 1: DosSleep(50); break;
	case 0: DosSleep(70); break;
	}
    }

    /* free resources */

    free( star );
    DosUnsetExceptionHandler(&xcpthand);
    _endthread();
}
예제 #10
0
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static INT aiPuzzle[NUMROWS][NUMCOLS],
                iBlankRow, iBlankCol, cxSquare, cySquare ;
     CHAR       szNum[10] ;
     HPS        hps ;
     HWND       hwndFrame ;
     INT        iRow, iCol, iMouseRow, iMouseCol, i ;
     POINTL     ptl ;
     RECTL      rcl, rclInvalid, rclIntersect ;
     SIZEL      sizl ;

     switch (msg)
          {
          case WM_CREATE:
                              // Calculate square size in pixels

               hps = WinGetPS (hwnd) ;
               sizl.cx = sizl.cy = 0 ;
               GpiSetPS (hps, &sizl, PU_LOENGLISH) ;
               ptl.x = SQUARESIZE ;
               ptl.y = SQUARESIZE ;
               GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptl) ;
               WinReleasePS (hps) ;

               cxSquare = ptl.x ;
               cySquare = ptl.y ;

                              // Calculate client window size and position

               rcl.xLeft   = (WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) -
                                           NUMCOLS * cxSquare) / 2 ;
               rcl.yBottom = (WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) -
                                           NUMROWS * cySquare) / 2 ;
               rcl.xRight  = rcl.xLeft   + NUMCOLS * cxSquare ;
               rcl.yTop    = rcl.yBottom + NUMROWS * cySquare ;

                              // Set frame window position and size

               hwndFrame = WinQueryWindow (hwnd, QW_PARENT) ;
               WinCalcFrameRect (hwndFrame, &rcl, FALSE) ;
               WinSetWindowPos  (hwndFrame, NULLHANDLE,
                                 rcl.xLeft, rcl.yBottom,
                                 rcl.xRight - rcl.xLeft,
                                 rcl.yTop - rcl.yBottom,
                                 SWP_MOVE | SWP_SIZE | SWP_ACTIVATE) ;

                              // Initialize the aiPuzzle array

               WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (IDM_NORMAL), NULL) ;
               return 0 ;

          case WM_PAINT:
               hps = WinBeginPaint (hwnd, NULLHANDLE, &rclInvalid) ;

                              // Draw the squares

               for (iRow = NUMROWS - 1 ; iRow >= 0 ; iRow--)
                    for (iCol = 0 ; iCol < NUMCOLS ; iCol++)
                         {
                         rcl.xLeft   = cxSquare * iCol ;
                         rcl.yBottom = cySquare * iRow ;
                         rcl.xRight  = rcl.xLeft   + cxSquare ;
                         rcl.yTop    = rcl.yBottom + cySquare ;

                         if (!WinIntersectRect (0, &rclIntersect,
                                                &rcl, &rclInvalid))
                              continue ;

                         if (iRow == iBlankRow && iCol == iBlankCol)
                              WinFillRect (hps, &rcl, CLR_BLACK) ;
                         else
                              {
                              WinDrawBorder (hps, &rcl, 5, 5,
                                             CLR_PALEGRAY, CLR_DARKGRAY,
                                             DB_STANDARD | DB_INTERIOR) ;

                              WinDrawBorder (hps, &rcl, 2, 2,
                                             CLR_BLACK, 0L, DB_STANDARD) ;

                              sprintf (szNum, "%d", aiPuzzle[iRow][iCol]) ;

                              WinDrawText (hps, -1, szNum,
                                           &rcl, CLR_WHITE, CLR_DARKGRAY,
                                           DT_CENTER | DT_VCENTER) ;
                              }
                         }
               WinEndPaint (hps) ;
               return 0 ;

          case WM_BUTTON1DOWN:
               iMouseCol = MOUSEMSG(&msg)->x / cxSquare ;
               iMouseRow = MOUSEMSG(&msg)->y / cySquare ;

                              // Check if mouse was in valid area

               if ( iMouseRow < 0          || iMouseCol < 0           ||
                    iMouseRow >= NUMROWS   || iMouseCol >= NUMCOLS    ||
                   (iMouseRow != iBlankRow && iMouseCol != iBlankCol) ||
                   (iMouseRow == iBlankRow && iMouseCol == iBlankCol))
                         break ;

                              // Move a row right or left

               if (iMouseRow == iBlankRow)
                    {
                    if (iMouseCol < iBlankCol)
                         for (iCol = iBlankCol ; iCol > iMouseCol ; iCol--)
                              aiPuzzle[iBlankRow][iCol] =
                                   aiPuzzle[iBlankRow][iCol - 1] ;
                    else
                         for (iCol = iBlankCol ; iCol < iMouseCol ; iCol++)
                              aiPuzzle[iBlankRow][iCol] =
                                   aiPuzzle[iBlankRow][iCol + 1] ;
                    }
                              // Move a column up or down
               else
                    {
                    if (iMouseRow < iBlankRow)
                         for (iRow = iBlankRow ; iRow > iMouseRow ; iRow--)
                              aiPuzzle[iRow][iBlankCol] =
                                   aiPuzzle[iRow - 1][iBlankCol] ;
                    else
                         for (iRow = iBlankRow ; iRow < iMouseRow ; iRow++)
                              aiPuzzle[iRow][iBlankCol] =
                                   aiPuzzle[iRow + 1][iBlankCol] ;
                    }
                              // Calculate invalid rectangle

               rcl.xLeft   = cxSquare *  min (iMouseCol, iBlankCol) ;
               rcl.yBottom = cySquare *  min (iMouseRow, iBlankRow) ;
               rcl.xRight  = cxSquare * (max (iMouseCol, iBlankCol) + 1) ;
               rcl.yTop    = cySquare * (max (iMouseRow, iBlankRow) + 1) ;

                              // Set new array and blank values

               iBlankRow = iMouseRow ;
               iBlankCol = iMouseCol ;
               aiPuzzle[iBlankRow][iBlankCol] = 0 ;

                              // Invalidate rectangle

               WinInvalidateRect (hwnd, &rcl, FALSE) ;
               break ;

          case WM_CHAR:
               if (!(CHARMSG(&msg)->fs & KC_VIRTUALKEY) ||
                     CHARMSG(&msg)->fs & KC_KEYUP)
                         return 0 ;

                              // Mimic a WM_BUTTON1DOWN message

               iMouseCol = iBlankCol ;
               iMouseRow = iBlankRow ;

               switch (CHARMSG(&msg)->vkey)
                    {
                    case VK_LEFT:   iMouseCol++ ;  break ;
                    case VK_RIGHT:  iMouseCol-- ;  break ;
                    case VK_UP:     iMouseRow-- ;  break ;
                    case VK_DOWN:   iMouseRow++ ;  break ;
                    default:        return 0 ;
                    }
               WinSendMsg (hwnd, WM_BUTTON1DOWN,
                           MPFROM2SHORT (iMouseCol * cxSquare,
                                         iMouseRow * cySquare), NULL) ;
               return 0 ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                              // Initialize aiPuzzle array

                    case IDM_NORMAL:
                    case IDM_INVERT:
                         for (iRow = 0 ; iRow < NUMROWS ; iRow++)
                              for (iCol = 0 ; iCol < NUMCOLS ; iCol++)
                                   aiPuzzle[iRow][iCol] = iCol + 1 +
                                        NUMCOLS * (NUMROWS - iRow - 1) ;

                         if (COMMANDMSG(&msg)->cmd == IDM_INVERT)
                              {
                              aiPuzzle[0][NUMCOLS-2] = NUMCOLS * NUMROWS - 2 ;
                              aiPuzzle[0][NUMCOLS-3] = NUMCOLS * NUMROWS - 1 ;
                              }
                         aiPuzzle[iBlankRow = 0][iBlankCol = NUMCOLS - 1] = 0 ;
                         WinInvalidateRect (hwnd, NULL, FALSE) ;
                         return 0 ;

                              // Randomly scramble the squares

                    case IDM_SCRAMBLE:
                         WinSetPointer (HWND_DESKTOP, WinQuerySysPointer (
                                        HWND_DESKTOP, SPTR_WAIT, FALSE)) ;

                         srand ((int) WinGetCurrentTime (0)) ;

                         for (i = 0 ; i < SCRAMBLEREP ; i++)
                              {
                              WinSendMsg (hwnd, WM_BUTTON1DOWN,
                                   MPFROM2SHORT (rand() % NUMCOLS * cxSquare,
                                        iBlankRow * cySquare), NULL) ;
                              WinUpdateWindow (hwnd) ;

                              WinSendMsg (hwnd, WM_BUTTON1DOWN,
                                   MPFROM2SHORT (iBlankCol * cxSquare,
                                        rand() % NUMROWS * cySquare), NULL) ;
                              WinUpdateWindow (hwnd) ;
                              }
                         WinSetPointer (HWND_DESKTOP, WinQuerySysPointer (
                                        HWND_DESKTOP, SPTR_ARROW, FALSE));
                         return 0 ;
                    }
               break ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static HAB   hab ;
     static HWND  hwndMenu ;
     static INT   iCurrentRep = IDM_10 ;
     static INT   iStatus = STATUS_READY ;
     static LONG  lCalcRep, lRepAmts [] = { 10, 100, 1000, 10000, 100000 } ;
     static ULONG ulElapsedTime ;
     double       A ;
     LONG         lRep ;

     switch (msg)
          {
          case WM_CREATE:
               hab = WinQueryAnchorBlock (hwnd) ;

               hwndMenu = WinWindowFromID (
                               WinQueryWindow (hwnd, QW_PARENT),
                               FID_MENU) ;
               return 0 ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                    case IDM_10:
                    case IDM_100:
                    case IDM_1000:
                    case IDM_10000:
                    case IDM_100000:
                         WinCheckMenuItem (hwndMenu, iCurrentRep, FALSE) ;
                         iCurrentRep = COMMANDMSG(&msg)->cmd ;
                         WinCheckMenuItem (hwndMenu, iCurrentRep, TRUE) ;
                         return 0 ;

                    case IDM_START:
                         WinEnableMenuItem (hwndMenu, IDM_START, FALSE) ;
                         WinEnableMenuItem (hwndMenu, IDM_ABORT, TRUE) ;

                         iStatus = STATUS_WORKING ;
                         WinInvalidateRect (hwnd, NULL, FALSE) ;
                         WinUpdateWindow (hwnd) ;

                         WinSetPointer (HWND_DESKTOP,
                                   WinQuerySysPointer (HWND_DESKTOP,
                                                       SPTR_WAIT, FALSE)) ;

                         if (WinQuerySysValue (HWND_DESKTOP, SV_MOUSEPRESENT)
                                   == 0)
                              WinShowPointer (HWND_DESKTOP, TRUE) ;

                         lCalcRep = lRepAmts [iCurrentRep - IDM_10] ;
                         ulElapsedTime = WinGetCurrentTime (hab) ;

                         for (A = 1.0, lRep = 0 ; lRep < lCalcRep ; lRep++)
                              A = Savage (A) ;

                         ulElapsedTime = WinGetCurrentTime (hab) -
                                        ulElapsedTime ;

                         if (WinQuerySysValue (HWND_DESKTOP, SV_MOUSEPRESENT)
                                   == 0)
                              WinShowPointer (HWND_DESKTOP, FALSE) ;

                         WinSetPointer (HWND_DESKTOP,
                                   WinQuerySysPointer (HWND_DESKTOP,
                                                       SPTR_ARROW, FALSE)) ;
                         iStatus = STATUS_DONE ;
                         WinInvalidateRect (hwnd, NULL, FALSE) ;
                         WinUpdateWindow (hwnd) ;

                         WinEnableMenuItem (hwndMenu, IDM_START, TRUE) ;
                         WinEnableMenuItem (hwndMenu, IDM_ABORT, FALSE) ;
                         return 0 ;

                    case IDM_ABORT:     // Not much we can do here
                         return 0 ;
                    }
               break ;

          case WM_PAINT:
               PaintWindow (hwnd, iStatus, lCalcRep, ulElapsedTime) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
예제 #12
0
/*
	draw_thread
	This is the drawing-thread.
	You have a valid presentation space handle (hps), a valid window
	handle (hwndSaver) and the configuration_data structure is loaded.
	The screen size is stored in "screenSizeX" and "screenSizeY".
	IMPORTANT NOTE 1:
	You must check the "stop_draw_thread" flag regularly. If it is set,
	free all resources you have allocated and call _endthread (or just
	return) to end the drawing-thread.
	IMPORTANT NOTE 2:
	If the "low_priority" flag is NOT set (that means you run with
	regular priority, sharing CPU usage with other programs), you should
	call DosSleep(x) with "x" set at least to 1 as often as possible, to
	allow other programs to do their work. A screen saver should not eat
	up other program's CPU time!
	IMPORTANT NOTE 3:
	For some of the PM calls to work properly, your thread needs an
	own HAB and maybe even a message queue. You have to get and release
	both of them here if you use such PM calls.

	The following sample code is from the "Pyramids" module that comes
	with the ScreenSaver distribution.
	It selects a random color and a random point on the screen, then
	draws lines in the selected color from each corner of the screen
	to the selected point (looks somewhat like a pyramid).
	It remembers a number of points (this number can be set in the
	configuration dialog). Having filled the point memory, it redraws
	the "oldest" visible pyramid in black. This has the effect that more
	and more pixels on the screen get black, only a few constantly
	changing colored lines remain.
*/
void	draw_thread(void *args)
{
	POINTL	BitmapPoints[4] = { 1, 1, screenSizeX + 2, screenSizeY + 2,
											-1, -1, screenSizeX, screenSizeY };
   POINTL l_b = { 0, 0 },
			 l_t = { 0, screenSizeY - 1 },
   		 r_b = { screenSizeX - 1, 0 },
			 r_t = { screenSizeX - 1, screenSizeY - 1 };
											
	INT i, step;
	VOID l_left()
	{
		GpiMove( hps, &l_b );
		GpiLine( hps, &l_t );
	}
	VOID l_right()
	{
		GpiMove( hps, &r_b );
		GpiLine( hps, &r_t );
	}
	VOID l_top()
	{
		GpiMove( hps, &l_t );
		GpiLine( hps, &r_t );
	}
	VOID l_bottom()
	{
		GpiMove( hps, &l_b );
		GpiLine( hps, &r_b );
	}
											

	srand(WinGetCurrentTime( hab ));
	GpiSetColor( hps, CLR_BLACK );
	l_left();
	while(!stop_draw_thread){
		if( configuration_data.drunken ){
			step = (unsigned)rand() % 8;
			switch ( step ){
				case 0:  BitmapPoints[0].x = -1;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX;
							BitmapPoints[1].y = screenSizeY + 1;
							l_bottom();
							break;
				case 1: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY + 1;
							l_bottom();
							l_left();
							break;						 
				case 2: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = -1;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY;
							l_left();
							break;							
				case 3: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY - 1;
							l_left();
							l_top();
							break;							
				case 4: 	BitmapPoints[0].x = -1;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX;
							BitmapPoints[1].y = screenSizeY - 1;
							l_top();
							break;							
				case 5: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY - 1;
							l_top();
							l_right();
							break;							
				case 6: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = -1;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY;
							l_right();
							break;							
				case 7: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY + 1;
							l_right();
							l_bottom();
							break;
			}
		}
		for( i = 1; i < 5; i++){	
			GpiBitBlt( hps, hps, 3, BitmapPoints, ROP_SRCCOPY, BBO_IGNORE );	
			if( stop_draw_thread) i = 10;
		}
		
		// sleep if necessary
		if(low_priority == FALSE)
			DosSleep(1);

		// sleep if user requests slower animation
		switch(configuration_data.animation_speed){
		case 4: break;
		case 3: DosSleep(10); break;
		case 2: DosSleep(30); break;
		case 1: DosSleep(50); break;
		case 0: DosSleep(70); break;
		}
	}

	// free resources

	_endthread();
}