home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / windows / c / fldrvw / icons.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-27  |  24.6 KB  |  997 lines

  1. /********************************************************************/
  2. /*            Folder View - Drag and drop directory viewer          */
  3. /*               Public Domain (P) 1992  Benjamin Cooley            */
  4. /*                 icons.cpp - FolderView Icon Classes              */
  5. /********************************************************************/
  6.  
  7. #include "include.h"
  8. #pragma hdrstop
  9.  
  10. #include "fldrview.h"
  11.  
  12. // Make big enough for 32 * 32 by 256 pixel image
  13. #define MAXPIXELS (32 * 32) 
  14. char pixelbuf[MAXPIXELS];
  15.  
  16. TStreamableClass RegIconImage("IconImage", TIconImage::build, __DELTA(TIconImage));
  17. TStreamableClass RegFileIcon("FileIcon", TFileIcon::build, __DELTA(TFileIcon));
  18. TStreamableClass RegDirIcon("DirIcon", TDirIcon::build, __DELTA(TDirIcon));
  19. TStreamableClass RegProgIcon("ProgIcon", TProgIcon::build, __DELTA(TProgIcon));
  20.  
  21. /************************* IconImage Stuff *************************/
  22.  
  23. TIconImage::TIconImage(Pchar Afilename, int Animage, HICON Anicon)
  24. {
  25.   /* If no bitmap, hose out */
  26.     if (!Anicon) DebugBreak();
  27.  
  28.   /* Set filename and image number */
  29.     filename = new char[strlen(Afilename) + 1];
  30.     strcpy(filename, Afilename);
  31.     strupr(filename);
  32.     image = Animage;
  33.  
  34.   /* Create memdc2 */
  35.     HDC scrndc = GetDC(NULL);
  36.     HDC memdc2 = CreateCompatibleDC(MemDC);
  37.     HBITMAP oldbitmap2;
  38.  
  39.   /* Create XOR bitmap */
  40.     bmih16->biWidth = IconWidth;
  41.     bmih16->biHeight = IconHeight;
  42.     memset(pixelbuf, 0, IconWidth * IconHeight / 2);
  43.     xorbitmap = CreateDIBitmap(scrndc, bmih16,
  44.         CBM_INIT, pixelbuf, bmi16, DIB_RGB_COLORS); 
  45.     HBITMAP oldbitmap = SelectObject(MemDC, xorbitmap);
  46.     DrawIcon(MemDC, 0, 0, Anicon);
  47.  
  48.   /* Create small XOR bitmap */
  49.     bmih16->biWidth = SmallIconWidth;
  50.     bmih16->biHeight = SmallIconHeight;
  51.     smallxorbitmap = CreateDIBitmap(scrndc, bmih16,
  52.         CBM_INIT, pixelbuf, bmi16, DIB_RGB_COLORS); 
  53.     oldbitmap2 = SelectObject(memdc2, smallxorbitmap);
  54.     StretchBlt(memdc2, 0, 0, SmallIconWidth, SmallIconHeight,
  55.       MemDC, 0, 0, IconWidth, IconHeight, SRCCOPY);
  56.  
  57.   /* Create AND bitmap */
  58.     bmih2->biWidth = IconWidth;
  59.     bmih2->biHeight = IconHeight;
  60.     memset(pixelbuf, 0, IconWidth * IconHeight / 8);
  61.     andbitmap = CreateDIBitmap(scrndc, bmih2,
  62.         CBM_INIT, pixelbuf, bmi2, DIB_RGB_COLORS); 
  63.     SelectObject(MemDC, andbitmap);
  64.     DrawIcon(MemDC, 0, 0, Anicon);
  65.  
  66.     memset(pixelbuf, 0xFF, IconWidth * IconHeight / 8);
  67.     HBITMAP tempbitmap = CreateDIBitmap(scrndc, bmih2,
  68.         CBM_INIT, pixelbuf, bmi2, DIB_RGB_COLORS); 
  69.     SelectObject(memdc2, tempbitmap);
  70.     DrawIcon(memdc2, 0, 0, Anicon);
  71.     BitBlt(MemDC, 0, 0, IconWidth, IconHeight, memdc2, 0, 0, SRCINVERT); 
  72.  
  73.   /* Create small AND bitmap */
  74.     bmih2->biWidth = SmallIconWidth;
  75.     bmih2->biHeight = SmallIconHeight;
  76.     smallandbitmap = CreateDIBitmap(scrndc, bmih2,
  77.         CBM_INIT, pixelbuf, bmi2, DIB_RGB_COLORS); 
  78.     SelectObject(memdc2, smallandbitmap);
  79.     StretchBlt(memdc2, 0, 0, SmallIconWidth, SmallIconHeight,
  80.       MemDC, 0, 0, IconWidth, IconHeight, SRCCOPY);
  81.  
  82.   /* Free DC's */
  83.     SelectObject(memdc2, oldbitmap2);
  84.     DeleteObject(tempbitmap);
  85.     DeleteDC(memdc2);
  86.     SelectObject(MemDC, oldbitmap);
  87.     ReleaseDC(NULL, scrndc); 
  88. }
  89.  
  90. TIconImage::~TIconImage()
  91. {
  92.     if (filename) delete filename;
  93.     if (xorbitmap) DeleteObject(xorbitmap);
  94.     if (andbitmap) DeleteObject(andbitmap);
  95.     if (smallxorbitmap) DeleteObject(smallxorbitmap);
  96.     if (smallandbitmap) DeleteObject(smallandbitmap);
  97. }
  98.  
  99.  
  100. Pvoid TIconImage::read(Ripstream is)
  101. {
  102.  
  103.   /* Name */
  104.     char namebuf[MAXPATH];
  105.     is.readString(namebuf, MAXPATH);
  106.     filename = new char[strlen(namebuf) + 1];
  107.     strcpy(filename, namebuf);
  108.  
  109.   /* Image number */
  110.     is >> image;
  111.       
  112.   /* Get Screen DC */
  113.       HDC scrndc = GetDC(NULL);
  114.  
  115.   /* XOR Bitmap */
  116.     is.readBytes(pixelbuf, IconWidth * IconHeight / 2);
  117.     bmih16->biWidth = IconWidth;
  118.     bmih16->biHeight = IconHeight;
  119.     xorbitmap = CreateDIBitmap(scrndc, bmih16,
  120.         CBM_INIT, pixelbuf, bmi16, DIB_RGB_COLORS); 
  121.  
  122.   /* AND Bitmap */
  123.     is.readBytes(pixelbuf, IconWidth * IconHeight / 8);
  124.     bmih2->biWidth = IconWidth;
  125.     bmih2->biHeight = IconHeight;
  126.     andbitmap = CreateDIBitmap(scrndc, bmih2,
  127.         CBM_INIT, pixelbuf, bmi2, DIB_RGB_COLORS); 
  128.  
  129.   /* Small XOR bitmap */
  130.     is.readBytes(pixelbuf, SmallIconWidth * SmallIconHeight / 2);
  131.     bmih16->biWidth = SmallIconWidth;
  132.     bmih16->biHeight = SmallIconHeight;
  133.     smallxorbitmap = CreateDIBitmap(scrndc, bmih16,
  134.         CBM_INIT, pixelbuf, bmi16, DIB_RGB_COLORS); 
  135.  
  136.   /* Small AND bitmap (Note: small icon has 4 bytes, not 2, per scan) */
  137.     is.readBytes(pixelbuf, SmallIconWidth * SmallIconHeight / 4);
  138.     bmih2->biWidth = SmallIconWidth;
  139.     bmih2->biHeight = SmallIconHeight;
  140.     smallandbitmap = CreateDIBitmap(scrndc, bmih2,
  141.         CBM_INIT, pixelbuf, bmi2, DIB_RGB_COLORS); 
  142.  
  143.   /* Release Screen DC */
  144.       ReleaseDC(NULL, scrndc);
  145.  
  146.     return this;
  147. }
  148.  
  149. void TIconImage::write(Ropstream os)
  150. {
  151.   /* Name and image num */
  152.     os.writeString(filename);
  153.     os << image;
  154.  
  155.   /* Get Screen DC */
  156.       HDC scrndc = GetDC(NULL);
  157.  
  158.   /* XOR bitmap bits */
  159.     bmih16->biWidth = IconWidth;
  160.     bmih16->biHeight = IconHeight;
  161.     GetDIBits(scrndc, xorbitmap, 0, IconHeight,
  162.         pixelbuf, bmi16, DIB_RGB_COLORS); 
  163.     os.writeBytes(pixelbuf, IconWidth * IconHeight / 2);
  164.  
  165.   /* AND bitmap bits */
  166.     bmih2->biWidth = IconWidth;
  167.     bmih2->biHeight = IconHeight;
  168.     GetDIBits(scrndc, andbitmap, 0, IconHeight,
  169.         pixelbuf, bmi2, DIB_RGB_COLORS); 
  170.     os.writeBytes(pixelbuf, IconWidth * IconHeight / 8);
  171.  
  172.   /* Small XOR bitmap bits */
  173.     bmih16->biWidth = SmallIconWidth;
  174.     bmih16->biHeight = SmallIconHeight;
  175.     GetDIBits(scrndc, smallxorbitmap, 0, SmallIconHeight,
  176.         pixelbuf, bmi16, DIB_RGB_COLORS); 
  177.     os.writeBytes(pixelbuf, SmallIconWidth * SmallIconHeight / 2);
  178.  
  179.   /* Small AND bitmap (Note: small icon has 4 bytes, not 2, per scan) */
  180.     bmih2->biWidth = SmallIconWidth;
  181.     bmih2->biHeight = SmallIconHeight;
  182.     GetDIBits(scrndc, smallandbitmap, 0, SmallIconHeight,
  183.         pixelbuf, bmi2, DIB_RGB_COLORS); 
  184.     os.writeBytes(pixelbuf, SmallIconWidth * SmallIconHeight / 4);
  185.  
  186.   /* Release Screen DC */
  187.       ReleaseDC(NULL, scrndc);
  188. }
  189.  
  190. /************************* IconList Stuff *************************/
  191.  
  192. PTIconImage TIconList::FindIconImage(Pchar filename, int image)
  193. {
  194.     for (int c = 0; c < IconImages(); c++)
  195.     {
  196.         PTIconImage iconimage = GetIconImage(c);
  197.         if (!stricmp(filename, iconimage->FileName()) &&
  198.             image == iconimage->Image()) return iconimage;
  199.     }
  200.     return NULL;
  201. }
  202.  
  203. void TIconList::AddIconImage(PTIconImage iconimage)
  204. {
  205.     for (int c = 0; c < IconImages(); c++)
  206.     {
  207.         PTIconImage animage = GetIconImage(c);
  208.         if (!strcmp(animage->filename, iconimage->filename) &&
  209.            (animage->image == iconimage->image))
  210.         {
  211.             if (animage != iconimage)
  212.             {
  213.                 detach(c, TShouldDelete::Delete);
  214.                 add(*iconimage);
  215.             }
  216.             return;
  217.         }
  218.     }
  219.     add(*iconimage);
  220. }
  221.  
  222. /*************************** Icon Stuff ***************************/
  223.  
  224. PTIcon TIcon::NewIcon(RTFolderView AFolderView, ffblk &Affblk)
  225. {
  226.     if (Affblk.ff_attrib == FA_DIREC)
  227.     {
  228.         return new TDirIcon(AFolderView, Affblk);
  229.     }
  230.     else if (strstr(Affblk.ff_name, ".exe") ||
  231.                strstr(Affblk.ff_name, ".com") ||
  232.                strstr(Affblk.ff_name, ".bat") ||
  233.                strstr(Affblk.ff_name, ".pif"))
  234.     {
  235.         return new TProgIcon(AFolderView, Affblk);
  236.     }
  237.     else
  238.     {
  239.         return new TFileIcon(AFolderView, Affblk);
  240.     }
  241. }  
  242.  
  243. TIcon::TIcon(RTFolderView AFolderView, ffblk &Affblk)
  244. {
  245.      folderview = &AFolderView;
  246.     time = Affblk.ff_ftime;
  247.     date = Affblk.ff_fdate;
  248.     size = Affblk.ff_fsize;
  249.     strcpy(name, Affblk.ff_name);
  250.     strlwr(name);
  251.     icon = 0;  // Set me when painting
  252.     strcpy(desc, Affblk.ff_name);
  253.     strlwr(desc);
  254.     rect.left = rect.right = rect.top = rect.bottom = 0;
  255.     state = 0;
  256.     textrect.left = -1;
  257. }
  258.  
  259. int TIcon::SortOrder() const
  260. {
  261.     return folderview->GetSortOrder();
  262. }
  263.  
  264. int TIcon::View() const
  265. {
  266.     return folderview->GetView();
  267. }
  268.  
  269. Pvoid TIcon::read(Ripstream is)
  270. {
  271.     is.readString(name, 13);
  272.     is.readString(desc, DESCLEN);
  273.     is >> date >> time >> size;
  274.     is >> state;
  275.     textrect.left = -1;
  276.  
  277.     icon = NULL;
  278.     is >> icon;
  279.     IconList.AddIconImage(icon);
  280.  
  281.     return this;
  282. }
  283.  
  284. void TIcon::write(Ropstream os)
  285. {
  286.     os.writeString(name);
  287.     os.writeString(desc);
  288.     os << date << time << size;
  289.     os << state;
  290.     os << icon;
  291. }
  292.  
  293. HCURSOR TIcon::CreateCursor(int hotspotx, int hotspoty)
  294. {
  295.     static char cursorandbits[32 * 32 / 8];
  296.     static char cursorxorbits[32 * 32 / 8];
  297.  
  298.     HBITMAP bm = CreateBitmap(32, 32, 1, 1, cursorandbits);
  299.     HBITMAP oldbitmap = SelectObject(MemDC, bm);
  300.     HDC memdc2 = CreateCompatibleDC(MemDC);
  301.  
  302.     HBITMAP oldbitmap2 = SelectObject(memdc2, icon->ANDBitmap());
  303.     BitBlt(MemDC, 0, 0, 32, 32, memdc2, 0, 0, SRCCOPY);
  304.     GetBitmapBits(bm, 32 * 32 / 8, cursorandbits);
  305.  
  306.     SelectObject(memdc2, icon->XORBitmap());
  307.     BitBlt(MemDC, 0, 0, 32, 32, memdc2, 0, 0, SRCCOPY);
  308.     GetBitmapBits(bm, 32 * 32 / 8, cursorxorbits);
  309.  
  310.     SelectObject(memdc2, oldbitmap2);
  311.     DeleteDC(memdc2);
  312.     SelectObject(MemDC, oldbitmap);
  313.     DeleteObject(bm);
  314.  
  315.     return ::CreateCursor(hInstance, hotspotx, hotspoty,
  316.         IconWidth, IconHeight, cursorandbits, cursorxorbits);
  317. }
  318.  
  319. BOOL TIcon::ShouldUpdate(ffblk &affblk)
  320. {
  321.     if (strcmp(name, affblk.ff_name) ||
  322.         date != affblk.ff_fdate ||
  323.         time != affblk.ff_ftime ||
  324.         size != affblk.ff_fsize) return TRUE;
  325.     return FALSE;
  326. }
  327.  
  328. void TIcon::PaintIcon(HDC PaintDC, int drawmode)
  329. {
  330.  
  331.     if (drawmode == PAINTICON_REDRAW)
  332.     {
  333.         FillRect(PaintDC, &rect, WindowBrush);
  334.     }
  335.  
  336.     if ((drawmode == PAINTICON_ALL) || (drawmode == PAINTICON_REDRAW))
  337.     {
  338.         if (!icon) icon = GetIconImage();
  339.         if (!icon) DebugBreak();
  340.         SetTextColor(PaintDC, RGB(0, 0, 0));
  341.         SetBkColor(PaintDC, RGB(255, 255, 255));
  342.         HBITMAP oldbitmap = SelectObject(MemDC, icon->ANDBitmap());
  343.         BitBlt(PaintDC, rect.left + IconLeft, rect.top + IconTop,
  344.           IconWidth, IconHeight, MemDC, 0, 0, SRCAND);
  345.         SelectObject(MemDC, icon->XORBitmap());
  346.         BitBlt(PaintDC, rect.left + IconLeft, rect.top + IconTop,
  347.             IconWidth, IconHeight, MemDC, 0, 0, SRCPAINT);
  348.         SelectObject(MemDC, oldbitmap);
  349.     }
  350.  
  351.     if (textrect.left == -1)
  352.     {
  353.         DWORD l = GetTextExtent(PaintDC, desc, strlen(desc));
  354.         POINT size = MAKEPOINT(l);
  355.         size.x += 2;
  356.         size.y += 2;
  357.         textrect.left = rect.left + (IconSpaceWidth / 2) - (size.x / 2);
  358.         textrect.right = textrect.left + size.x;
  359.         textrect.top = rect.top + IconTop + IconHeight + 2;
  360.         textrect.bottom = textrect.top + size.y;
  361.     }
  362.  
  363.     if ((drawmode == PAINTICON_ALL) ||
  364.         (drawmode == PAINTICON_REDRAW) ||
  365.         (drawmode == PAINTICON_DESC))
  366.     {
  367.         HBRUSH backbrush;
  368.         if (state & IS_SELECTED)
  369.         {
  370.             SetTextColor(PaintDC, SelectedTextColor);
  371.             SetBkColor(PaintDC, SelectedTextBkColor);
  372.             backbrush = SelectedBrush;
  373.         }
  374.         else
  375.         {
  376.             SetTextColor(PaintDC, TextColor);
  377.             SetBkColor(PaintDC, TextBkColor);
  378.             backbrush = WindowBrush;
  379.         }
  380.  
  381.         FillRect(PaintDC, &textrect, backbrush);
  382.         DrawText(PaintDC, desc, strlen(desc), &textrect,
  383.             DT_NOPREFIX | DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOCLIP);
  384.     }
  385.  
  386.     if ((drawmode == PAINTICON_ALL) ||
  387.         (drawmode == PAINTICON_REDRAW) ||
  388.         (drawmode == PAINTICON_FOCUS)) 
  389.     {
  390.         if (state & IS_FOCUSED)
  391.         {
  392.             InflateRect(&textrect, 1, 1);
  393.             DrawFocusRect(PaintDC, &textrect);
  394.             InflateRect(&textrect, -1, -1);
  395.         }
  396.     }
  397.  
  398. }
  399.  
  400. void TIcon::PaintInfo(HDC PaintDC, int drawmode)
  401. {
  402.     rect.right++;
  403.     rect.bottom++;
  404.  
  405.     if ((drawmode == PAINTICON_ALL) ||
  406.         (drawmode == PAINTICON_REDRAW) ||
  407.         (drawmode == PAINTICON_DESC))
  408.     {
  409.  
  410.       /* Get brush */
  411.         HBRUSH backbrush;
  412.         if (state & IS_SELECTED)
  413.         {
  414.             SetTextColor(PaintDC, SelectedTextColor);
  415.             SetBkColor(PaintDC, SelectedTextBkColor);
  416.             backbrush = SelectedBrush;
  417.         }
  418.         else
  419.         {
  420.             SetTextColor(PaintDC, TextColor);
  421.             SetBkColor(PaintDC, TextBkColor);
  422.             backbrush = WindowBrush;
  423.         }
  424.  
  425.       /* Redraw background */
  426.         FillRect(PaintDC, &rect, backbrush);
  427.  
  428.       /* Add space on left */
  429.         rect.left += SmallIconWidth + 4;
  430.  
  431.       /* Get text to display */
  432.         Pchar ptr;
  433.         int tabs = 0;
  434.         int tabarray[10];
  435.         if (View() == VIEW_ALL)
  436.         {
  437.             static char buf[128];
  438.  
  439.             ptr = buf;
  440.             int dispitems = folderview->GetDisplayItems();
  441.             if (dispitems & DISPLAY_NAME)
  442.             {
  443.                 ptr = stpcpy(ptr, name);
  444.                 *ptr++ = '\t';
  445.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  446.                     else tabarray[tabs] = rect.left; 
  447.                 tabarray[tabs++] += AllNameWidth;
  448.             }
  449.             if (dispitems & DISPLAY_DATE)
  450.             {
  451.                 struct ftime *f = (struct ftime *)&time;
  452.                 ptr += wsprintf(ptr, "%d/%d/%d",
  453.                     f->ft_month, f->ft_day, f->ft_year + 80);
  454.                 *ptr++ = '\t';
  455.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  456.                     else tabarray[tabs] = rect.left; 
  457.                 tabarray[tabs++] += AllDateWidth;
  458.             }
  459.             if (dispitems & DISPLAY_TIME)
  460.             {
  461.                 struct ftime *f = (struct ftime *)&time;
  462.                 int hour;
  463.                 Pchar ampm;
  464.                 if (f->ft_hour > 12)
  465.                 {
  466.                     hour = f->ft_hour - 12;
  467.                     ampm = "pm";
  468.                 }
  469.                 else
  470.                 {
  471.                     hour = f->ft_hour;
  472.                     if (!hour) hour = 12;
  473.                     ampm = "am";
  474.                 }
  475.                 ptr += wsprintf(ptr, "%d:%02d%s", hour, f->ft_min, ampm);
  476.                 *ptr++ = '\t';
  477.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  478.                     else tabarray[tabs] = rect.left; 
  479.                 tabarray[tabs++] += AllTimeWidth;
  480.             }
  481.             if (dispitems & DISPLAY_SIZE)
  482.             {
  483.                 ltoa(size, ptr, 10);
  484.                 ptr += strlen(ptr);
  485.                 *ptr++ = '\t';
  486.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  487.                     else tabarray[tabs] = rect.left; 
  488.                 tabarray[tabs++] += AllSizeWidth;
  489.             }
  490.             if (dispitems & DISPLAY_ATTRIB)
  491.             {
  492.                 if (attrib & FA_RDONLY) *ptr++ = 'r';
  493.                 if (attrib & FA_HIDDEN) *ptr++ = 'h';
  494.                 if (attrib & FA_SYSTEM) *ptr++ = 's';
  495.                 if (attrib & FA_LABEL) *ptr++ = 'l';
  496.                 if (attrib & FA_DIREC) *ptr++ = 'd';
  497.                 if (attrib & FA_ARCH) *ptr++ = 'a';
  498.                 *ptr++ = '\t';
  499.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  500.                     else tabarray[tabs] = rect.left; 
  501.                 tabarray[tabs++] += AllAttribWidth;
  502.             }
  503.             if (dispitems & DISPLAY_DESC)
  504.             {
  505.                 ptr = stpcpy(ptr, desc);
  506.                 *ptr++ = '\t';
  507.                 if (tabs) tabarray[tabs] = tabarray[tabs - 1];
  508.                     else tabarray[tabs] = rect.left; 
  509.                 tabarray[tabs++] += AllDescWidth;
  510.             }
  511.             *ptr = NULL;
  512.             ptr = buf;
  513.         } else ptr = name; // Just name for name view
  514.  
  515.       /* Output text */
  516.         TabbedTextOut(PaintDC, rect.left, rect.top, ptr, strlen(ptr),
  517.              tabs, tabarray, rect.left);
  518.  
  519.       /* Restore recangle */
  520.         rect.left -= SmallIconWidth + 4; 
  521.     }
  522.  
  523.     if ((drawmode == PAINTICON_ALL) ||
  524.         (drawmode == PAINTICON_REDRAW) ||
  525.         (drawmode == PAINTICON_DESC))
  526.     {
  527.         int t = (IconNameHeight - SmallIconHeight) / 2;
  528.         if (!icon) icon = GetIconImage();
  529.         if (!icon) DebugBreak();
  530.         SetTextColor(PaintDC, RGB(0, 0, 0));
  531.         SetBkColor(PaintDC, RGB(255, 255, 255));
  532.         HBITMAP oldbitmap = SelectObject(MemDC, icon->SmallANDBitmap());
  533.         BitBlt(PaintDC, rect.left + 2, rect.top + t,
  534.             SmallIconWidth, SmallIconHeight, MemDC, 0, 0, SRCAND);
  535.         SelectObject(MemDC, icon->SmallXORBitmap());
  536.         BitBlt(PaintDC, rect.left + 2, rect.top + t,
  537.             SmallIconWidth, SmallIconHeight, MemDC, 0, 0, SRCPAINT);
  538.         SelectObject(MemDC, oldbitmap);
  539.     }
  540.  
  541.     if ((drawmode == PAINTICON_ALL) ||
  542.         (drawmode == PAINTICON_REDRAW) ||
  543.         (drawmode == PAINTICON_FOCUS) ||
  544.         (drawmode == PAINTICON_DESC)) 
  545.     {
  546.         if (state & IS_FOCUSED)
  547.         {
  548.             DrawFocusRect(PaintDC, &rect);
  549.         }
  550.     }
  551.  
  552.     rect.right--;
  553.     rect.bottom--;
  554. }
  555.  
  556. void TIcon::Paint(HDC PaintDC, int drawmode)
  557. {
  558.     if (View() == VIEW_ICON) PaintIcon(PaintDC, drawmode);
  559.         else PaintInfo(PaintDC, drawmode);
  560. }
  561.  
  562. void TIcon::RedrawIcon()
  563. {
  564.     HDC dc = folderview->GetDC();
  565.     Paint(dc, PAINTICON_REDRAW);
  566.     folderview->ReleaseDC(dc);
  567. }
  568.  
  569. void TIcon::RedrawDescription()
  570. {
  571.     HDC dc = folderview->GetDC();
  572.     Paint(dc, PAINTICON_DESC);
  573.     folderview->ReleaseDC(dc);
  574. }
  575.  
  576. void TIcon::ToggleFocusRect()
  577. {
  578.     HDC dc = folderview->GetDC();
  579.  
  580.     if (View() == VIEW_ICON)
  581.     {    
  582.         InflateRect(&textrect, 1, 1);
  583.         DrawFocusRect(dc, &textrect);
  584.         InflateRect(&textrect, -1, -1);
  585.     }
  586.     else
  587.     {
  588.         rect.right++;
  589.         rect.bottom++;
  590.         DrawFocusRect(dc, &rect);
  591.         rect.right--;
  592.         rect.bottom--;
  593.     }
  594.  
  595.     folderview->ReleaseDC(dc);
  596. }
  597.  
  598. void TIcon::SetState(int flags)
  599. {
  600.     if ((IS_FOCUSED & flags) != (IS_FOCUSED & state))
  601.     {
  602.         ToggleFocusRect();
  603.         state = (state & ~IS_FOCUSED) | (flags & IS_FOCUSED);
  604.     }
  605.     if ((IS_SELECTED & flags) != (IS_SELECTED & state))
  606.     {
  607.         state = (state & ~IS_SELECTED) | (flags & IS_SELECTED);
  608.         RedrawDescription();
  609.     }
  610. }
  611.  
  612. BOOL TIcon::PointOn(POINT p)
  613. {
  614.     RECT r, *rptr;
  615.  
  616.     if (View() == VIEW_ICON)
  617.     {
  618.         r.left = rect.left + IconLeft;
  619.         r.top = rect.top + IconTop;
  620.         r.right = r.left + IconWidth - 1;
  621.         r.bottom = r.top + IconHeight - 1;
  622.         rptr = &r;
  623.     } else rptr = ▭
  624.  
  625.     return PtInRect(rptr, p);
  626. }
  627.  
  628. int TIcon::isEqual(RCObject object) const
  629. {
  630.     RTIcon icon = (RTIcon)object;
  631.  
  632.     switch (SortOrder())
  633.     {
  634.       case SORT_BYNAME:
  635.           return strcmp(name, icon.name) == 0;
  636.       case SORT_BYEXT:
  637.         Pchar ext1 = strchr(name, '.');
  638.         if (!ext1) ext1 = (Pchar)(name + strlen(name));
  639.         Pchar ext2 = strchr(icon.name, '.');
  640.         if (!ext2) ext2 = (Pchar)(icon.name + strlen(icon.name));
  641.         int result = strcmp(ext1, ext2);
  642.         if (result == 0) result = strcmp(name, icon.name);
  643.           return result == 0;
  644.       case SORT_BYDATE:
  645.         return (date == icon.date) && (time == icon.time);
  646.       case SORT_BYSIZE:
  647.         return size == icon.size;
  648.       case SORT_BYDESC:
  649.       default:
  650.         return strcmp(desc, icon.desc) == 0;
  651.     }
  652. }
  653.  
  654. int TIcon::isLessThan(RCObject object) const
  655. {
  656.     RTIcon icon = (RTIcon)object;
  657.  
  658.     switch (SortOrder())
  659.     {
  660.       case SORT_BYNAME:
  661.           return strcmp(name, icon.name) < 0;
  662.       case SORT_BYEXT:
  663.         Pchar ext1 = strchr(name, '.');
  664.         if (!ext1) ext1 = (Pchar)(name + strlen(name));
  665.         Pchar ext2 = strchr(icon.name, '.');
  666.         if (!ext2) ext2 = (Pchar)(icon.name + strlen(icon.name));
  667.         int result = strcmp(ext1, ext2);
  668.         if (result == 0) result = strcmp(name, icon.name);
  669.           return result < 0;
  670.       case SORT_BYDATE:
  671.         return (date < icon.date) || ((date == icon.date) && (time < icon.time));
  672.       case SORT_BYSIZE:
  673.         return size < icon.size;
  674.       case SORT_BYDESC:
  675.       default:
  676.         return strcmp(desc, icon.desc) < 0;
  677.     }
  678. }
  679.  
  680. void TIcon::Delete()
  681. {
  682. }
  683.  
  684. void TIcon::Copy(Pchar to)
  685. {
  686. }
  687.  
  688. void TIcon::Move(Pchar to)
  689. {
  690. }
  691.  
  692. #if 0
  693. struct dostate
  694. {
  695.     int pos;
  696.     ffblk affblk;
  697.     BOOL found;
  698. }
  699.  
  700. static int DoFirstFile(dostate *state, Pchar dir, Pchar to,
  701.     int (*do)(Pchar name), void (*func)(Pchar name, Pchar to))
  702. {
  703.     int ok = do(dir);
  704.     if (ok != IDYES) return ok;
  705.  
  706.     state->pos = strlen(dir);
  707.     strcpy(dir + state->pos, "\\*.*");
  708.  
  709.     state->found = !findfirst(dir, &(state->affblk),
  710.         FA_DIREC | FA_SYSTEM | FA_HIDDEN_;
  711.  
  712.     return IDYES;
  713. }
  714.  
  715.  
  716. #define MAXDIRLEVELS (6)
  717.  
  718. class _CLASSTYPE TProcessingDialog : public TDialog
  719. {
  720.   public:
  721.     TProcessingDialog(Pchar Adirname, Pchar Atoname,
  722.         int (*do)(Pchar name), BOOL (*func)(Pchar name, Pchar to)); 
  723.  
  724.   protected:
  725.     PTStatic fromdesc;
  726.     PTStatic fromfile;
  727.     PTStatic todesc;
  728.     PTStatic tofile;
  729.     Pchar desc;
  730.     char dirname[MAXPATH];
  731.     char toname[MAXPATH];
  732.     int (TIcon::*do)(Pchar name);
  733.     BOOL (TIcon::*func)(Pchar name, Pchar to);
  734.     dirstate dirarray[MAXDIRLEVELS];
  735.     dirstate *dir;
  736.     int dirlevel;
  737.     int iconnum;
  738.  
  739.     virtual void WMNextFile(RTMessage Msg) = [WM_FIRST + WM_NEXTFILE];
  740. }
  741.  
  742. TProcessingDialog::TProcessingDialog(Pchar Adesc, Pchar Atoname,
  743.     int (*Ado)(Pchar name), BOOL (*Afunc)(Pchar name, Pchar to)) :
  744.     TDialog(FolderView, DLG_Processing)
  745. {
  746.  
  747.  /* Data items */
  748.     desc = Adesc;
  749.     strcpy(dirname, FolderView->Dir());
  750.     if (Atoname)
  751.         strcpy(toname, Atoname);
  752.         else *toname = NULL;
  753.     do = Ado;
  754.     func = Afunc;
  755.  
  756.   /* Controls */
  757.     fromdesc = new TStatic(this, 101, 0);
  758.     fromfile = new TStatic(this, 102, 0);
  759.     todesc = new TStatic(this, 103, 0);
  760.     tofile = new TStatic(this, 104, 0);
  761.     dirlevel = 0;
  762.  
  763.   /* Get first icon */
  764.     iconnum = 0;
  765.     while (iconnum < NumAllIcons() &&
  766.         !GetAllIcon(iconnum)->GetStateFlag(IS_SELECTED))
  767.             iconnum++;
  768. }
  769.  
  770. TProcessingDialog::SetupWindow()
  771. {
  772.     TDialog::SetupWindow();
  773.  
  774.     fromdesc->SetText(desc);
  775.     if (!*toname) todesc->SetText("");
  776.  
  777.         
  778.     SendDlgMsg
  779.  
  780.         ; 
  781. TProcessingDialog::TProcessingDialog(
  782.  
  783. int TProcessingDialog::DoFirstFile()
  784. {
  785.     int ok = do(dirname);
  786.     if (ok != IDYES && ok != IDOK) return ok;
  787.  
  788.     dir->frompos = strlen(dirname);
  789.     strcpy(dirname + dir->frompos, "\\*.*");
  790.     dir->topos = strlen(toname);
  791.     strcpy(toname + dir->topos, "\\");
  792.  
  793.     dir->found = !findfirst(dirname, &(dir->affblk),
  794.         FA_DIREC | FA_SYSTEM | FA_HIDDEN);
  795. }
  796.  
  797. int TProcessingDialog::DoNextFile()
  798. {
  799.     if (dir->affblk.ff_name[0] != '.')
  800.     {
  801.         strcpy(dirname + dir->frompos + 1, dir->affblk.ff_name);
  802.         if (*toname)
  803.             strcpy(toname + dir->topos + 1, dir->affblk.ff_name);
  804.         if (dir->affblk.ff_attrib & FA_DIREC)
  805.         {
  806.             if (dirlevel >= MAXDIRLEVELS)
  807.             {
  808.                 MessageBox(FolderView->HWindow, "Directory level too deep!", ProgramName,
  809.                     MB_ICONSTOP | MB_OK);
  810.                 return IDCANCEL;
  811.             }
  812.             dirlevel++;
  813.             dir = &(dirarray[dirlevel]);
  814.             if (DoFirstFile() == IDCANCEL) return IDCANCEL;
  815.         }
  816.         else
  817.         {
  818.             fromfile->SetText(dirname);
  819.             if (*toname) tofile->SetText(toname);
  820.             func(dirname, toname);
  821.         }
  822.     }
  823.  
  824.     dir->found = !findnext(&(dir->affblk));
  825.     while (!dir->found && dirlevel > 0)
  826.     {
  827.         dirlevel--;
  828.         dir = &(dirarray[dirlevel]);
  829.         dir->found = !findnext(&(dir->affblk));
  830.     }
  831.  
  832.     return IDYES;
  833. }
  834.  
  835. void TProcessingDialog::WMNextFile(RTMessage Msg)
  836. {
  837.     int status;
  838.  
  839.     fromfile->SetText(dirname);
  840.     if (*toname) tofile->SetText(toname);
  841.  
  842.     status = icon->NextFile(frompath, topath);    
  843.     if (status == IDCANCEL)
  844.     {
  845.         CloseWindow(IDCANCEL);
  846.         return;
  847.     }
  848.  
  849.     if (status == IDNO)
  850.     {
  851.         iconnum++;
  852.         while (iconnum < NumAllIcons() &&
  853.             !GetAllIcon(iconnum)->GetStateFlag(IS_SELECTED))
  854.                 iconnum++;
  855.         if (iconnum > NumAllIcons())
  856.         {
  857.             CloseWindow(IDOK);
  858.             return;
  859.         }
  860.         icon->FirstFile(
  861.     }
  862.     PostMessage(HWindow, WM_NEXTFILE, 0, 0L);
  863. }
  864.  
  865.     DoNextFile(
  866.     if (dirlevel)
  867.  
  868.  
  869.     (icon->*func)(dirname, toname);
  870.  
  871.  
  872.  
  873.  
  874. static int DoDeleteDir(Pchar dir)
  875. {
  876.     wsprintf(TextBuf,
  877.         "Are you sure you want to delete all files in directory %s", dir);
  878.     int MessageBox(FolderView->HWindow, TextBuf, ProgramName,
  879.         MB_ICONQUESTION | MB_YESNOCANCEL);
  880. }
  881.  
  882.  
  883.  
  884.  
  885. void TDirIcon::Delete()
  886. {
  887.     
  888.  
  889. void TIcon::Move(Pchar to)
  890. {
  891. }
  892.  
  893. void TIcon::Copy(Pchar to)
  894. {
  895.     _dos_open(
  896.  
  897. }
  898.  
  899. #endif
  900.  
  901. // *************** TFileIcon Class ***************
  902.  
  903. PTIconImage TFileIcon::GetIconImage()
  904. {
  905.     char exepath[MAXPATH];
  906.     PTIconImage iconimage;
  907.  
  908.     int ret = (int)FindExecutable(name, folderview->MainView()->Directory(), exepath);
  909.     if (ret > 32)
  910.     {
  911.         iconimage = IconList.FindIconImage(exepath, 0);
  912.         if (iconimage) return iconimage;
  913.         HICON icon = ExtractIcon(hInstance, exepath, 0);
  914.         if (icon)
  915.         {
  916.             iconimage = new TIconImage(exepath, 0, icon);
  917.             IconList.add(*iconimage);
  918.         }
  919.         else
  920.         {
  921.             iconimage = IconList.FindIconImage(FileIconName, 0);
  922.         }
  923.     }
  924.     else
  925.     {
  926.         iconimage = IconList.FindIconImage(FileIconName, 0);
  927.     }
  928.     return iconimage;
  929. }
  930.  
  931. void TFileIcon::Open()
  932. {
  933.     char filepath[MAXPATH];
  934.  
  935.     strcpy(filepath, folderview->MainView()->Directory());
  936.     strcat(filepath, name);
  937.     ShellExecute(folderview->HWindow, NULL,
  938.         filepath, NULL, folderview->MainView()->Directory(), SW_SHOWNORMAL);
  939. }
  940.  
  941. // *************** TDirIcon Class ***************
  942.  
  943. PTIconImage TDirIcon::GetIconImage()
  944. {
  945.     return IconList.FindIconImage(DirIconName, 0);
  946. }
  947.  
  948. void TDirIcon::Open()
  949. {
  950.     char dirbuf[MAXPATH];
  951.  
  952.     strcpy(dirbuf, folderview->MainView()->Directory());
  953.     strcat(dirbuf, name);
  954.     strcat(dirbuf, "\\");
  955.     ShellExecute(folderview->HWindow, NULL,
  956.         FolderViewFileName, dirbuf, dirbuf, SW_SHOWNORMAL);
  957. }
  958.  
  959. // *************** TProgIcon Class ***************
  960.  
  961. PTIconImage TProgIcon::GetIconImage()
  962. {
  963.     char exepath[MAXPATH];
  964.  
  965.     strcpy(exepath, folderview->MainView()->Directory());
  966.     strcat(exepath, name);
  967.     PTIconImage iconimage = IconList.FindIconImage(exepath, 0);
  968.     if (iconimage) return iconimage;
  969.     HICON icon = ExtractIcon(hInstance, exepath, 0);
  970.     if (icon && icon != 1)
  971.     {
  972.         iconimage = new TIconImage(exepath, 0, icon);
  973.         IconList.add(*iconimage);
  974.     }
  975.     else
  976.     {
  977.         if (strstr(name, ".bat"))
  978.           iconimage = IconList.FindIconImage(BatchIconName, 0);
  979.         else if (strstr(name, ".pif"))
  980.           iconimage = IconList.FindIconImage(PifIconName, 0);
  981.         else
  982.           iconimage = IconList.FindIconImage(ProgIconName, 0);
  983.     }
  984.     return iconimage;
  985. }
  986.  
  987. void TProgIcon::Open()
  988. {
  989.     char exepath[MAXPATH];
  990.  
  991.     strcpy(exepath, folderview->MainView()->Directory());
  992.     strcat(exepath, name);
  993.     ShellExecute(folderview->HWindow, NULL,
  994.         exepath, NULL, folderview->MainView()->Directory(), SW_SHOWNORMAL);
  995. }
  996.  
  997.