home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / delphi / imagelib / imgvw2.cp_ / imgvw2.cp
Text File  |  1995-09-29  |  19KB  |  818 lines

  1. #include <owl\owlpch.h>
  2. #pragma hdrstop
  3. #include <owl\framewin.h>
  4. #include <owl\scroller.h>
  5. #include <owl\opensave.h>
  6. #include <string.h>
  7. #include <dir.h>
  8. #include <time.h>
  9. #include <stdio.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <sys\stat.h>
  13. #include "viewdlg.h"
  14. #include "imagevw.h"
  15. #include "imglib30.h"
  16.  
  17. #define MAXAPPNAME  20
  18. #define JPG 1
  19. #define PCX 2
  20. #define GIF 3
  21. #define BMP 4
  22. #define PNG 5
  23.  
  24. static const char AppName[] = "ImgView2";
  25. TGaugeDialog* Gdlg;
  26. TGauge2Dialog* Gdlg2;
  27. short Callback(int i)
  28.  {
  29.     return Gdlg->SetValue(i);
  30.   };
  31. short Callback2(int i)
  32.  {
  33.     return Gdlg2->SetValue(i);
  34.  };
  35.  
  36.  
  37. class TViewWindow : virtual public TWindow {
  38.   public:
  39.         char      FileName[MAXPATH];
  40.         TBitmap*  Bitmap;
  41.         TPalette* Palette;
  42.         TBrush*   BkgndBrush;
  43.         long      Rop;
  44.         int       PixelWidth;
  45.         int       PixelHeight;
  46.         WORD      Colors;
  47.         BOOL      Fit;
  48.  
  49.         TViewWindow();
  50.       ~TViewWindow();
  51.  
  52.   protected:
  53.         void      CmOpenJpg();
  54.         void      CmOpenBmp();
  55.         void      CmOpenGif();
  56.         void      CmOpenPcx();
  57.         void      CmOpenPng();
  58.         void      CmImageInfo();
  59.         void      CmFit();
  60.         void      CeFit(TCommandEnabler& ce);
  61.  
  62.         void      Paint(TDC&, BOOL erase, TRect&);
  63.         void      EvSize(UINT sizeType, TSize&);
  64.  
  65.         void      EvPaletteChanged(HWND hWndPalChg);
  66.         BOOL      EvQueryNewPalette();
  67.         void      EvSetFocus(HWND); // should use above when working
  68.         void      EvDestroy();
  69.  
  70.         BOOL      UpdatePalette(BOOL alwaysRepaint);
  71.         void      AdjustScroller();
  72.         void      SetCaption(const char*);
  73.         void      CmSaveToJpg();
  74.         void      CmSaveToBmp();
  75.         void      CmSaveToPng();
  76.         void      CmSaveToGif();
  77.         void      CmSaveToPcx();
  78.         int       ReadFile(const char * filename, const char * filetitle, int type);
  79.         int       WriteFile(const char * filename, int type);
  80.   private:
  81.         DecTransfer DecBuffer;
  82.         ComTransfer ComBuffer;
  83.         EncTransfer EncBuffer;
  84.  
  85.   DECLARE_RESPONSE_TABLE(TViewWindow);
  86. };
  87.  
  88. DEFINE_RESPONSE_TABLE1(TViewWindow, TWindow)
  89.   EV_COMMAND(CM_OPENJPG, CmOpenJpg),
  90.   EV_COMMAND(CM_OPENBMP, CmOpenBmp),
  91.   EV_COMMAND(CM_OPENGIF, CmOpenGif),
  92.   EV_COMMAND(CM_OPENPCX, CmOpenPcx),
  93.   EV_COMMAND(CM_OPENPNG, CmOpenPng),
  94.   EV_COMMAND(CM_INFO, CmImageInfo),
  95.   EV_COMMAND(CM_FIT, CmFit),
  96.   EV_COMMAND(CM_SAVETOJPG, CmSaveToJpg),
  97.   EV_COMMAND(CM_SAVETOBMP, CmSaveToBmp),
  98.   EV_COMMAND(CM_SAVETOPNG, CmSaveToPng),
  99.   EV_COMMAND(CM_SAVETOGIF, CmSaveToGif),
  100.   EV_COMMAND(CM_SAVETOPCX, CmSaveToPcx),
  101.   EV_COMMAND_ENABLE(CM_FIT, CeFit),
  102.   EV_WM_SIZE,
  103.   EV_WM_PALETTECHANGED,
  104.   EV_WM_QUERYNEWPALETTE,
  105.   EV_WM_SETFOCUS,
  106.   EV_WM_DESTROY,
  107. END_RESPONSE_TABLE;
  108.  
  109. //
  110. // Constructor for a TViewWindow, sets scroll styles andconstructs
  111. // the Scroller object.  Also sets the Rop based on whether thedisplay
  112. // is monochrome (two-color) or polychrome.
  113. //
  114. TViewWindow::TViewWindow()
  115.   : TWindow(0, 0, 0)
  116. {
  117.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  118.   Bitmap = 0;
  119.   Palette = 0;
  120.   BkgndBrush = new TBrush(::GetSysColor(COLOR_WINDOW));
  121.   Scroller = new TScroller(this, 1, 1, 200, 200);
  122.   Fit = FALSE;
  123.  
  124.   TScreenDC screenDC;
  125.   if (screenDC.GetDeviceCaps(NUMCOLORS) < 3 )
  126.      Rop = NOTSRCCOPY;
  127.   else
  128.      Rop = SRCCOPY;
  129.   memset(&DecBuffer, 0, sizeof(DecBuffer));
  130.   DecBuffer.Res8But = BF_CHECKED;
  131.   DecBuffer.Scl1But = BF_CHECKED;
  132.   DecBuffer.Rad1DBut = BF_CHECKED;
  133.   memset(&EncBuffer, 0, sizeof(EncBuffer));
  134.   EncBuffer.Res8But = BF_CHECKED;
  135.   memset(&ComBuffer, 0, sizeof(ComBuffer));
  136.   strcpy(ComBuffer.Cquality, "75");
  137.   strcpy(ComBuffer.Csmooth, "00");
  138.  
  139.   SetCaption(0);
  140. }
  141.  
  142. TViewWindow::~TViewWindow()
  143. {
  144.   delete Bitmap;
  145.   delete Palette;
  146.   delete BkgndBrush;
  147.   delete Scroller;
  148. }
  149.  
  150. //
  151. // Build up a caption based on a filename, and set it into the title.
  152. //
  153. void
  154. TViewWindow::SetCaption(const char* name)
  155. {
  156.   char caption[MAXPATH + MAXAPPNAME + 2 + 1];
  157.   strcpy(FileName, name ? name : "(Untitled)");
  158.   strcpy(caption, GetApplication()->GetName());
  159.   strcat(caption, " - ");
  160.   strcat(caption, FileName);
  161.   if (Parent)
  162.      Parent->SetCaption(caption);
  163. }
  164.  
  165. //
  166. // Toggle Fit member variable & adjust scroller as needed
  167. //
  168. void
  169. TViewWindow::CmFit()
  170. {
  171.   Fit = !Fit;
  172.   AdjustScroller();
  173. }
  174.  
  175. //
  176. // The fit menu item is checked if the Fit member is true
  177. //
  178. void
  179. TViewWindow::CeFit(TCommandEnabler& ce)
  180. {
  181.   ce.SetCheck(Fit ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  182. }
  183.  
  184. int TViewWindow::ReadFile(const char * filename, const char * filetitle, int type)
  185. {
  186.   int resolution, option, scale, res;
  187.   unsigned int hddb, hpal;
  188.   char message[40];
  189.  
  190.   // If type equal JPEG then get input parameters
  191.   TDecDialog* pDlg = new TDecDialog(this, &DecBuffer);
  192.   if (pDlg->Execute() != IDOK)
  193.         // leave
  194.   return 0;
  195.  
  196.   SetCursor(0, IDC_WAIT);
  197.   delete Bitmap;
  198.   delete Palette;
  199.   // Set Bitmap output resolution  - 24, 8, or 4 bit
  200.   if (DecBuffer.Res24But == BF_CHECKED)
  201.      resolution = 24;
  202.   else if (DecBuffer.Res8But == BF_CHECKED)
  203.      resolution = 8;
  204.   else
  205.      resolution = 4;
  206.  
  207.   // Set Color Quantization and dithering methods for output.
  208.   // This is used if Resolution != 24
  209.  
  210.   if (DecBuffer.Rad1But == BF_CHECKED)
  211.      option = 0;
  212.   else
  213.      option = 1;
  214.  
  215.   // Set output Bitmap scale factor either 1/1, 1/2, 1/4, or 1/8
  216.   // of origional size
  217.   if (DecBuffer.Scl1But == BF_CHECKED)
  218.      scale = 1;
  219.   else if (DecBuffer.Scl2But == BF_CHECKED)
  220.      scale = 2;
  221.   else if (DecBuffer.Scl4But == BF_CHECKED)
  222.      scale = 4;
  223.   else
  224.      scale = 8;
  225.  
  226.   // Show progress display modaless dialog box
  227.   if (type == 1)
  228.      sprintf(message, "Decompressing JPG File");
  229.   else if (type == 2)
  230.      sprintf(message, "Decompressing PCX File");
  231.   else if (type == 3)
  232.      sprintf(message, "Decompressing GIF File");
  233.   else if (type == 5)
  234.     sprintf(message, "Decompressing PNG File");
  235.   else
  236.      sprintf(message, "Decompressing BMP File");
  237.   Gdlg = new TGaugeDialog(this);
  238.   Gdlg->SetCaption(message);
  239.   Gdlg->Create();
  240.  
  241.   // password variable - the code is given when you register
  242.   int password = 0;
  243.   res = 0;
  244.   // call the DLL function to read the image in global memory
  245.   switch (type)
  246.     {
  247.      case 1:
  248.         res = readjpgfile(filename, resolution, scale, option, password,
  249.                           &hddb, &hpal, Callback, 1);
  250.         break;
  251.      case 2:
  252.         res = readpcxfile(filename, resolution, option, password,
  253.                                 &hddb, &hpal, Callback, 1);
  254.         break;
  255.      case 3:
  256.         res = readgiffile(filename, resolution, option, password,
  257.                           &hddb, &hpal, Callback, 1);
  258.         break;
  259.      case 4:
  260.         res = readbmpfile(filename, resolution, option, password,
  261.                           &hddb, &hpal, Callback, 1);
  262.         break;
  263.      case 5:
  264.         res = readpngfile(filename, resolution, option, password, &hddb,
  265.                           &hpal, Callback, 1);
  266.       break;
  267.     }
  268.  
  269.   // destroy progress display dialog and free global memory
  270.   Gdlg->Destroy();
  271.   delete Gdlg;
  272.   SetCursor(0, IDC_ARROW);
  273.  
  274.   // if success set Bitmap and Palette for Painting
  275.   if (res != 1)
  276.      return 0;
  277.  
  278.  
  279.   Palette = new TPalette((HPALETTE)hpal, AutoDelete);
  280.   Bitmap = new TBitmap((HBITMAP)hddb, AutoDelete);
  281.   PixelWidth = Bitmap->Width();
  282.   PixelHeight = Bitmap->Height();
  283.   UpdatePalette(TRUE);
  284.   AdjustScroller();
  285.   SetCaption(filetitle);
  286.   return 1;
  287. }
  288.  
  289.  
  290. void
  291. TViewWindow::CmOpenJpg()
  292. {
  293.   TOpenSaveDialog::TData data (
  294.         OFN_FILEMUSTEXIST,
  295.         "JPEG Files (*.JPG)|*.jpg|",
  296.         0,
  297.         "",
  298.         "JPG"
  299.   );
  300.   int res = 0;
  301.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  302.   if (tmpdlg->Execute() == IDOK)
  303.     {
  304.      char fileTitle[MAXPATH];
  305.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  306.      res = ReadFile(data.FileName, fileTitle, 1);
  307.      if (!res)
  308.         MessageBox("Error Opening JPG File", "Error", MB_ICONSTOP | MB_OK);
  309.     }
  310.   delete tmpdlg;
  311. }
  312.  
  313. void
  314. TViewWindow::CmOpenGif()
  315. {
  316.   TOpenSaveDialog::TData data (
  317.         OFN_FILEMUSTEXIST,
  318.         "GIF Files (*.GIF)|*.gif|",
  319.         0,
  320.         "",
  321.         "GIF"
  322.   );
  323.   int res = 0;
  324.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  325.   if (tmpdlg->Execute() == IDOK)
  326.     {
  327.      char fileTitle[MAXPATH];
  328.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  329.      res = ReadFile(data.FileName, fileTitle, 3);
  330.      if (!res)
  331.         MessageBox("Error Opening GIF File", "Error", MB_ICONSTOP | MB_OK);
  332.     }
  333.   delete tmpdlg;
  334. }
  335.  
  336. void
  337. TViewWindow::CmOpenPcx()
  338. {
  339.   TOpenSaveDialog::TData data (
  340.         OFN_FILEMUSTEXIST,
  341.         "PCX Files (*.PCX)|*.pcx|",
  342.         0,
  343.         "",
  344.         "PCX"
  345.   );
  346.   int res = 0;
  347.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  348.   if (tmpdlg->Execute() == IDOK)
  349.     {
  350.      char fileTitle[MAXPATH];
  351.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  352.      res = ReadFile(data.FileName, fileTitle, 2);
  353.      if (!res)
  354.         MessageBox("Error Opening PCX File", "Error", MB_ICONSTOP | MB_OK);
  355.     }
  356.   delete tmpdlg;
  357. }
  358.  
  359. void
  360. TViewWindow::CmOpenPng()
  361. {
  362.   TOpenSaveDialog::TData data (
  363.         OFN_FILEMUSTEXIST,
  364.         "PNG Files (*.PNG)|*.png|",
  365.         0,
  366.         "",
  367.         "PNG"
  368.   );
  369.   int res = 0;
  370.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  371.   if (tmpdlg->Execute() == IDOK)
  372.     {
  373.      char fileTitle[MAXPATH];
  374.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  375.      res = ReadFile(data.FileName, fileTitle, 5);
  376.      if (!res)
  377.         MessageBox("Error Opening PNG File", "Error", MB_ICONSTOP | MB_OK);
  378.     }
  379.   delete tmpdlg;
  380. }
  381.  
  382. void
  383. TViewWindow::CmOpenBmp()
  384. {
  385.   TOpenSaveDialog::TData data (
  386.         OFN_FILEMUSTEXIST,
  387.         "Bitmap Files (*.BMP)|*.bmp|",
  388.         0,
  389.         "",
  390.         "BMP"
  391.   );
  392.   int res = 0;
  393.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  394.   if (tmpdlg->Execute() == IDOK)
  395.     {
  396.      char fileTitle[MAXPATH];
  397.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  398.      res = ReadFile(data.FileName, fileTitle, 4);
  399.      if (!res)
  400.         MessageBox("Error Opening BMP File", "Error", MB_ICONSTOP | MB_OK);
  401.     }
  402.   delete tmpdlg;
  403. }
  404.  
  405. void TViewWindow::CmSaveToBmp()
  406. {
  407.  TOpenSaveDialog::TData bmpdata (
  408.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  409.         "Bmp Files (*.BMP)|*.BMP|",
  410.         0,
  411.         0,
  412.         "*.bmp"
  413.       );
  414.  int res = 0;
  415.  if (Bitmap)
  416.   {
  417.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,bmpdata);
  418.     if (tmpdlg->Execute() == IDOK)
  419.      {
  420.       res = WriteFile(bmpdata.FileName, 4);
  421.       if (!res)
  422.          MessageBox("Error Writing BMP File", "Error", MB_ICONSTOP | MB_OK);
  423.      }
  424.     delete tmpdlg;
  425.   }
  426.     else
  427.       MessageBox("No Image Loaded!", "Error Writing BMP", MB_OK);
  428. }
  429.  
  430. void TViewWindow::CmSaveToJpg()
  431. {
  432.  TOpenSaveDialog::TData jpgdata (
  433.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  434.         "Jpg Files (*.JPG)|*.JPG|",
  435.         0,
  436.         0,
  437.         "*.jpg"
  438.       );
  439.  int res = 0;
  440.  if (Bitmap)
  441.   {
  442.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  443.     if (tmpdlg->Execute() == IDOK)
  444.      {
  445.       res = WriteFile(jpgdata.FileName, 1);
  446.       if (!res)
  447.          MessageBox("Error Writing JPG File", "Error", MB_ICONSTOP | MB_OK);
  448.      }
  449.     delete tmpdlg;
  450.   }
  451.     else
  452.       MessageBox("No Image Loaded!", "Error Writing JPG", MB_OK);
  453. }
  454.  
  455. void TViewWindow::CmSaveToPng()
  456. {
  457.  TOpenSaveDialog::TData jpgdata (
  458.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  459.         "Png Files (*.PNG)|*.PNG|",
  460.         0,
  461.         0,
  462.         "*.png"
  463.       );
  464.  int res = 0;
  465.  if (Bitmap)
  466.   {
  467.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  468.     if (tmpdlg->Execute() == IDOK)
  469.      {
  470.       res = WriteFile(jpgdata.FileName, 5);
  471.       if (!res)
  472.          MessageBox("Error Writing PNG File", "Error", MB_ICONSTOP | MB_OK);
  473.      }
  474.     delete tmpdlg;
  475.   }
  476.     else
  477.       MessageBox("No Image Loaded!", "Error Writing PNG", MB_OK);
  478. }
  479.  
  480. void TViewWindow::CmSaveToGif()
  481. {
  482.  TOpenSaveDialog::TData jpgdata (
  483.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  484.         "Gif Files (*.GIF)|*.GIF|",
  485.         0,
  486.         0,
  487.         "*.gif"
  488.       );
  489.  int res = 0;
  490.  if (Bitmap)
  491.   {
  492.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  493.     if (tmpdlg->Execute() == IDOK)
  494.      {
  495.       res = WriteFile(jpgdata.FileName, 3);
  496.       if (!res)
  497.          MessageBox("Error Writing GIF File", "Error", MB_ICONSTOP | MB_OK);
  498.      }
  499.     delete tmpdlg;
  500.   }
  501.     else
  502.       MessageBox("No Image Loaded!", "Error Writing GIF", MB_OK);
  503. }
  504.  
  505. void TViewWindow::CmSaveToPcx()
  506. {
  507.  TOpenSaveDialog::TData jpgdata (
  508.         OFN_HIDEREADONLY|OFN_NOREADONLYRETURN,
  509.         "Pcx Files (*.PCX)|*.PCX|",
  510.         0,
  511.         0,
  512.         "*.pcx"
  513.       );
  514.  int res = 0;
  515.  if (Bitmap)
  516.   {
  517.     TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,jpgdata);
  518.     if (tmpdlg->Execute() == IDOK)
  519.      {
  520.       res = WriteFile(jpgdata.FileName, 2);
  521.       if (!res)
  522.          MessageBox("Error Writing PCX File", "Error", MB_ICONSTOP | MB_OK);
  523.      }
  524.     delete tmpdlg;
  525.   }
  526.     else
  527.       MessageBox("No Image Loaded!", "Error Writing PCX", MB_OK);
  528. }
  529.  
  530. int TViewWindow::WriteFile(const char * filename, int type)
  531. {
  532.     HBITMAP hddb;
  533.     HPALETTE hpal;
  534.     int ret = 0;
  535.     int quality, smooth, resolution;
  536.     char message[20];
  537.     if (type == 1)
  538.      {
  539.       TComDialog* pDlg = new TComDialog(this, &ComBuffer);
  540.  
  541.       // Display the options for writing a JPEG file
  542.       if (pDlg->Execute() != IDOK)
  543.         {
  544.          delete pDlg;
  545.          return 0;
  546.         }
  547.       // Set the quality of the JPEG image.  A higher quality
  548.       // yields a better JPEG image that takes more space.
  549.  
  550.       sscanf(ComBuffer.Cquality, "%d", &quality);
  551.  
  552.       // Set a smoothing factor on the JPEG image.
  553.       sscanf(ComBuffer.Csmooth, "%d", &smooth);
  554.      }
  555.     else
  556.      {
  557.       TEncDialog* pDlg = new TEncDialog(this, &EncBuffer);
  558.       if (pDlg->Execute() != IDOK)
  559.          // leave
  560.          return 0;
  561.  
  562.       SetCursor(0, IDC_WAIT);
  563.  
  564.       // Set Bitmap output resolution  - 24, 8, or 4 bit
  565.       if (EncBuffer.Res24But == BF_CHECKED)
  566.          resolution = 24;
  567.       else if (EncBuffer.Res8But == BF_CHECKED)
  568.          resolution = 8;
  569.       else
  570.          resolution = 4;
  571.      }
  572.     SetCursor(0, IDC_WAIT);
  573.  
  574.     hddb = *Bitmap;
  575.     hpal = *Palette;
  576.  
  577.     Gdlg2 = new TGauge2Dialog(this);
  578.     if (type == 1)
  579.       sprintf(message, "Creating JPEG File");
  580.     else if (type == 2)
  581.      sprintf(message, "Creating PCX File");
  582.     else if (type == 3)
  583.       sprintf(message, "Creating GIF FIle");
  584.     else if (type == 4)
  585.       sprintf(message, "Creating BMP File");
  586.     else
  587.       sprintf(message, "Creating PNG File");
  588.     Gdlg2->SetCaption(message);
  589.     Gdlg2->Create();
  590.  
  591.     switch (type)
  592.      {
  593.       case 1:
  594.          ret = writejpegfile(filename, quality, smooth, 0,
  595.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 1);
  596.          break;
  597.       case 2:
  598.          ret = writepcxfile(filename, resolution, 0,
  599.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 1);
  600.          break;
  601.       case 3:
  602.          ret = writegiffile(filename, resolution, 0,
  603.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 1);
  604.          break;
  605.       case 4:
  606.          ret = writebmpfile(filename, resolution, 0,
  607.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 1);
  608.          break;
  609.       case 5:
  610.          ret = writepngfile(filename, resolution, 1, 0,
  611.                             (unsigned int)hddb, (unsigned int)hpal, Callback2, 1);
  612.          break;
  613.      }
  614.  
  615.     Gdlg2->Destroy();
  616.     delete Gdlg2;
  617.     if (ret == 1)
  618.      {
  619.      }
  620.     else
  621.       MessageBox("Error creating File", "Error", MB_OK);
  622.     SetCursor(0, IDC_ARROW);
  623.     if (ret == 1)
  624.       return 1;
  625.     else
  626.       return 0;
  627. }
  628.  
  629. //
  630. // Adjust the Scroller range so that the the origin is the
  631. // upper-most scrollable point and the corner is the
  632. // bottom-most.
  633. //
  634. void
  635. TViewWindow::AdjustScroller()
  636. {
  637.   TRect  clientRect = GetClientRect();
  638.  
  639.   // only show scrollbars when image is larger than
  640.   // the client area and we are not stretching to fit.
  641.   //
  642.   if (Fit)
  643.      Scroller->SetRange(0, 0);
  644.  
  645.   else
  646.     {
  647.      TPoint Range(Max(PixelWidth-clientRect.Width(), 0),
  648.                                     Max(PixelHeight-clientRect.Height(),0));
  649.      Scroller->SetRange(Range.x, Range.y);
  650.     }
  651.   Scroller->ScrollTo(0, 0);
  652.   if (!GetUpdateRect(clientRect, FALSE))
  653.      Invalidate(FALSE);
  654. }
  655.  
  656. //
  657. // Reset scroller range.
  658. //
  659. void
  660. TViewWindow::EvSize(UINT SizeType, TSize& Size)
  661. {
  662.   TWindow::EvSize(SizeType, Size);
  663.   if (SizeType != SIZEICONIC)
  664.     {
  665.      AdjustScroller();
  666.      Invalidate(FALSE);
  667.     }
  668. }
  669.  
  670. //
  671. // Somebody changed the palette. If its not us, then we need toupdate.
  672. //
  673. void
  674. TViewWindow::EvPaletteChanged(HWND hWndPalChg)
  675. {
  676.   if (hWndPalChg != HWindow)
  677.      UpdatePalette(TRUE);    // pass FALSE to UpdateColors()instead of repaint
  678. }
  679.  
  680. //
  681. // We need to re-realize the logical palette each time
  682. // we regain the input focus
  683. //
  684. BOOL
  685. TViewWindow::EvQueryNewPalette()
  686. {
  687.   return UpdatePalette(TRUE);
  688. }
  689.  
  690. //
  691. // Use this message temporarily until the palette msgs get routedto us
  692. //
  693. void
  694. TViewWindow::EvSetFocus(HWND)
  695. {
  696.   UpdatePalette(TRUE);
  697. }
  698.  
  699. void
  700. TViewWindow::EvDestroy()
  701. {
  702.   TWindow::EvDestroy();
  703. }
  704.  
  705. BOOL
  706. TViewWindow::UpdatePalette(BOOL alwaysRepaint)
  707. {
  708.   if (Palette)
  709.     {
  710.      TClientDC clientDC(*this);
  711.      #if !defined(__WIN32__)
  712.         Palette->UnrealizeObject();
  713.      #endif
  714.      clientDC.SelectObject(*Palette, FALSE);
  715.      if (alwaysRepaint)
  716.         Invalidate(FALSE);
  717.      else
  718.         clientDC.UpdateColors();
  719.      return TRUE;
  720.     }
  721.   return FALSE;
  722. }
  723.  
  724. void
  725. TViewWindow::Paint(TDC& dc, BOOL, TRect&)
  726. {
  727.   TRect clientRect = GetClientRect();
  728.   dc.SelectObject(*BkgndBrush);
  729.  
  730.   if (Bitmap)
  731.     {
  732.      TMemoryDC memoryDC(dc);
  733.      memoryDC.SelectObject(*Bitmap);
  734.      dc.SetStretchBltMode(COLORONCOLOR);
  735.      if (Palette)
  736.       {
  737.         dc.SelectObject(*Palette, FALSE);
  738.         dc.RealizePalette();
  739.         memoryDC.SelectObject(*Palette, FALSE);
  740.       }
  741.  
  742.      TRect imageRect(0,0, PixelWidth, PixelHeight);
  743.      if (Parent->IsIconic())
  744.       {
  745.         dc.StretchBlt(Parent->GetClientRect(), memoryDC,imageRect, Rop);
  746.       }
  747.      else
  748.       {
  749.         clientRect += TPoint((int)Scroller->XPos,(int)Scroller->YPos);
  750.         if (Fit)
  751.           dc.StretchBlt(clientRect, memoryDC,imageRect, Rop);
  752.         else
  753.           dc.BitBlt(imageRect, memoryDC, TPoint(0,0), Rop);
  754.         // Clear borders here for no flicker
  755.         //
  756.         if (!Fit)
  757.          {
  758.           dc.PatBlt(TRect(TPoint(PixelWidth,0),clientRect.BottomRight()));
  759.           dc.PatBlt(TRect(TPoint(0,PixelHeight),clientRect.BottomRight()));
  760.        }
  761.       }
  762.     }
  763.   else
  764.     dc.PatBlt(clientRect, PATCOPY);
  765. }
  766.  
  767.  
  768. void
  769. TViewWindow::CmImageInfo()
  770. {
  771.   TOpenSaveDialog::TData data (
  772.         OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN,
  773.         "Image Files (*.*)|*.*|",
  774.         0,
  775.         "",
  776.         ""
  777.   );
  778.   int result, width, height, numcolors, bitspixel, planes;
  779.   char filetype[20], filecomp[20];
  780.   char message[300];
  781.   TFileOpenDialog *tmpdlg = new TFileOpenDialog(this,data);
  782.   if (tmpdlg->Execute() == IDOK)
  783.     {
  784.      char fileTitle[MAXPATH];
  785.      TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle,MAXPATH);
  786.      result = fileinfo(data.FileName, filetype, &width, &height, &bitspixel,
  787.                              &planes, &numcolors, filecomp, 1);
  788.      if (result == 1)
  789.       {
  790.         sprintf(message, "%s %s\nw: %d h: %d\nbits per pixel: %d planes: %d\n colors: %d",
  791.                         filetype, filecomp, width, height, bitspixel, planes, numcolors);
  792.         MessageBox(message, fileTitle, MB_ICONINFORMATION | MB_OK);
  793.       }
  794.     }
  795.   delete tmpdlg;
  796. }
  797.  
  798. //----------------------------------------------------------------------------
  799.  
  800. class TViewApp : public TApplication {
  801.   public:
  802.         TViewApp(const char far* name) : TApplication(name) {}
  803.         void InitMainWindow()
  804.          {
  805.           MainWindow = new TFrameWindow(0, Name, new TViewWindow);
  806.           MainWindow->AssignMenu(JPGMENU);
  807.           MainWindow->SetIcon(this, JPGVIEW);
  808.          }
  809. };
  810.  
  811. //----------------------------------------------------------------------------
  812.  
  813. int
  814. OwlMain(int /*argc*/, char* /*argv*/ [])
  815. {
  816.   return TViewApp(AppName).Run();
  817. }
  818.