home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / gotch175.zip / src / savebmp.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  21KB  |  652 lines

  1. /***
  2.  This file belongs to the Gotcha! distribution.
  3.  Copyright (C) 1998-2002 Thorsten Thielen <thth@gmx.net>
  4.  
  5.  This program is free software; you can redistribute it and/or modify
  6.  it under the terms of the GNU General Public License as published by
  7.  the Free Software Foundation; either version 2 of the License, or
  8.  (at your option) any later version.
  9.  
  10.  This program is distributed in the hope that it will be useful,
  11.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  GNU General Public License for more details.
  14.  
  15.  You should have received a copy of the GNU General Public License
  16.  along with this program; if not, write to the Free Software
  17.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  ***/
  19.  
  20. // ** SaveBitmap ********************************************************** /*FOLD00*/
  21.  
  22. VOID SaveBitmap (HBITMAP hbm, HPS hps)
  23. {
  24. #ifdef _DOLOGMEM_
  25.     LogMem("SaveBitmap", TRUE);
  26. #endif
  27.  
  28.     if( pset->QueryFileSaveStyle () == FSS_FORCEFILE )
  29.     {
  30.         PSZ psz = pset->QueryForceSaveFile();
  31.         psz = AddExtensionToFilename( psz );
  32.         SaveBitmapToFile( hbm, psz, hps );
  33. #ifdef _DOLOGMEM_
  34.         LogMem( "SaveBitmap-1", FALSE );
  35. #endif
  36.         return;
  37.     }
  38.  
  39.     if (pset->DoSound ())
  40.     {
  41.         DosBeep ( 500, 100);
  42.         DosBeep (1000, 100);
  43.         DosBeep (1500, 100);
  44.     }
  45.  
  46.     switch (pset->QuerySaveStyle ())
  47.     {
  48.     case SAVESTYLE_CLIPBOARD:
  49.         SaveBitmapToClipboard (hbm);
  50.         break;
  51.  
  52.     default:
  53. #ifdef _DOLOGDEBUG_
  54.         LogDebug( "SaveBitmap()" );
  55. #endif
  56.         if (SelectSaveFile ()) {
  57. #ifdef _DOLOGDEBUG_
  58.             LogDebug( "Before call to SaveBitmapToFile()" );
  59. #endif
  60.             SaveBitmapToFile (hbm, pset->QuerySaveFile (), hps);
  61. #ifdef _DOLOGDEBUG_
  62.             LogDebug( "After call to SaveBitmapToFile()" );
  63. #endif
  64.         }
  65.         break;
  66.     }
  67.  
  68. #ifdef _DOLOGMEM_
  69.     LogMem("SaveBitmap-2", FALSE);
  70. #endif
  71. }
  72.  
  73. // ** SaveBitmapToClipboard *********************************************** /*FOLD00*/
  74.  
  75. VOID SaveBitmapToClipboard (HBITMAP hbm)
  76. {
  77. #ifdef _DOLOGMEM_
  78.     LogMem("SaveBitmapToClipboard", TRUE);
  79. #endif
  80.     // copy the thing to the clipboard
  81.     WinOpenClipbrd (hab);
  82.     WinEmptyClipbrd (hab);
  83.     WinSetClipbrdData (hab, ULONG (hbm), CF_BITMAP, CFI_HANDLE);
  84.     WinCloseClipbrd (hab);
  85. #ifdef _DOLOGMEM_
  86.     LogMem("SaveBitmapToClipboard", FALSE);
  87. #endif
  88. }
  89.  
  90. // ** SaveBitmapToFile **************************************************** /*FOLD00*/
  91.  
  92. #define CB_12HEADER       sizeof (BITMAPINFOHEADER) // == 12
  93. #define CB_16HEADER       (sizeof (BITMAPINFOHEADER2)-24)
  94. #define CB_20HEADER       sizeof (BITMAPINFOHEADER2) // == 64
  95.  
  96. VOID SaveBitmapToFile (HBITMAP hbm, PSZ psz, HPS hps)
  97. {
  98.     ULONG rc;
  99.  
  100. #ifdef _DOLOGMEM_
  101.     LogMem("SaveBitmapToFile", TRUE);
  102. #endif
  103. #ifdef _DOLOGDEBUG_
  104.     LogDebug( "Start of SaveBitmapToFile()" );
  105. #endif
  106.     // get the fullsized bitmap info header from the bitmap
  107.     BITMAPINFOHEADER2  bih2;
  108.  
  109.     bih2.cbFix = sizeof (BITMAPINFOHEADER2);
  110.     if (! GpiQueryBitmapInfoHeader (hbm, &bih2))
  111.     {
  112. #ifdef _DOLOGDEBUG_
  113.         LogDebug( "SaveBitmapToFile(): Exit GpiQueryBitmapInfoHeader" );
  114. #endif
  115.         DisplayError (RSTR(IDS_HEADER_ERROR),
  116.                       RSTR(IDS_ERROR_COULDNOTRETRIEVEHEADER),
  117.                       WinGetLastError (hab));
  118.         return;
  119.     }
  120. #ifdef _DOLOGDEBUG_
  121.     LogDebug( "SaveBitmapToFile(): GpiQueryBitmapInfoHeader ok." );
  122. #endif
  123.  
  124.     // get the size of the colortable
  125.     ULONG   cbColtab = 0L, cColors = 0L;
  126.  
  127.     if (bih2.cBitCount == 8)
  128.         cColors = 256L;
  129.     else if (bih2.cBitCount == 4)
  130.         cColors = 16L;
  131.     else if (bih2.cBitCount == 1)
  132.         cColors = 2L;
  133.  
  134.     cbColtab = cColors * sizeof( RGB2 );
  135.  
  136.     // get size of bits buffer and allocate it
  137.     ULONG cbBits =
  138.         (bih2.cBitCount * bih2.cx + 31L)/32L * bih2.cPlanes * 4L * bih2.cy;
  139.     PBYTE pb =
  140.         PBYTE (malloc (cbBits));
  141.  
  142.     // allocate and init the file info header
  143.     PBITMAPFILEHEADER2 pbfh2 =
  144.         PBITMAPFILEHEADER2 (malloc (sizeof (BITMAPFILEHEADER2)+cbColtab));
  145. #ifdef _DOLOGDEBUG_
  146.     LogDebug( "SaveBitmapToFile(): Filling header." );
  147. #endif
  148.  
  149.     // fill the bitmap header with the bitmap data
  150.     memcpy (&(pbfh2->bmp2), &bih2, sizeof (BITMAPINFOHEADER2));
  151.     pbfh2->bmp2.cbImage = cbBits;
  152.  
  153. #ifdef _DOLOGDEBUG_
  154.     LogDebug( "SaveBitmapToFile(): Before GpiQueryBitmapBits." );
  155. #endif
  156.     // grab the bits!! ;-) - and the colortable
  157.     if (GpiQueryBitmapBits (hps, 0, bih2.cy, pb, PBITMAPINFO2 (&(pbfh2->bmp2)))
  158.         == GPI_ALTERROR)
  159.     {
  160. #ifdef _DOLOGDEBUG_
  161.         LogDebug( "SaveBitmapToFile(): Exit GpiQueryBitmapBits" );
  162. #endif
  163.         DisplayError (RSTR(IDS_HEADER_ERROR),
  164.                       RSTR(IDS_ERROR_COULDNOTGETBITMAPBITS),
  165.                       WinGetLastError (hab));
  166.         free (pb);
  167.         return;
  168.     }
  169. #ifdef _DOLOGDEBUG_
  170.     LogDebug( "SaveBitmapToFile(): GpiQueryBitmapBits ok." );
  171. #endif
  172.  
  173.     pbfh2->usType   = BFT_BMAP;
  174.     pbfh2->offBits  = sizeof (BITMAPFILEHEADER2)-sizeof (BITMAPINFOHEADER2);
  175.  
  176.     switch (pset->QueryFileFormat ())
  177.     {
  178.     case BMF_12:
  179.         pbfh2->offBits += CB_12HEADER + cColors*sizeof (RGB);
  180.         break;
  181.  
  182.     case BMF_20:
  183.         pbfh2->offBits += CB_20HEADER + cColors*sizeof (RGB2);
  184.         break;
  185.  
  186.     default:
  187.         pbfh2->offBits += CB_16HEADER + cColors*sizeof (RGB2);
  188.         break;
  189.     }
  190.  
  191.     pbfh2->cbSize   = pbfh2->offBits+cbBits;
  192.     pbfh2->xHotspot = pbfh2->yHotspot = 0;
  193.  
  194. #ifdef _DOLOGDEBUG_
  195.     LogDebug( "SaveBitmapToFile(): Before if." );
  196. #endif
  197.     if( ( pset->QueryFileFormat() == BMF_12 ) ||
  198.         ( pset->QueryFileFormat() == BMF_16 ) ||
  199.         ( pset->QueryFileFormat() == BMF_20 ) )
  200.     {
  201.         // open out file
  202.         FILE  *pf = fopen (psz, "wb");
  203.         if (! pf)
  204.         {
  205.             DisplayError (RSTR(IDS_HEADER_ERROR), RSTR(IDS_ERROR_COULDNOTOPENFILE),
  206.                           psz);
  207.             free (pb);
  208.             return;
  209.         }
  210.  
  211.         // write file info header
  212.         fwrite (pbfh2, sizeof (BITMAPFILEHEADER2)-sizeof (BITMAPINFOHEADER2),
  213.                 1, pf);
  214.  
  215.         // write bitmap info header
  216.         switch (pset->QueryFileFormat ())
  217.         {
  218.         case BMF_12:
  219.             {
  220.                 BITMAPINFOHEADER   bih;
  221.  
  222.                 bih.cbFix     = CB_12HEADER;
  223.                 bih.cx        = USHORT (bih2.cx);
  224.                 bih.cy        = USHORT (bih2.cy);
  225.                 bih.cPlanes   = bih2.cPlanes;
  226.                 bih.cBitCount = bih2.cBitCount;
  227.  
  228.                 fwrite (&bih, CB_12HEADER, 1, pf);
  229.             }
  230.             break;
  231.  
  232.         case BMF_20:
  233.             pbfh2->bmp2.cbFix = CB_20HEADER;
  234.             fwrite (&(pbfh2->bmp2), CB_20HEADER, 1, pf);
  235.             break;
  236.  
  237.         default:
  238.             pbfh2->bmp2.cbFix = CB_16HEADER;
  239.             fwrite (&(pbfh2->bmp2), CB_16HEADER, 1, pf);
  240.             break;
  241.         }
  242.  
  243.         // write colortable if present
  244.         if (cbColtab)
  245.         {
  246.             switch (pset->QueryFileFormat ())
  247.             {
  248.             case BMF_12:
  249.                 {
  250.                     RGB  rgb;
  251.                     for (USHORT i = 0; i < cColors; i++)
  252.                     {
  253.                         rgb.bRed   = PBITMAPINFO2 (&(pbfh2->bmp2))
  254.                             ->argbColor[i].bRed;
  255.                         rgb.bGreen = PBITMAPINFO2 (&(pbfh2->bmp2))
  256.                             ->argbColor[i].bGreen;
  257.                         rgb.bBlue  = PBITMAPINFO2 (&(pbfh2->bmp2))
  258.                             ->argbColor[i].bBlue;
  259.                         fwrite (&rgb, sizeof (rgb), 1, pf);
  260.                     }
  261.                 }
  262.                 break;
  263.  
  264.             default:
  265.                 fwrite (PBYTE (&(pbfh2->bmp2))+sizeof (BITMAPINFOHEADER2),
  266.                     cbColtab, 1, pf);
  267.                 break;
  268.             }
  269.         }
  270.  
  271.         // write the actual bitmap data bits
  272.         fwrite (pb, cbBits, 1, pf);
  273.         fclose (pf);
  274.     } else {
  275. #ifdef _DOLOGDEBUG_
  276.         LogDebug( "SaveBitmapToFile(): Starting 'else' path." );
  277. #endif
  278.         PFN xmmioClose = pset->GetMMIO()->pfmmioClose;
  279.         PFN xmmioOpen = pset->GetMMIO()->pfmmioOpen;
  280.         PFN xmmioWrite = pset->GetMMIO()->pfmmioWrite;
  281.         PFN xmmioQueryHeaderLength = pset->GetMMIO()->pfmmioQueryHeaderLength;
  282.         PFN xmmioSetHeader = pset->GetMMIO()->pfmmioSetHeader;
  283.  
  284. #ifdef _DOLOGDEBUG_
  285.     LogDebug( "SaveBitmapToFile(): Before GetFOURCC." );
  286. #endif
  287.         // ********* WRITE TARGET
  288.         FOURCC fccTargetIOProc = pset->GetFOURCC();
  289.  
  290.         // Initialize our info MMIOINFO structure.
  291.         MMIOINFO mmioinfoTarget;
  292. #ifdef _DOLOGDEBUG_
  293.     LogDebug( "SaveBitmapToFile(): Before memset." );
  294. #endif
  295.         memset( &mmioinfoTarget, 0L, sizeof( MMIOINFO ) );
  296.         mmioinfoTarget.fccIOProc   = fccTargetIOProc;
  297.         mmioinfoTarget.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;
  298.  
  299. #ifdef _DOLOGDEBUG_
  300.         LogDebug( "SaveBitmapToFile(): Trying to open file." );
  301. #endif
  302.         // Open target file.
  303.         HMMIO hmmioTarget;
  304.         if( ! ( hmmioTarget = pset->GetMMIO()->pfmmioOpen( psz,
  305.                                         &mmioinfoTarget,
  306.                                         MMIO_CREATE | MMIO_WRITE |
  307.                                         MMIO_DENYWRITE | MMIO_NOIDENTIFY ) ) ) {
  308.             DisplayError ("mmioOpen()-Error",
  309.                           "mmioOpen()-Error %ld", mmioinfoTarget.ulErrorRet );
  310.             return;
  311.         }
  312. #ifdef _DOLOGDEBUG_
  313.         LogDebug( "SaveBitmapToFile(): Open file ok." );
  314. #endif
  315.  
  316.         // Set the target header.
  317.         ULONG ulImageHeaderLength;
  318.  
  319.         xmmioQueryHeaderLength( hmmioTarget, (PLONG)&ulImageHeaderLength, 0L, 0L );
  320.         if( ulImageHeaderLength != sizeof( MMIMAGEHEADER ) )
  321.         {
  322.             // We have a problem.....possibly incompatible versions.
  323.             xmmioClose( hmmioTarget, 0L );
  324.             DisplayError ("mmioQueryHeaderLength()-Error",
  325.                           "mmioQueryHeaderLength()-Error",
  326.                           WinGetLastError (hab));
  327.             return;
  328.         }
  329. #ifdef _DOLOGDEBUG_
  330.         LogDebug( "SaveBitmapToFile(): xmmioQueryHeaderLength ok." );
  331. #endif
  332.  
  333.         MMIMAGEHEADER mmImgHdr;
  334.         mmImgHdr.ulHeaderLength = ulImageHeaderLength;
  335.         mmImgHdr.ulContentType  = MMIO_IMAGE_UNKNOWN;
  336.         mmImgHdr.ulMediaType    = MMIO_MEDIATYPE_IMAGE;
  337.  
  338. #ifdef _DOLOGDEBUG_
  339.     LogDebug( "SaveBitmapToFile(): Before memcpy (colors)." );
  340. #endif
  341.         memcpy( mmImgHdr.bmiColors,
  342.                 PBYTE( &( pbfh2->bmp2 ) ) + sizeof( BITMAPINFOHEADER2 ),
  343.                 cbColtab );
  344.  
  345.         mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize = cbBits; // FIXME;
  346.         mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulPelFormat = 0; // FIXME;
  347.         mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.usTransType = 0; // FIXME
  348.         mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulTransVal = 0;  // FIXME
  349.         memcpy( &(mmImgHdr.mmXDIBHeader.BMPInfoHeader2), &bih2, sizeof (BITMAPINFOHEADER2));
  350.  
  351. #ifdef _DOLOGDEBUG_
  352.     LogDebug( "SaveBitmapToFile(): Before xmmioSetHeader." );
  353. #endif
  354.         ULONG ulBytesRead;
  355.         if( ( rc = (LONG)xmmioSetHeader( hmmioTarget, (MMIMAGEHEADER*)&mmImgHdr,
  356.                                          (LONG)sizeof( MMIMAGEHEADER ), (PLONG)&ulBytesRead,
  357.                                          0L, 0L ) ) != MMIO_SUCCESS )
  358.         {
  359.             // Header unavailable.
  360.             xmmioClose( hmmioTarget, 0L );
  361.             DisplayError ("mmioSetHeader()-Error",
  362.                           "mmioSetHeader()-Error %ld", rc );
  363.             return;
  364.         }
  365. #ifdef _DOLOGDEBUG_
  366.         LogDebug( "SaveBitmapToFile(): xmmioSetHeader ok." );
  367. #endif
  368.  
  369.         // write the actual bitmap data bits
  370.         if( ( rc = xmmioWrite( hmmioTarget, pb, cbBits ) ) == MMIO_ERROR )
  371.             DisplayError ("mmioWrite()-Error",
  372.                           "mmioWrite()-Error %ld", rc );
  373. #ifdef _DOLOGDEBUG_
  374.         LogDebug( "SaveBitmapToFile(): xmmioWrite ok." );
  375. #endif
  376.  
  377.         if( ( rc = xmmioClose( hmmioTarget, 0 ) ) != MMIO_SUCCESS )
  378.             DisplayError ("mmioClose()-Error",
  379.                           "mmioClose()-Error %ld", rc );
  380. #ifdef _DOLOGDEBUG_
  381.         LogDebug( "SaveBitmapToFile(): xmmioClose ok." );
  382. #endif
  383.     }
  384.  
  385. #ifdef _DOLOGDEBUG_
  386.     LogDebug( "SaveBitmapToFile(): Everything done, closed file" );
  387. #endif
  388.  
  389.     // set BITMAP file type ea
  390.     SetEAs( psz );
  391.  
  392.     // cleanup and return
  393.     free (pbfh2);
  394.     free (pb);
  395. #ifdef _DOLOGMEM_
  396.     LogMem("SaveBitmapToFile", FALSE);
  397. #endif
  398. }
  399.  
  400. // ** SetEAs ************************************************************** /*fold00*/
  401.  
  402. BOOL SetEAs (PSZ psz)
  403. {
  404. #ifdef _DOLOGMEM_
  405.     LogMem("SetEAs", TRUE);
  406. #endif
  407.     // alloc memory for EA data
  408.     PSZ     pszName = ".TYPE";
  409.     PSZ     pszValue = pset->GetFileEAType();
  410.     USHORT  cbName = strlen (pszName)+1;
  411.     USHORT  cbValue = strlen (pszValue)+1;
  412.     USHORT  usMemNeeded = sizeof (FEA2LIST) + cbName + cbValue;
  413.     PBYTE  pb = PBYTE (malloc (usMemNeeded));
  414.  
  415.     EAOP2   eaop2;
  416.  
  417.     eaop2.fpFEA2List = (FEA2LIST FAR *) pb;
  418.     eaop2.fpFEA2List->cbList = usMemNeeded;
  419.  
  420.     eaop2.fpFEA2List->list[0].fEA     = 0;  // EA is no "must have"
  421.     eaop2.fpFEA2List->list[0].cbName  = cbName-1;
  422.     eaop2.fpFEA2List->list[0].cbValue = cbValue;
  423.  
  424.     strcpy (eaop2.fpFEA2List->list[0].szName, pszName);
  425.     memcpy (eaop2.fpFEA2List->list[0].szName+cbName, pszValue, cbValue);
  426.  
  427.     if (DosSetPathInfo (psz, FIL_QUERYEASIZE, PVOID (&eaop2),
  428.                         sizeof (EAOP2), DSPI_WRTTHRU))
  429.     {
  430.         DisplayError (RSTR(IDS_HEADER_ERROR),
  431.                       RSTR(IDS_ERROR_COULDNOTWRITEFILETYPEEA));
  432.         free (pb);
  433. #ifdef _DOLOGMEM_
  434.     LogMem("SetEAs-1", FALSE);
  435. #endif
  436.         return FALSE;
  437.     }
  438.  
  439.     free (pb);
  440. #ifdef _DOLOGMEM_
  441.     LogMem("SetEAs-2", FALSE);
  442. #endif
  443.     return TRUE;
  444. }
  445.  
  446. // ** SelectSaveFile ****************************************************** /*fold00*/
  447.  
  448. BOOL SelectSaveFile (VOID)
  449. {
  450. #ifdef _DOLOGMEM_
  451.     LogMem("SelectSaveFile", TRUE);
  452. #endif
  453.     // if FSS_NUMFILES, create and return a new name
  454.     if (pset->QueryFileSaveStyle () == FSS_NUMFILES)
  455.     {
  456.         CHAR   ach[_MAX_PATH];
  457.         for (USHORT i = 0; i < 10000; i++)
  458.         {
  459.             sprintf( ach, "%s\\got%05d.%s", pset->QueryNumSaveDir(), i,
  460.                      pset->GetFileExtension() );
  461.             if (access (ach, 0) != 0)
  462.             {
  463.                 pset->SetSaveFile (ach);
  464.                 return TRUE;
  465.             }
  466.         }
  467.         return FALSE;
  468.     }
  469.  
  470.     // ... else do a file dlg
  471.     FILEDLG    fdlg;
  472.  
  473.     memset (&fdlg, 0, sizeof (fdlg));
  474.  
  475.     fdlg.hMod       = GETMODULE;
  476.     fdlg.usDlgId    = ID_DLG_FILE;
  477.     fdlg.pfnDlgProc = FileDLGProcedure;
  478.     fdlg.cbSize     = sizeof (fdlg);
  479.     fdlg.fl         = FDS_SAVEAS_DIALOG | FDS_CENTER | FDS_CUSTOM;
  480.     fdlg.pszTitle   = RSTR(IDS_SAVESCREENSHOTTO);
  481.     strcpy (fdlg.szFullFile, pset->QuerySaveFile ());
  482.  
  483.     if (WinFileDlg (HWND_DESKTOP, HWND_DESKTOP, &fdlg))
  484.     {
  485.         if (fdlg.lReturn != DID_OK)
  486.             return FALSE;
  487.  
  488.         PSZ pszOut = fdlg.szFullFile;
  489.  
  490.         // Add bmp extension if not already present.
  491.         if( pset->AutoaddExtension() )
  492.             pszOut = AddExtensionToFilename( pszOut );
  493.  
  494.         // if file exists and user wants it, confirm overwriting
  495.         if (pset->ConfirmOverwrite ())
  496.             if (access (pszOut, 0) == 0)
  497.                 // let user confirm operation
  498.                 if (WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  499.                                    RSTR(IDS_FILEEXISTSOVERWRITE),
  500.                                    RSTR(IDS_HEADER_WARNING), 0L,
  501.                                    MB_OKCANCEL | MB_QUERY | MB_DEFBUTTON2 |
  502.                                    MB_MOVEABLE)
  503.                     != MBID_OK)
  504.                     return FALSE;
  505.  
  506.         pset->SetSaveFile (pszOut);
  507.         return TRUE;
  508.     }
  509.     return FALSE;
  510. #ifdef _DOLOGMEM_
  511.     LogMem("SelectSaveFile", FALSE);
  512. #endif
  513. }
  514.  
  515. // ** FileDLGProcedure **************************************************** /*fold00*/
  516.  
  517. MRESULT EXPENTRY FileDLGProcedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  518. {
  519. #ifdef _DOFNCOMPLETION_
  520.     static HDIR   hdir = NULLHANDLE;
  521.     static BOOL   fCompletion = FALSE;
  522. #endif
  523.  
  524.     switch (msg)
  525.     {
  526.     case WM_INITDLG:
  527.         WinSendDlgItemMsg (hwnd, WID_CB_AUTOADDEXTENSION, BM_SETCHECK,
  528.                            MPFROMLONG (pset->AutoaddExtension ()),
  529.                            MPFROMLONG (0));
  530.         WinSendDlgItemMsg (hwnd, WID_CB_CONFIRMOVERWRITE, BM_SETCHECK,
  531.                            MPFROMLONG (pset->ConfirmOverwrite ()),
  532.                            MPFROMLONG (0));
  533. /* FIXME neither work ...       WinSendDlgItemMsg (hwnd, DID_FILES_LB, WM_ENABLE,
  534.                            MPFROMLONG (TRUE),
  535.                            MPFROMLONG (0));
  536.         //WinEnableWindow( WinWindowFromID( hwnd, DID_FILES_LB ), TRUE ); */
  537.         break;
  538.  
  539. #ifdef _DOFNCOMPLETION_
  540.     case WM_CHAR: {
  541.         HWND hwndFNE = WinWindowFromID (hwnd, DID_FILENAME_ED);
  542.         if (WinQueryFocus (HWND_DESKTOP) == hwndFNE)
  543.         {
  544.             // tab key, downpress
  545.             if ((CHARMSG (&msg)->chr == 9) && !
  546.                 (CHARMSG (&msg)->fs & KC_KEYUP))
  547.             {
  548.                 ULONG         c = 1, fl;
  549.                 FILEFINDBUF3  findbuf;
  550.                 APIRET        rc;
  551.                 CHAR          ach[_MAX_PATH];
  552.  
  553.                 if (! hdir)
  554.                 {
  555.                     WinQueryWindowText (hwndFNE, _MAX_PATH-1, ach);
  556.                     strcat (ach, "*");
  557.                     fl   = FILE_NORMAL;
  558.                     hdir = HDIR_CREATE;
  559.                     rc = DosFindFirst (ach, &hdir, fl, &findbuf,
  560.                                        sizeof (findbuf), &c,
  561.                                        FIL_STANDARD);
  562.                 }
  563.                 else
  564.                 {
  565.                     rc = DosFindNext (hdir, &findbuf,
  566.                                       sizeof (findbuf), &c);
  567.                 }
  568.  
  569.                 if (! rc)
  570.                 {
  571.                     fCompletion = TRUE;
  572.                     WinSetWindowText (hwndFNE, findbuf.achName);
  573.                     fCompletion = FALSE;
  574.                 }
  575.                 else
  576.                     DosBeep (1000, 10);
  577.                 return MRESULT (FALSE);
  578.             }
  579.         } } break;
  580.  
  581.     case WM_CONTROL:
  582.         switch (SHORT1FROMMP (mp1))
  583.         {
  584.         case DID_FILENAME_ED:
  585.             if ((SHORT2FROMMP (mp1) == EN_CHANGE) ||
  586.                 (SHORT2FROMMP (mp1) == EN_KILLFOCUS))
  587.                 if (hdir && !fCompletion)
  588.                 {
  589.                     // FIXME maybe do this to when closing dialog?
  590.                     DosFindClose (hdir);
  591.                     hdir = NULLHANDLE;
  592.                 }
  593.             break;
  594.         }
  595.         break;
  596. #endif
  597.  
  598.     case WM_COMMAND:
  599.     case WM_CLOSE:
  600.         pset->AutoaddExtension
  601.             (BOOL (WinSendDlgItemMsg (hwnd, WID_CB_AUTOADDEXTENSION,
  602.                                       BM_QUERYCHECK, 0, 0)));
  603.         pset->ConfirmOverwrite
  604.             (BOOL (WinSendDlgItemMsg (hwnd, WID_CB_CONFIRMOVERWRITE,
  605.                                       BM_QUERYCHECK, 0, 0)));
  606.         break;
  607.     }
  608.  
  609.     return WinDefFileDlgProc (hwnd, msg, mp1, mp2);
  610. }
  611.  
  612. // ** AddExtensionToFilename ********************************************** /*fold00*/
  613.  
  614. PSZ AddExtensionToFilename( PSZ psz )
  615. {
  616.     // Using a static buffer here is not really good, but good enough
  617.     // currently as we know there will be no concurrent access.
  618.     static CHAR ach[_MAX_PATH];
  619.     PSZ pszExtension;
  620.  
  621.     PSZ apszValidExtensions[10] =
  622.     { "bmp", "tif", "tiff", "tga", "targa", "pcx", "gif", "jpg", "jpeg", "dib" };
  623.  
  624.     if( ! ( pszExtension = strrchr( psz, '.' ) ) ) {
  625.         // No extension at all - add the appropriate one.
  626.         sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
  627.     } else if( stricmp ( pszExtension+1, pset->GetFileExtension() ) == 0 ) {
  628.         // Correct extension already - just return unchanged filename.
  629.         strcpy( ach, psz );
  630.     } else {
  631.         // Some extension, but not the correct one - change or append.
  632.         BOOL fValidExtension = FALSE;
  633.         for( int i = 0; i < 10; i++ ) {
  634.             if( stricmp( pszExtension+1, apszValidExtensions[i] ) == 0 ) {
  635.                 fValidExtension = TRUE;
  636.                 break;
  637.             }
  638.         }
  639.         if( fValidExtension ) {
  640.             // Valid extension, but not right for current format - replace.
  641.             *pszExtension = '\0';
  642.             sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
  643.         } else {
  644.             // Some extension but not a valid image file format extension - add.
  645.             sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
  646.         }
  647.     }
  648.     return ach;
  649. }
  650.  
  651. // ************************************************************************
  652.