Icons erzeugen

08/09/2010 - 19:44 von Stefan Reuther | Report spam
Hallo,

ich versuche, Icons dynamisch zu erzeugen. Im Wesentlichen nehme ich
existierende Icons und drehe die ein bisschen durch den Wolf, z.B. so
dass man den Icons in der Taskleiste ansieht, zu welcher Instanz meines
Programms sie gehören. Ich entwickle in einer "nackten" Win32-Umgebung
(kein MFC, kein C#, etc.), Zielplattform ist Windows 2000 und neuer.


(a) Ich habe eine Bitmap mit einem Bild und eine mit einer Maske, wie
man sie halt von GetIconInfo bekommt. Um die irgendwohin zu zeichnen,
habe ich folgenden Code:

// HDC dstdc ist der DC wo das ganze hinsoll
// HBITMAP hmask ist die Maske
// HBITMAP hbitmap ist das Bild
HDC screendc = CreateDC("DISPLAY", 0, 0, 0);
HDC srcdc = CreateCompatibleDC(screendc);
SelectObject(srcdc, hbitmap);
MaskBlt(dstdc, 0, 0, width, height, srcdc, 0, 0, hmask,
0, 0, MAKEROP4(0x00AA0029, SRCCOPY));

Gibt es für diese Operation wirklich keine bessere Möglichkeit, als hier
mit einer wilden in den Untiefen der MSDN ausgegrabenen Hex-Konstante zu
jonglieren (sie hàtte wohl DSTCOPY heißen sollen)? DrawIcon reicht hier
nicht aus, da ich mit den Bitmaps noch mehr mache.


(b) Mit dem Ressourceneditor kann man Icons in verschiedenen Auflösungen
machen, Windows sucht sich dann die passende für den jeweiligen Zweck
aus. Kann man solche Icons dynamisch erzeugen? CreateIconIndirect er-
zeugt nur eine Auflösung (und GetIconInfo gibt mir nur eine), demzufolge
sehen meine Icons zwar bei Alt-Tab gut, aber in der Taskleiste doof aus.



Stefan
 

Lesen sie die antworten

#1 Markus Schaaf
08/09/2010 - 21:04 | Warnen spam
Ich verstehe Deine Fragen nicht ganz, was vermutlich an mir liegt. Das
mit den kleinen und großen Icons sind jedoch zwei verschiedene
Mechanismen: Das eine ist ein zusàtzliches Feld in den Fensterdaten
(z.B. hIconSm in WNDCLASSEX, sicher gibt's auch einen GWL-Offset); das
andere ist der Mechanismus, aus einer Icon-Resource die passende
Auflösung zu suchen. Der wird zwar auch benutzt, falls man hIconSm nicht
angibt und hIcon auf eine passende Resource zeigt, aber eben nur dann.
Wenn Du das so willst, kannst Du ja mal CreateIconFromResource(Ex)
versuchen. Ich weiß jetzt bloß nicht, wo Du das Resourcenformat findest ...

Ok, ich habe da mal in den Untiefen meines Rechners gesucht. Die Datei
heißt Resfmt.txt und ist (Dank der neuen "Offenheit") vielleicht sogar
auf irgendeinem Microsoft-Server zu finden. Ich zitiere unten die
relevanten Stellen. Was davon die CreateIconFromResource(Ex) erwarten,
musst Du mal selbst austüdeln.

MfG

Resfmt.txt >>>







[...]

3. Resource Header Format

The general format of the entire file is simply a number of resource
file entries concatenated together. Each resource contains the
information about a single resource, such as a dialog or a string
table.

Each entry consists of a resource header followed by the data for
that resource. A resource header (which is DWORD aligned) is
composed of four elements: two dwords containing the size of the
header and the size of the resource data, the resource type, the
resource name, and additional resource information. The data for the
resource follows the resource header and is specific to each
particular type of resource.

3.1 DataSize

This field gives the size of the data that follows the header, not
including any file padding between this resource and any resource
that follows this resource in the resource file.

3.2 HeaderSize

The HeaderSize field gives the size of the resource header structure
that follows.

3.3 Type

The type field can either be a number or a null-terminated UNICODE
string specifying the name of the type. This variable kind of type
is known as a `Name or Ordinal' field, and is used in most places in
a resource file where an ID may appear.

The first WORD of a Name or Ordinal field identifies whether the
field is a number or a string. If the first WORD is 0xffff (an
invalid UNICODE character), then the following WORD of information is
the type number. Otherwise, the field is specified by a UNICODE
string.

If the type field is a number, then the number specifies a standard
or user-defined resource type. All standard Windows resource types
have been assigned numbers, which are listed below. This list is
taken from the header file used to make RC and contains the type
number of the various resource types:

/* Predefined resource types */
#define RT_NEWRESOURCE 0x2000
#define RT_ERROR 0x7fff
#define RT_CURSOR 1
#define RT_BITMAP 2
#define RT_ICON 3
#define RT_MENU 4
#define RT_DIALOG 5
#define RT_STRING 6
#define RT_FONTDIR 7
#define RT_FONT 8
#define RT_ACCELERATORS 9
#define RT_RCDATA 10
#define RT_MESSAGETABLE 11
#define RT_GROUP_CURSOR 12
#define RT_GROUP_ICON 14
#define RT_VERSION 16
#define RT_NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
#define RT_NEWMENU (RT_MENU|RT_NEWRESOURCE)
#define RT_NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)

If the type field is a string, then the type is a user-defined type.

3.4 Names

A name identifies the particular resource. A name (like a type) may
be a number or a string, and they are distinguished in the same way
as numbers and strings are distinguished in the type field.

Note that no padding (for DWORD alignment) is needed between the Type
and Name fields, as they contain only WORD data and hence the Name
field will always be properly aligned. However, there may need to be
a WORD of padding after the Name field to align the rest of the
header on DWORD boundaries.

3.5 Additional Header Information

The additional information contains more information about the
particular resource data, including size and language ID. The
structure of the Header, plus it's additional information is as
follows:

struct tagResource {
DWORD DataSize; // size of data without header
DWORD HeaderSize; // Length of the additional header
[Ordinal or name TYPE] // type identifier, id or string
[Ordinal or name NAME] // name identifier, id or string
DWORD DataVersion; // predefined resource data version
WORD MemoryFlags; // state of the resource
WORD LanguageId; // UNICODE support for NLS
DWORD Version; // Version of the resource data
DWORD Characteristics; // Characteristics of the data
} ;

The additional information structure will always begin on a DWORD
boundary within the resource file, which may require adding some
padding in between the name field and the ResAdditional structure.

3.5.1 DataVersion

The DataVersion field determines the format of the information
within the resource header that follows. This may be used in the
future to allow additional information to be entered into the
predefined formats.

3.5.2 MemoryFlags

The field wMemoryFlags contains flags telling the state of a given
resource. These attributes are given to a given resource by
modifiers in the .RC script. The script identifiers inject the
following flag values:

#define MOVEABLE 0x0010
#define FIXED ~MOVEABLE
#define PURE 0x0020
#define IMPURE ~PURE
#define PRELOAD 0x0040
#define LOADONCALL ~PRELOAD
#define DISCARDABLE 0x1000

The resource compiler for NT always ignores the setting of the
MOVEABLE, IMPURE, and PRELOAD flags.

3.5.3 LanguageId

The language ID is included in each resource to specify the language
that the strings are written with when they need to be translated
back to a single byte strings. As well, there may be multiple
resources of exactly the same type and name which differ in only the
language of the strings within the resources.

The language IDs are documented in Appendix A of the NLS
specification, or in winnt.h. The language of a resource or set of
resources is specified by the LANGUAGE statement.

3.5.4 Version and Characteristics

Currently, there is space in the resource file format for version and
characteristic information of the resource. These values can be set
by the resource compiler by using the VERSION or CHARACTERISTICS
statements.

3.6 Differentiating 16 and 32-bit resource files.

Because it might be desirable for an ISV's tool that reads and writes
resource files to be able to read either the older Windows 16 format
files and the new Windows 32 format, Microsoft has devised a method
to do this using illegal type and name ordinal numbers.

The method involved is to place an illegal resource in the resource
file. The following eight bytes were chosen:

0x00 0x00 0x00 0x00 0x20 0x00 0x00 0x00

Assume that it is a 16-bit file. In that case, the Type is illegal
since the first 0x00 says string, but a zero-length string is an
illegal string. This, then is an illegal 16-bit resource header,
indicating that the file is a 32-bit file.

Assume that it is a 32-bit file. Given that, the size of the data is
zero, which surely will never be the case.

The Windows 32 resource compiler prefaces each 32-bit resource file
with this string of data (followed by an additional data structure
describing a zero-length resource with 0 ordinal type and 0 ordinal
name), allowing differentiation of 16 and 32-bit resource files. Any
tools reading resource files should ignore this resource.

3.7 File Alignment.

Because it is sometimes useful to separate resources into several
scripts and then concatenate them after compiling the resource files
separately, it is necessary to specify that resource files are padded
to a dword size. If this padding were not included, it could result
in the first resource of the second and/or subsequent resource files
not aligning upon a dword boundary.

4. Resource Data Format

For any of the pre-defined data types, all structures are DWORD
aligned, including the bitmap, icon, and font header structures. As
well, the data will always begin on a DWORD boundary.

[...]

4.2 Icon Resources

The ICON statement in the .RC script does not create a single
resource object, but creates a group of resources. This allows
Windows programs a degree of device-independence through the use of
different pixel bitmaps on hardware configurations with differing
capabilities. Icons, most often designed for differing numbers of
pixel planes and pixel counts, are grouped and treated by Windows as
a single resource. In the .RES and .EXE files, however, they are
stored as a group of resources. These groups are stored in a .RES
file with the components first (in this case the different icons
[type 3]) and a group header following (Type 14). The group header
contains the information necessary to allow Windows to select the
proper icon to display.

The components have the following structure:

[Resource header (type = 3)]

[DIB Header]
[Color DIBits of icon XOR mask]
[Monochrome DIBits of AND mask]

Each component is given an ordinal ID that is unique from all other
icon components.

The Device Independent Bitmap (DIB) header's fields represent the
masks' information separately with two exceptions. First, the height
field represents both the XOR and AND masks. Before converting the
two DIBs to Device Dependent Bitmaps (DDB), the height should be
divided by two. The masks are always the same size and are one-half
the size given in the DIB header. Second, the number of bits per
pixel and bit count refer to the XOR mask. The AND mask is always
monochrome and should be interpreted as having one plane and one bit
per pixel. Before using an icon with Windows refer to the SDK
reference materials for more information on DIBs. Since the format
of an icon component closely resembles the format of the .ICO file,
the documentation in section 9.2 of the Windows SDK Reference is
useful. DDBs should not be used for Windows 32 applications.

The group header is described here:

[Resource header (type = 14)]

struct IconHeader {
WORD wReserved; // Currently zero
WORD wType; // 1 for icons
WORD wCount; // Number of components
WORD padding; // filler for DWORD alignment
};

The next portion is repeated for each component resource:

struct ResourceDirectory {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD lBytesInRes;
WORD wNameOrdinal; // Points to component
WORD padding; // filler for DWORD alignment
};

Notice that the group header consists of a fixed header and data that
repeats for each group component. Both of these parts are fixed
length allowing for random access of the group component information.

This group header contains all of the data from the .ICO header and
from the individual resource descriptors.

Ähnliche fragen