001: /* icontools.c */
002: /* Farbe funktioniert (noch) nicht! */
003: 
004: #include <alloc.h>
005: 
006: #define NO_DUMP_ICON_DATA
007: 
008: #ifdef DUMP_ICON_DATA
009: void DumpIconBmpData(ICONINFO *IconInfoRec)
010: { BITMAP bmand, bmxor;
011:   char Zeile[2000];
012:   int X, Y;
013:   static int do_it = 1;
014:   HDC hdc;
015:   GetObject(IconInfoRec->hbmMask, sizeof(bmand), &bmand);
016:   GetObject(IconInfoRec->hbmColor, sizeof(bmxor), &bmxor);
017:   sprintf(Zeile, "AND-Bitmap - %d * %d, %d Planes, %d Bits per Pixel\n"
018:                  "XOR-Bitmap - %d * %d, %d Planes, %d Bits per Pixel",
019:     bmand.bmWidth, bmand.bmHeight, bmand.bmPlanes, bmand.bmBitsPixel,
020:     bmxor.bmWidth, bmxor.bmHeight, bmxor.bmPlanes, bmxor.bmBitsPixel);
021:   if ((hdc = GetDC(NULL)) != NULL) {
022:     SelectObject(hdc, IconInfoRec->hbmColor);
023:     for (Y = 0; Y < bmxor.bmHeight ; Y++) {
024:       strcat(Zeile, "\n");
025:       for (X = 0; X < bmxor.bmWidth; X++)
026:         sprintf(&(Zeile[strlen(Zeile)]), " %.6lx", (unsigned long) GetPixel(hdc, X, Y));
027:     }
028:     ReleaseDC(NULL, hdc);
029:   }
030:   if (MessageBox(NULL, Zeile, "ICON Data", MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL) do_it = 0;
031: }
032: 
033: void DumpIconData(int nWidth, int nHeight, int Colorplanes,
034:                   int width_bytes_and, int width_bytes_xor,
035:                   unsigned char *AND_Bytes, unsigned char *XOR_Bytes, int first)
036: { char Zeile[2000];
037:   int X, Y;
038:   static int do_it = 1;
039:   if (first) do_it = 1;
040:   if (!do_it) return;
041:   sprintf(Zeile, "CreateIcon(hInstance, %d, %d, 1, %d, ...", nWidth, nHeight, Colorplanes);
042:   sprintf(&(Zeile[strlen(Zeile)]), "\nAND-Bytes per Line: %d, XOR-Bytes per Line: %d\n"
043:     "XOR_Pointer = 0x%.8lx",
044:     width_bytes_and, width_bytes_xor, (unsigned long) XOR_Bytes);
045:   if (XOR_Bytes != NULL) 
046:   for (Y = 0; Y < nHeight ; Y++) {
047:     strcat(Zeile, "\n&");
048:     for (X = 0; X < width_bytes_and; X++)
049:       sprintf(&(Zeile[strlen(Zeile)]), " %.2x", (unsigned int) AND_Bytes[Y * width_bytes_and + X]);
050:     if (nHeight > 16) strcat(Zeile, "  ^"); else strcat(Zeile, "\n^");
051:     for (X = 0; X < width_bytes_xor; X++)
052:       sprintf(&(Zeile[strlen(Zeile)]), " %.2x", (unsigned int) XOR_Bytes[Y * width_bytes_xor + X]);
053:   }
054:   if (MessageBox(NULL, Zeile, "ICON Data", MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL) do_it = 0;
055: }
056: #endif

057: 
058: HICON CreateIconString(HINSTANCE hInstance,
059:                        int nWidth, int nHeight,
060:                        int nWidthMul, int nHeightMul,
061:                        int Color,
062:                        char *Data)
063: { int width_bytes_and, width_bytes_xor;
064:   static int AND_Bytes_allocated = 0;
065:   static int XOR_Bytes_allocated = 0;
066:   static unsigned char *AND_Bytes = NULL;
067:   static unsigned char *XOR_Bytes = NULL;
068:   int plauf, pmerk, Y, Yr, X, Xr, Farbe, byte, bit;
069:   HDC hdc;
070:   COLORREF CR;
071:   HICON icon;
072:   ICONINFO IconInfoRec;
073: 
074:   width_bytes_and = (nWidth + 7) / 8;
075:   if (width_bytes_and & 1) width_bytes_and++;
076:   if ((AND_Bytes == NULL) || (AND_Bytes_allocated < width_bytes_and * nHeight)) {
077:     if (AND_Bytes != NULL) { free(AND_Bytes); AND_Bytes_allocated = 0; }
078:     if ((AND_Bytes = malloc(width_bytes_and * nHeight)) == NULL) return NULL;
079:     AND_Bytes_allocated = width_bytes_and * nHeight;
080:   }
081:   memset(AND_Bytes, 0, AND_Bytes_allocated);
082: 
083:   if (Color) {
084:     if ((hdc = GetDC(NULL)) == NULL) return NULL;
085:     if ((IconInfoRec.hbmColor = CreateCompatibleBitmap(hdc, nWidth, nHeight)) == NULL) {
086:       ReleaseDC(NULL, hdc);
087:       return NULL;
088:     }
089:     SelectObject(hdc, IconInfoRec.hbmColor);
090:     // GetObject(hbmp, sizeof(bm), &bm);

091:   } else {
092:     width_bytes_xor = (nWidth + 7) / 8;
093:     if ((XOR_Bytes == NULL) || (XOR_Bytes_allocated < width_bytes_xor * nHeight)) {
094:       if (XOR_Bytes != NULL) { free(XOR_Bytes); XOR_Bytes_allocated = 0; }
095:       if ((XOR_Bytes = malloc(width_bytes_xor * nHeight)) == NULL) return NULL;
096:       XOR_Bytes_allocated = width_bytes_xor * nHeight;
097:     }
098:     memset(XOR_Bytes, 0, XOR_Bytes_allocated);
099:   }
100: 
101:   pmerk = 0;
102: 
103:   Yr = nHeightMul;
104:   for (Y = 0; Y < nHeight; Y++) {
105:     plauf = pmerk;
106:     Xr = nWidthMul;
107:     for (X = 0; X < nWidth; X++) {
108:       Farbe = -1;
109:       switch (Data[plauf]) {
110:         case ' ':           Farbe = -1; /* durchsichtig */ break;
111:         case '/':           Farbe = -2; /* invertieren  */ break;
112:         case '.': case 'w': Farbe = 15; CR = RGB(255, 255, 255); /* Weiss        */ break;
113:         case 'K': case '#': Farbe =  0; CR = RGB(  0,   0,   0); /* Schwarz      */ break;
114:         case 'b':           Farbe =  1; CR = RGB(  0,   0, 255); /* Blau         */ break;
115:         case 'g':           Farbe =  2; CR = RGB(  0, 255,   0); /* Grün         */ break;
116:         case 'c':           Farbe =  3; CR = RGB(  0, 255, 255); /* Cyanblau     */ break;
117:         case 'r':           Farbe =  4; CR = RGB(255,   0,   0); /* Rot          */ break;
118:         case 'm':           Farbe =  5; CR = RGB(255,   0, 255); /* Magentarot   */ break;
119:         case 'y':           Farbe =  6; CR = RGB(255, 255,   0); /* Gelb         */ break;
120:         case 'l':           Farbe =  7; CR = RGB(192, 192, 192); /* Hellgrau     */ break;
121:         case 'D':           Farbe =  8; CR = RGB(128, 128, 128); /* Dunkelgrau   */ break;
122:         case 'B':           Farbe =  9; CR = RGB(  0,   0, 128); /* Dunkelblau   */ break;
123:         case 'G':           Farbe = 10; CR = RGB(  0, 128,   0); /* Dunkelgrün   */ break;
124:         case 'C':           Farbe = 11; CR = RGB(  0, 128, 128); /* Dunkelcyan   */ break;
125:         case 'R':           Farbe = 12; CR = RGB(128,   0,   0); /* Dunkelrot    */ break;
126:         case 'M':           Farbe = 13; CR = RGB(128,   0, 128); /* Lila         */ break;
127:         case 'Y':           Farbe = 14; CR = RGB(128, 128,   0); /* Braun        */ break;
128:       }
129:       if (Farbe < 0) {
130:         byte = width_bytes_and * Y + (X / 8);
131:         bit = 7 - (X & 7);
132:         AND_Bytes[byte] |= (1 << bit);
133:         if (Farbe == -2) { Farbe = 15; CR = RGB(255, 255, 255); } else { Farbe = 0; CR = RGB(0, 0, 0); }
134:       }
135:       if (Color) {
136:         SetPixel(hdc, X, Y, CR);
137:       } else {
138:         byte = width_bytes_and * Y + (X / 8);
139:         bit = 7 - (X & 7);
140:         if (Farbe) XOR_Bytes[byte] |= (1 << bit);
141: #ifdef DUMP_ICON_DATA
142:           DumpIconData(nWidth, nHeight, Color ? 4 : 1, width_bytes_and, width_bytes_xor, AND_Bytes, XOR_Bytes,
143:             (X == 0) && (Y == 0));
144: #endif

145:       }
146:       if (!(--Xr)) {
147:         Xr = nWidthMul;
148:         if (Data[plauf]) plauf++;
149:       }
150:     }
151:     if (!(--Yr)) {
152:       Yr = nHeightMul;
153:       pmerk = plauf;
154:     }
155:   }
156: #ifdef DUMP_ICON_DATA
157:   if (!Color)
158:   { char Zeile[2000];
159:     sprintf(Zeile, "CreateIcon(hInstance, %d, %d, 1, %d, ...", nWidth, nHeight, Color ? 4 : 1);
160:     for (Y = 0; Y < nHeight; Y++) {
161:       strcat(Zeile, "\n&");
162:       for (X = 0; X < width_bytes_and; X++)
163:         sprintf(&(Zeile[strlen(Zeile)]), " %.2x", (unsigned int) AND_Bytes[Y * width_bytes_and + X]);
164:       strcat(Zeile, "\n^");
165:       for (X = 0; X < width_bytes_xor; X++)
166:         sprintf(&(Zeile[strlen(Zeile)]), " %.2x", (unsigned int) XOR_Bytes[Y * width_bytes_xor + X]);
167:     }
168:     MessageBox(NULL, Zeile, "ICON Data", MB_ICONINFORMATION | MB_OK);
169:   }
170: #endif

171:   if (Color) {
172:     // DumpIconData(nWidth, nHeight, GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL),

173:     //   width_bytes_and, bm.bmWidthBytes, AND_Bytes, bm.bmBits);

174:     // DumpIconData(nWidth, nHeight, -1, width_bytes_and, width_bytes_xor, AND_Bytes, XOR_Bytes);

175:    
176:     IconInfoRec.fIcon = TRUE;
177:     IconInfoRec.xHotspot = IconInfoRec.yHotspot = 0;
178:     IconInfoRec.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, AND_Bytes);
179: #ifdef DUMP_ICON_DATA
180:     DumpIconBmpData(&IconInfoRec);
181: #endif

182:     icon = CreateIconIndirect(&IconInfoRec);
183:     ReleaseDC(NULL, hdc); // DeleteObject(IconInfoRec.hbmColor); DeleteObject(IconInfoRec.hbmMask);

184:     return icon;
185:   } else
186:     return (CreateIcon(hInstance, nWidth, nHeight, 1, 1, AND_Bytes, XOR_Bytes));
187: }
188: