home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / MSWSRC35 / MAINWIND.CPP < prev    next >
C/C++ Source or Header  |  1993-10-12  |  54KB  |  2,218 lines

  1. #include "allwind.h"
  2.  
  3. int critical = 0;
  4.  
  5. void qlist::insert(ent a, int t)
  6.    {
  7.    
  8.    /* class "event list queue" member to insert event */
  9.    
  10.    qlink *h;
  11.    qlink *ph;
  12.    
  13.    if (last)
  14.       {
  15.       ph = last->next;
  16.       h = new qlink(a, NULL, NULL, t);
  17.       last->next = h;
  18.       h->prev = last;
  19.       h->next = ph;
  20.       ph->prev = h;
  21.       last = last->next;
  22.       }
  23.    else
  24.       {
  25.       last = new qlink(a, NULL, NULL, t);
  26.       last->next = last;
  27.       last->prev = last;
  28.       }
  29.    }
  30.  
  31. ent qlist::get(void)
  32.    {
  33.    
  34.    /* class "event list queue" member to get event */
  35.    
  36.    if (last==NULL) return NULL;
  37.    
  38.    return(last->next->e);
  39.    }
  40.  
  41. void qlist::zap(void)
  42.    {
  43.    
  44.    /* class "event list queue" member to zap all events */
  45.    
  46.    qlink* p;
  47.    
  48.    if (last==NULL) return;
  49.    
  50.    p = last->next;
  51.    
  52.    if (last == p)
  53.       {
  54.       last = NULL;
  55.       }
  56.    else
  57.       {
  58.       p->prev->next = p->next;
  59.       p->next->prev = p->prev;
  60.       }
  61.    
  62.    delete p;
  63.    
  64.    }
  65.  
  66. void qlist::clear()
  67.    {
  68.    qlink* l = last;
  69.    
  70.    if (l == NULL) return;
  71.    
  72.    do
  73.       {
  74.       qlink* ll = l;
  75.       l = l->next;
  76.       delete ll;
  77.       }
  78.    while (l!=last);
  79.    }
  80.  
  81. calllist calllists;
  82.  
  83. TMyWindow::TMyWindow(PTWindowsObject AParent, LPSTR ATitle)
  84. : TWindow(AParent, ATitle)
  85.    {
  86.    /* main window initialization */
  87.    
  88.    AssignMenu("COMMANDS");
  89.    PenSize = 1;
  90.    
  91.    /* build the bitmap */
  92.    
  93.    bitCount = 8;
  94.    
  95.    size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
  96.    BitmapInfo = (BITMAPINFO *)new char[size];
  97.    
  98.    BitmapInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
  99.    BitmapInfo->bmiHeader.biWidth         = BitMapWidth;
  100.    BitmapInfo->bmiHeader.biHeight        = BitMapHeight;
  101.    BitmapInfo->bmiHeader.biPlanes        = 1;
  102.    BitmapInfo->bmiHeader.biBitCount      = bitCount;
  103.    BitmapInfo->bmiHeader.biCompression   = BI_RGB;
  104.    BitmapInfo->bmiHeader.biSizeImage     = ((((BitmapInfo->bmiHeader.biWidth*BitmapInfo->bmiHeader.biBitCount)+31)/32)*4)*BitmapInfo->bmiHeader.biHeight;
  105.    BitmapInfo->bmiHeader.biXPelsPerMeter = 0;
  106.    BitmapInfo->bmiHeader.biYPelsPerMeter = 0;
  107.    BitmapInfo->bmiHeader.biClrUsed       = 0;
  108.    BitmapInfo->bmiHeader.biClrImportant  = 0;
  109.    
  110.    /* check if a palette exists */
  111.    
  112.    ScreenDC = CreateDC("Display", NULL, NULL, NULL);
  113.    
  114.    if ((GetDeviceCaps(ScreenDC, RASTERCAPS) & RC_PALETTE) == 0)
  115.       {
  116.       EnablePalette = 0;
  117.       }
  118.    else
  119.       {
  120.       EnablePalette = 1;
  121.       }
  122.    
  123.    /* pack memory and eat up a whole bunch of memory */
  124.    
  125.    MemoryBitMap = CreateDIBitmap(ScreenDC, &(BitmapInfo->bmiHeader), 0L, NULL, NULL, DIB_RGB_COLORS);
  126.    
  127.    /* If fail try again after a compact */
  128.    
  129.    if (!MemoryBitMap)
  130.       {
  131.       GlobalCompact(-1);
  132.       MemoryBitMap = CreateDIBitmap(ScreenDC, &(BitmapInfo->bmiHeader), 0L, NULL, NULL, DIB_RGB_COLORS);
  133.       }   
  134.    
  135.    /* this is not fatal, you just loose backing store */
  136.    
  137.    if (!MemoryBitMap) MessageBox(0, "Not enough Memory to repaint", "Warning", MB_OK | MB_ICONEXCLAMATION);
  138.    
  139.    /* clear window */
  140.    
  141.    MemDC = CreateCompatibleDC(ScreenDC);
  142.    OldBitmap = (HBITMAP)SelectObject(MemDC, MemoryBitMap);
  143.    
  144.    PatBlt(MemDC, 0, 0, BitMapWidth, BitMapHeight, WHITENESS);
  145.    
  146.    SelectObject(MemDC, OldBitmap);
  147.    DeleteDC(MemDC);
  148.    DeleteDC(ScreenDC);
  149.    
  150.    /* create printer object */
  151.    
  152.    Printer = new TPrinter;
  153.    
  154.    /* flag that screen clean */
  155.    
  156.    IsNewFile = TRUE;
  157.    IsNewBitmap = TRUE;
  158.    
  159.    /* setup scrollers (LOTS of code for these things) */
  160.    
  161.    Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  162.    Scroller = new TScroller(this, 1, 1, BitMapWidth, BitMapHeight);
  163.    
  164.    /* If palette then build one */
  165.    
  166.    if (EnablePalette)
  167.       {
  168.       MyLogPalette = (LPLOGPALETTE) new char[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*MaxColors];
  169.       MyLogPalette->palVersion = 0x300;
  170.       MyLogPalette->palNumEntries = 2;
  171.       
  172.       MyLogPalette->palPalEntry[0].peRed = 0;
  173.       MyLogPalette->palPalEntry[0].peGreen = 0;
  174.       MyLogPalette->palPalEntry[0].peBlue = 0;
  175.       MyLogPalette->palPalEntry[0].peFlags = 0;
  176.       
  177.       MyLogPalette->palPalEntry[1].peRed = 255;
  178.       MyLogPalette->palPalEntry[1].peGreen = 255;
  179.       MyLogPalette->palPalEntry[1].peBlue = 255;
  180.       MyLogPalette->palPalEntry[1].peFlags = 0;
  181.       
  182.       ThePalette = CreatePalette(MyLogPalette);
  183.       }
  184.    
  185.    }
  186.  
  187. TMyWindow::~TMyWindow()
  188.    {
  189.    int i;
  190.    
  191.    /* clean things up */
  192.    
  193.    delete Printer;
  194.    delete Scroller;
  195.    DeleteObject(MemoryBitMap);
  196.    delete EditboxWindow;
  197.    delete ListboxWindow;
  198.    delete CommandWindow;
  199.    
  200.    /* if palette clean it too */
  201.    
  202.    if (EnablePalette)
  203.       {
  204.       DeleteObject(ThePalette);
  205.       delete MyLogPalette;
  206.       }
  207.    
  208.    free(gcstack);
  209.    free(hash_table);
  210.    
  211.    /* Note Bitmap index 0 belongs to CLipboard */
  212.    
  213.    for (i=1;i<MaxBitCuts;i++)
  214.    if (CutBmp[i].CutFlag) DeleteObject(CutBmp[i].CutMemoryBitMap);
  215.    
  216.    // Borland will take care of freeing most mallocs (I hope)
  217.    
  218.    //    GlobalUnlock(HashHandle);
  219.    //    GlobalFree(HashHandle);
  220.    
  221.    //    GlobalUnlock(StackHandle);
  222.    //    GlobalFree(StackHandle);
  223.    
  224.    }
  225.  
  226. void TMyWindow::WMGetDlgCode( RTMessage msg )
  227.    {
  228.    TWindow::DefWndProc( msg );
  229.    msg.Result |= DLGC_WANTARROWS;
  230.    }
  231.  
  232. void TMyWindow::WMKeyDown(RTMessage Msg)
  233.    { 
  234.    callthing *callevent;
  235.    
  236.    // if keyboard was on and up and down is enabled then continue
  237.    
  238.    if (keyboard_on == 2)
  239.       {
  240.       
  241.       // if key is down skip it
  242.       
  243.       if (!(Msg.LParam & 0x40000000))
  244.          {
  245.          callevent = new callthing;
  246.          
  247.          callevent->func = keyboard_keydown;
  248.          callevent->arg1 = Msg.WParam;
  249.          callevent->kind = 2;
  250.          
  251.          calllists.insert(callevent,2);
  252.          checkqueue();
  253.          //        PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  254.          }
  255.       }
  256.    
  257.    // scroll main window with arrow keys
  258.    
  259.    switch (Msg.WParam)
  260.       {
  261.       case VK_UP:
  262.          {
  263.          Scroller->ScrollBy(0,-Scroller->YLine);
  264.          break;
  265.          }
  266.       case VK_DOWN:
  267.          {
  268.          Scroller->ScrollBy(0,Scroller->YLine);
  269.          break;
  270.          }
  271.       case VK_LEFT:
  272.          {
  273.          Scroller->ScrollBy(-Scroller->XLine,0);
  274.          break;
  275.          }
  276.       case VK_RIGHT:
  277.          {
  278.          Scroller->ScrollBy(Scroller->XLine,0);
  279.          break;
  280.          }
  281.       
  282.       // else do your normal stuff
  283.       
  284.       default:
  285.          {
  286.          DefWndProc( Msg );
  287.          break;
  288.          }
  289.       }
  290.    }
  291.  
  292. void TMyWindow::WMKeyUp(RTMessage Msg)
  293.    { 
  294.    callthing *callevent;
  295.    
  296.    // if keyboard was on and up and down is enabled then continue
  297.    
  298.    if (keyboard_on == 2)
  299.       {
  300.       callevent = new callthing;
  301.       
  302.       callevent->func = keyboard_keyup;
  303.       callevent->arg1 = Msg.WParam;
  304.       callevent->kind = 2;
  305.       
  306.       calllists.insert(callevent,2);
  307.       checkqueue();
  308.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  309.       }
  310.    
  311.    // else do your normal stuff
  312.    
  313.    else
  314.       {
  315.       DefWndProc( Msg );
  316.       }
  317.    }
  318.  
  319. void TMyWindow::WMChar(RTMessage Msg)
  320.    { 
  321.    callthing *callevent;
  322.    
  323.    // if keyboard was on and NOT up and down is enabled then continue
  324.    
  325.    if (keyboard_on == 1)
  326.       {
  327.       callevent = new callthing;
  328.       
  329.       callevent->func = keyboard_keyup;
  330.       callevent->arg1 = Msg.WParam;
  331.       callevent->kind = 2;
  332.       
  333.       calllists.insert(callevent,2);
  334.       checkqueue();
  335.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  336.       }
  337.    
  338.    // else do your normal stuff
  339.    
  340.    else
  341.       {
  342.       DefWndProc( Msg );
  343.       }
  344.    }
  345.  
  346. void TMyWindow::GetWindowClass(WNDCLASS& WndClass)
  347.    {
  348.    TWindow::GetWindowClass( WndClass );
  349.    WndClass.lpszMenuName = "Logo";
  350.    WndClass.hIcon = LoadIcon( GetApplication()->hInstance, "LogoIcon");
  351.    }
  352.  
  353. void TMyWindow::Paint( HDC PaintDC, PAINTSTRUCT& )
  354.    {
  355.    
  356.    /*
  357.    This is a compromise between speed and memory (as is most code).
  358.    All drawing is written to the backing store 1 to 1 even when zoomed.
  359.    When zoomed all drawing and painting is scaled to the display on the fly.
  360.    Painting can be a bit slow while zoomed. It also can be inaccurate when
  361.    mixing scaled painting and scaled drawing. Printing is never zoomed.
  362.    User can use Bitfit if he/she wants data scaled.
  363.    
  364.    Must of rewrote this routine 20 times, at least.
  365.    */
  366.    
  367.    HDC MemDC;
  368.    
  369.    RECT RRR;
  370.    
  371.    int i;
  372.    int Pnx;
  373.    int Pny;
  374.    int Snx;
  375.    int Sny;
  376.    int Pox;
  377.    int Poy;
  378.    int Sox;
  379.    int Soy;
  380.    
  381.    /* grab the backing store (a bitmap) */
  382.    
  383.    ScreenDC = GetDC(0);
  384.    MemDC = CreateCompatibleDC(ScreenDC);
  385.    
  386.    OldBitmap = (HBITMAP)SelectObject(MemDC, MemoryBitMap);
  387.    
  388.    /* if palette allocate it */
  389.    
  390.    if (EnablePalette)
  391.       {
  392.       OldPalette = SelectPalette(PaintDC, ThePalette, FALSE);
  393.       RealizePalette(PaintDC);
  394.       
  395.       OldPalette2 = SelectPalette(MemDC, ThePalette, FALSE);
  396.       RealizePalette(MemDC);
  397.       }
  398.    
  399.    /* if 1 to 1 the just do normal paint */
  400.    
  401.    if (the_zoom == 1.0)
  402.       {
  403.       BitBlt(PaintDC,
  404.       0,
  405.       0,
  406.       BitMapWidth,
  407.       BitMapHeight,
  408.       MemDC,
  409.       0,
  410.       0,
  411.       SRCCOPY);
  412.       }
  413.    
  414.    /* else compute scaling and then display */
  415.    
  416.    else
  417.       {
  418.       GetClientRect(HWindow,&RRR);
  419.       
  420.       Sox = (RRR.right-RRR.left)/the_zoom;
  421.       Soy = (RRR.bottom-RRR.top)/the_zoom;
  422.       
  423.       Pox = ((TMyWindow *)MainWindowx)->Scroller->XPos/the_zoom;
  424.       Poy = ((TMyWindow *)MainWindowx)->Scroller->YPos/the_zoom;
  425.       
  426.       Snx = (RRR.right-RRR.left);
  427.       Sny = (RRR.bottom-RRR.top);
  428.       
  429.       Pnx = ((TMyWindow *)MainWindowx)->Scroller->XPos; 
  430.       Pny = ((TMyWindow *)MainWindowx)->Scroller->YPos;
  431.       
  432.       if (Pox+Sox > BitMapWidth)
  433.          {
  434.          Sox = BitMapWidth-Pox;
  435.          Snx = Sox*the_zoom;
  436.          }
  437.       
  438.       if (Poy+Soy > BitMapHeight)
  439.          {
  440.          Soy = BitMapHeight-Poy;
  441.          Sny = Soy*the_zoom;
  442.          }
  443.       
  444.       SetStretchBltMode(PaintDC,COLORONCOLOR);
  445.       
  446.       // Load hour-glass cursor.
  447.       
  448.       hCursor = SetCursor(hCursorWait);
  449.       
  450.       /* streeeeeeeeeeeeeeeeeeeech it */
  451.       
  452.       StretchBlt(PaintDC,
  453.       Pnx,
  454.       Pny,
  455.       Snx,
  456.       Sny,
  457.       MemDC,
  458.       Pox,
  459.       Poy,
  460.       Sox,
  461.       Soy,
  462.       SRCCOPY);
  463.       
  464.       // Reload arrow cursor.
  465.       SetCursor(hCursor);
  466.       
  467.       }
  468.    
  469.    /* restore resources */
  470.    
  471.    if (EnablePalette)
  472.       {
  473.       SelectPalette(MemDC, OldPalette2, FALSE);
  474.       SelectPalette(PaintDC, OldPalette, FALSE);
  475.       }
  476.    
  477.    SelectObject(MemDC, OldBitmap);
  478.    DeleteDC(MemDC);
  479.    ReleaseDC(0, ScreenDC);
  480.    
  481.    /* if turtle do it */
  482.    
  483.    if (turtle_shown)
  484.       {
  485.       SetROP2(PaintDC, R2_NOT);
  486.       
  487.       for (i=0;i<3;i++)
  488.          {
  489.          MoveTo(PaintDC, TurtlePoints[i].from.x*the_zoom, TurtlePoints[i].from.y*the_zoom);
  490.          LineTo(PaintDC, TurtlePoints[i].to.x*the_zoom, TurtlePoints[i].to.y*the_zoom);
  491.          }
  492.       }
  493.    }
  494.  
  495. void TMyWindow::Printit( HDC hdc )
  496.    {
  497.    
  498.    /*
  499.    Must of rewrote this at least 25 times :-) and it still does not
  500.    work in some situations. This is just the "Paint" of printing.
  501.    See the print module for all the other stuff.
  502.    */  
  503.    
  504.    HDC ScreenDC;
  505.    int TempWidth;
  506.    int TempHeight;
  507.    LPSTR BitsPtr;
  508.    HBITMAP BitsHandle;
  509.    
  510.    /* do we even have a chance ? */
  511.    
  512.    if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_BITBLT) == 0)
  513.       {
  514.       MessageBox(HWindow, "Driver NOT supported", "Error", MB_OK | MB_ICONEXCLAMATION);
  515.       }
  516.    
  517.    /* we don't need hour glass here because print module takes care of it */
  518.    
  519.    BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  520.    
  521.    /* If fail try again after a compact */
  522.    
  523.    if (!BitsHandle)
  524.       {
  525.       GlobalCompact(-1);
  526.       BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  527.       }
  528.    
  529.    /* if we got the memory continue */
  530.    
  531.    if (BitsHandle)
  532.       {
  533.       
  534.       /* get printer size */
  535.       
  536.       TempWidth = GetDeviceCaps(hdc,LOGPIXELSX);
  537.       TempHeight = GetDeviceCaps(hdc,LOGPIXELSY);
  538.       
  539.       ScreenDC = GetDC(0);
  540.       
  541.       /* set up an assured contrast ? */
  542.       
  543.       SetTextColor(hdc, 0x00000000L);
  544.       SetBkColor(hdc, 0x00ffffffL);
  545.       
  546.       /* where is that memory anyway */
  547.       
  548.       BitsPtr = (LPSTR)GlobalLock((HGLOBAL)BitsHandle);
  549.       
  550.       /* if "active area" just print that */
  551.       
  552.       if (CustomFlag)
  553.          {
  554.          GetDIBits(ScreenDC, MemoryBitMap, 0, BitMapHeight, BitsPtr, BitmapInfo, DIB_RGB_COLORS);
  555.          
  556.          StretchDIBits(hdc,
  557.          0,
  558.          0,
  559.          TempWidth*(int)((PrinterAreaXHigh-PrinterAreaXLow)/100),
  560.          TempHeight*(int)((PrinterAreaYHigh-PrinterAreaYLow)/100),
  561.          +PrinterAreaXLow+xoffset,
  562.          BitMapHeight-(-PrinterAreaYLow+yoffset),
  563.          PrinterAreaXHigh-PrinterAreaXLow,
  564.          PrinterAreaYHigh-PrinterAreaYLow,
  565.          BitsPtr, BitmapInfo, DIB_RGB_COLORS, SRCCOPY);        
  566.          }
  567.       
  568.       /* else print the whole thing */
  569.       
  570.       else
  571.          {
  572.          GetDIBits(ScreenDC, MemoryBitMap, 0, BitMapHeight, BitsPtr, BitmapInfo, DIB_RGB_COLORS);
  573.          
  574.          StretchDIBits(hdc,
  575.          0,
  576.          0,
  577.          TempWidth*(int)(BitMapWidth/100),
  578.          TempHeight*(int)(BitMapHeight/100),
  579.          0,
  580.          0,
  581.          BitMapWidth,
  582.          BitMapHeight, BitsPtr, BitmapInfo, DIB_RGB_COLORS, SRCCOPY);
  583.          }      
  584.       
  585.       GlobalUnlock(BitsHandle);
  586.       
  587.       GlobalFree(BitsHandle);
  588.       
  589.       ReleaseDC(0, ScreenDC);
  590.       
  591.       }
  592.    
  593.    /* can't do it */
  594.    
  595.    else
  596.       {
  597.       MessageBox(HWindow, "No Memory to Print", "Error", MB_OK | MB_ICONEXCLAMATION);
  598.       }  
  599.    }
  600.  
  601. BOOL TMyWindow::CanClose()
  602.    {
  603.    
  604.    // if not halted warn user and give chance to abort shutdown
  605.    
  606.    if (halt_flag != 0)
  607.    return MessageBox(HWindow, "Return to LOGO?","Logo is not Halted", MB_YESNO | MB_ICONQUESTION) == IDNO;
  608.    
  609.    // if dirty warn user and give chance to abort shutdown
  610.    
  611.    if ( !IsDirty )
  612.    return TRUE;
  613.    return MessageBox(HWindow, "Return to LOGO?","You have not done a SAVE", MB_YESNO | MB_ICONQUESTION) == IDNO;
  614.    
  615.    }
  616.  
  617. void TMyWindow::CMExit(RTMessage Msg)
  618.    { 
  619.    
  620.    /* here on FILE-EXIT main window (screen) */
  621.    
  622.    if (halt_flag != 0) Time_To_Halt = 1;
  623.    Time_To_Exit = 1;
  624.    }
  625.  
  626. BOOL TMyWindow::WriteDIB(int TheFile)
  627.    {
  628.    WORD bitCount;
  629.    WORD size;
  630.    
  631.    HDC TempMemDC;
  632.    HDC MemDC;
  633.    
  634.    LPSTR BitsPtr;
  635.    HBITMAP BitsHandle;
  636.    BITMAPFILEHEADER BitmapFileHeader;
  637.    
  638.    /* hard code to 8-bit bitmap */
  639.    
  640.    bitCount = 8;
  641.    
  642.    /* compute size of bitmap */
  643.    
  644.    size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
  645.    
  646.    /* grab a DC */
  647.    
  648.    ScreenDC = CreateDC("Display", NULL, NULL, NULL);
  649.    
  650.    // allocate space for the raw DIB data
  651.    
  652.    BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  653.    
  654.    /* If fail try again after a compact */
  655.    
  656.    if (!BitsHandle)
  657.       {
  658.       GlobalCompact(-1);
  659.       BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  660.       }
  661.    
  662.    /* bummer */
  663.    if (!BitsHandle)
  664.       {
  665.       DeleteDC(ScreenDC);
  666.       
  667.       return(FALSE);
  668.       }
  669.    
  670.    /* go find it */
  671.    
  672.    BitsPtr = (LPSTR)GlobalLock((HGLOBAL)BitsHandle);
  673.    
  674.    /* if palette yank it in */
  675.    
  676.    if (EnablePalette)
  677.       {
  678.       OldPalette2 = SelectPalette(ScreenDC, ThePalette, FALSE);
  679.       RealizePalette(ScreenDC);
  680.       }
  681.    
  682.    /* if custom then use custom dimensions */
  683.    
  684.    if (CustomFlag)
  685.       {
  686.       AreaMemoryBitMap = CreateCompatibleBitmap(ScreenDC, 
  687.       PrinterAreaXHigh-PrinterAreaXLow,
  688.       PrinterAreaYHigh-PrinterAreaYLow);
  689.       if (!AreaMemoryBitMap) MessageBox(MainHWindow, "Write failed, Possibly no Memory", "Error", MB_OK | MB_ICONEXCLAMATION);
  690.       
  691.       MemDC = CreateCompatibleDC(ScreenDC);
  692.       OldBitmap = (HBITMAP)SelectObject(MemDC, MemoryBitMap);
  693.       
  694.       TempMemDC = CreateCompatibleDC(ScreenDC);
  695.       OldBitmap2 = (HBITMAP)SelectObject(TempMemDC, AreaMemoryBitMap);
  696.       
  697.       BitmapInfo->bmiHeader.biWidth         = PrinterAreaXHigh-PrinterAreaXLow;
  698.       BitmapInfo->bmiHeader.biHeight        = PrinterAreaYHigh-PrinterAreaYLow;
  699.       BitmapInfo->bmiHeader.biSizeImage     = ((((BitmapInfo->bmiHeader.biWidth*BitmapInfo->bmiHeader.biBitCount)+31)/32)*4)*BitmapInfo->bmiHeader.biHeight;
  700.       
  701.       BitBlt(TempMemDC,
  702.       0,
  703.       0,
  704.       PrinterAreaXHigh-PrinterAreaXLow,
  705.       PrinterAreaYHigh-PrinterAreaYLow,
  706.       MemDC, 
  707.       +PrinterAreaXLow+xoffset,
  708.       -PrinterAreaYHigh+yoffset,
  709.       SRCCOPY);
  710.       
  711.       SelectObject(TempMemDC, OldBitmap2);
  712.       DeleteDC(TempMemDC);
  713.       
  714.       SelectObject(MemDC, OldBitmap);
  715.       DeleteDC(MemDC);
  716.       
  717.       // convert logo bitmap to raw DIB in BitsPtr
  718.       GetDIBits(ScreenDC, AreaMemoryBitMap, 0, PrinterAreaYHigh-PrinterAreaYLow, BitsPtr, BitmapInfo, DIB_RGB_COLORS);
  719.       
  720.       DeleteObject(AreaMemoryBitMap);
  721.       }
  722.    
  723.    /* else do whole thing */
  724.    
  725.    else
  726.       {
  727.       // convert logo bitmap to raw DIB in BitsPtr
  728.       GetDIBits(ScreenDC, MemoryBitMap, 0, BitMapHeight, BitsPtr, BitmapInfo, DIB_RGB_COLORS);
  729.       }      
  730.    
  731.    /* restore some of the resourese */ 
  732.    
  733.    if (EnablePalette) SelectPalette(ScreenDC, OldPalette2, FALSE);
  734.    DeleteDC(ScreenDC);
  735.    
  736.    /* build header */
  737.    
  738.    BitmapFileHeader.bfType      = 19778;
  739.    BitmapFileHeader.bfSize      = size + sizeof(BITMAPFILEHEADER) + (int)(BitmapInfo->bmiHeader.biWidth*BitmapInfo->bmiHeader.biHeight*(bitCount/8));
  740.    BitmapFileHeader.bfReserved1 = 0;
  741.    BitmapFileHeader.bfReserved2 = 0;
  742.    BitmapFileHeader.bfOffBits   = size + sizeof(BITMAPFILEHEADER);
  743.    
  744.    // write header
  745.    
  746.    _lwrite(TheFile, (LPSTR)&BitmapFileHeader, sizeof(BitmapFileHeader));
  747.    _lwrite(TheFile, (LPSTR)BitmapInfo, size);
  748.    
  749.    // write out raw DIB data to file
  750.    
  751.    GlobalUnlock(BitsHandle);
  752.    
  753.    PutBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
  754.    
  755.    GlobalFree(BitsHandle);
  756.    
  757.    /* if custom we need to set the original bitmap back to the right size */
  758.    
  759.    if (CustomFlag)
  760.       {
  761.       BitmapInfo->bmiHeader.biWidth         = BitMapWidth;
  762.       BitmapInfo->bmiHeader.biHeight        = BitMapHeight;
  763.       BitmapInfo->bmiHeader.biSizeImage     = ((((BitmapInfo->bmiHeader.biWidth*BitmapInfo->bmiHeader.biBitCount)+31)/32)*4)*BitmapInfo->bmiHeader.biHeight;
  764.       }      
  765.    
  766.    return TRUE;
  767.    }
  768.  
  769. BOOL TMyWindow::DumpBitmapFile(LPSTR Name)
  770.    {
  771.    int TheFile;
  772.    
  773.    /* open and check if ok */
  774.    
  775.    TheFile = _lcreat(Name, 0);
  776.    if ( TheFile != -1 )
  777.       {
  778.       
  779.       // Load hour-glass cursor.
  780.       hCursor = SetCursor(hCursorWait);
  781.       
  782.       /* do it and if error then let user know */
  783.       
  784.       if (!WriteDIB(TheFile))
  785.          {
  786.          MessageBox(HWindow, "Could not Write .BMP", "Error", MB_OK | MB_ICONEXCLAMATION);
  787.          }
  788.       
  789.       // Reload arrow cursor.
  790.       SetCursor(hCursor);
  791.       
  792.       _lclose(TheFile);
  793.       }
  794.    
  795.    /* else file never opened */
  796.    
  797.    else
  798.       {
  799.       MessageBox(HWindow, "Could not Open .BMP", "Error", MB_OK | MB_ICONEXCLAMATION);
  800.       }
  801.    
  802.    return TRUE;
  803.    }
  804.  
  805.  
  806. /* Attempt to open a Windows 3.0 device independent bitmap. */
  807.  
  808. BOOL TMyWindow::OpenDIB(int TheFile)
  809.    {
  810.    WORD bitCount;
  811.    WORD size;
  812.    
  813.    long longWidth;
  814.    HDC DCHandle;
  815.    LPSTR BitsPtr;
  816.    BITMAPINFO *BitmapInfo;
  817.    
  818.    HBITMAP BitsHandle;
  819.    HBITMAP NewBitmapHandle;
  820.    
  821.    DWORD NewPixelWidth;
  822.    DWORD NewPixelHeight;
  823.    
  824.    BITMAPFILEHEADER BitmapFileHeader;
  825.    int i;
  826.    
  827.    /* get header */
  828.    
  829.    _llseek(TheFile, 0, 0);
  830.    _lread(TheFile, (LPSTR)&BitmapFileHeader, sizeof(BitmapFileHeader));
  831.    
  832.    /* get the bit count */
  833.    
  834.    _llseek(TheFile, 28, 0);
  835.    _lread(TheFile, (LPSTR)&bitCount, sizeof(bitCount));
  836.    
  837.    /* only allow 8 bit or less */
  838.    
  839.    if (bitCount > 8) return FALSE;
  840.    
  841.    /* compute size of bitmap */
  842.    
  843.    size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
  844.    BitmapInfo = (BITMAPINFO *)new char[size];
  845.    
  846.    /* get to the bits */
  847.    
  848.    _llseek(TheFile, sizeof(BITMAPFILEHEADER), 0);
  849.    _lread(TheFile, (LPSTR)BitmapInfo, size);
  850.    
  851.    /* if palette load up palette from bitmap color table */
  852.    
  853.    if (EnablePalette)
  854.       {
  855.       for (i=0;i<(1<<bitCount);i++) LoadColor(
  856.       BitmapInfo->bmiColors[i].rgbRed,
  857.       BitmapInfo->bmiColors[i].rgbGreen,
  858.       BitmapInfo->bmiColors[i].rgbBlue);
  859.       }
  860.    
  861.    /* save some typing */
  862.    
  863.    NewPixelWidth = BitmapInfo->bmiHeader.biWidth;
  864.    NewPixelHeight = BitmapInfo->bmiHeader.biHeight;
  865.    
  866.    /* compute image size */
  867.    
  868.    longWidth = (((NewPixelWidth * bitCount) + 31)/32) * 4;
  869.    
  870.    BitmapInfo->bmiHeader.biSizeImage = longWidth * NewPixelHeight;
  871.    
  872.    /* pack and allocate */
  873.    
  874.    BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  875.    
  876.    /* If fail try again after a compact */
  877.    
  878.    if (!BitsHandle)
  879.       {
  880.       GlobalCompact(-1);
  881.       BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BitmapInfo->bmiHeader.biSizeImage);
  882.       }
  883.    
  884.    /* sorry */
  885.    
  886.    if (!BitsHandle)
  887.       {
  888.       delete BitmapInfo;
  889.       return FALSE;
  890.       }
  891.    
  892.    /* read the file into the bitmap */
  893.    
  894.    GetBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
  895.    
  896.    /* Create DC comaptible with screen */
  897.    
  898.    ScreenDC = GetDC(MainHWindow);
  899.    
  900.    MemDC = CreateCompatibleDC(ScreenDC);
  901.    DCHandle = CreateCompatibleDC(ScreenDC);
  902.    
  903.    /* if palette yank it */
  904.    
  905.    if (EnablePalette)
  906.       {
  907.       OldPalette2 = SelectPalette(ScreenDC, ThePalette, FALSE);
  908.       RealizePalette(ScreenDC);
  909.       
  910.       OldPalette = SelectPalette(MemDC, ThePalette, FALSE);
  911.       RealizePalette(MemDC);
  912.       }
  913.    
  914.    /* find it */
  915.    
  916.    BitsPtr = (LPSTR)GlobalLock((HGLOBAL)BitsHandle);
  917.    
  918.    /* now create the bitmap with the bits just loaded */
  919.    
  920.    NewBitmapHandle = CreateDIBitmap(ScreenDC, &(BitmapInfo->bmiHeader), CBM_INIT, BitsPtr,BitmapInfo, 0);
  921.    
  922.    /* now dump the bits */
  923.    
  924.    GlobalUnlock(BitsHandle);
  925.    GlobalFree(BitsHandle);
  926.    
  927.    delete BitmapInfo;
  928.    
  929.    if (EnablePalette) SelectPalette(ScreenDC, OldPalette2, FALSE);
  930.    ReleaseDC(MainHWindow,ScreenDC);
  931.    
  932.    /* now that things are clean we can check if we are ok */
  933.    
  934.    if ( !NewBitmapHandle ) return FALSE;
  935.    
  936.    /*
  937.    We've now made a bonafied bitmap. But we want to copy it into the
  938.    existing backing store.
  939.    */
  940.    
  941.    if (EnablePalette)
  942.       {
  943.       OldPalette2 = SelectPalette(DCHandle, ThePalette, FALSE);
  944.       RealizePalette(DCHandle);
  945.       }
  946.    
  947.    OldBitmap2 = (HBITMAP)SelectObject(DCHandle, NewBitmapHandle);
  948.    OldBitmap = (HBITMAP)SelectObject(MemDC, MemoryBitMap);
  949.    
  950.    /* if either dimension is more than half then put in corner */
  951.    
  952.    if ((NewPixelWidth > (BitMapWidth/2)) || (NewPixelHeight > (BitMapHeight/2)))
  953.       {
  954.       BitBlt(MemDC, 0, 0, NewPixelWidth, NewPixelHeight, DCHandle, 0, 0, SRCCOPY);
  955.       }
  956.    
  957.    /* else put at turtle */
  958.    
  959.    else
  960.       {
  961.       BitBlt(MemDC,
  962.       +turtle_x+xoffset,
  963.       -turtle_y+yoffset-NewPixelHeight,
  964.       NewPixelWidth,
  965.       NewPixelHeight, DCHandle, 0, 0, SRCCOPY);
  966.       }
  967.    
  968.    /* return resources */
  969.    
  970.    if (EnablePalette)
  971.       {
  972.       SelectPalette(MemDC, OldPalette, FALSE);
  973.       SelectPalette(DCHandle, OldPalette2, FALSE);
  974.       }
  975.    SelectObject(MemDC, OldBitmap);
  976.    SelectObject(DCHandle, OldBitmap2);
  977.    DeleteDC(MemDC);
  978.    DeleteDC(DCHandle);
  979.    DeleteObject(NewBitmapHandle);
  980.    
  981.    return TRUE;
  982.    }
  983.  
  984. BOOL TMyWindow::LoadBitmapFile(LPSTR Name)
  985.    {
  986.    
  987.    /* Test if the passed file is a Windows 3.0 DIB bitmap and if so read it */
  988.    
  989.    int TheFile;
  990.    long TestWin30Bitmap;
  991.    char ErrorMsg[50] = "";
  992.    BOOL retval;
  993.    
  994.    /* open then check if open */
  995.    
  996.    TheFile = _lopen(Name, OF_READ);
  997.    if ( TheFile != -1 )
  998.       {
  999.       
  1000.       /* check if valid bitmap */
  1001.       
  1002.       _llseek(TheFile, 14, 0);
  1003.       _lread(TheFile, (LPSTR)&TestWin30Bitmap, sizeof(TestWin30Bitmap));
  1004.       if ( TestWin30Bitmap == 40 )
  1005.          {
  1006.          // Load hour-glass cursor.
  1007.          hCursor = SetCursor(hCursorWait);
  1008.          
  1009.          /* if loaded ok then invalidate to display */
  1010.          
  1011.          if ( OpenDIB(TheFile) )
  1012.             {
  1013.             InvalidateRect(MainHWindow, NULL, TRUE);
  1014.             }
  1015.          
  1016.          /* else error */
  1017.          
  1018.          else
  1019.             {
  1020.             strcpy(ErrorMsg, "Unable to create Windows 3.0 bitmap");
  1021.             }
  1022.          
  1023.          // Reload arrow cursor.
  1024.          SetCursor(hCursor);
  1025.          }
  1026.       
  1027.       /* not a bitmap */
  1028.       
  1029.       else
  1030.          {
  1031.          strcpy(ErrorMsg, "Not a Windows 3.0 bitmap");
  1032.          }
  1033.       _lclose(TheFile);
  1034.       }
  1035.    
  1036.    /* else file not there */
  1037.    
  1038.    else
  1039.       {
  1040.       strcpy(ErrorMsg, "Cannot open bitmap file");
  1041.       }
  1042.    
  1043.    /* if no message the we are ok else display error message */
  1044.    
  1045.    if ( ErrorMsg[0] == '\0' )
  1046.       {
  1047.       retval= TRUE;
  1048.       }
  1049.    else
  1050.       {
  1051.       MessageBox(HWindow, ErrorMsg, "Error", MB_OK);
  1052.       retval= FALSE;
  1053.       }
  1054.    
  1055.    return retval;
  1056.    }
  1057.  
  1058. /* __ahIncr, ordinal 114, is a 'magic' function. Defining this
  1059. function causes Windows to patch the value into the passed
  1060. reference.  This makes it a type of global variable. To use
  1061. the value of AHIncr, use FP_OFF(AHIncr). */
  1062.  
  1063.    extern "C" {
  1064.    void FAR PASCAL  __ahIncr();
  1065.    }
  1066.  
  1067. /* Copys the bitmap bit data from the file into memory. Since
  1068. copying cannot cross a segment (64K) boundary, we are forced
  1069. to do segment arithmetic to compute the next segment.  Created
  1070. a LongType type to simplify the process. */
  1071.  
  1072. void TMyWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  1073.    {
  1074.    long Count;
  1075.    long Start, ToAddr, Bits;
  1076.    
  1077.    Start = 0L;
  1078.    Bits = (long)GlobalLock(BitsHandle);
  1079.    Count = BitsByteSize - Start;
  1080.    while ( Count > 0 )
  1081.       {
  1082.       ToAddr = MAKELONG(LOWORD(Start),
  1083.       HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
  1084.       if ( Count > 0x4000 )
  1085.       Count = 0x4000;
  1086.       _lread(TheFile, (LPSTR)ToAddr, (WORD)Count);
  1087.       Start = Start + Count;
  1088.       Count = BitsByteSize - Start;
  1089.       }
  1090.    GlobalUnlock(BitsHandle);
  1091.    }
  1092.  
  1093. /* Copys the bitmap bit data from the memory into file. Since
  1094. copying cannot cross a segment (64K) boundary, we are forced
  1095. to do segment arithmetic to compute the next segment.  Created
  1096. a LongType type to simplify the process. */
  1097.  
  1098. void TMyWindow::PutBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  1099.    {
  1100.    long Count;
  1101.    long Start, ToAddr, Bits;
  1102.    
  1103.    Start = 0L;
  1104.    Bits = (long)GlobalLock(BitsHandle);
  1105.    Count = BitsByteSize - Start;
  1106.    
  1107.    while ( Count > 0 )
  1108.       {
  1109.       ToAddr = MAKELONG(LOWORD(Start),
  1110.       HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
  1111.       if ( Count > 0x4000 )
  1112.       Count = 0x4000;
  1113.       _lwrite(TheFile, (LPSTR)ToAddr, (WORD)Count);
  1114.       Start = Start + Count;
  1115.       Count = BitsByteSize - Start;
  1116.       }
  1117.    
  1118.    GlobalUnlock(BitsHandle);
  1119.    }
  1120.  
  1121. void TMyWindow::WMSize(RTMessage Msg)
  1122.    { 
  1123.    RECT RRR;
  1124.    int Xr;
  1125.    int Yr;
  1126.    NUMBER XRatio,YRatio;
  1127.    
  1128.    /* pass message down */
  1129.    
  1130.    TWindow::WMSize(Msg);
  1131.    
  1132.    /*
  1133.    Adjust scroller range so that thumb at each extreme corresponds
  1134.    to edge of extreme image.
  1135.    */
  1136.    
  1137.    GetClientRect(HWindow,&RRR);
  1138.    
  1139.    Xr = (BitMapWidth*the_zoom)-RRR.right;
  1140.    Yr = (BitMapHeight*the_zoom)-RRR.bottom;
  1141.    
  1142.    if (Xr < 0) Xr = 0;
  1143.    if (Yr < 0) Yr = 0;
  1144.    
  1145.    if (Scroller->XRange <= 0)
  1146.       {
  1147.       XRatio = 0.5;
  1148.       }
  1149.    else
  1150.       {
  1151.       XRatio = (NUMBER)Scroller->XPos/(NUMBER)Scroller->XRange;
  1152.       }
  1153.    
  1154.    if (Scroller->YRange <= 0)
  1155.       {
  1156.       YRatio = 0.5;
  1157.       }
  1158.    else
  1159.       {
  1160.       YRatio = (NUMBER)Scroller->YPos/(NUMBER)Scroller->YRange;
  1161.       }
  1162.    
  1163.    Scroller->SetRange(Xr,Yr);
  1164.    Scroller->ScrollTo(XRatio*Xr,YRatio*Yr);
  1165.    
  1166.    //   Scroller->SetPageSize();
  1167.    
  1168.    }
  1169.  
  1170. void TMyWindow::CMBitmapNew(RTMessage Msg)
  1171.    { 
  1172.    HBRUSH TempBrush;
  1173.    HDC TempDC;
  1174.    
  1175.    /* basically all that is done here is to reset things */
  1176.    
  1177.    TempBrush = CreateBrushIndirect(&ScreenBrush);
  1178.    TempDC = GetDC(MainHWindow);
  1179.    
  1180.    //memory
  1181.    
  1182.    MemDC = CreateCompatibleDC(TempDC);
  1183.    SelectObject(MemDC, MemoryBitMap);
  1184.    
  1185.    FillRect(MemDC, &FullRect, TempBrush);
  1186.    
  1187.    SetBkColor(MemDC, scolor);
  1188.    SetBkMode(MemDC, TRANSPARENT);
  1189.    
  1190.    DeleteDC(MemDC);
  1191.    
  1192.    ReleaseDC(MainHWindow, TempDC);
  1193.    DeleteObject(TempBrush);
  1194.    
  1195.    //screen
  1196.    
  1197.    InvalidateRect(HWindow, NULL, TRUE);
  1198.    
  1199.    IsNewBitmap = TRUE;
  1200.    }
  1201.  
  1202. void TMyWindow::CMBitmapOpen(RTMessage Msg)
  1203.    { 
  1204.    
  1205.    /* if user found a file then try to load it  */
  1206.    
  1207.    if ( GetApplication()->ExecDialog(new TFileDialog(this, SD_FILEOPEN,strcpy(BitmapName, "*.BMP"))) == IDOK )
  1208.       {
  1209.       IsNewBitmap = FALSE;
  1210.       LoadBitmapFile(BitmapName);
  1211.       }
  1212.    }
  1213.  
  1214. void TMyWindow::CMBitmapSave(RTMessage Msg)
  1215.    { 
  1216.    
  1217.    /* if new file then switch to save file as, else save */
  1218.    
  1219.    if ( IsNewBitmap )
  1220.    SaveBitmapAs();
  1221.    else SaveBitmap();
  1222.    }
  1223.  
  1224. void TMyWindow::SaveBitmapAs()
  1225.    { 
  1226.    
  1227.    /* if new then nulify File name */
  1228.    
  1229.    if ( IsNewBitmap ) strcpy(BitmapName, "");
  1230.    
  1231.    /* Get file name from user and then save the file */   
  1232.    
  1233.    if ( GetApplication()->ExecDialog(new TFileDialog(this, SD_FILESAVE,strcpy(BitmapName, "*.BMP"))) == IDOK )
  1234.       {
  1235.       IsNewBitmap = FALSE;
  1236.       SaveBitmap();
  1237.       }
  1238.    }
  1239.  
  1240. void TMyWindow::CMBitmapSaveAs(RTMessage Msg)
  1241.    { 
  1242.    SaveBitmapAs();
  1243.    }
  1244.  
  1245. void TMyWindow::SaveBitmap()
  1246.    { 
  1247.    DumpBitmapFile(BitmapName);
  1248.    }
  1249.  
  1250. void TMyWindow::CMFileNew(RTMessage Msg)
  1251.    { 
  1252.    NODE *arg;
  1253.    
  1254.    // if doing new and dirty giver user a chance to abort the new
  1255.    
  1256.    if ( IsDirty )
  1257.       {
  1258.       if (MessageBox(HWindow, "Continue with NEW?","You have not done a SAVE", MB_YESNO | MB_ICONQUESTION) == IDNO) return;
  1259.       }
  1260.    
  1261.    // else start with a clean plate
  1262.    
  1263.    IsNewFile = TRUE;
  1264.    IsDirty = FALSE;
  1265.    
  1266.    arg = lcontents();
  1267.    
  1268.    lerase(arg);
  1269.    }
  1270.  
  1271. void TMyWindow::CMFileOpen(RTMessage Msg)
  1272.    { 
  1273.    int i;
  1274.    
  1275.    /* if user found a file the try to load it  */
  1276.    
  1277.    if ( GetApplication()->ExecDialog(new TFileDialog(this, SD_FILEOPEN,strcpy(FileName, "*.*"))) == IDOK )
  1278.       {
  1279.       IsNewFile = FALSE;
  1280.       halt_flag++;
  1281.       if (halt_flag < 1) halt_flag = 1;
  1282.       fileload(FileName);
  1283.       
  1284.       // use dummy loop so that original code with "Breaks" does the right thing
  1285.       
  1286.       for (i=0;i<1;i++)
  1287.          {
  1288.             if (stopping_flag == THROWING) {
  1289.                if (compare_node(throw_node, Error, TRUE) == 0) {
  1290.                err_print();
  1291.                } else if (compare_node(throw_node, System, TRUE) == 0)
  1292.             break;
  1293.                else if (compare_node(throw_node, Toplevel, TRUE) != 0) {
  1294.                err_logo(NO_CATCH_TAG, throw_node);
  1295.                err_print();
  1296.                }
  1297.             stopping_flag = RUN;
  1298.             }
  1299.             if (stopping_flag == STOP || stopping_flag == OUTPUT) {
  1300.             print_node(stdout, make_static_strnode(
  1301.             "You must be in a procedure to use OUTPUT or STOP.\n"));
  1302.             stopping_flag = RUN;
  1303.             }
  1304.          }
  1305.       
  1306.       halt_flag--;
  1307.       if (halt_flag < 0) halt_flag = 0;
  1308.       }
  1309.    }
  1310.  
  1311. void TMyWindow::CMFileSave(RTMessage Msg)
  1312.    { 
  1313.    
  1314.    /* if new file the switch to save file as, else save */
  1315.    
  1316.    if ( IsNewFile )
  1317.    SaveFileAs();
  1318.    else SaveFile();
  1319.    }
  1320.  
  1321. void TMyWindow::SaveFileAs()
  1322.    { 
  1323.    
  1324.    /* if new the nulify File name */
  1325.    
  1326.    if ( IsNewFile ) strcpy(FileName, "");
  1327.    
  1328.    /* Get file name from user and then save the file */   
  1329.    
  1330.    if ( GetApplication()->ExecDialog(new TFileDialog(this, SD_FILESAVE,strcpy(FileName, "*.*"))) == IDOK )
  1331.       {
  1332.       IsNewFile = FALSE;
  1333.       SaveFile();
  1334.       }
  1335.    }
  1336.  
  1337. void TMyWindow::CMFileSaveAs(RTMessage Msg)
  1338.    { 
  1339.    SaveFileAs();
  1340.    }
  1341.  
  1342. void TMyWindow::SaveFile()
  1343.    { 
  1344.    filesave(FileName);
  1345.    }
  1346.  
  1347. void TMyWindow::CMBitmapPrinterArea(RTMessage Msg)
  1348.    { 
  1349.    
  1350.    /* copy real to dynamic */
  1351.    
  1352.    TPrinterAreaXLow  = PrinterAreaXLow;
  1353.    TPrinterAreaXHigh = PrinterAreaXHigh;
  1354.    TPrinterAreaYLow  = PrinterAreaYLow;
  1355.    TPrinterAreaYHigh = PrinterAreaYHigh;
  1356.    TCustomFlag       = CustomFlag;
  1357.    
  1358.    /* if user does not cancel then copy dynamic to real */
  1359.    
  1360.    PrinterAreaWindow = new TMyPrinterAreaWindow(this, "PrinterArea");
  1361.    
  1362.    if ( GetApplication()->ExecDialog(PrinterAreaWindow) == IDOK )
  1363.       {
  1364.       PrinterAreaXLow  = TPrinterAreaXLow;
  1365.       PrinterAreaXHigh = TPrinterAreaXHigh;
  1366.       PrinterAreaYLow  = TPrinterAreaYLow;
  1367.       PrinterAreaYHigh = TPrinterAreaYHigh;
  1368.       CustomFlag       = TCustomFlag;
  1369.       }
  1370.    }
  1371.  
  1372. void TMyWindow::CMFileEdit(RTMessage Msg)
  1373.    { 
  1374.    NODE *arg;
  1375.    
  1376.    // create dialog for which procedure to edit
  1377.    
  1378.    FileEditWindow = new TMyFileEditWindow(this, "DIALOGEDIT");
  1379.    
  1380.    FileEditWindow->FileEditAll = 0;
  1381.    
  1382.    // now do it
  1383.    
  1384.    if ( GetApplication()->ExecDialog(FileEditWindow) == IDOK )
  1385.       {
  1386.       
  1387.       // if user clicked ALL get all procedures
  1388.       
  1389.       if (FileEditWindow->FileEditAll == 1)
  1390.          {
  1391.          arg = lprocedures();
  1392.          }
  1393.       
  1394.       // else find what user selected
  1395.       
  1396.       else
  1397.          {
  1398.          arg = cons(make_strnode(SelectedText, NULL, strlen(SelectedText), STRING, strnzcpy),NIL);
  1399.          }
  1400.       
  1401.       // if something edit it
  1402.       
  1403.       if (arg != NIL) ledit(arg);
  1404.       
  1405.       }
  1406.    }
  1407.  
  1408. void TMyWindow::CMFileErase(RTMessage Msg)
  1409.    { 
  1410.    NODE *arg;
  1411.    
  1412.    // create dialog for which procedure to erase
  1413.    
  1414.    FileEditWindow = new TMyFileEditWindow(this, "DIALOGERASE");
  1415.    
  1416.    FileEditWindow->FileEditAll = 0;
  1417.    
  1418.    // now do it
  1419.    
  1420.    if ( GetApplication()->ExecDialog(FileEditWindow) == IDOK )
  1421.       {
  1422.       
  1423.       // if user clicked ALL get all procedures
  1424.       
  1425.       if (FileEditWindow->FileEditAll == 1)
  1426.          {
  1427.          arg = lprocedures();
  1428.          
  1429.          IsNewFile = TRUE;
  1430.          IsDirty = FALSE;
  1431.          }
  1432.       
  1433.       // else find what user selected
  1434.       
  1435.       else
  1436.          {
  1437.          arg = cons(make_strnode(SelectedText, NULL, strlen(SelectedText), STRING, strnzcpy),NIL);
  1438.          }
  1439.       
  1440.       // if something erase it
  1441.       
  1442.       if (arg != NIL) lerase(arg);
  1443.       
  1444.       }
  1445.    }
  1446.  
  1447. void TMyWindow::MyPopupEdit(char *FileName, NODE *args)
  1448.    { 
  1449.    char TempFileName[32];
  1450.    char *cp;
  1451.    char szWinLocStr[WININISIZ];
  1452.    char dfWinLocStr[WININISIZ];
  1453.    
  1454.    int x;
  1455.    int y;
  1456.    int w;
  1457.    int h;
  1458.    
  1459.    PTModule pm;
  1460.    TWindowAttr aw;
  1461.    
  1462.    /* if called with NULL filename then prompt user */
  1463.    
  1464.    if ( FileName == NULL )
  1465.       {
  1466.       GetApplication()->ExecDialog(new TFileDialog(this, SD_FILEOPEN,_fstrcpy(TempFileName, "*.*")));
  1467.       EditWindow = new TMyFileWindow(this, "Editor", TempFileName, args);
  1468.       }
  1469.    
  1470.    /* else use given arg */
  1471.    
  1472.    else
  1473.       {
  1474.       EditWindow = new TMyFileWindow(this, "Editor", FileName, args);
  1475.       }
  1476.    
  1477.    /* Do win.ini stuff. Build default coords */
  1478.    
  1479.    x = (int)(MaxWidth*0.25);
  1480.    y = (int)(MaxHeight*0.25);
  1481.    w = (int)(MaxWidth*0.75);
  1482.    h = (int)(MaxHeight*ScreenSz*0.75);
  1483.    
  1484.    /* convert */
  1485.    
  1486.    sprintf(dfWinLocStr, "%d,%d,%d,%d", x, y, w, h);
  1487.    
  1488.    // Get last location and size of Edit Window from WIN.INI file.
  1489.    
  1490.    GetPrivateProfileString(
  1491.    "LOGO",
  1492.    "Editor",
  1493.    dfWinLocStr,
  1494.    szWinLocStr,
  1495.    sizeof(szWinLocStr),
  1496.    "LOGO.INI");
  1497.    
  1498.    // Decode location and size of window from profile string.
  1499.    
  1500.    cp = szWinLocStr;
  1501.    x = (int) strtol(cp, &cp, 10);
  1502.    cp++;
  1503.    y = (int) strtol(cp, &cp, 10);
  1504.    cp++;
  1505.    w = (int) strtol(cp, &cp, 10);
  1506.    cp++;
  1507.    h = (int) strtol(cp, &cp, 10);
  1508.    
  1509.    checkwindow(&x, &y, &w, &h);
  1510.    
  1511.    /* now set them */   
  1512.    
  1513.    EditWindow->Attr.Style |= WS_POPUPWINDOW | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
  1514.    EditWindow->Attr.X = x;
  1515.    EditWindow->Attr.Y = y;
  1516.    EditWindow->Attr.W = w;
  1517.    EditWindow->Attr.H = h;
  1518.    
  1519.    /* flag for how to handle focus */
  1520.    
  1521.    if (args != NULL) JustDidEdit = 1;
  1522.    
  1523.    aw = EditWindow->Editor->Attr;
  1524.    delete EditWindow->Editor;
  1525.    EditWindow->hEditHeap = GlobalAlloc(GMEM_ZEROINIT, 0xFFFF);
  1526.    pm = new TModule("", (HMODULE)EditWindow->hEditHeap, "");
  1527.    EditWindow->Editor = new TEdit( EditWindow, aw.Id, "", aw.X, aw.Y, aw.W, aw.H, -1, TRUE, pm);
  1528.    
  1529.    /* let user edit */
  1530.    
  1531.    GetApplication()->MakeWindow(EditWindow);
  1532.    
  1533.    if (args != NULL) 
  1534.       {
  1535.       
  1536.       /* retitle without filename */
  1537.       
  1538.       SetWindowText(EditWindow->HWindow, "Editor");
  1539.       
  1540.       // if an error occured "force" a change so that we still in
  1541.       // "dirty" state
  1542.       
  1543.       if (error_happen)
  1544.          {
  1545.          error_happen = 0;
  1546.          EditWindow->Editor->Insert(" ");
  1547.          EditWindow->Editor->DeleteSubText(0,1);
  1548.          }
  1549.       
  1550.       /* keep global pointer for hacking around */
  1551.       
  1552.       EdtHWindow = EditWindow->HWindow;
  1553.       }
  1554.    }
  1555.  
  1556. int TMyWindow::MyPopupInput(char *str,char *pmt)
  1557.    { 
  1558.    
  1559.    // get user input
  1560.    
  1561.    if (GetApplication()->ExecDialog(new TInputDialog(this, pmt,"Input:",str,MAX_BUFFER_SIZE)) == IDOK)
  1562.       {
  1563.       return(1);
  1564.       }
  1565.    else
  1566.       {
  1567.       return(0);
  1568.       }
  1569.    }
  1570.  
  1571. void TMyWindow::SetupWindow()
  1572.    { 
  1573.    
  1574.    TWindow::SetupWindow();
  1575.    
  1576.    MainHWindow = HWindow;
  1577.    
  1578.    /* adjust scrollers */
  1579.    
  1580.    GetClientRect(HWindow,&RR);
  1581.    Scroller->SetRange(BitMapWidth-RR.right,BitMapHeight-RR.bottom);
  1582.    Scroller->ScrollTo((BitMapWidth/2)-(0.5*RR.right),(BitMapHeight/2)-(0.5*RR.bottom));
  1583.    
  1584.    /* save size */
  1585.    
  1586.    MaxX = BitMapWidth;
  1587.    MaxY = BitMapHeight;
  1588.    
  1589.    /* it's show time for our little friend */
  1590.    
  1591.    ibmturt(0);
  1592.    term_init();
  1593.    
  1594.    /* pop up commander */
  1595.    
  1596.    MyPopupCommander();
  1597.    }
  1598.  
  1599. void TMyWindow::MyPopupCommander()
  1600.    { 
  1601.    
  1602.    /* init commander window */
  1603.    
  1604.    char      *cp;
  1605.    char       szWinLocStr[WININISIZ];
  1606.    char       dfWinLocStr[WININISIZ];
  1607.    int        x, y, w, h;
  1608.    
  1609.    /* create resourced window */
  1610.    
  1611.    CommandWindow = new TMyCommandWindow(this, "DIALOGCOMMAND");
  1612.    GetApplication()->MakeWindow(CommandWindow);
  1613.    
  1614.    CmdHWindow = ((TMyCommandWindow *)((TMyWindow *)MainWindowx)->CommandWindow)->HWindow;
  1615.    
  1616.    EditboxWindow = new TMyEditboxWindow(CommandWindow, ID_EDITINPUT, 0);
  1617.    GetApplication()->MakeWindow(EditboxWindow);
  1618.    
  1619.    ListboxWindow = new TMyListboxWindow(CommandWindow, ID_LISTBOX);
  1620.    GetApplication()->MakeWindow(ListboxWindow);
  1621.    
  1622.    /* get handle to each child window for resize purposes */
  1623.    
  1624.    ListHWindow    = GetDlgItem(CmdHWindow,ID_LISTBOX);
  1625.    EditHWindow    = GetDlgItem(CmdHWindow,ID_EDITINPUT);
  1626.    ExecuteHWindow = GetDlgItem(CmdHWindow,ID_EXECUTE);
  1627.    HaltHWindow    = GetDlgItem(CmdHWindow,ID_HALT);
  1628.    TraceHWindow   = GetDlgItem(CmdHWindow,ID_TRACE);
  1629.    PauseHWindow   = GetDlgItem(CmdHWindow,ID_PAUSE);
  1630.    StatusHWindow  = GetDlgItem(CmdHWindow,ID_STATUS);
  1631.    YieldHWindow   = GetDlgItem(CmdHWindow,ID_YIELD);
  1632.    ResetHWindow   = GetDlgItem(CmdHWindow,ID_RESET);
  1633.    
  1634.    /* build default coords */
  1635.    
  1636.    x = ((TMyWindow *)MainWindowx)->Attr.X;
  1637.    y = ((TMyWindow *)MainWindowx)->Attr.Y+((TMyWindow *)MainWindowx)->Attr.H;
  1638.    w = ((TMyWindow *)MainWindowx)->Attr.W;
  1639.    h = MaxHeight*CommandSz;// 47; //((TMyWindow *)MainWindowx)->Attr.H*0.25;
  1640.    
  1641.    /* convert */
  1642.    
  1643.    sprintf(dfWinLocStr, "%d,%d,%d,%d", x, y, w, h);
  1644.    szWinLocStr[0] = '\0';
  1645.    
  1646.    // Get last location and size of command window from WIN.INI file.
  1647.    
  1648.    GetPrivateProfileString(
  1649.    "LOGO",
  1650.    "Commander",
  1651.    dfWinLocStr,
  1652.    szWinLocStr,
  1653.    sizeof(szWinLocStr),
  1654.    "LOGO.INI");
  1655.    
  1656.    // Decode location and size of window from profile string.
  1657.    
  1658.    cp = szWinLocStr;
  1659.    x = (int) strtol(cp, &cp, 10);
  1660.    cp++;
  1661.    y = (int) strtol(cp, &cp, 10);
  1662.    cp++;
  1663.    w = (int) strtol(cp, &cp, 10);
  1664.    cp++;
  1665.    h = (int) strtol(cp, &cp, 10);
  1666.    
  1667.    checkwindow(&x, &y, &w, &h);
  1668.    
  1669.    /* set it */
  1670.    
  1671.    SetWindowPos(CmdHWindow, NULL, x, y, w, h, 0);
  1672.    ShowWindow(CmdHWindow, SW_SHOW);
  1673.    
  1674.    Command_OK = 1;
  1675.    
  1676.    }
  1677.  
  1678. void TMyWindow::MyPopupStatusKill()
  1679.    { 
  1680.    RECT  wrect;
  1681.    int   w, h;
  1682.    char  szWinLocStr[WININISIZ];
  1683.    
  1684.    status_flag = 0;
  1685.    
  1686.    // Get location and size of our window on the screen so we can
  1687.    // come back up in the same spot next time we are invoked.
  1688.    
  1689.    GetWindowRect(StatHWindow, (LPRECT) &wrect);
  1690.    w = wrect.right - wrect.left;
  1691.    h = wrect.bottom - wrect.top;
  1692.    
  1693.    // Make a string with our window location and size.
  1694.    sprintf(szWinLocStr, "%d,%d,%d,%d", wrect.left, wrect.top, w, h);
  1695.    
  1696.    // Save in WIN.INI file.
  1697.    WritePrivateProfileString(
  1698.    "LOGO",
  1699.    "Status",
  1700.    szWinLocStr,
  1701.    "LOGO.INI");
  1702.    
  1703.    /* now kill it */
  1704.    
  1705.    delete StatusWindow;
  1706.    ((TMyCommandWindow *)((TMyWindow *)MainWindowx)->CommandWindow)->
  1707.    SendDlgItemMsg(ID_STATUS, WM_SETTEXT, 0, (DWORD)"Status");
  1708.    }
  1709.  
  1710. void TMyWindow::MyPopupStatus()
  1711.    { 
  1712.    
  1713.    /* popup status window */
  1714.    
  1715.    char      *cp;
  1716.    char       szWinLocStr[WININISIZ];
  1717.    char       dfWinLocStr[WININISIZ];
  1718.    int        x, y, w, h;
  1719.    
  1720.    /* flag so that updates are sent */
  1721.    
  1722.    status_flag = 1;
  1723.    
  1724.    /* pop it up */
  1725.    
  1726.    StatusWindow = new TMyStatusWindow(this, "DIALOGSTATUS");
  1727.    
  1728.    /* update button */
  1729.    
  1730.    ((TMyCommandWindow *)((TMyWindow *)MainWindowx)->CommandWindow)->
  1731.    SendDlgItemMsg(ID_STATUS, WM_SETTEXT, 0, (DWORD)"NoStatus");
  1732.    
  1733.    GetApplication()->MakeWindow(StatusWindow);
  1734.    
  1735.    /* save a handle */
  1736.    
  1737.    StatHWindow = StatusWindow->HWindow;
  1738.    
  1739.    /* build default coords */
  1740.    
  1741.    x = (int)(0);
  1742.    y = (int)(0);
  1743.    w = (int)(0);
  1744.    h = (int)(0);
  1745.    
  1746.    /* convert */
  1747.    
  1748.    sprintf(dfWinLocStr, "%d,%d,%d,%d", x, y, w, h);
  1749.    
  1750.    // Get last location and size of status window from WIN.INI file.
  1751.    
  1752.    GetPrivateProfileString(
  1753.    "LOGO",
  1754.    "Status",
  1755.    dfWinLocStr,
  1756.    szWinLocStr,
  1757.    sizeof(szWinLocStr),
  1758.    "LOGO.INI");
  1759.    
  1760.    // Decode location and size of window from profile string.
  1761.    
  1762.    cp = szWinLocStr;
  1763.    x = (int) strtol(cp, &cp, 10);
  1764.    cp++;
  1765.    y = (int) strtol(cp, &cp, 10);
  1766.    cp++;
  1767.    w = (int) strtol(cp, &cp, 10);
  1768.    cp++;
  1769.    h = (int) strtol(cp, &cp, 10);
  1770.    
  1771.    checkwindow(&x, &y, &w, &h);
  1772.    
  1773.    /* now set position */
  1774.    
  1775.    SetWindowPos(StatHWindow, NULL, x, y, 0, 0, SWP_NOSIZE);
  1776.    ShowWindow(StatHWindow, SW_SHOW);
  1777.    
  1778.    /* update all fields */
  1779.    
  1780.    update_status_turtleposition();
  1781.    update_status_pencolor();
  1782.    update_status_floodcolor();
  1783.    update_status_screencolor();
  1784.    update_status_paletteuse();
  1785.    update_status_penwidth();
  1786.    update_status_turtleheading();
  1787.    update_status_penstyle();
  1788.    update_status_pencontact();
  1789.    update_status_turtlevisability();
  1790.    update_status_fontsize();
  1791.    update_status_fontwieght();
  1792.    update_status_fontname();
  1793.    update_status_evals();
  1794.    update_status_memory();
  1795.    }
  1796.  
  1797. void TMyWindow::CMControlHalt(RTMessage Msg)
  1798.    { 
  1799.    lhalt();
  1800.    }
  1801.  
  1802. void TMyWindow::CMControlExecute(RTMessage Msg)
  1803.    { 
  1804.    HWND EditH;
  1805.    HWND TempH;
  1806.    
  1807.    EditH = FindWindow(NULL, "Editor");
  1808.    TempH = GetActiveWindow();
  1809.    
  1810.    // if Main is active find alternate
  1811.    
  1812.    if (TempH == MainHWindow)
  1813.       {
  1814.       
  1815.       // if commander up then focud to input box
  1816.       
  1817.       if (!IsIconic(CmdHWindow))
  1818.          {
  1819.          SetFocus(EditHWindow);
  1820.          } 
  1821.       
  1822.       // else if a available editor go there
  1823.       
  1824.       else if (EditH != NULL)
  1825.          {
  1826.          if (!IsIconic(EditH))
  1827.             {
  1828.             SetFocus(EditH);
  1829.             }
  1830.          }
  1831.       }
  1832.    
  1833.    // else if active is commander find alternate
  1834.    
  1835.    else if (TempH == CmdHWindow)
  1836.       {
  1837.       
  1838.       // if a available editor maybe go there
  1839.       
  1840.       if (EditH != NULL)
  1841.          {
  1842.          
  1843.          // if really available then go there
  1844.          
  1845.          if (!IsIconic(EditH))
  1846.             {
  1847.             SetFocus(EditH);
  1848.             }
  1849.          
  1850.          // else go to main
  1851.          
  1852.          else
  1853.             {
  1854.             SetFocus(MainHWindow);
  1855.             }
  1856.          }
  1857.       
  1858.       // else go to main
  1859.       
  1860.       else
  1861.          {
  1862.          SetFocus(MainHWindow);
  1863.          }
  1864.       }
  1865.    
  1866.    // else go to main
  1867.    
  1868.    else
  1869.       {
  1870.       SetFocus(MainHWindow);
  1871.       }
  1872.    }
  1873.  
  1874. void TMyWindow::CMSetFont(RTMessage Msg)
  1875.    { 
  1876.    
  1877.    static CHOOSEFONT CF;
  1878.    
  1879.    // clear the struct
  1880.    
  1881.    memset(&CF,0,sizeof(CF));
  1882.    
  1883.    // fill it with the right stuff
  1884.    
  1885.    CF.lStructSize    = sizeof(CF);
  1886.    CF.hwndOwner      = MainHWindow;
  1887.    CF.Flags          = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
  1888.    CF.nFontType      = SCREEN_FONTTYPE;
  1889.    CF.lpLogFont      = &FontRec;
  1890.    CF.hInstance      = 0;
  1891.    
  1892.    // FontRec is not trashed in case of cancel
  1893.    
  1894.    ChooseFont(&CF);
  1895.    
  1896.    // show changes
  1897.    
  1898.    if (status_flag)
  1899.       {
  1900.       update_status_fontwieght();
  1901.       update_status_fontsize();
  1902.       update_status_fontname();
  1903.       }
  1904.    
  1905.    }
  1906.  
  1907. void TMyWindow::CMSetPenColor(RTMessage Msg)
  1908.    { 
  1909.    
  1910.    COLORREF TheColor;
  1911.    
  1912.    TheColor = pcolor;
  1913.    
  1914.    // if OK then make change
  1915.    
  1916.    if ( GetApplication()->ExecDialog(new TColorDialog(this, TheColor, "Pen Color")) == IDOK )
  1917.       {
  1918.       thepencolor(GetRValue(TheColor),GetGValue(TheColor),GetBValue(TheColor));
  1919.       save_color_pen();
  1920.       }
  1921.    
  1922.    }
  1923.  
  1924. void TMyWindow::CMSetFloodColor(RTMessage Msg)
  1925.    { 
  1926.    
  1927.    COLORREF TheColor;
  1928.    
  1929.    TheColor = fcolor;
  1930.    
  1931.    // if OK then make changes
  1932.    
  1933.    if ( GetApplication()->ExecDialog(new TColorDialog(this, TheColor, "Flood Color")) == IDOK )
  1934.       {
  1935.       thefloodcolor(GetRValue(TheColor),GetGValue(TheColor),GetBValue(TheColor));
  1936.       save_color_flood();
  1937.       }
  1938.    
  1939.    }
  1940.  
  1941. void TMyWindow::CMSetScreenColor(RTMessage Msg)
  1942.    { 
  1943.    
  1944.    COLORREF TheColor;
  1945.    
  1946.    TheColor = scolor;
  1947.    
  1948.    // if OK then make changes
  1949.    
  1950.    if ( GetApplication()->ExecDialog(new TColorDialog(this, TheColor, "Screen Color")) == IDOK )
  1951.       {
  1952.       thescreencolor(GetRValue(TheColor),GetGValue(TheColor),GetBValue(TheColor));
  1953.       save_color_screen();
  1954.       }
  1955.    
  1956.    }
  1957.  
  1958. void TMyWindow::CMHelp(RTMessage Msg)
  1959.    { 
  1960.    WinHelp(MainHWindow,szHelpFileName,HELP_INDEX,0L);
  1961.    }
  1962.  
  1963. void TMyWindow::CMHelpMCI(RTMessage Msg)
  1964.    { 
  1965.    WinHelp(MainHWindow,MCIHelpFileName,HELP_INDEX,0L);
  1966.    }
  1967.  
  1968. void TMyWindow::CMHelpHelp(RTMessage Msg)
  1969.    { 
  1970.    WinHelp(MainHWindow,"WINHELP.HLP",HELP_INDEX,0L);
  1971.    }
  1972.  
  1973. void TMyWindow::CMHelpAbout(RTMessage Msg)
  1974.    { 
  1975.    
  1976.    lpProcAbout = (DLGPROC)MakeProcInstance((FARPROC)About, ModulehInstance);
  1977.    DialogBox(ModulehInstance, "AboutBox", MainHWindow, lpProcAbout);
  1978.    FreeProcInstance((FARPROC)lpProcAbout);
  1979.    }
  1980.  
  1981. // Execute File:Print command
  1982.  
  1983. void TMyWindow::CMBitmapPrint(RTMessage Msg)
  1984.    {
  1985.    PTRulerOut Printout = 0;
  1986.    
  1987.    if ( Printer )
  1988.       {
  1989.       
  1990.       Printout = new TRulerOut("Logo Picture");
  1991.       if ( Printout )
  1992.          {
  1993.          // turned back on in 3.5
  1994. #ifdef ISWIN31
  1995.          Printout->SetBanding( TRUE ); // fails in 3.0?
  1996. #endif
  1997.          Printout->SetBanding( FALSE );
  1998.          Printer->Print(this, Printout);
  1999.          delete Printout;
  2000.          }
  2001.       }
  2002.    }
  2003.  
  2004. // Execute File:Printer-setup command
  2005.  
  2006. void TMyWindow::CMBitmapPrinterSetup(RTMessage Msg)
  2007.    {
  2008.    if ( Printer )
  2009.    Printer->Setup(this);
  2010.    }
  2011.  
  2012. void TMyWindow::DefWndProc( RTMessage msg )
  2013.    {
  2014.    RECT  wrect;
  2015.    char  szWinLocStr[WININISIZ];
  2016.    
  2017.    int   w, h;
  2018.    
  2019.    // if shutdown then get sizes for logo.ini
  2020.    
  2021.    if (msg.Message == WM_DESTROY)
  2022.       {
  2023.       
  2024.       // don't save sizes if iconed
  2025.       
  2026.       if (!IsIconic(MainHWindow))
  2027.          {
  2028.          // Get location and size of our window on the screen so we can
  2029.          // come back up in the same spot next time we are invoked.
  2030.          
  2031.          GetWindowRect(MainHWindow, (LPRECT) &wrect);
  2032.          w = wrect.right - wrect.left;
  2033.          h = wrect.bottom - wrect.top;
  2034.          
  2035.          // Make a string with our window location and size.
  2036.          sprintf(szWinLocStr, "%d,%d,%d,%d", wrect.left, wrect.top, w, h);
  2037.          
  2038.          // Save in WIN.INI file.
  2039.          WritePrivateProfileString(
  2040.          "LOGO",
  2041.          "Screen",
  2042.          szWinLocStr,
  2043.          "LOGO.INI");
  2044.          }
  2045.       }
  2046.    
  2047.    TWindow::DefWndProc( msg );
  2048.    }
  2049.  
  2050. void TMyWindow::WMLButtonDown(RTMessage msg)
  2051.    {
  2052.    callthing *callevent;
  2053.    
  2054.    // if user turned on mouse the queue up event
  2055.    
  2056.    if (mouse_on == 1)
  2057.       {
  2058.       callevent = new callthing;
  2059.       
  2060.       callevent->func = mouse_lbuttondown;
  2061.       callevent->arg1 = msg.LP.Lo;
  2062.       callevent->arg2 = msg.LP.Hi;
  2063.       callevent->kind = 1;
  2064.       
  2065.       calllists.insert(callevent,1);
  2066.       checkqueue();
  2067.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2068.       }
  2069.    }
  2070.  
  2071. void TMyWindow::WMLButtonUp(RTMessage msg)
  2072.    {
  2073.    callthing *callevent;
  2074.    
  2075.    // if user turned on mouse the queue up event
  2076.    
  2077.    if (mouse_on == 1)
  2078.       {
  2079.       callevent = new callthing;
  2080.       
  2081.       callevent->func = mouse_lbuttonup;
  2082.       callevent->arg1 = msg.LP.Lo;
  2083.       callevent->arg2 = msg.LP.Hi;
  2084.       callevent->kind = 1;
  2085.       
  2086.       calllists.insert(callevent,1);
  2087.       checkqueue();
  2088.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2089.       }
  2090.    
  2091.    }
  2092.  
  2093. void TMyWindow::WMRButtonDown(RTMessage msg)
  2094.    {
  2095.    callthing *callevent;
  2096.    
  2097.    // if user turned on mouse the queue up event
  2098.    
  2099.    if (mouse_on == 1)
  2100.       {
  2101.       callevent = new callthing;
  2102.       
  2103.       callevent->func = mouse_rbuttondown;
  2104.       callevent->arg1 = msg.LP.Lo;
  2105.       callevent->arg2 = msg.LP.Hi;
  2106.       callevent->kind = 1;
  2107.       
  2108.       calllists.insert(callevent,1);
  2109.       checkqueue();
  2110.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2111.       }
  2112.    
  2113.    }
  2114.  
  2115. void TMyWindow::WMRButtonUp(RTMessage msg)
  2116.    {
  2117.    callthing *callevent;
  2118.    
  2119.    // if user turned on mouse the queue up event
  2120.    
  2121.    if (mouse_on == 1)
  2122.       {
  2123.       callevent = new callthing;
  2124.       
  2125.       callevent->func = mouse_rbuttonup;
  2126.       callevent->arg1 = msg.LP.Lo;
  2127.       callevent->arg2 = msg.LP.Hi;
  2128.       callevent->kind = 1;
  2129.       
  2130.       calllists.insert(callevent,1);
  2131.       checkqueue();
  2132.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2133.       }
  2134.    
  2135.    }
  2136.  
  2137. void TMyWindow::WMMouseMove(RTMessage msg)
  2138.    {
  2139.    callthing *callevent;
  2140.    
  2141.    // if user turned on mouse the queue up event
  2142.    
  2143.    if (mouse_on == 1)
  2144.       {
  2145.       callevent = new callthing;
  2146.       
  2147.       callevent->func = mouse_mousemove;
  2148.       callevent->arg1 = msg.LP.Lo;
  2149.       callevent->arg2 = msg.LP.Hi;
  2150.       callevent->kind = 1;
  2151.       
  2152.       calllists.insert(callevent,1);
  2153.       checkqueue();
  2154.       //      PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2155.       }
  2156.    }
  2157.  
  2158. void TMyWindow::WMCheckQueue(RTMessage msg)
  2159.    {
  2160.    checkqueue();
  2161.    }
  2162.  
  2163. #ifdef ISWIN31
  2164. void TMyWindow::MMMCINotify(RTMessage msg)
  2165.    {
  2166.    // if user fired up a callback mci event the queue it up here
  2167.    
  2168.    callthing *callevent;
  2169.    
  2170.    callevent = new callthing;
  2171.    
  2172.    callevent->func = mci_callback;
  2173.    callevent->kind = 4;
  2174.    
  2175.    calllists.insert(callevent,4);
  2176.    
  2177.    PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2178.    }
  2179. #endif
  2180.  
  2181. void TMyWindow::WMTIMER(RTMessage msg)
  2182.    {
  2183.    // if user fired up a callback mci event the queue it up here
  2184.    
  2185.    callthing *callevent;
  2186.    
  2187.    callevent = new callthing;
  2188.    
  2189.    // the ID can only be 1-31 and select appropriate callback code
  2190.    
  2191.    callevent->func = timer_callback[msg.WParam];
  2192.    if (msg.WParam > 16)
  2193.       {
  2194.       callevent->kind = 3;
  2195.       calllists.insert(callevent,3);
  2196.       }
  2197.    else
  2198.       {
  2199.       callevent->kind = 4;
  2200.       calllists.insert(callevent,4);
  2201.       }
  2202.    
  2203.    PostMessage(MainHWindow, WM_CHECKQUEUE, 0, 0);
  2204.    }
  2205.  
  2206. void checkwindow(int *x,int *y, int *w, int *h)
  2207.    {
  2208.    
  2209.    // sanity check window coordinates
  2210.    
  2211.    if (*x < 0) *x = 0;
  2212.    if (*y < 0) *y = 0;
  2213.    if (*w > MaxWidth) *w = MaxWidth;
  2214.    if (*h > MaxHeight) *h = MaxHeight;
  2215.    if ((*x+*w) > MaxWidth) *x = *x - (*x+*w-MaxWidth);
  2216.    if ((*y+*h) > MaxHeight) *y = *y - (*y+*h-MaxHeight);
  2217.    }
  2218.