🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: de.comp.lang.c++
Article #1178

Re: Bitmap unter Windows

#1178
From: Karl-Heinz Krause
Date: Thu, 04 Jan 1996 19:20
180 lines
5492 bytes
Am 2. Jan. 1996 schrieb Markus Becker (becker@zess.uni-siegen.de):

> sn120fl@unidui.uni-duisburg.de (Flecht) wrote:
> >Ich versuche seit einiger Zeit Bitmaps in Windows C++-Programme einzubinden.

> >Idee, woran das liegt? Die Einbindung im Programm erfolgt bei mir mit

> >  LoadBitmap
> >  GetObject
> >  SelectObject
> >  BitBlt

Falls die Bitmaps andere als die 20 Standardfarben enthalten, so ist von
den Funktionen LoadBitmap und BitBlt abzuraten. In diesem Fall muß eine
eigene Palette benutzt werden und BitBlt funktioniert zusammen mit einer
Benutzerpalette nicht zufriedenstellend. Stattdessen sollte man die
Bitmapresource mit LoadResource laden und zum Zeichnen die Funktion
SetDIBitsToDevice benutzen. 

Die Palettenfarben muß man der Bitmapbeschreibung entnehmen und man
sollte auch die Botschaften WM_QUERYNEWPALETTE und WM_PALETTECHANGED
bearbeiten. 

Ich habe mal ein Gerüst für solche Programme geschrieben:

// Programm Bitmaptest

#include <windows.h>

char ProgName[] "Bitmaptest";
HINSTANCE hInstance;

// die Bitmapresource:
HGLOBAL BitmapRes;

BITMAPINFOHEADER bih;   // enthält die Basisdaten der Bitmap
int farben;             // Anzahl der Paletteneiträge
HPALETTE palette;       // die Palette

// Umrechnung der Farbwerte aus der BITMAPINFO-Struktur
// in Paletteeinträge:
inline void RGBToPe (PALETTEENTRY &pe, RGBQUAD q)
{
    pe.peRed q.rgbRed;
    pe.peGreen q.rgbGreen;
    pe.peBlue q.rgbBlue;
    pe.peFlags ;
}

// berechnet die Basisdaten der Bitmap und initialisiert die Palette:
void InitPalette()
{
  LPBITMAPINFO pbi (LPBITMAPINFO)LockResource(BitmapRes);
  bih pbi->bmiHeader;

  // Achtung! Das folgende funktioniert nicht mit 24-Bit-Maps.
  // dieser Fall müßte gesondert behandelt werden.
  if (bih.biClrUsed) farben ih.biClrUsed;
  else farben  << bih.biBitCount;

  LOGPALETTE *lp 
    (LOGPALETTE*)LocalAlloc (LMEM_FIXED, sizeof(LOGPALETTE) + 
                                       (farben-1)*sizeof(PALETTEENTRY));

  lp->palVersion x300;
  lp->palNumEntries úrben;
  for (int i; i < farben; i++)
    RGBToPe (lp->palPalEntry[i], pbi->bmiColors[i]);

  palette reatePalette (lp);

  LocalFree(lp);
  UnlockResource(BitmapRes);
}

// zeichnet die Bitmap:
void PaintBitmap (HDC dc)
{
  LPBITMAPINFO pbi (LPBITMAPINFO)LockResource(BitmapRes);
  LPBYTE bits LPBYTE(pbi) + sizeof(BITMAPINFOHEADER) + 
                  farben*sizeof(RGBQUAD);
  SetDIBitsToDevice (dc, 0, 0, bih.biWidth, bih.biHeight, 0, 0, 0,
                        bih.biHeight, bits, pbi, DIB_RGB_COLORS);
  UnlockResource(BitmapRes);
}

// die Fensterfunktion:
LRESULT CALLBACK wndproc (HWND wnd, UINT msg, WPARAM w, LPARAM l)
{
  switch(msg) {
    case WM_CREATE:
      BitmapRes 
        LoadResource (hInstance, 
                      FindResource (hInstance,"TestBitmap",RT_BITMAP));
      InitPalette();
      return 0;

    case WM_DESTROY:
      DeleteObject (palette);     // Palette bei Programmende löschen
      FreeResource (BitmapRes);
      PostQuitMessage(0);
      return 0;

    case WM_QUERYNEWPALETTE: {    // Palette realisieren, wenn
      HDC dc GetDC(wnd);        // man den Focus erhält.
      HPALETTE altpalette SelectPalette (dc, palette, 0);
      if (RealizePalette(dc)) InvalidateRect (wnd, 0, 1);
      SelectPalette (dc, altpalette, 0);
      ReleaseDC (wnd, dc);
      return 1;
    }

    case WM_PALETTECHANGED:     // Farbkorrekturen falls Palette
      if (wnd !HWND(w)) {     // von anderem Programm
        HDC dc GetDC(wnd);    // verändert wurde
        HPALETTE altpalette SelectPalette (dc, palette, 0);
        RealizePalette(dc);
        UpdateColors(dc);
        SelectPalette (dc, altpalette, 0);
        ReleaseDC (wnd, dc);
      }
      return 0;

    case WM_PAINT: {
      PAINTSTRUCT ps;
      BeginPaint (wnd, &ps);
      HPALETTE altpalette SelectPalette (ps.hdc, palette, 0);
      PaintBitmap (ps.hdc);
      SelectPalette (ps.hdc, altpalette, 0);
      EndPaint (wnd, &ps);
      return 0;
    }
  }
  return DefWindowProc (wnd, msg, w, l);
}

void Register ()
{
  WNDCLASS wc {
    0,
    wndproc,
    0,
    0,
    hInstance,
    LoadIcon (hInstance, "ProgramIcon"),
    LoadCursor (0, IDC_ARROW),
    HBRUSH(COLOR_WINDOW+1),
    "ProgrammMenu",
    ProgName
  };

  RegisterClass(&wc);
}

int PASCAL WinMain (HINSTANCE hInst, HINSTANCE prev, LPSTR, int show)
{
  hInstance hInst;
  if (!prev) Register();

  HWND wnd reateWindow (ProgName, ProgName,
                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                    CW_USEDEFAULT, show,
                    CW_USEDEFAULT, 0,
                    0, 0, hInstance, 0);

  if (!wnd) return -1;    // Fenster konnte nicht erzeugt werden

  MSG msg;

  while (GetMessage (&msg, 0, 0, 0)) {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
  }

  return msg.wParam;
}



Karl-Heinz Krause
Technical Details
Message-ID: <4chcr3$vuh@news00.btx.dtag.de>
Path: arc1-ca.pugleaf.net!news00.btx.dtag.de!not-for-mail!Krause
References: <4bp6k2$7l@h20-hrze.uni-duisburg.de> <4cbb2k$hk1@si-nic.hrz.uni-siegen.de>

Show Full Headers
Complete Article Headers
Newsgroups: de.comp.lang.c++
Message-ID: <4chcr3$vuh@news00.btx.dtag.de>
From: Krause@t-online.de (Karl-Heinz Krause)
Path: arc1-ca.pugleaf.net!news00.btx.dtag.de!not-for-mail!Krause
Subject: Re: Bitmap unter Windows
Date: Thu, 04 Jan 1996 19:20:51 +0000
References: <4bp6k2$7l@h20-hrze.uni-duisburg.de> <4cbb2k$hk1@si-nic.hrz.uni-siegen.de>
X-Gateway: ZCONNECT XX ius.gun.de [UNIX/Connect v0.73]
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit