home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dovetail.zip / winproc.cc < prev   
C/C++ Source or Header  |  1994-04-07  |  16KB  |  451 lines

  1. #define INCL_WIN
  2. #define INCL_GPI
  3. #define INCL_DEV
  4. #define INCL_SPL
  5. #define INCL_SPLDOSPRINT
  6. #define INCL_SPLERRORS
  7. #define INCL_BASE
  8. #include <os2.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include "dove.h"
  13. #include "process.h"
  14.  
  15. extern "C"
  16.  {
  17.    // This function must be exported so don't mangle the name
  18.  
  19.    MRESULT ClientWndProc (HWND, USHORT, MPARAM, MPARAM);
  20.  
  21.    MRESULT EXPENTRY ParmDlgProc (HWND, USHORT, MPARAM, MPARAM);
  22.    MRESULT EXPENTRY StockDlgProc (HWND, USHORT, MPARAM, MPARAM);
  23.    MRESULT EXPENTRY FileDlgProc (HWND, USHORT, MPARAM, MPARAM);
  24.  }
  25. BOOL calc_dt(void);
  26. void draw_dovetail(HPS hPS);
  27. extern int ok_to_post;
  28. float *pfPins = NULL;
  29. float *pfTails = NULL;
  30. static int print_count=0;
  31. int read_write;
  32.                                
  33. MRESULT EXPENTRY ClientWndProc (HWND    hwnd,
  34.                                    USHORT  msg,
  35.                                    MPARAM  mp1,
  36.                                    MPARAM  mp2)
  37.  
  38.   {// Variable Declarations
  39.  
  40.               RECTL    INVLDRECT;
  41.               HPS      hPresSp;
  42.        static HWND hWnd = 0;
  43.        POINTL coords;
  44.        MATRIXLF matrix;
  45.        float width, height,bot,scale;
  46.        ULONG whole, frac;
  47.    //  Main Program Logic  
  48.  
  49.    switch (msg)
  50.      {
  51.       case WM_CREATE:
  52.  
  53.            return 0;
  54.  
  55.       case WM_DESTROY:
  56.            if(hWnd) WinDestroyWindow(hWnd);
  57.            return 0;
  58.  
  59.       case WM_PAINT:
  60.            if(hWnd == 0)
  61. //           hWnd=WinLoadDlg(HWND_DESKTOP,hwnd,ParmDlgProc,0,ID_PARAMS,0);
  62.              hWnd=WinLoadDlg(hwnd,hwnd,ParmDlgProc,0,ID_PARAMS,0);
  63. /*
  64.   scale the graphics as follows:  1mm = 100 units in world space.
  65.   Therefore the length of the graphics will be 100*fLength x 100*fWidth.
  66.   Want this to fit within the window, with say %5 slop on each side.
  67. */
  68.            if(pfPins) {
  69.              hPresSp = WinBeginPaint (hwnd, 0, NULL);
  70.              WinQueryWindowRect (hwnd, &INVLDRECT);
  71.              WinFillRect (hPresSp, &INVLDRECT, CLR_WHITE);
  72.              width = INVLDRECT.xRight - INVLDRECT.xLeft;
  73.              height = INVLDRECT.yTop - INVLDRECT.yBottom;
  74.  
  75.              matrix.lM13 = matrix.lM23 = 0;
  76.              matrix.lM33 = 1;
  77.              matrix.fxM12 = matrix.fxM21 = MAKEFIXED(0,0);
  78.              matrix.lM31 = INVLDRECT.xLeft+(ULONG)(width/20.);
  79.              scale = .9*width/(100.*fLength);
  80.              whole = (ULONG)scale;
  81.              frac = (ULONG)(65536*(scale-whole));
  82.              matrix.fxM22 = matrix.fxM11 = MAKEFIXED(whole,frac);
  83. /*
  84.   set y translation so that top of part will be 5% from top of window
  85. */
  86.              bot = .95*height-100.*fThickness*scale;
  87.              matrix.lM32 = INVLDRECT.yBottom+(ULONG) bot;
  88.  
  89.              GpiSetModelTransformMatrix(hPresSp,9,&matrix,TRANSFORM_REPLACE);
  90.              draw_dovetail(hPresSp);
  91.              WinEndPaint (hPresSp);
  92.            }
  93.            return 0;
  94.       case WM_COMMAND:
  95.         switch(SHORT1FROMMP(mp1))
  96.           {
  97.          case IDM_STOCK:
  98.            WinDlgBox(HWND_DESKTOP,hwnd,StockDlgProc,0,ID_SDBOX,0);
  99.            return 0;
  100.          case IDM_FILE_OPEN:
  101.            read_write=0;
  102.            WinDlgBox(HWND_DESKTOP,hwnd,FileDlgProc,0,ID_FILEDB,0);
  103.            return 0;
  104.          case IDM_FILE_SAVE:
  105.            read_write=1;
  106.            WinDlgBox(HWND_DESKTOP,hwnd,FileDlgProc,0,ID_FILEDB,0);
  107.            return 0;
  108.          case IDM_FILE_DEL:
  109.            read_write=2;
  110.            WinDlgBox(HWND_DESKTOP,hwnd,FileDlgProc,0,ID_FILEDB,0);
  111.            return 0;
  112.          case IDM_PRINT:
  113. /*
  114.   want to print this sucker out.
  115. */
  116.            extern Process Proc;
  117.            DEVOPENSTRUC dop;
  118.            HDC hdcPrinter;
  119.            char msg[64];
  120. /*
  121.   first, get DC for default printer
  122. */
  123.            SPLERR splerr;
  124.            ULONG  cTotal;
  125.            ULONG  cReturned ;
  126.            ULONG  cbNeeded,cbBuf ;
  127.            int i,j;
  128.            PRQINFO3 *prq ;
  129.            PBYTE pBuf;
  130.  
  131.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)"Getting Queue",
  132.                      (PSZ) "Print", (USHORT)0,
  133.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  134.            splerr = SplEnumQueue((PSZ)NULL, 3, pBuf, 0,
  135.                               &cReturned, &cTotal,
  136.                               &cbNeeded, NULL);
  137.            if(splerr != ERROR_MORE_DATA && splerr != 2123) {  /* error */
  138.               WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  139.                      (PSZ)"Error getting printer info",
  140.                      (PSZ) "Print", (USHORT)0,
  141.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  142.              return 0;
  143.            }
  144.            pBuf = (PBYTE) malloc(cbNeeded);
  145.            cbBuf = cbNeeded;
  146.            splerr = SplEnumQueue((PSZ)NULL, 3, pBuf, cbBuf,
  147.                               &cReturned, &cTotal,
  148.                               &cbNeeded, NULL);
  149.            if(splerr != 0) {  /* error */
  150.               WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  151.                      (PSZ)"Error getting printer info",
  152.                      (PSZ) "Print", (USHORT)0,
  153.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  154.              return 0;
  155.            }
  156.            prq = (PPRQINFO3) pBuf;
  157.            for (i=j=0;i < cReturned ; i++)
  158.              if ( (prq+i)->fsType & 4 ) {  /* get default printer */
  159.                j=i;
  160.                break;
  161.              }
  162.            char Dname[32];
  163.            sprintf(Dname,"ret=%d, j=%d",cReturned,j);
  164.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)Dname,
  165.                      (PSZ) "Print", (USHORT)0,
  166.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  167.            HAB hab = Proc.AnchorBlock();
  168.         prq += j;
  169.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, prq->pszName,
  170.                      (PSZ) "Device name", (USHORT)0,
  171.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  172.            dop.pszLogAddress = prq->pszName;
  173.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, prq->pszDriverName,
  174.                      (PSZ) "Copying name", (USHORT)0,
  175.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  176.            for(i=0; i<31 && prq->pszDriverName[i] &&
  177.                             prq->pszDriverName[i] != '.'; i++)
  178.                 Dname[i]=prq->pszDriverName[i];
  179.            Dname[i]=0;
  180.            dop.pszDriverName = (PSZ) Dname;
  181. //           dop.pdriv = (PDRIVDATA) NULL;
  182.            dop.pdriv = prq->pDriverData;
  183.            dop.pszDataType = (PSZ) "PM_Q_STD";
  184.         free(pBuf);
  185.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)Dname,
  186.                      (PSZ) "Get PDC", (USHORT)0,
  187.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  188.            hdcPrinter = DevOpenDC(hab,OD_QUEUED,(PSZ) "*",4,
  189.                          (PDEVOPENDATA)&dop,(HDC)NULL);
  190.            if(hdcPrinter == 0) {
  191.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)"Null printer DC",
  192.                      (PSZ) "Print", (USHORT)0,
  193.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  194.            } else {
  195.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)"Got printer DC",
  196.                      (PSZ) "Print", (USHORT)0,
  197.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  198.              SIZEL sizl={0,0};
  199.              HPS hps=GpiCreatePS(hab,hdcPrinter,&sizl,
  200.                         PU_HIMETRIC | GPIT_MICRO | GPIA_ASSOC);
  201.              if(hps == 0) {
  202.              sprintf(msg,"Null HPS: rt = %x",WinGetLastError(hab));
  203.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)msg,
  204.                      (PSZ) "Print", (USHORT)0,
  205.                      MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  206.              } else {
  207.              char name[8];
  208.              sprintf(name,"DT%4.4d",print_count++);
  209.              DevEscape(hdcPrinter,DEVESC_STARTDOC,7,(PSZ) name,0,NULL);
  210.              matrix.lM13 = matrix.lM23 = 0;
  211.              matrix.lM33 = 1;
  212.              matrix.fxM12 = MAKEFIXED(1,0);
  213.              matrix.fxM21 = MAKEFIXED(1,0);
  214.              matrix.fxM22 = matrix.fxM11 = MAKEFIXED(0,0);
  215. /*
  216.   set x & y translation so that plot will be centered in paper
  217. */
  218.              LONG paperwh[6];
  219.              DevQueryCaps(hdcPrinter,4,6,paperwh);
  220.  
  221.              paperwh[0] *= 100000./(float) paperwh[4];  /* width in .01 mm*/
  222.              paperwh[1] *= 100000./(float) paperwh[5];  /* height in .01 mm */
  223.  
  224. //        sprintf(msg,"Scale factors %d %d",paperwh[0],paperwh[1]);
  225. //        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)msg,
  226. //                     (PSZ) "Print", (USHORT)0,
  227. //                     MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  228.              matrix.lM31 = (ULONG)(-50.*fThickness+paperwh[0]/2.);
  229.              matrix.lM32 = (ULONG)(-50.*fLength+paperwh[1]/2.);
  230.  
  231.              GpiSetModelTransformMatrix(hps,9,&matrix,TRANSFORM_REPLACE);
  232.              draw_dovetail(hps);
  233.              USHORT rt;
  234.              DevEscape(hdcPrinter,DEVESC_ENDDOC,0,NULL,2,(PSZ) &rt);
  235.              GpiDestroyPS(hps);
  236.              DevCloseDC(hdcPrinter);
  237.              }
  238.            }
  239.            return 0;
  240.           }
  241.          break;
  242.        case UM_UPDATE:  // pass through from file dialog proc to param dlg proc
  243.            WinPostMsg(hWnd,UM_UPDATE,0,0);
  244.            WinPostMsg(hwnd,UM_RECALC,0,0); // repaint new data
  245.          break;
  246.        case UM_RECALC:
  247.            if(calc_dt()) WinPostMsg(hWnd,UM_UPDATE,0,0);
  248.            WinInvalidateRect (hwnd,NULL,FALSE);
  249.            ok_to_post = 1;
  250.          break;
  251.      }
  252.    return WinDefWindowProc (hwnd, msg, mp1, mp2);
  253.   }
  254.  
  255. #define MINSIZE 3.
  256. BOOL calc_dt()
  257. {
  258. /*
  259.   first, compute the minimum pin and tail sizes.  All units are in
  260.   inches.
  261. */
  262. // FILE *fp;
  263. // fp=fopen("calclog","w");
  264. BOOL need_update = FALSE;
  265. float MinSize = fThickness/fSlope+MINSIZE;
  266. int NumTails = (int) (fLength/MinSize/2.);
  267. if(NumTails > iNumTails) NumTails = iNumTails;
  268. // fprintf(fp,"Numtails = %d, iNumTails = %d\n",NumTails,iNumTails);
  269. if(NumTails < iNumTails) need_update = TRUE;
  270. iNumTails = NumTails;
  271. float StockLeft = fLength - 2.*MinSize*NumTails;
  272. // fprintf(fp,"Length=%f, MinSize=%f, StockLeft=%f\n",fLength,MinSize,StockLeft);
  273. if(pfPins != NULL) delete pfPins;
  274. pfPins = new float[NumTails+1];
  275. if(pfTails != NULL) delete pfTails;
  276. pfTails = new float[NumTails];
  277. for(int i=0; i<NumTails; i++) {
  278.   pfPins[i] = pfTails[i] = MinSize;
  279. }
  280. pfPins[0] /= 2.;
  281. pfPins[NumTails] = pfPins[0];
  282. /*
  283.    The pfPins and pfTails arrays now hold the centerline width of each
  284.    pin and tail, respectively.  These are the minimum possible sizes
  285.    allowed.  We will now use the remaining stock to enforce the
  286.    Tail to Pin ratio -- as much as the stock allows.
  287. */
  288. float StockWant = NumTails*MinSize*(fTailPinRatio-1.);
  289.  
  290. if(StockWant > StockLeft) {
  291.    StockWant = StockLeft;
  292.    fTailPinRatio = StockWant/(NumTails*MinSize)+1.;
  293.    need_update = TRUE;
  294. }
  295. // fprintf(fp,"PTRatio want,left =%f %f %f\n",fTailPinRatio,StockWant, StockLeft-StockWant);
  296. for(i=0; i<NumTails; i++) {
  297.   pfTails[i] += StockWant/NumTails;
  298. }
  299. StockLeft -= StockWant;
  300. if(StockLeft <= 0.) {
  301.     fMidEdgeRatio = 1.;
  302.     fEndPinSize = .5;
  303.     need_update = TRUE;
  304. }
  305. /*
  306.    Now pad out the end pins to the proper ratio, if StockLeft allows
  307. */
  308. StockWant = (fEndPinSize-.5)*MinSize*2.;
  309. if(StockWant > StockLeft) {
  310.    StockWant = StockLeft;
  311.    fEndPinSize = StockWant/(2.*MinSize)+.5;
  312.    need_update = TRUE;
  313. }
  314. pfPins[0] += StockWant/2.;
  315. pfPins[NumTails] += StockWant/2.;
  316. StockLeft -= StockWant;
  317. // fprintf(fp,"EPSize want,left =%f %f %f\n",fEndPinSize,StockWant, StockLeft);
  318.  
  319. if(StockLeft <= 0.) {
  320.     fMidEdgeRatio = 1.;
  321.     need_update = TRUE;
  322. }
  323. /*
  324.   Now, if there is stock left, expand the center pins to enforce the
  325.   MidEdgeRatio.  First must figure out how much stock we want.
  326.   At this point we assume the end pins and last tails are fixed in size.
  327.  
  328.   All of this is of course meaningless if there are fewer than 3 tails.
  329. */
  330. if(NumTails < 3) goto expand;
  331. if(iMultOrAdd || 1) {  /* Add --> constant difference between adjacent tails */
  332.   int NumSteps = (NumTails-1)/2;
  333.   float PinStep = MinSize*(fMidEdgeRatio-1.)/NumSteps;
  334.   float Step = PinStep*fTailPinRatio;
  335.   int NumPinSteps, NumTailSteps;
  336.   if(NumTails %2 == 0) {
  337.       NumTailSteps = (NumTails*(NumTails-2))/4;
  338.       NumPinSteps = ((NumTails-2)*(NumTails-2))/4;
  339.   } else {
  340.       NumTailSteps = ((NumTails-1)*(NumTails-1))/4;
  341.       NumPinSteps = ((NumTails-1)*(NumTails-3))/4;
  342.   }
  343. // fprintf(fp,"NPS=%d, PS=%f  NTS=%d  TS=%f\n",NumPinSteps,PinStep,NumTailSteps,Step);
  344.   StockWant = NumPinSteps*PinStep+NumTailSteps*Step;
  345.   if(StockWant > StockLeft) {
  346.     StockWant = StockLeft;
  347.     PinStep = StockWant/(NumPinSteps+fTailPinRatio*NumTailSteps);
  348.     Step = PinStep*fTailPinRatio;
  349.     fMidEdgeRatio = (float) (PinStep*NumSteps)/MinSize+1.;
  350.     need_update = TRUE;
  351.   }
  352.   StockLeft -= StockWant;
  353. // fprintf(fp,"MERatio want,left =%f %f %f\n",fMidEdgeRatio,StockWant, StockLeft);
  354.   int j=NumTails-2;
  355.   for(i=1;i<j; i++,j--) {
  356.       pfTails[j] = pfTails[i] = pfTails[i-1]+Step;
  357.   }
  358.   if(NumTails%2) pfTails[NumTails/2] = pfTails[NumTails/2-1]+Step;
  359.   for(i=2, j=NumTails-2; i<j; i++,j--) {
  360.       pfPins[j] = pfPins[i] = pfPins[i-1]+PinStep;
  361.   }
  362.   if(NumTails%2 == 0) pfPins[NumTails/2] = pfPins[NumTails/2-1]+PinStep;
  363. } else if(fMidEdgeRatio != 1.) {  /* Mult --> constant ratio between adjacent tails */
  364.   int NumTailSteps = (NumTails-1)/2;
  365.   int NumPinSteps = (NumTails-1)/2;
  366.   double Ratio = pow((double)fMidEdgeRatio,1./(double)NumTailSteps);
  367.   float StockWant = 2.*(1.+fTailPinRatio)*(Ratio*(1.-fMidEdgeRatio)/
  368.                                       (1.-Ratio)-NumTailSteps);
  369.   if(NumTails %2) {  /* One Extra Tail */
  370.        StockWant += fTailPinRatio*(fMidEdgeRatio*Ratio-1.);
  371.   } else {  /* One Extra Pin */
  372.        StockWant += fMidEdgeRatio*Ratio-1.;
  373.   }
  374.   if(StockWant > StockLeft) {   /* Bummer!  Will have to use Newton */
  375.     StockWant = StockLeft;
  376.  
  377.  
  378. //    fMidEdgeRatio = Step*NumSteps/MinSize+1.;
  379. //    need_update = TRUE;
  380.   }
  381. }
  382.  
  383. /*
  384.   Now, if there is still any stock left (and there should be),
  385.   expand the size of all pins and tails.
  386. */
  387.  
  388. expand:
  389. float mult = fLength/(fLength-StockLeft);
  390. // fprintf(fp,"At expand, StockLeft, mult= %f %f\n",StockLeft,mult);
  391. for(i=0; i<NumTails; i++) {
  392.    pfPins[i] *= mult;
  393.    pfTails[i] *= mult;
  394. }
  395. pfPins[NumTails] = pfPins[0];
  396. // fprintf(fp,"FinalData:\n");
  397. // for(i=0; i<=NumTails; i++)
  398. //   fprintf(fp,"Pin %d: %f\n",i,pfPins[i]);
  399. // for(i=0; i<NumTails; i++)
  400. //   fprintf(fp,"Tail %d: %f\n",i,pfTails[i]);
  401. // fclose(fp);
  402. /*
  403.   must still do multiplication case (messy ??) and put in checks for
  404.   knife edge pins.  If knife edge pins, just set the pin increments
  405.   to 0 for the ME ratio part and be careful doing expansion.  Really,
  406.   can even skip TailPin ratio in this case since it is meaningless.
  407. */
  408.    return (need_update);
  409. }
  410. /*
  411.   this routine does the actual drawing.  Units are in mm, and we will
  412.   draw with 100 world units per mm, with the lower left corner of the
  413.   image at (0,0)
  414. */
  415. void draw_dovetail(HPS hPS)
  416. {
  417.   POINTL coords;
  418.   int i;
  419.   float curx;
  420.  
  421.   ULONG dy = (ULONG)(50.*fThickness);
  422.   ULONG dx = (ULONG)(50.*fThickness/fSlope);
  423.   coords.x = 0;
  424.   coords.y = 0;
  425.   GpiSetCurrentPosition(hPS,&coords);
  426.   coords.x = (ULONG)(100*fLength);
  427.   GpiLine(hPS,&coords);
  428.   coords.y = (ULONG)(100*fThickness);
  429.   GpiLine(hPS,&coords);
  430.   coords.x = 0;
  431.   GpiLine(hPS,&coords);
  432.   coords.y = 0;
  433.   GpiLine(hPS,&coords);
  434.   curx=0;
  435.   for(i=0; i<iNumTails; i++) {
  436.     curx += pfPins[i];
  437.     coords.x = (ULONG)(100.*curx)-dx;
  438.     coords.y = 2*dy;
  439.     GpiSetCurrentPosition(hPS,&coords);
  440.     coords.x += 2*dx;
  441.     coords.y = 0;
  442.     GpiLine(hPS,&coords);
  443.     curx += pfTails[i];
  444.     coords.x = (ULONG)(100.*curx)-dx;
  445.     GpiSetCurrentPosition(hPS,&coords);
  446.     coords.x += 2*dx;
  447.     coords.y = 2*dy;
  448.     GpiLine(hPS,&coords);
  449.   }
  450. }
  451.