home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / bmp3.zip / GETICO.C < prev    next >
C/C++ Source or Header  |  1995-10-18  |  45KB  |  1,165 lines

  1. #pragma    title("Icon/Pointer Viewer  --  Version 1.0  --  (GetIco.C)")
  2. #pragma    subtitle("   Icon Load - Interface Definitions")
  3.  
  4. #pragma    info(noext)
  5.  
  6. #define    INCL_BITMAPFILEFORMAT       /* Include OS/2 Bitmap Information    */
  7. #define    INCL_DOS           /* Include OS/2 DOS Kernal        */
  8. #define    INCL_GPI           /* Include OS/2 GPI Interface    */
  9.  
  10. #include <malloc.h>
  11. #include <os2.h>
  12. #include <string.h>
  13.  
  14. #include "appdefs.h"
  15. #include "winbmp.h"
  16.  
  17.  
  18. /* This    module contains    the functions to load a    requested .ICO file.    */
  19.  
  20. /* Filename:   GetIco.C                            */
  21.  
  22. /*  Version:   1.0                            */
  23. /*  Created:   1995-10-18                        */
  24. /*  Revised:   1995-10-18                        */
  25.  
  26. /* Routines:   static HBITMAP CreateImage(HBITMAP hbmMask,        */
  27. /*                      HBITMAP hbmImage, LONG cx,    */
  28. /*                      LONG cy);            */
  29. /*           static VOID BuildImageStack(                 */
  30. /*                   PBITMAPARRAYFILEHEADER2 pbafh2,    */
  31. /*                   ULONG cbFile);            */
  32. /*           static VOID BuildImageStack1(                 */
  33. /*                   PBITMAPARRAYFILEHEADER pbafh,    */
  34. /*                   ULONG cbFile);            */
  35. /*           static HBITMAP GetSingleImage(PBITMAPFILEHEADER2    pbfh2,     */
  36. /*                        ULONG cbFile);        */
  37. /*           static HBITMAP GetSingleImage1(PBITMAPFILEHEADER    pbfh,     */
  38. /*                         ULONG cbFile);        */
  39. /*           VOID GetIcon(PSZ    pszFileName);                */
  40. /*           static PBITMAPFILEHEADER2 pbfh2GetWindowsBmp(        */
  41. /*               PBYTE pbData, ULONG cbData, PULONG pcbFile);    */
  42.  
  43.  
  44. /* Copyright ╕ 1995  CodeSmithery Corp.     All Rights Reserved.        */
  45.  
  46. /* --------------------------------------------------------------------    */
  47.  
  48. /* --- Module Prototype    Definitions -----------------------------------    */
  49.  
  50. static VOID BuildImageStack(PBITMAPARRAYFILEHEADER2 pbafh2, ULONG ulType);
  51. static VOID BuildImageStack1(PBITMAPARRAYFILEHEADER pbafh, ULONG ulType);
  52.  
  53. static VOID GetSingleImage(PBITMAPFILEHEADER2 pbfh2, ULONG ulType);
  54. static VOID GetSingleImage1(PBITMAPFILEHEADER pbfh, ULONG ulType);
  55.  
  56. static PBITMAPFILEHEADER2 pbfh2GetWindowsIco(PBYTE pbData);
  57. static PBITMAPFILEHEADER2 pbfh2GetWindowsCur(PBYTE pbData);
  58.  
  59. static VOID CreateImage(HBITMAP    hbmMask, HBITMAP hbmImage, LONG    cx, LONG cy, LONG iImage);
  60.  
  61. #pragma    subtitle("   Images Create - Icon/Pointer Bitmap Create Function")
  62. #pragma    page( )
  63.  
  64. /* --- CreateImage ------------------------------------    [ Private ] ---    */
  65. /*                                    */
  66. /*     This function is    used to    create the final image for an icon or    */
  67. /*     pointer.     This is done since the    OS/2 APIs will stretch the    */
  68. /*     image to    the default pointer or icon size.  The idea is to show    */
  69. /*     the actual size recorded    within the file.            */
  70. /*                                    */
  71. /*     Upon Entry:                            */
  72. /*                                    */
  73. /*     Nothing                                */
  74. /*                                    */
  75. /*     Upon Exit:                            */
  76. /*                                    */
  77. /*     Nothing                                */
  78. /*                                    */
  79. /* --------------------------------------------------------------------    */
  80.  
  81. static VOID CreateImage(HBITMAP    hbmMask, HBITMAP hbmImage, LONG    cx, LONG cy, LONG iImage)
  82.  
  83. {
  84. BITMAPINFOHEADER2 bmInfo;       /* Bitmap Information Header        */
  85. HBITMAP          hbm;           /* Bitmap Handle            */
  86. HDC          hDC;           /* Screen Device Context Handle    */
  87. HPS          hpsMem;       /* Memory Presentation Space    Handle    */
  88. LONG          alBmpFormats[2]; /* Bitmap Formats Array        */
  89. POINTL          aptl[4];       /* Bitmap Region Points Array    */
  90. SIZEL          sizl;           /* Size Holder            */
  91.  
  92.                /* Get the memory device    context    handle and    */
  93.                /* calculate the    width and height of the    window/    */
  94.                /* dialogue and save for    the window/dialogue    */
  95.                /* before creating the memory presentation space    */
  96.                /* that is to be    used for the bitmap        */
  97. sizl.cx    = cx;
  98. sizl.cy    = cy;
  99.                /* Get the bitmap format    before creating    the    */
  100.                /* bitmap.  Since different video configurations    */
  101.                /* exist, need to find the number of planes and    */
  102.                /* bits for the current configuration.        */
  103.  
  104. GpiQueryDeviceBitmapFormats(hpsMem = GpiCreatePS(hAB, hDC = DevOpenDC(hAB, OD_MEMORY, "*", 0L, (PDEVOPENDATA)NULL, (HDC)NULL),
  105.                          &sizl,    PU_PELS    | GPIT_MICRO | GPIA_ASSOC), 2L,    alBmpFormats);
  106.  
  107.                /* Initialize the bitmap    header information for    */
  108.                /* the window/dialogue being copied to the    */
  109.                /* clipboard                    */
  110.  
  111. memset(&bmInfo,    0, sizeof(BITMAPINFOHEADER2));
  112. bmInfo.cbFix     = sizeof(BITMAPINFOHEADER2);
  113. bmInfo.cx     = (ULONG)cx;
  114. bmInfo.cy     = (ULONG)cy;
  115. bmInfo.cPlanes     = (USHORT)alBmpFormats[0];
  116. bmInfo.cBitCount = (USHORT)alBmpFormats[1];
  117.  
  118. GpiSetBitmap(hpsMem, hbm = GpiCreateBitmap(hpsMem, &bmInfo, 0L,    NULL, NULL));
  119.  
  120. memset(aptl, 0,    sizeof(POINTL) * 4);
  121.  
  122. aptl[1].x = cx;
  123. aptl[1].y = cy;
  124.  
  125. aptl[3].x = cx + 1L;
  126. aptl[3].y = cy + 1L;
  127.  
  128. GpiSetColor(hpsMem, CLR_WHITE);
  129. GpiSetBackColor(hpsMem,    CLR_BLACK);
  130.  
  131. GpiErase(hpsMem);
  132.  
  133. GpiWCBitBlt(hpsMem, hbmMask, 4L, aptl, ROP_SRCAND, BBO_OR);
  134. if ( hbmImage )
  135.    GpiWCBitBlt(hpsMem, hbmImage, 4L, aptl, ROP_SRCPAINT, BBO_OR);
  136. aptl[2].y = cy;
  137. aptl[3].y = cy * 2L + 1L;
  138. GpiWCBitBlt(hpsMem, hbmMask, 4L, aptl, ROP_SRCINVERT, BBO_OR);
  139.  
  140.                /* Set the memory bitmap    as the current bitmap    */
  141.  
  142. GpiSetBitmap(hpsMem, (HBITMAP)NULL);
  143.  
  144.                /* Destroy the memory device context        */
  145.  
  146. GpiAssociate(hpsMem, (HDC)NULL);
  147. DevCloseDC(hDC);
  148.                /* Destroy the presentation spaces used        */
  149. GpiDestroyPS(hpsMem);
  150.  
  151. abm[iImage].cx = cx;
  152. abm[iImage].cy = cy;
  153.  
  154. abm[iImage].hbmMask = hbmMask;
  155.  
  156. abm[iImage].hbmImage = hbmImage;
  157.  
  158. abm[iImage].hbm    = hbm;
  159. }
  160. #pragma    subtitle("   Icon/Pointer Retrieve - Build Image Stack Function")
  161. #pragma    page( )
  162.  
  163. /* --- BuildImageStack --------------------------------    [ Private ] ---    */
  164. /*                                    */
  165. /*     This function is    used to    build the icon or pointer images for    */
  166. /*     a icon or pointer array and place the icons or pointers within    */
  167. /*     the image stack.                            */
  168. /*                                    */
  169. /*     Upon Entry:                            */
  170. /*                                    */
  171. /*     PBITMAPARRAYFILEHEADER2 pbafh2; = Bitmap    Array Header Pointer    */
  172. /*     ULONG               ulType; = Image Type            */
  173. /*                                    */
  174. /*     Upon Exit:                            */
  175. /*                                    */
  176. /*     Nothing                                */
  177. /*                                    */
  178. /* --------------------------------------------------------------------    */
  179.  
  180. static VOID BuildImageStack(PBITMAPARRAYFILEHEADER2 pbafh2, ULONG ulType)
  181.  
  182. {
  183. HPS            hPS;       /* Presentation Space        */
  184. PBITMAPARRAYFILEHEADER2    pbafhOrg;  /* Bitmap Array File    Header Origin    */
  185. PBITMAPFILEHEADER2    pbfh2Clr;  /* Colour Bitmap File Header        */
  186. PBITMAPFILEHEADER2    pbfh2Mask; /* Mask Bitmap File Header        */
  187.  
  188. pbafhOrg = (PBITMAPARRAYFILEHEADER2)pbafh2;
  189.  
  190. pbfh2Clr  = (PBITMAPFILEHEADER2)((PBYTE)(pbfh2Mask = &pbafh2->bfh2) + sizeof(BITMAPFILEHEADER2)    + 2 * sizeof(RGB2));
  191.  
  192.                /* Save the start of the    bitmap file header    */
  193.                /* since    all offsets are    from the beginning of    */
  194.                /* the header                    */
  195.  
  196. hPS = WinGetPS(HWND_DESKTOP);
  197.  
  198. if ( pbfh2Mask->usType == ulType )
  199.  
  200.                /* Initialize the pointer information        */
  201.  
  202.    CreateImage(GpiCreateBitmap(hPS, &pbfh2Mask->bmp2, CBM_INIT,
  203.                   (PBYTE)pbafhOrg +    pbfh2Mask->offBits, (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  204.            GpiCreateBitmap(hPS, &pbfh2Clr->bmp2, CBM_INIT, (PBYTE)pbafhOrg + pbfh2Clr->offBits,
  205.                    (PBITMAPINFO2)(PVOID)&pbfh2Clr->bmp2), pbfh2Clr->bmp2.cx, pbfh2Clr->bmp2.cy, cBitmaps++);
  206. else
  207.                /* Initialize the pointer information        */
  208.  
  209.    CreateImage(GpiCreateBitmap(hPS, &pbfh2Mask->bmp2, CBM_INIT,
  210.                     (PBYTE)pbafhOrg    + pbfh2Mask->offBits, (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  211.                    (HBITMAP)NULL, pbfh2Mask->bmp2.cx, pbfh2Mask->bmp2.cy / 2L, cBitmaps++);
  212.  
  213.                /* Scan the bitmap array    for the    desired    icon    */
  214.                /* type based on    the current screen display    */
  215. while (    pbafh2->offNext    )
  216.    {
  217.                /* Point    to the next array header        */
  218.  
  219.    pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbafhOrg +    pbafh2->offNext);
  220.    pbfh2Clr  = (PBITMAPFILEHEADER2)((PBYTE)(pbfh2Mask =    &pbafh2->bfh2) + sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2));
  221.  
  222.    if (    pbfh2Mask->usType == ulType )
  223.  
  224.                /* Initialize the pointer information        */
  225.  
  226.        CreateImage(GpiCreateBitmap(hPS,    &pbfh2Mask->bmp2, CBM_INIT, (PBYTE)pbafhOrg + pbfh2Mask->offBits,
  227.                    (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  228.            GpiCreateBitmap(hPS,    &pbfh2Clr->bmp2, CBM_INIT, (PBYTE)pbafhOrg + pbfh2Clr->offBits,
  229.                    (PBITMAPINFO2)(PVOID)&pbfh2Clr->bmp2), pbfh2Clr->bmp2.cx, pbfh2Clr->bmp2.cy,    cBitmaps);
  230.    else
  231.                /* Initialize the pointer information        */
  232.  
  233.       CreateImage(GpiCreateBitmap(hPS, &pbfh2Mask->bmp2, CBM_INIT, (PBYTE)pbafhOrg + pbfh2Mask->offBits,
  234.                  (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  235.           (HBITMAP)NULL, pbfh2Mask->bmp2.cx, pbfh2Mask->bmp2.cy    / 2L, cBitmaps);
  236.  
  237.    if (    ++cBitmaps == 32L )
  238.        break;
  239.    }
  240.                /* Release the memory presentation space        */
  241. WinReleasePS(hPS);
  242.  
  243. }
  244. #pragma    subtitle("   Icon/Pointer Retrieve - Build Image Stack Function")
  245. #pragma    page( )
  246.  
  247. /* --- BuildImageStack1    -------------------------------    [ Private ] ---    */
  248. /*                                    */
  249. /*     This function is    used to    build the icon or pointer images for    */
  250. /*     a icon or pointer array and place the icons or pointers within    */
  251. /*     the image stack.                            */
  252. /*                                    */
  253. /*     Upon Entry:                            */
  254. /*                                    */
  255. /*     PBITMAPARRAYFILEHEADER pbafh;  =    Bitmap Array Header Pointer    */
  256. /*     ULONG              ulType; =    Image Type            */
  257. /*                                    */
  258. /*     Upon Exit:                            */
  259. /*                                    */
  260. /*     Nothing                                */
  261. /*                                    */
  262. /* --------------------------------------------------------------------    */
  263.  
  264. static VOID BuildImageStack1(PBITMAPARRAYFILEHEADER pbafh, ULONG ulType)
  265.  
  266. {
  267. HPS               hPS;       /* Presentation Space        */
  268. PBITMAPARRAYFILEHEADER pbafhOrg;   /* Bitmap Array File    Header Origin    */
  269. PBITMAPFILEHEADER      pbfhClr;       /* Colour Bitmap File Header        */
  270. PBITMAPFILEHEADER      pbfhMask;   /* Mask Bitmap File Header        */
  271.  
  272. pbafhOrg = (PBITMAPARRAYFILEHEADER)pbafh;
  273.  
  274. pbfhClr     = (PBITMAPFILEHEADER)((PBYTE)(pbfhMask    = &pbafh->bfh) + sizeof(BITMAPFILEHEADER) + 2 *    sizeof(RGB2));
  275.  
  276.  
  277. hPS = WinGetPS(HWND_DESKTOP);
  278.  
  279.                /* Save the start of the    bitmap file header    */
  280.                /* since    all offsets are    from the beginning of    */
  281.                /* the header                    */
  282.  
  283. if ( pbfhMask->usType == ulType    )
  284.    CreateImage(GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhMask->bmp,    CBM_INIT,
  285.                    (PBYTE)pbafhOrg + pbfhMask->offBits, (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  286.            GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhClr->bmp, CBM_INIT, (PBYTE)pbafhOrg + pbfhClr->offBits,
  287.                    (PBITMAPINFO2)(PVOID)&pbfhClr->bmp), pbfhClr->bmp.cx, pbfhClr->bmp.cy, cBitmaps++);
  288. else
  289.    CreateImage(GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhMask->bmp,    CBM_INIT,
  290.                    (PBYTE)pbafhOrg + pbfhMask->offBits, (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  291.            (HBITMAP)NULL, pbfhMask->bmp.cx,    pbfhMask->bmp.cy / 2L, cBitmaps++);
  292.  
  293.                /* Scan the bitmap array    for the    desired    icon    */
  294.                /* type based on    the current screen display    */
  295. while (    pbafh->offNext )
  296.    {
  297.                /* Point    to the next array header        */
  298.  
  299.    pbafh = (PBITMAPARRAYFILEHEADER)((PBYTE)pbafhOrg + pbafh->offNext);
  300.    pbfhClr  = (PBITMAPFILEHEADER)((PBYTE)(pbfhMask = &pbafh->bfh) + sizeof(BITMAPFILEHEADER) + 2 * sizeof(RGB2));
  301.  
  302.  
  303.    if (    pbfhMask->usType == ulType )
  304.  
  305.                /* Initialize the pointer information        */
  306.  
  307.        CreateImage(GpiCreateBitmap(hPS,    (PBITMAPINFOHEADER2)&pbfhMask->bmp, CBM_INIT, (PBYTE)pbafhOrg +    pbfhMask->offBits,
  308.                    (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  309.            GpiCreateBitmap(hPS,    (PBITMAPINFOHEADER2)&pbfhClr->bmp, CBM_INIT, (PBYTE)pbafhOrg + pbfhClr->offBits,
  310.                    (PBITMAPINFO2)(PVOID)&pbfhClr->bmp),    pbfhClr->bmp.cx, pbfhClr->bmp.cy, cBitmaps);
  311.    else
  312.                /* Initialize the pointer information        */
  313.  
  314.        CreateImage(GpiCreateBitmap(hPS,    (PBITMAPINFOHEADER2)&pbfhMask->bmp, CBM_INIT, (PBYTE)pbafhOrg +    pbfhMask->offBits,
  315.                   (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  316.           (HBITMAP)NULL, pbfhMask->bmp.cx, pbfhMask->bmp.cy / 2L, cBitmaps);
  317.  
  318.    if (    ++cBitmaps == 32L )
  319.        break;
  320.    }
  321.                /* Release the memory presentation space        */
  322. WinReleasePS(hPS);
  323. }
  324. #pragma    subtitle("   Icon/Pointer Retrieve - Retrieve Single Image Function")
  325. #pragma    page( )
  326.  
  327. /* --- GetSingleImage ---------------------------------    [ Private ] ---    */
  328. /*                                    */
  329. /*     This function is    used to    load a single icon from    an OS/2    2.x    */
  330. /*     icon or pointer file.                        */
  331. /*                                    */
  332. /*     Upon Entry:                            */
  333. /*                                    */
  334. /*     PBITMAPFILEHEADER2 pbafh2; = Bitmap File    Header Pointer        */
  335. /*     ULONG          ulType; = Image Type                */
  336. /*                                    */
  337. /*     Upon Exit:                            */
  338. /*                                    */
  339. /*     Nothing                                */
  340. /*                                    */
  341. /* --------------------------------------------------------------------    */
  342.  
  343. static VOID GetSingleImage(PBITMAPFILEHEADER2 pbfh2, ULONG ulType)
  344.  
  345. {
  346. HPS           hPS;           /* Presentation Space        */
  347. PBITMAPFILEHEADER2 pbfh2Clr;       /* Colour Bitmap File Header        */
  348. PBITMAPFILEHEADER2 pbfh2Mask;       /* Mask Bitmap File Header        */
  349.  
  350.                /* Check    to see that the    size of    the bitmap    */
  351.                /* info header is correct otherwise the icon    */
  352.                /* cannot be created                */
  353.  
  354. if ( pbfh2->bmp2.cbFix != sizeof(BITMAPINFOHEADER2) )
  355.  
  356.                /* Invalid header size                */
  357.    return;
  358.  
  359. cBitmaps = 1L;
  360.  
  361. pbfh2Clr = (PBITMAPFILEHEADER2)((PBYTE)(pbfh2Mask = pbfh2) + sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2));
  362.  
  363.  
  364. hPS = WinGetPS(HWND_DESKTOP);
  365.  
  366. if ( pbfh2Mask->usType == ulType )
  367.  
  368.                /* Initialize the pointer information        */
  369.  
  370.    CreateImage(GpiCreateBitmap(hPS, &pbfh2Mask->bmp2, CBM_INIT,    (PBYTE)pbfh2 + pbfh2Mask->offBits,
  371.                    (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  372.            GpiCreateBitmap(hPS, &pbfh2Clr->bmp2, CBM_INIT, (PBYTE)pbfh2 + pbfh2Clr->offBits,
  373.                    (PBITMAPINFO2)(PVOID)&pbfh2Clr->bmp2), pbfh2Clr->bmp2.cx, pbfh2Clr->bmp2.cy, 0);
  374. else
  375.                /* Initialize the pointer information        */
  376.  
  377.    CreateImage(GpiCreateBitmap(hPS = WinGetPS(HWND_DESKTOP), &pbfh2Mask->bmp2, CBM_INIT,
  378.                    (PBYTE)pbfh2 + pbfh2Mask->offBits, (PBITMAPINFO2)(PVOID)&pbfh2Mask->bmp2),
  379.            (HBITMAP)NULL, pbfh2Mask->bmp2.cx, pbfh2Mask->bmp2.cy / 2L, 0);
  380.  
  381.                /* Release the desktop presentation space    */
  382. WinReleasePS(hPS);
  383.  
  384. }
  385. #pragma    subtitle("   Icon/Pointer Retrieve - Retrieve Single Image Function")
  386. #pragma    page( )
  387.  
  388. /* --- GetSingleImage1 --------------------------------    [ Private ] ---    */
  389. /*                                    */
  390. /*     This function is    used to    load a single icon from    an OS/2    1.x    */
  391. /*     icon or pointer file.                        */
  392. /*                                    */
  393. /*     Upon Entry:                            */
  394. /*                                    */
  395. /*     PBITMAPFILEHEADER pbafh;     = Bitmap File Header Pointer        */
  396. /*     ULONG         ulType; = Image Type                */
  397. /*                                    */
  398. /*     Upon Exit:                            */
  399. /*                                    */
  400. /*     Nothing                                */
  401. /*                                    */
  402. /* --------------------------------------------------------------------    */
  403.  
  404. static VOID GetSingleImage1(PBITMAPFILEHEADER pbfh, ULONG ulType)
  405.  
  406. {
  407. HPS          hPS;           /* Presentation Space        */
  408. PBITMAPFILEHEADER pbfhClr;       /* Colour Bitmap File Header        */
  409. PBITMAPFILEHEADER pbfhMask;       /* Mask Bitmap File Header        */
  410.  
  411.                /* Check    to see that the    size of    the bitmap    */
  412.                /* info header is correct otherwise the icon    */
  413.                /* cannot be created                */
  414.  
  415. if ( pbfh->bmp.cbFix !=    sizeof(BITMAPINFOHEADER) )
  416.  
  417.                /* Invalid header size                */
  418.    return;
  419.  
  420. cBitmaps = 1L;
  421.  
  422. pbfhClr     = (PBITMAPFILEHEADER)((PBYTE)(pbfhMask    = pbfh)    + sizeof(BITMAPFILEHEADER) + 2 * sizeof(RGB));
  423.  
  424. hPS = WinGetPS(HWND_DESKTOP);
  425.  
  426. if ( pbfhMask->usType == ulType    )
  427.  
  428.                /* Initialize the pointer information        */
  429.  
  430.    CreateImage(GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhMask->bmp,    CBM_INIT,
  431.                    (PBYTE)pbfh + pbfhMask->offBits,    (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  432.            GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhClr->bmp, CBM_INIT, (PBYTE)pbfh + pbfhClr->offBits,
  433.                    (PBITMAPINFO2)(PVOID)&pbfhClr->bmp), pbfhClr->bmp.cx, pbfhClr->bmp.cy, 0);
  434. else
  435.                /* Initialize the pointer information        */
  436.  
  437.    CreateImage(GpiCreateBitmap(hPS, (PBITMAPINFOHEADER2)&pbfhMask->bmp,    CBM_INIT,
  438.                    (PBYTE)pbfh + pbfhMask->offBits,    (PBITMAPINFO2)(PVOID)&pbfhMask->bmp),
  439.            (HBITMAP)NULL, pbfhMask->bmp.cx,    pbfhMask->bmp.cy / 2L, 0);
  440.  
  441.                /* Release the desktop presentation space    */
  442. WinReleasePS(hPS);
  443.  
  444. }
  445. #pragma    subtitle("   Icon/Pointer Retrieve - Icon/Pointer Retrieve Function")
  446. #pragma    page( )
  447.  
  448. /* --- GetIcon ----------------------------------------- [ Public ] ---    */
  449. /*                                    */
  450. /*     This function is    used to    load the requested icon    file and to    */
  451. /*     create a    icon set that can be displayed within the client    */
  452. /*     window to allow the user    to select the icon image to convert.    */
  453. /*                                    */
  454. /*     Upon Entry:                            */
  455. /*                                    */
  456. /*     PSZ pszFileName;    = Icon Filename                    */
  457. /*                                    */
  458. /*     Upon Exit:                            */
  459. /*                                    */
  460. /*     Nothing                                */
  461. /*                                    */
  462. /* --------------------------------------------------------------------    */
  463.  
  464. VOID GetIconPointer(PSZ    pszFileName, BOOL fIcon)
  465.  
  466. {
  467. FILESTATUS3           fs;       /* File Status Information        */
  468. HFILE               hFile;       /* File Handle            */
  469. PBITMAPARRAYFILEHEADER pbafh = 0;  /* Bitmap File Header Pointer    */
  470. ULONG               cbRead;       /* Bytes Read            */
  471. ULONG               ulResult;   /* File Open    Fail Result        */
  472. register INT i;               /* Loop Counter            */
  473.  
  474.                /* Open the requested icon file            */
  475.  
  476. if ( DosOpen(pszFileName, &hFile, &ulResult, 0UL, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
  477.          OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL) )
  478.  
  479.                /* Could    not open the file            */
  480.    return;
  481.                /* Get the file information to allow the    proper    */
  482.                /* amount of memory to be allocated for the    */
  483.                /* icon information                */
  484.  
  485. DosQueryFileInfo(hFile,    FIL_STANDARD, (PVOID)&fs, sizeof(FILESTATUS3));
  486.  
  487.                /* Allocate memory for the icon information    */
  488.  
  489. if ( (pbafh = (PBITMAPARRAYFILEHEADER)malloc(fs.cbFile)) == NULL )
  490.  
  491.                /* Memory allocation failed            */
  492.    return;
  493.                /* Read into memory the icon file          */
  494.  
  495. if ( DosRead(hFile, (PVOID)pbafh, fs.cbFile, (PULONG)&cbRead) || (cbRead != fs.cbFile) )
  496.    {
  497.                /* Release the memory allocated for the icon    */
  498.                /* information                    */
  499.    free(pbafh);
  500.                /* Close    the icon file                */
  501.    DosClose(hFile);
  502.                /* Error    occurred in reading the    icon file    */
  503.    return;
  504.    }
  505. else
  506.                /* Close    the icon file                */
  507.    DosClose(hFile);
  508.  
  509. for ( i    = 0; i < cBitmaps; i++ )
  510.    {
  511.    GpiDeleteBitmap(abm[i].hbmMask);
  512.  
  513.    if (    abm[i].hbmImage    )
  514.        GpiDeleteBitmap(abm[i].hbmImage);
  515.  
  516.    GpiDeleteBitmap(abm[i].hbm);
  517.    }
  518.  
  519. memset(abm, 0, 32UL * sizeof(BITMAPSTACK));
  520. cBitmaps = 0L;
  521.  
  522. if ( (pbafh->cbSize == sizeof(BITMAPARRAYFILEHEADER)) || (pbafh->cbSize    == sizeof(BITMAPFILEHEADER)) )
  523.    {
  524.    fWindowsBitmap = f20Bitmap =    fBitmapArray = FALSE;
  525.  
  526.                /* Check    to see if the icon is monochrome      */
  527.  
  528.    if (    (pbafh->usType == BFT_ICON)    || (pbafh->usType == BFT_COLORICON) ||
  529.     (pbafh->usType == BFT_POINTER) || (pbafh->usType == BFT_COLORPOINTER) )
  530.  
  531.                /* Monochrome icon, convert into    a memory      */
  532.                /* icon and a valid icon    handle            */
  533.  
  534.        GetSingleImage1((PBITMAPFILEHEADER)(PVOID)pbafh,    fIcon ?    BFT_COLORICON :    BFT_COLORPOINTER);
  535.    else
  536.                /* Check    to see if the icon is a    bitmap array    */
  537.                /* thereby indicating a coloured    icon          */
  538.  
  539.        if ( pbafh->usType == BFT_BITMAPARRAY )
  540.        {
  541.                /* Coloured icon, convert into a    memory icon */
  542.                /* icon and a valid icon    handle            */
  543.  
  544.        BuildImageStack1((PBITMAPARRAYFILEHEADER)pbafh, fIcon ? BFT_COLORICON : BFT_COLORPOINTER);
  545.        fBitmapArray    = TRUE;
  546.        }
  547.    }
  548. else
  549.    if (    (pbafh->cbSize == sizeof(BITMAPARRAYFILEHEADER2)) || (pbafh->cbSize == sizeof(BITMAPFILEHEADER2)) )
  550.        {
  551.        f20Bitmap = TRUE;
  552.        fWindowsBitmap =    fBitmapArray = FALSE;
  553.  
  554.                /* Check    to see if the icon is monochrome      */
  555.  
  556.        if ( (pbafh->usType == BFT_ICON)       || (pbafh->usType ==    BFT_COLORICON) ||
  557.         (pbafh->usType == BFT_POINTER) || (pbafh->usType ==    BFT_COLORPOINTER) )
  558.  
  559.                /* Monochrome icon, convert into    a memory      */
  560.                /* icon and a valid icon    handle            */
  561.  
  562.        GetSingleImage((PBITMAPFILEHEADER2)(PVOID)pbafh, fIcon ? BFT_COLORICON : BFT_COLORPOINTER);
  563.        else
  564.                /* Check    to see if the icon is a    bitmap array    */
  565.                /* thereby indicating a coloured    icon          */
  566.  
  567.        if (    pbafh->usType == BFT_BITMAPARRAY )
  568.            {
  569.                /* Coloured icon, convert into a    memory icon */
  570.                /* icon and a valid icon    handle            */
  571.  
  572.            BuildImageStack((PBITMAPARRAYFILEHEADER2)(PVOID)pbafh, fIcon ? BFT_COLORICON : BFT_COLORPOINTER);
  573.            fBitmapArray = TRUE;
  574.            }
  575.        }
  576.    else
  577.                /* Appears to be    a Windows icon,    try to          */
  578.                /* convert it to    an OS/2    2.x format icon          */
  579.        {
  580.        fBitmapArray = FALSE;
  581.        if ( fIcon )
  582.        pbafh = (PBITMAPARRAYFILEHEADER)pbfh2GetWindowsIco((PBYTE)pbafh);
  583.        else
  584.        pbafh = (PBITMAPARRAYFILEHEADER)pbfh2GetWindowsCur((PBYTE)pbafh);
  585.  
  586.                /* Check    to see if the icon is monochrome      */
  587.  
  588.        if ( (pbafh->usType == BFT_ICON)       || (pbafh->usType ==    BFT_COLORICON) ||
  589.         (pbafh->usType == BFT_POINTER) || (pbafh->usType ==    BFT_COLORPOINTER) )
  590.  
  591.                /* Monochrome icon, convert into    a memory      */
  592.                /* icon and a valid icon    handle            */
  593.  
  594.        GetSingleImage((PBITMAPFILEHEADER2)(PVOID)pbafh, fIcon ? BFT_COLORICON : BFT_COLORPOINTER);
  595.        else
  596.                /* Check    to see if the icon is a    bitmap array    */
  597.                /* thereby indicating a coloured    icon          */
  598.  
  599.        if (    pbafh->usType == BFT_BITMAPARRAY )
  600.            {
  601.             /* Coloured icon, convert into a memory    icon */
  602.                /* icon and a valid icon    handle            */
  603.  
  604.            BuildImageStack((PBITMAPARRAYFILEHEADER2)(PVOID)pbafh, fIcon ? BFT_COLORICON : BFT_COLORPOINTER);
  605.            fBitmapArray = TRUE;
  606.            }
  607.  
  608.        fWindowsBitmap =    f20Bitmap = TRUE;
  609.        }
  610.  
  611. if ( pb    )
  612.    free(pb);
  613. pb = (PBYTE)pbafh;
  614.  
  615. }
  616. #pragma    subtitle("   Icon/Pointer Retrieve - Windows Icon Image Retrieve Function")
  617. #pragma    page( )
  618.  
  619. /* --- pbfh2GetWindowsIco ------------------------------ [ Public ] ---    */
  620. /*                                    */
  621. /*     This function is    used to    convert    a Windows icon to an OS/2    */
  622. /*     2.x type    of icon.                        */
  623. /*                                    */
  624. /*     Upon Entry:                            */
  625. /*                                    */
  626. /*     PBYTE pbIcon; = Pointer to Windows Icon Data            */
  627. /*     ULONG cbData; = Windows Icon Data Size                */
  628. /*                                    */
  629. /*     Upon Exit:                            */
  630. /*                                    */
  631. /*     pbfh2GetWindowsIco = Convert Icon Data Pointer            */
  632. /*                                    */
  633. /* --------------------------------------------------------------------    */
  634.  
  635. static PBITMAPFILEHEADER2 pbfh2GetWindowsIco(PBYTE pbIcon)
  636.  
  637. {
  638. PBITMAPFILEHEADER2    pbfh2Clr;  /* Bitmap File Header Pointer    */
  639. PBITMAPFILEHEADER2    pbfh2Mask; /* Bitmap File Header Pointer    */
  640. PwinBITMAPINFOHEADER    pwbmpi;       /* Bitmap File Header        */
  641. RGB2               *prgb2;       /* RGB Table    Pointer            */
  642. PBITMAPARRAYFILEHEADER2    pbafh2;       /* Bitmap Array File    Header Pointer    */
  643. ULONG            cClrs;       /* Colours Table Count        */
  644. ULONG            cbXorAnd;  /* Bytes Read            */
  645. PBYTE            pbImage;   /* Image Pointer            */
  646. PBYTE            pbWinImage;/* Image Pointer            */
  647. PBYTE            pbOS2Ico;  /* Data Pointer            */
  648. PwinICONDIR        pwid;       /* Icon Directory Pointer        */
  649. ULONG            cbImage;   /* Image Size            */
  650. ULONG            cbMask;       /* Mask Size                */
  651. ULONG            cbFile;       /* File Size                */
  652. register INT i;               /* Loop Counter            */
  653.  
  654. pwid = (PwinICONDIR)pbIcon;
  655. if ( pwid->idCount )
  656.    for ( i = 0,    cbFile = 0UL; i    < pwid->idCount; i++ )
  657.        {
  658.        pwbmpi =    (PwinBITMAPINFOHEADER)(pbIcon +    pwid->idEntries[i].dwImageOffset);
  659.  
  660.        cbImage = (((pwbmpi->biWidth * pwbmpi->biBitCount + 31L)    & 0xffffffe0) >> 3) * pwbmpi->biHeight / 2L;
  661.        cbMask  = (((pwbmpi->biWidth + 31L) & 0xffffffe0) >> 3) * pwbmpi->biHeight;
  662.  
  663.        if ( (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2 )
  664.        cbFile += sizeof(BITMAPARRAYFILEHEADER2) + 2    * sizeof(RGB2) + cbMask;
  665.        else
  666.        cbFile += sizeof(BITMAPARRAYFILEHEADER2) + sizeof(BITMAPFILEHEADER2)    + (cClrs + 2) *    sizeof(RGB2) + cbImage + cbMask;
  667.        }
  668. else
  669.    {
  670.    pwbmpi = (PwinBITMAPINFOHEADER)(pbIcon + pwid->idEntries[i].dwImageOffset);
  671.  
  672.    cbImage = (((pwbmpi->biWidth    * pwbmpi->biBitCount + 31L) & 0xffffffe0) >> 3)    * pwbmpi->biHeight / 2L;
  673.    cbMask  = (((pwbmpi->biWidth    + 31L) & 0xffffffe0) >>    3) * pwbmpi->biHeight;
  674.  
  675.    if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2    )
  676.        cbFile += sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2) +    cbMask;
  677.    else
  678.        cbFile += sizeof(BITMAPFILEHEADER2) * 2 + (cClrs    + 2) * sizeof(RGB2) + cbImage +    cbMask / 2L;
  679.    }
  680.                /* Initialize the bitmap    array header        */
  681.  
  682. memset(pbOS2Ico    = (PBYTE)malloc(cbFile), 0, cbFile);
  683.  
  684. if ( pwid->idCount == 1    )
  685.    {
  686.    pbfh2Mask = (PBITMAPFILEHEADER2)pbOS2Ico;
  687.    pbWinImage =    (PBYTE)(pwbmpi = (PwinBITMAPINFOHEADER)(pbIcon + pwid->idEntries[0].dwImageOffset)) + sizeof(winBITMAPINFOHEADER);
  688.  
  689.    cClrs   = (ULONG)(1 << pwbmpi->biBitCount);
  690.    cbMask  = (((pwbmpi->biWidth    + 31L) & 0xffffffe0) >>    3) * pwbmpi->biHeight;
  691.  
  692.                /* Initialize the first icon header for the    */
  693.                /* icon                          */
  694.  
  695.    pbfh2Mask->usType   = (USHORT)(cClrs    == 2 ? BFT_ICON: BFT_COLORICON);
  696.    pbfh2Mask->cbSize   = sizeof(BITMAPFILEHEADER2);
  697.    pbfh2Mask->xHotspot = (SHORT)(pwbmpi->biWidth  / 2);
  698.    pbfh2Mask->yHotspot = (SHORT)(pwbmpi->biHeight / 4);
  699.    pbfh2Mask->offBits  = cClrs == 2 ? sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2 : sizeof(BITMAPFILEHEADER2) * 2 + sizeof(RGB2) * (cClrs + 2);
  700.    pbfh2Mask->bmp2.cbFix     =       sizeof(BITMAPINFOHEADER2);
  701.    pbfh2Mask->bmp2.cx         =  (ULONG)pwbmpi->biWidth;
  702.    pbfh2Mask->bmp2.cy         =  (ULONG)pwbmpi->biHeight;
  703.    pbfh2Mask->bmp2.cPlanes     = (USHORT)1;
  704.    pbfh2Mask->bmp2.cBitCount     = (USHORT)1;
  705.    pbfh2Mask->bmp2.cclrImportant =       2;
  706.  
  707.    prgb2 = (RGB2 *)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2));
  708.    prgb2[0].bBlue     =    (BYTE)0x00;
  709.    prgb2[0].bGreen    =    (BYTE)0x00;
  710.    prgb2[0].bRed      =    (BYTE)0x00;
  711.    prgb2[0].fcOptions =    (BYTE)0x00;
  712.    prgb2[1].bBlue     =    (BYTE)0xff;
  713.    prgb2[1].bGreen    =    (BYTE)0xff;
  714.    prgb2[1].bRed      =    (BYTE)0xff;
  715.    prgb2[1].fcOptions =    (BYTE)0x00;
  716.  
  717.    if (    cClrs != 2 )
  718.        {
  719.                /* Initialize the icon information for the     */
  720.                /* icon based on    the values from    the Windows   */
  721.                /* 3.1 icon                      */
  722.  
  723.        pbfh2Clr    = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask    + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2);
  724.        pbfh2Clr->usType      = (USHORT)BFT_COLORICON;
  725.        pbfh2Clr->cbSize      = sizeof(BITMAPFILEHEADER2);
  726.        pbfh2Clr->xHotspot = (SHORT)(pwbmpi->biWidth  / 2);
  727.        pbfh2Clr->yHotspot = (SHORT)(pwbmpi->biHeight / 4);
  728.        pbfh2Clr->offBits  = sizeof(BITMAPFILEHEADER2) *    2 + sizeof(RGB2) * (cClrs + 2) + cbMask;
  729.  
  730.        pbfh2Clr->bmp2.cbFix        = sizeof(BITMAPINFOHEADER2);
  731.        pbfh2Clr->bmp2.cx        = (ULONG)pwbmpi->biWidth;
  732.        pbfh2Clr->bmp2.cy        = (ULONG)pwbmpi->biHeight /    2UL;
  733.        pbfh2Clr->bmp2.cPlanes        =         pwbmpi->biPlanes;
  734.        pbfh2Clr->bmp2.cBitCount        =         pwbmpi->biBitCount;
  735.        pbfh2Clr->bmp2.cclrImportant = cClrs;
  736.  
  737.        pbImage      = (PBYTE)pbfh2Clr + sizeof(BITMAPFILEHEADER2);
  738.  
  739.                /* When a colour    table present, write out the    */
  740.                /* colour table                    */
  741.        if ( cClrs )
  742.        {
  743.        memcpy(pbImage, pbWinImage, sizeof(winRGBQUAD) * cClrs);
  744.        pbImage    += sizeof(RGB2) *    cClrs;
  745.        pbWinImage += sizeof(winRGBQUAD) * cClrs;
  746.        }
  747.  
  748.        if ( (cbXorAnd =    cbMask / 2) != 0 )
  749.        {
  750.        memcpy(pbImage += cbXorAnd, pbWinImage + pwbmpi->biSizeImage    - cbXorAnd, cbXorAnd);
  751.        pbImage += cbXorAnd;
  752.        }
  753.  
  754.        memcpy(pbImage, pbWinImage, pwbmpi->biSizeImage - cbXorAnd);
  755.        }
  756.    else
  757.        memcpy((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2), pbWinImage + sizeof(winRGBQUAD) * 2, pwbmpi->biSizeImage);
  758.    }
  759. else
  760.    {
  761.    pbafh2 = (PBITMAPARRAYFILEHEADER2)pbOS2Ico;
  762.    for ( i = 0;    i < pwid->idCount; i++ )
  763.        {
  764.        pwbmpi =    (PwinBITMAPINFOHEADER)(pbIcon +    pwid->idEntries[i].dwImageOffset);
  765.  
  766.        pbafh2->usType  = (USHORT)BFT_BITMAPARRAY;
  767.        pbafh2->cbSize  = sizeof(BITMAPARRAYFILEHEADER2);
  768.  
  769.        if ( i != (pwid->idCount    - 1) )
  770.        if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2    )
  771.            pbafh2->offNext = (ULONG)((PBYTE)pbafh2 - pbOS2Ico) + sizeof(BITMAPARRAYFILEHEADER2) + sizeof(RGB2) * 2;
  772.        else
  773.            pbafh2->offNext = (ULONG)((PBYTE)pbafh2 - pbOS2Ico) + sizeof(BITMAPARRAYFILEHEADER2) + sizeof(BITMAPFILEHEADER2)    +
  774.                  sizeof(RGB2) *    (cClrs + 2);
  775.        else
  776.        cClrs = (ULONG)(1 <<    pwbmpi->biBitCount);
  777.        pbfh2Mask = &pbafh2->bfh2;
  778.  
  779.                /* Initialize the first icon header for the    */
  780.                /* icon                          */
  781.  
  782.        pbfh2Mask->usType   = (USHORT)(cClrs == 2 ? BFT_ICON: BFT_COLORICON);
  783.        pbfh2Mask->cbSize   = sizeof(BITMAPFILEHEADER2);
  784.        pbfh2Mask->xHotspot = (SHORT)(pwbmpi->biWidth  /    2);
  785.        pbfh2Mask->yHotspot = (SHORT)(pwbmpi->biHeight /    4);
  786.        pbfh2Mask->bmp2.cbFix         =          sizeof(BITMAPINFOHEADER2);
  787.        pbfh2Mask->bmp2.cx         = (ULONG)pwbmpi->biWidth;
  788.        pbfh2Mask->bmp2.cy         = (ULONG)pwbmpi->biHeight;
  789.        pbfh2Mask->bmp2.cPlanes         = (USHORT)1;
  790.        pbfh2Mask->bmp2.cBitCount     = (USHORT)1;
  791.        pbfh2Mask->bmp2.cclrImportant =          2;
  792.  
  793.        prgb2 = (RGB2 *)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2));
  794.        prgb2[0].bBlue      = (BYTE)0x00;
  795.        prgb2[0].bGreen      = (BYTE)0x00;
  796.        prgb2[0].bRed      = (BYTE)0x00;
  797.        prgb2[0].fcOptions = (BYTE)0x00;
  798.        prgb2[1].bBlue      = (BYTE)0xff;
  799.        prgb2[1].bGreen      = (BYTE)0xff;
  800.        prgb2[1].bRed      = (BYTE)0xff;
  801.        prgb2[1].fcOptions = (BYTE)0x00;
  802.  
  803.                /* Initialize the icon information for the     */
  804.                /* icon based on    the values from    the Windows   */
  805.                /* 3.1 icon                      */
  806.        if ( cClrs != 2 )
  807.        {
  808.        pbfh2Clr = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2);
  809.        pbfh2Clr->usType   =    (USHORT)BFT_COLORICON;
  810.        pbfh2Clr->cbSize   =    sizeof(BITMAPFILEHEADER2);
  811.        pbfh2Clr->xHotspot =    (SHORT)(pwbmpi->biWidth     / 2);
  812.        pbfh2Clr->yHotspot =    (SHORT)(pwbmpi->biHeight / 4);
  813.  
  814.        pbfh2Clr->bmp2.cbFix        = sizeof(BITMAPINFOHEADER2);
  815.        pbfh2Clr->bmp2.cx        = (ULONG)pwbmpi->biWidth;
  816.        pbfh2Clr->bmp2.cy        = (ULONG)pwbmpi->biHeight / 2UL;
  817.        pbfh2Clr->bmp2.cPlanes    =     pwbmpi->biPlanes;
  818.        pbfh2Clr->bmp2.cBitCount    =     pwbmpi->biBitCount;
  819.        pbfh2Clr->bmp2.cclrImportant    = cClrs;
  820.  
  821.                /* When a colour    table present, write out the    */
  822.                /* colour table                    */
  823.  
  824.        memcpy(pbImage = (PBYTE)pbfh2Clr + sizeof(BITMAPFILEHEADER2), pbWinImage = (PBYTE)pwbmpi + sizeof(winBITMAPINFOHEADER),
  825.           sizeof(winRGBQUAD) * cClrs);
  826.        pbafh2 = (PBITMAPARRAYFILEHEADER2)(pbImage += sizeof(RGB2) *    cClrs);
  827.        }
  828.        else
  829.        pbImage = (PBYTE)(pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2));
  830.        }
  831.  
  832.    pbafh2 = (PBITMAPARRAYFILEHEADER2)pbOS2Ico;
  833.  
  834.    for ( i = 0;    i < pwid->idCount; i++ )
  835.        {
  836.  
  837.        pbWinImage = (PBYTE)(pwbmpi = (PwinBITMAPINFOHEADER)(pbIcon + pwid->idEntries[i].dwImageOffset))    + sizeof(winBITMAPINFOHEADER);
  838.  
  839.        cbMask  = (((pwbmpi->biWidth + 31L) & 0xffffffe0) >> 3) * pwbmpi->biHeight;
  840.  
  841.        pbfh2Mask = &pbafh2->bfh2;
  842.  
  843.                /* Initialize the first icon header for the    */
  844.                /* icon                          */
  845.  
  846.        pbfh2Mask->offBits = (ULONG)(pbImage - pbOS2Ico);
  847.  
  848.        if ( (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) != 2 )
  849.        {
  850.                /* Initialize the icon information for the     */
  851.                /* icon based on    the values from    the Windows   */
  852.                /* 3.1 icon                      */
  853.  
  854.        pbfh2Clr = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2);
  855.        pbfh2Clr->offBits = (ULONG)(pbImage - pbOS2Ico) + cbMask;
  856.  
  857.                /* When a colour    table present, write out the    */
  858.                /* colour table                    */
  859.  
  860.        if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) != 0    )
  861.            pbWinImage += sizeof(winRGBQUAD)    * cClrs;
  862.  
  863.        if (    (cbXorAnd = cbMask / 2UL) != 0 )
  864.            {
  865.            memcpy(pbImage += cbXorAnd, pbWinImage +    pwbmpi->biSizeImage - cbXorAnd,    cbXorAnd);
  866.            pbImage += cbXorAnd;
  867.            }
  868.  
  869.        memcpy(pbImage, pbWinImage, pwbmpi->biSizeImage - cbXorAnd);
  870.        pbImage += pwbmpi->biSizeImage - cbXorAnd;
  871.        pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Clr +    sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * cClrs);
  872.        }
  873.        else
  874.        {
  875.        memcpy(pbImage, pbWinImage +    sizeof(winRGBQUAD) * 2,    pwbmpi->biSizeImage);
  876.        pbImage += pwbmpi->biSizeImage;
  877.        pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2);
  878.        }
  879.        }
  880.    }
  881.  
  882. free(pbIcon);
  883.  
  884. return((PBITMAPFILEHEADER2)pbOS2Ico);
  885. }
  886. #pragma    subtitle("   Icon/Pointer Retrieve - Windows Cursor Image Retrieve Function")
  887. #pragma    page( )
  888.  
  889. /* --- pbfh2GetWindowsCur ------------------------------ [ Public ] ---    */
  890. /*                                    */
  891. /*     This function is    used to    convert    a Windows cursor to an OS/2    */
  892. /*     2.x type    of icon.                        */
  893. /*                                    */
  894. /*     Upon Entry:                            */
  895. /*                                    */
  896. /*     PBYTE pbCur;  = Pointer to Windows Cursor Data            */
  897. /*     ULONG cbData; = Windows Icon Data Size                */
  898. /*                                    */
  899. /*     Upon Exit:                            */
  900. /*                                    */
  901. /*     pbfh2GetWindowsCur = Convert Icon Data Pointer            */
  902. /*                                    */
  903. /* --------------------------------------------------------------------    */
  904.  
  905. static PBITMAPFILEHEADER2 pbfh2GetWindowsCur(PBYTE pbCur)
  906.  
  907. {
  908. PBITMAPFILEHEADER2    pbfh2Clr;  /* Bitmap File Header Pointer    */
  909. PBITMAPFILEHEADER2    pbfh2Mask; /* Bitmap File Header Pointer    */
  910. PBITMAPARRAYFILEHEADER2    pbafh2;       /* Bitmap Array File    Header Pointer    */
  911. PwinBITMAPINFOHEADER    pwbmpi;       /* Bitmap File Header        */
  912. RGB2               *prgb2;       /* RGB Table    Pointer            */
  913. ULONG            cClrs;       /* Colours Table Count        */
  914. ULONG            cbXorAnd;  /* Bytes Read            */
  915. PBYTE            pbImage;   /* Image Pointer            */
  916. PBYTE            pbWinImage;/* Image Pointer            */
  917. PBYTE            pbOS2Ptr;  /* Data Pointer            */
  918. PwinCURSORDIR        pwcd;       /* Cursor Directory Pointer        */
  919. ULONG            cbImage;   /* Image Size            */
  920. ULONG            cbMask;       /* Mask Size                */
  921. ULONG            cbFile;       /* File Size                */
  922. register INT i;               /* Loop Counter            */
  923.  
  924. pwcd = (PwinCURSORDIR)pbCur;
  925. if ( pwcd->cdCount )
  926.    for ( i = 0,    cbFile = 0UL; i    < pwcd->cdCount; i++ )
  927.        {
  928.        pwbmpi =    (PwinBITMAPINFOHEADER)(pbCur + pwcd->cdEntries[i].dwImageOffset);
  929.  
  930.        cbImage = (((pwbmpi->biWidth * pwbmpi->biBitCount + 31L)    & 0xffffffe0) >> 3) * pwbmpi->biHeight / 2L;
  931.        cbMask  = (((pwbmpi->biWidth + 31L) & 0xffffffe0) >> 3) * pwbmpi->biHeight;
  932.  
  933.        if ( (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2 )
  934.        cbFile += sizeof(BITMAPARRAYFILEHEADER2) + 2    * sizeof(RGB2) + cbMask;
  935.        else
  936.        cbFile += sizeof(BITMAPARRAYFILEHEADER2) + sizeof(BITMAPFILEHEADER2)    + (cClrs + 2) *    sizeof(RGB2) +
  937.                cbImage + cbMask;
  938.        }
  939. else
  940.    {
  941.    pwbmpi = (PwinBITMAPINFOHEADER)(pbCur + pwcd->cdEntries[i].dwImageOffset);
  942.  
  943.    cbImage = (((pwbmpi->biWidth    * pwbmpi->biBitCount + 31L) & 0xffffffe0) >> 3)    * pwbmpi->biHeight / 2L;
  944.    cbMask  = (((pwbmpi->biWidth    + 31L) & 0xffffffe0) >>    3) * pwbmpi->biHeight;
  945.  
  946.    if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2    )
  947.        cbFile += sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2) +    cbMask;
  948.    else
  949.        cbFile += sizeof(BITMAPFILEHEADER2) * 2 + (cClrs    + 2) * sizeof(RGB2) + cbImage +    cbMask / 2L;
  950.    }
  951.                /* Initialize the bitmap    array header        */
  952.  
  953. memset(pbOS2Ptr    = (PBYTE)malloc(cbFile), 0, cbFile);
  954.  
  955. if ( pwcd->cdCount == 1    )
  956.    {
  957.    pbfh2Mask = (PBITMAPFILEHEADER2)pbOS2Ptr;
  958.    pbWinImage =    (PBYTE)(pwbmpi = (PwinBITMAPINFOHEADER)(pbCur +    pwcd->cdEntries[0].dwImageOffset)) + sizeof(winBITMAPINFOHEADER);
  959.  
  960.    cClrs = (ULONG)(1 <<    pwbmpi->biBitCount);
  961.    cbMask  = (((pwbmpi->biWidth    + 31L) & 0xffffffe0) >>    3) * pwbmpi->biHeight;
  962.  
  963.                /* Initialize the first icon header for the    */
  964.                /* icon                          */
  965.  
  966.    pbfh2Mask->usType   = (USHORT)(cClrs    == 2 ? BFT_POINTER: BFT_COLORPOINTER);
  967.    pbfh2Mask->cbSize   = sizeof(BITMAPFILEHEADER2);
  968.    pbfh2Mask->xHotspot = (SHORT)pwcd->cdEntries[0].wXHotspot;
  969.    pbfh2Mask->yHotspot = (SHORT)pwcd->cdEntries[0].wYHotspot;
  970.    pbfh2Mask->offBits  = cClrs == 2 ? sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2 : sizeof(BITMAPFILEHEADER2) * 2 + sizeof(RGB2) * (cClrs + 2);
  971.    pbfh2Mask->bmp2.cbFix     =       sizeof(BITMAPINFOHEADER2);
  972.    pbfh2Mask->bmp2.cx         =  (ULONG)pwbmpi->biWidth;
  973.    pbfh2Mask->bmp2.cy         =  (ULONG)pwbmpi->biHeight;
  974.    pbfh2Mask->bmp2.cPlanes     = (USHORT)1;
  975.    pbfh2Mask->bmp2.cBitCount     = (USHORT)1;
  976.    pbfh2Mask->bmp2.cclrImportant =       2;
  977.  
  978.    prgb2 = (RGB2 *)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2));
  979.    prgb2[0].bBlue     =    (BYTE)0x00;
  980.    prgb2[0].bGreen    =    (BYTE)0x00;
  981.    prgb2[0].bRed      =    (BYTE)0x00;
  982.    prgb2[0].fcOptions =    (BYTE)0x00;
  983.    prgb2[1].bBlue     =    (BYTE)0xff;
  984.    prgb2[1].bGreen    =    (BYTE)0xff;
  985.    prgb2[1].bRed      =    (BYTE)0xff;
  986.    prgb2[1].fcOptions =    (BYTE)0x00;
  987.  
  988.    if (    cClrs != 2 )
  989.        {
  990.                /* Initialize the icon information for the     */
  991.                /* icon based on    the values from    the Windows   */
  992.                /* 3.1 icon                      */
  993.  
  994.        pbfh2Clr    = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask    + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2);
  995.        pbfh2Clr->usType      = (USHORT)BFT_COLORPOINTER;
  996.        pbfh2Clr->cbSize      = sizeof(BITMAPFILEHEADER2);
  997.        pbfh2Clr->xHotspot = (SHORT)pwcd->cdEntries[0].wXHotspot;
  998.        pbfh2Clr->yHotspot = (SHORT)pwcd->cdEntries[0].wYHotspot;
  999.        pbfh2Clr->offBits  = sizeof(BITMAPFILEHEADER2) *    2 + sizeof(RGB2) * (cClrs + 2) + cbMask;
  1000.  
  1001.        pbfh2Clr->bmp2.cbFix        = sizeof(BITMAPINFOHEADER2);
  1002.        pbfh2Clr->bmp2.cx        = (ULONG)pwbmpi->biWidth;
  1003.        pbfh2Clr->bmp2.cy        = (ULONG)pwbmpi->biHeight /    2UL;
  1004.        pbfh2Clr->bmp2.cPlanes        =         pwbmpi->biPlanes;
  1005.        pbfh2Clr->bmp2.cBitCount        =         pwbmpi->biBitCount;
  1006.        pbfh2Clr->bmp2.cclrImportant = cClrs;
  1007.  
  1008.        pbImage      = (PBYTE)pbfh2Clr + sizeof(BITMAPFILEHEADER2);
  1009.  
  1010.                /* When a colour    table present, write out the    */
  1011.                /* colour table                    */
  1012.        if ( cClrs )
  1013.        {
  1014.        memcpy(pbImage, pbWinImage, sizeof(winRGBQUAD) * cClrs);
  1015.        pbImage    += sizeof(RGB2) *    cClrs;
  1016.        pbWinImage += sizeof(winRGBQUAD) * cClrs;
  1017.        }
  1018.  
  1019.        if ( (cbXorAnd =    cbMask / 2UL) != 0 )
  1020.        {
  1021.        memcpy(pbImage += cbXorAnd, pbWinImage + pwbmpi->biSizeImage    - cbXorAnd, cbXorAnd);
  1022.        pbImage += cbXorAnd;
  1023.        }
  1024.  
  1025.        memcpy(pbImage, pbWinImage, pwbmpi->biSizeImage - cbXorAnd);
  1026.        }
  1027.    else
  1028.        {
  1029.        memcpy((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + 2 * sizeof(RGB2), pbWinImage + sizeof(winRGBQUAD) * 2, pwbmpi->biSizeImage);
  1030.        }
  1031.    }
  1032. else
  1033.    {
  1034.    pbafh2 = (PBITMAPARRAYFILEHEADER2)pbOS2Ptr;
  1035.    for ( i = 0;    i < pwcd->cdCount; i++ )
  1036.        {
  1037.        pwbmpi =    (PwinBITMAPINFOHEADER)(pbCur + pwcd->cdEntries[i].dwImageOffset);
  1038.  
  1039.        pbafh2->usType  = (USHORT)BFT_BITMAPARRAY;
  1040.        pbafh2->cbSize  = sizeof(BITMAPARRAYFILEHEADER2);
  1041.  
  1042.        if ( i != (pwcd->cdCount    - 1) )
  1043.        if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) == 2    )
  1044.            pbafh2->offNext = (ULONG)((PBYTE)pbafh2 - pbOS2Ptr) + sizeof(BITMAPARRAYFILEHEADER2) + sizeof(RGB2) * 2;
  1045.        else
  1046.            pbafh2->offNext = (ULONG)((PBYTE)pbafh2 - pbOS2Ptr) + sizeof(BITMAPARRAYFILEHEADER2) + sizeof(BITMAPFILEHEADER2)    +
  1047.                  sizeof(RGB2) *    (cClrs + 2);
  1048.        else
  1049.        cClrs = (ULONG)(1 <<    pwbmpi->biBitCount);
  1050.        pbfh2Mask = &pbafh2->bfh2;
  1051.  
  1052.                /* Initialize the first icon header for the    */
  1053.                /* icon                          */
  1054.  
  1055.        pbfh2Mask->usType   = (USHORT)(cClrs == 2 ? BFT_POINTER:    BFT_COLORPOINTER);
  1056.        pbfh2Mask->cbSize   = sizeof(BITMAPFILEHEADER2);
  1057.        pbfh2Mask->xHotspot = (SHORT)pwcd->cdEntries[i].wXHotspot;
  1058.        pbfh2Mask->yHotspot = (SHORT)pwcd->cdEntries[i].wYHotspot;
  1059.        pbfh2Mask->bmp2.cbFix         =          sizeof(BITMAPINFOHEADER2);
  1060.        pbfh2Mask->bmp2.cx         = (ULONG)pwbmpi->biWidth;
  1061.        pbfh2Mask->bmp2.cy         = (ULONG)pwbmpi->biHeight;
  1062.        pbfh2Mask->bmp2.cPlanes         = (USHORT)1;
  1063.        pbfh2Mask->bmp2.cBitCount     = (USHORT)1;
  1064.        pbfh2Mask->bmp2.cclrImportant =          2;
  1065.  
  1066.        prgb2 = (RGB2 *)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2));
  1067.        prgb2[0].bBlue      = (BYTE)0x00;
  1068.        prgb2[0].bGreen      = (BYTE)0x00;
  1069.        prgb2[0].bRed      = (BYTE)0x00;
  1070.        prgb2[0].fcOptions = (BYTE)0x00;
  1071.        prgb2[1].bBlue      = (BYTE)0xff;
  1072.        prgb2[1].bGreen      = (BYTE)0xff;
  1073.        prgb2[1].bRed      = (BYTE)0xff;
  1074.        prgb2[1].fcOptions = (BYTE)0x00;
  1075.  
  1076.                /* Initialize the icon information for the     */
  1077.                /* icon based on    the values from    the Windows   */
  1078.                /* 3.1 icon                      */
  1079.  
  1080.        if ( cClrs != 2 )
  1081.        {
  1082.        pbfh2Clr = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2);
  1083.        pbfh2Clr->usType   =    (USHORT)BFT_COLORPOINTER;
  1084.        pbfh2Clr->cbSize   =    sizeof(BITMAPFILEHEADER2);
  1085.        pbfh2Clr->xHotspot =    (SHORT)pwcd->cdEntries[i].wXHotspot;
  1086.        pbfh2Clr->yHotspot =    (SHORT)pwcd->cdEntries[i].wYHotspot;
  1087.  
  1088.        pbfh2Clr->bmp2.cbFix        = sizeof(BITMAPINFOHEADER2);
  1089.        pbfh2Clr->bmp2.cx        = (ULONG)pwbmpi->biWidth;
  1090.        pbfh2Clr->bmp2.cy        = (ULONG)pwbmpi->biHeight / 2UL;
  1091.        pbfh2Clr->bmp2.cPlanes    =     pwbmpi->biPlanes;
  1092.        pbfh2Clr->bmp2.cBitCount    =     pwbmpi->biBitCount;
  1093.        pbfh2Clr->bmp2.cclrImportant    = cClrs;
  1094.  
  1095.        pbImage    =    (PBYTE)pbfh2Clr    + sizeof(BITMAPFILEHEADER2);
  1096.        pbWinImage =    (PBYTE)pwbmpi +    sizeof(winBITMAPINFOHEADER);
  1097.  
  1098.                /* When a colour    table present, write out the    */
  1099.                /* colour table                    */
  1100.        if (    cClrs )
  1101.            {
  1102.            memcpy(pbImage, pbWinImage, sizeof(winRGBQUAD) *    cClrs);
  1103.            pbImage      += sizeof(RGB2) * cClrs;
  1104.            }
  1105.        pbafh2 = (PBITMAPARRAYFILEHEADER2)pbImage;
  1106.        }
  1107.        else
  1108.        pbImage = (PBYTE)(pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2));
  1109.        }
  1110.  
  1111.    pbafh2 = (PBITMAPARRAYFILEHEADER2)pbOS2Ptr;
  1112.  
  1113.    for ( i = 0;    i < pwcd->cdCount; i++ )
  1114.        {
  1115.  
  1116.        pbWinImage = (PBYTE)(pwbmpi = (PwinBITMAPINFOHEADER)(pbCur + pwcd->cdEntries[i].dwImageOffset)) + sizeof(winBITMAPINFOHEADER);
  1117.  
  1118.        cbMask  = (((pwbmpi->biWidth + 31L) & 0xffffffe0) >> 3) * pwbmpi->biHeight;
  1119.  
  1120.        pbfh2Mask = &pbafh2->bfh2;
  1121.  
  1122.                /* Initialize the first icon header for the    */
  1123.                /* icon                          */
  1124.  
  1125.        pbfh2Mask->offBits = (ULONG)(pbImage - pbOS2Ptr);
  1126.  
  1127.        if ( (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) != 2 )
  1128.        {
  1129.                /* Initialize the icon information for the     */
  1130.                /* icon based on    the values from    the Windows   */
  1131.                /* 3.1 icon                      */
  1132.  
  1133.        pbfh2Clr = (PBITMAPFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2)    + sizeof(RGB2) * 2);
  1134.        pbfh2Clr->offBits = (ULONG)(pbImage - pbOS2Ptr) + cbMask;
  1135.  
  1136.                /* When a colour    table present, write out the    */
  1137.                /* colour table                    */
  1138.  
  1139.        if (    (cClrs = (ULONG)(1 << pwbmpi->biBitCount)) != 0    )
  1140.            pbWinImage += sizeof(winRGBQUAD)    * cClrs;
  1141.  
  1142.        if (    (cbXorAnd = cbMask / 2UL) != 0 )
  1143.            {
  1144.            memcpy(pbImage += cbXorAnd, pbWinImage +    pwbmpi->biSizeImage - cbXorAnd,    cbXorAnd);
  1145.            pbImage += cbXorAnd;
  1146.            }
  1147.  
  1148.        memcpy(pbImage, pbWinImage, pwbmpi->biSizeImage - cbXorAnd);
  1149.        pbImage += pwbmpi->biSizeImage - cbXorAnd;
  1150.        pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Clr +    sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * cClrs);
  1151.        }
  1152.        else
  1153.        {
  1154.        memcpy(pbImage, pbWinImage +    sizeof(winRGBQUAD) * 2,    pwbmpi->biSizeImage);
  1155.        pbImage += pwbmpi->biSizeImage;
  1156.        pbafh2 = (PBITMAPARRAYFILEHEADER2)((PBYTE)pbfh2Mask + sizeof(BITMAPFILEHEADER2) + sizeof(RGB2) * 2);
  1157.        }
  1158.        }
  1159.    }
  1160.  
  1161. free(pbCur);
  1162.  
  1163. return((PBITMAPFILEHEADER2)pbOS2Ptr);
  1164. }
  1165.