Avatar billede sessa Nybegynder
25. april 2007 - 18:32 Der er 14 kommentarer og
1 løsning

Hvorfor kun sort/hvid?

For en del år siden begyndte jeg at skrive et program, et lille spil, men fik aldrig gjort det færdigt. Nu kikkede jeg så på det igen, men når jeg starter programmet, kommer der et vindue med nogle figurer, der bevæger sig rundt, men det hele er kun i sort/hvid!
Programmet er skrevet i C, men jeg husker ikke, om jeg havde Windows98 eller Windows95 dengang ( Jeg har XP idag ). Når jeg undersøger programmet i Borland C++Builder, ser det ud til, at alle funktioner lykkes, som de skal, såsom LoadBitmap, CreateCompatibleDC, SelectObject, BitBlt osv.

Jeg har forsøgt mig med forskellige kompatibilitetstilstande, skærmopløsninger og antal farver, men lige meget hvad jeg gør, er resultatet det samme: Sort/hvid!

Jeg er klar over, at der ikke er meget at gå efter i denne beskrivelse, men måske har en af jer oplevet noget lignende og kan give mig et tip til, hvad forklaringen kan være?
Avatar billede sessa Nybegynder
25. april 2007 - 19:26 #1
Jeg glemte at nævne, at figurerne i spillet befinder sig i en bitmap, der loades med pieces=LoadBitmap(hinst,MAKEINTRESOURCE(MANTA_PIECES)); Når jeg så åbner exe-filen med ResourceHacker, viser denne, at bitmappen er loadet korrekt, altså i farver.
Avatar billede bertelbrander Novice
25. april 2007 - 19:43 #2
Det er lidt svært at sige uden at se noget mere kode.
Et minimalt eksempel der viser fejlen ville være rart.
Avatar billede sessa Nybegynder
25. april 2007 - 20:00 #3
Du har helt ret, jeg var osse klar over, at det her er meget tyndt, men jeg ved ikke rigtigt, hvad jeg kan vise. Programmet har jo virket tidligere ( i WindowsXX ), og som sagt er der tilsyneladende ikke noget af koden, der kikser. Her er noget indledning:

  hMemDC=CreateCompatibleDC(NULL);
  bitmap=CreateCompatibleBitmap(hMemDC,windowwidth,windowheight);
  oldBM=SelectObject(hMemDC,bitmap);

  pieces=LoadBitmap(hinst,MAKEINTRESOURCE(MANTA_PIECES));
  hMemDC2=CreateCompatibleDC(NULL);
  oldBM2=SelectObject(hMemDC2,pieces);

...og her er Paint-funktionen:

void manta_OnPaint(HWND hwnd)
{
  int i,j;
  int x,y;
  PAINTSTRUCT pstruct;
  char streng[255];

  // der kan tilsyneladende sendes WM_PAINT messages, osse selv om
  // der ikke er nogen update-region.
  // GetUpdateRect() checker for den slags 'falske' messages
  if (GetUpdateRect(hwnd,NULL,FALSE)==0) return(0);

  hdc=BeginPaint(hwnd,&pstruct);

  //--------------------------------------------------------------------------

  SelectObject(hMemDC,bkgr);    // baggrundsfarven
  Rectangle(hMemDC,0,0,windowwidth,windowheight);

  for (i=0;i<dimi+2;i++) {
    for (j=0;j<dimj+2;j++) {
      if (i==0 OR i==dimi+1 OR j==0 OR j==dimj+1) drawborderpiece(i,j);
    }
  }
  for (i=1;i<=nblock;i++) {
    if (existblock[i]) drawblock(blockX[i],blockY[i]);
  }
  for (i=1;i<=nlady;i++) {
    if (existlady[i]) drawladybug(i);
  }
  for (i=1;i<=nmale;i++) {
    if (existmale[i]) drawmalebug(i);
  }
  for (i=1;i<=nuhyre;i++) {
    if (existuhyre[i]) drawuhyre(i);
  }

  BitBlt(hdc,0,0,windowwidth,windowheight,hMemDC,0,0,SRCCOPY);

//------------------------------------------------------------------------

  EndPaint(hwnd,&pstruct);
  return(0);
}

Det burde så vidt jeg kan se være korrekt kode...:)
Avatar billede sessa Nybegynder
25. april 2007 - 20:02 #4
Nå ja, og koden til f.eks drawblock:

void drawblock(int x,int y)
{
  BitBlt(hMemDC,x,y,unit,unit,hMemDC2,5*unit+5,0,SRCCOPY);
  return;
}
Avatar billede bertelbrander Novice
25. april 2007 - 20:32 #5
Jeg kan godt kikke på det, men det bliver først sent i aften.
Avatar billede bertelbrander Novice
25. april 2007 - 23:41 #6
Start med at bruge en "rigtig" dc når du kalder CreateCompatibleDC:

  HDC dc = GetDC(MainWindow);
  hMemDC = CreateCompatibleDC(dc);
Og husk at rydde op:
  ReleaseDC(MainWindow, dc);

Jeg har et lille eksempel der bygger på din kode, jeg kan godt poste det hvis det hjælper.
Avatar billede sessa Nybegynder
26. april 2007 - 08:46 #7
Det hjalp ikke med den "rigtige" dc, og "hMemDC = CreateCompatibleDC(NULL);" har jo osse virket før. Du skal nu ikke gøre for meget ud af det her. Jeg vil næppe abejde videre med spillet. Når jeg postede dette spørgsmål, er det mest fordi jeg er temmelig mystificeret over sagen.
Men jeg vil gerne se dit eksempel, min adresse er: torbenosted@vip,cybercity.dk
Avatar billede sessa Nybegynder
26. april 2007 - 08:48 #8
Arrrgh! abejde = arbejde, vip, = vip.  :)
Avatar billede bertelbrander Novice
26. april 2007 - 19:56 #9
Et komplet eksempel der viser en bmp, i farver.
Jeg loader fra fil, for at slippe for .rc filer.
Der er ikke så meget af din kode tilbage.

#include <windows.h>
#include <math.h>

HINSTANCE InstanceHandle;
HWND      MainWindow;

HDC hMemDC, hMemDC2;
HBITMAP bitmap, pieces;
HGDIOBJ oldBM, oldBM2;

int windowwidth = 500;
int windowheight = 500;

void Init()
{
  HDC dc = GetDC(MainWindow);
  hMemDC = CreateCompatibleDC(dc);
  bitmap = CreateCompatibleBitmap(hMemDC, windowwidth, windowheight);
  oldBM = SelectObject(hMemDC,bitmap);

  pieces = (HBITMAP )LoadImage(0, "sample.bmp", IMAGE_BITMAP, windowwidth, windowheight, LR_LOADFROMFILE);
  if(!pieces)
      MessageBox(MainWindow, "NoBitmap", "---", 0);
  hMemDC2 = CreateCompatibleDC(dc);
  oldBM2=SelectObject(hMemDC2,pieces);
  ReleaseDC(MainWindow, dc);
}

int OnPaint(HWND hwnd)
{
  PAINTSTRUCT pstruct;
  HDC hdc=BeginPaint(hwnd,&pstruct);

  BitBlt(hdc,0,0,windowwidth,windowheight,hMemDC2,0,0,SRCCOPY);
  EndPaint(hwnd,&pstruct);
  return(0);
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
  {
  case WM_DESTROY:
      PostQuitMessage(0);
      break;
  case WM_PAINT:
      OnPaint(hwnd);
      break;
  default:
      return DefWindowProc(hwnd,msg,wParam,lParam);
  }
  return 0;
}

HWND CreateMainWindow()
{
  WNDCLASS wc;
  memset(&wc, 0, sizeof(WNDCLASS));
  wc.style = CS_HREDRAW | CS_VREDRAW  | CS_DBLCLKS ;
  wc.lpfnWndProc = (WNDPROC )MainWndProc;
  wc.hInstance = InstanceHandle;
  wc.hbrBackground = (HBRUSH )(COLOR_WINDOW + 1);
  wc.lpszClassName = "SimpleWinWndClass";
  wc.lpszMenuName = 0;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  if(!RegisterClass(&wc))
      return 0;

  return CreateWindow("SimpleWinWndClass",
                      "Simple-Window",
                      WS_MINIMIZEBOX | WS_VISIBLE |
                      WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZEBOX |
                      WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_THICKFRAME,
                      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
                      0,
                      0,
                      InstanceHandle,
                      0);
}

int WINAPI WinMain(HINSTANCE hInstance,
                  HINSTANCE hPrevInstance,
                  LPSTR lpCmdLine,
                  INT nCmdShow)
{
  InstanceHandle = hInstance;

  if((MainWindow = CreateMainWindow()) == (HWND )0)
  {
      MessageBox(0, "Failed to create MainWindow!", "Warning", MB_OK);
      return 0;
  }
  Init();
  ShowWindow(MainWindow, SW_SHOW);
  MSG Msg;
  while(GetMessage(&Msg, 0, 0, 0))
  {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
  }
  return Msg.wParam;
}
Avatar billede sessa Nybegynder
27. april 2007 - 16:20 #10
Dit eksempel virker fint ( ikke uventet ), og nu har jeg prøvet at rette min kode til, så den minder mest muligt om din, men det sort/hvide problem er der stadig. Jeg mener at have kogt det ned til, at fejlen opstår, fordi jeg arbejder med 3 device contexts: hdc, hMemDC og hMemDC2.

I hMemDC2 befinder bitmappen med de forskellige figurer sig. Så tegner jeg først et rektangel med en baggrundsfarve i hMemDC, og derefter plukker jeg diverse figurer fra hMemDC2 og anbringer dem ovenpå baggrundsfarven i hMemDC. Og når hele billedet er færdigt, smækker jeg det over i hdc, hvorefter det BURDE vise sig på skærmen. Det gør det på sin vis osse, men i sort/hvid!
Denne metode har som nævnt virket tidligere, men duer åbenbart ikke mere? Som osse nævnt tidligere, er det her ikke spor vigtigt, men jeg KAN ikke lide den slags mysterier :)
Avatar billede bertelbrander Novice
27. april 2007 - 20:42 #11
Du kan prøve at sende mig hele koden, så skal jeg prøve at tage et kik på det en af de første dage.
Avatar billede sessa Nybegynder
27. april 2007 - 22:37 #12
Nu håber jeg ikke, at Eksperten brokker sig over, at jeg uploader så meget. Du må endelig ikke bruge for meget tid på det her, men måske kan du hurtigt se, hvad der er galt. Her er koden:

#include "windows.h"
#include "windowsx.h"
#include "stdlib.h"
#include "manta.h"
#include "math.h"
#define  AND &&
#define  OR  ||
#define  DIV /
#define  MOD %
#define  NOT !

#define  dimi  18    // spillefladens dimensioner
#define  dimj  13
#define  unit  40

#define  windowwidth  800
#define  windowheight  600

#define  numb  dimi*dimj  // number of fields

HDC hdc,hMemDC,hMemDC2;
HGDIOBJ oldBM,oldBM2;
HBITMAP bitmap,pieces;
HBRUSH bkgr;
RECT r;

int nblock;
int blockI[numb+1];              // brikkernes logiske koordinater
int blockJ[numb+1];
int blockX[numb+1];              // brikkernes faktiske koordinater
int blockY[numb+1];

BOOL existblock[numb+1];
BOOL existlady[numb+1];
BOOL existmale[numb+1];
BOOL existuhyre[numb+1];

int felt[dimi+3][dimj+3];    // +3 pga rand omkring spillefladen
int delay;

int nlady;
int ladyx[numb+1];
int ladyy[numb+1];
int ladyi[numb+1][2];        // for hver ladybug er der to felter af interesse,
int ladyj[numb+1][2];        // nemlig det, den forlader og det, den entrer
int ldirx[numb+1];
int ldiry[numb+1];
int lvelocity[numb+1];

int nmale;
int malex[numb+1];
int maley[numb+1];
int malei[numb+1][2];        // se under ladybug
int malej[numb+1][2];
int mdirx[numb+1];
int mdiry[numb+1];
int mvelocity[numb+1];

int nuhyre;
int uhyrex[numb+1];
int uhyrey[numb+1];
int uhyrei[numb+1][2];        // se under ladybug
int uhyrej[numb+1][2];
int udirx[numb+1];
int udiry[numb+1];
int uvelocity[numb+1];

int nbaby;
int babyi[numb+1];
int babyj[numb+1];

int antal=0;
int count=0;

BOOL JUST_BEGINNING=TRUE;

void calc_next_pos(HWND hwnd)
{
  int i,j;
  int I,J;

  // ladybugs ------------------------------------------------------
  for (i=1;i<=nlady;i++) {
    if (existlady[i]) {
      I=ladyx[i] DIV unit;
      J=ladyy[i] DIV unit;

      // er vi på et felt?
      if (on_felt(ladyx[i],ladyy[i])) {

        // skal der skiftes retning?
        if (NOT blokeret(I,J)) {
          while (felt[I+ldirx[i]][J+ldiry[i]] < 0) ny_lady_retning(i);
        }
        else existlady[i]=FALSE;

        // beregn feltet ladybuggen forlader og feltet den entrer
        ladyi[i][0]=I;
        ladyj[i][0]=J;
        beregn_felt_et_og_to(ldirx[i],ldiry[i],I,J,&ladyi[i][1],&ladyj[i][1]);
      }
      ladyx[i]=ladyx[i]+lvelocity[i]*ldirx[i];
      ladyy[i]=ladyy[i]+lvelocity[i]*ldiry[i];
    }
  }
  //------------------------------------------------------------

  // malebugs --------------------------------------------------
  for (i=1;i<=nmale;i++) {
    if (existmale[i]) {
      I=malex[i] DIV unit;
      J=maley[i] DIV unit;

      // er vi på et felt?
      if (on_felt(malex[i],maley[i])) {

        // skal der skiftes retning?
        if (!blokeret(I,J)) {
          while (felt[I+mdirx[i]][J+mdiry[i]] < 0) ny_male_retning(i);
        }
        else existmale[i]=FALSE;

        // beregn feltet malebuggen forlader og feltet den entrer
        malei[i][0]=I;
        malej[i][0]=J;
        beregn_felt_et_og_to(mdirx[i],mdiry[i],I,J,&malei[i][1],&malej[i][1]);

        if (male_and_lady(I,J)) {
          ;
        }

        // er der en lady i sigte? Hvis ja, så mere fart på
        if (lady_i_sigte(I,J)) mvelocity[i]=2; // og mdirx[i] og mdiry[i] ændres
        else                  mvelocity[i]=1; // i (lady_i_sigte)-funktionen
      }

      malex[i]=malex[i]+mvelocity[i]*mdirx[i];
      maley[i]=maley[i]+mvelocity[i]*mdiry[i];
    }
  }
  //--------------------------------------------------------------

  // uhyrer --------------------------------------------------------
  for (i=1;i<=nuhyre;i++) {
    if (existuhyre[i]) {
      I=uhyrex[i] DIV unit;
      J=uhyrey[i] DIV unit;

      // er vi på et felt?
      if (on_felt(uhyrex[i],uhyrey[i])) {  // on_felt bruger (x,y)-koordinater
                                          // og ikke (I,J)-koordinater
        // skal der skiftes retning?
        if (!blokeret(I,J)) {
          while (felt[I+udirx[i]][J+udiry[i]] < 0) ny_uhyre_retning(i);
        }
        else existuhyre[i]=FALSE;

        if (bug_fanget(I,J))  uvelocity[i]=1; // buggen myrdes i bug_fanget(I,J)

        // er der en bug i sigte? Hvis ja, så mere fart på
        if (bug_i_sigte(I,J)) uvelocity[i]=2; // og udirx[i] og udiry[i] ændres
        else                  uvelocity[i]=1; // i (bug_i_sigte)-funktionen

        // beregn feltet uhyret forlader og feltet den entrer
        uhyrei[i][0]=I;
        uhyrej[i][0]=J;
        beregn_felt_et_og_to(udirx[i],udiry[i],I,J,&uhyrei[i][1],&uhyrej[i][1]);
      }
    }

    uhyrex[i]=uhyrex[i]+uvelocity[i]*udirx[i];
    uhyrey[i]=uhyrey[i]+uvelocity[i]*udiry[i];
  }
  //--------------------------------------------------------------

  InvalidateRect(hwnd,NULL,FALSE);
  //PostMessage(hwnd,WM_PAINT,0,0);
}

void small_first(int *a1,int *a2)  // bytter om hvis a1 er større end a2
{
  int a;
  if (*a1>*a2) {a=*a1; *a1=*a2; *a2=a;}
}


// Enten I1=I2 (felterne lodret over hinanden)
// eller J1=J2 (felterne vandret ud for hinanden)
// Er der lutter tomme felter mellem (I1,J1) og (I2,J2) ?
BOOL fri_passage(int I1,int J1,int I2,int J2)
{
  int I,J;
  BOOL result=FALSE;

  small_first(&I1,&I2);              // det sikres at I1<=I2
  small_first(&J1,&J2);              // og at        J1<=J2

  if (I1==I2) {  // de to felter på samme lodrette linie
    I=I1;
    J=J1+1;
    while (felt[I][J]==0) J++;
    if (J>J2) result=TRUE;
  }
  if (J1==J2) {  // de to felter på samme vandrette linie
    I=I1+1;
    J=J1;
    while (felt[I][J]==0) I++;
    if (I>I2) result=TRUE;
  }

  return result;
}

int hvilket_uhyre(int I, int J)
{
  int i;
  int uhyreI,uhyreJ;

  for (i=1;i<=nuhyre;i++) {
    uhyreI=uhyrex[i] DIV unit;
    uhyreJ=uhyrey[i] DIV unit;
    if (I==uhyreI AND J==uhyreJ) return i;
  }
  return 0; // bare for en sikkerheds skyld, vi bør ikke nå hertil
}

int hvilken_lady(int I, int J)
{
  int i;
  int ladyI,ladyJ;

  for (i=1;i<=nlady;i++) {
    ladyI=ladyx[i] DIV unit;
    ladyJ=ladyy[i] DIV unit;
    if (I==ladyI AND J==ladyJ) return i;
  }
  return 0;
}

int hvilken_male( int I, int J)
{
  int i;
  int maleI,maleJ;

  for (i=1;i<=nmale;i++) {
    maleI=malex[i] DIV unit;
    maleJ=maley[i] DIV unit;
    if (I==maleI AND J==maleJ) return i;
  }
  return 0;
}

BOOL bug_i_sigte(int I,int J)  // set med et uhyres øjne
{
  BOOL result=FALSE;
  int i,n;
  int ladyI,ladyJ;
  int maleI,maleJ;

  for (i=1;i<=nlady;i++) {
    if (existlady[i]) {
      ladyI=ladyx[i] DIV unit;
      ladyJ=ladyy[i] DIV unit;
      if ((I==ladyI) OR (J==ladyJ)) {
        if (fri_passage(I,J,ladyI,ladyJ)) {
          result=TRUE;
          n=hvilket_uhyre(I,J);
          if (ladyI-I==0) udirx[n]=0;                  // uhyret sættes
          else udirx[n]=(ladyI-I)DIV abs(ladyI-I);    // i bevægelse
          if (ladyJ-J==0) udiry[n]=0;                  // hen mod
          else udiry[n]=(ladyJ-J)DIV abs(ladyJ-J);    // ladybuggen
        }
      }
    }
  }

  for (i=1;i<=nmale;i++) {
    if (existmale[i]) {
      maleI=malex[i] DIV unit;
      maleJ=maley[i] DIV unit;
      if ((I==maleI) OR (J==maleJ)) {
        if (fri_passage(I,J,maleI,maleJ)) {
          result=TRUE;
          n=hvilket_uhyre(I,J);
          if (maleI-I==0) udirx[n]=0;                  // uhyret sættes
          else udirx[n]=(maleI-I)DIV abs(maleI-I);    // i bevægelse
          if (maleJ-J==0) udiry[n]=0;                  // hen mod
          else udiry[n]=(maleJ-J)DIV abs(maleJ-J);    // malebuggen
        }
      }
    }
  }

  return result;
}

BOOL lady_i_sigte(int I,int J)  // set med en malebugs øjne
{
  BOOL result=FALSE;
  int i,n;
  int ladyI,ladyJ;

  for (i=1;i<=nlady;i++) {
    if (existlady[i]) {
      ladyI=ladyx[i] DIV unit;
      ladyJ=ladyy[i] DIV unit;
      if ((I==ladyI) OR (J==ladyJ)) {
        if (fri_passage(I,J,ladyI,ladyJ)) {
          result=TRUE;
          n=hvilken_male(I,J);
          if (ladyI-I==0) mdirx[n]=0;                  // malebuggen sættes
          else mdirx[n]=(ladyI-I)DIV abs(ladyI-I);    // i bevægelse
          if (ladyJ-J==0) mdiry[n]=0;                  // hen mod
          else mdiry[n]=(ladyJ-J)DIV abs(ladyJ-J);    // ladybuggen
        }
      }
    }
  }

  return result;
}

BOOL bug_fanget(int I,int J)  // af uhyre
{
  int i;
  int ladyI,ladyJ;
  int maleI,maleJ;
  BOOL result=FALSE;

  for (i=1;i<=nlady;i++) {
    if (existlady[i]) {
      ladyI=ladyx[i] DIV unit;
      ladyJ=ladyy[i] DIV unit;
      if (I==ladyI AND J==ladyJ) {
        ladyi[i][0]=-1;
        ladyj[i][0]=-1;
        ladyi[i][1]=-1;
        ladyj[i][1]=-1;
        existlady[i]=FALSE;
        result=TRUE;
      }
    }
  }
  for (i=1;i<=nmale;i++) {
    if (existmale[i]) {
      maleI=malex[i] DIV unit;
      maleJ=maley[i] DIV unit;
      if (I==maleI AND J==maleJ) {
        malei[i][0]=-1;
        malej[i][0]=-1;
        malei[i][1]=-1;
        malej[i][1]=-1;
        existmale[i]=FALSE;
        result=TRUE;
      }
    }
  }

  return result;
}

BOOL male_and_lady(int I,int J)  // på samme felt
{
  int i,n;
  int ladyI,ladyJ;
  BOOL result=FALSE;

  for (i=1;i<=nlady;i++) {
    if (existlady[i]) {
      ladyI=ladyx[i] DIV unit;
      ladyJ=ladyy[i] DIV unit;
      if (I==ladyI AND J==ladyJ AND on_felt(ladyx[i],ladyy[i])) {

        ladyi[i][0]=-1;
        ladyj[i][0]=-1;
        ladyi[i][1]=-1;
        ladyj[i][1]=-1;

        malei[i][0]=-1;
        malej[i][0]=-1;
        malei[i][1]=-1;
        malej[i][1]=-1;

        lvelocity[i]=0;
        mvelocity[hvilken_male(I,J)]=0;

        result=TRUE;
      }
    }
  }

  return result;
}

BOOL on_felt(int x,int y)
{
  if (x MOD unit ==0 AND y MOD unit ==0) return TRUE;
  else
  return FALSE;
}

void beregn_felt_et_og_to(int dir_x,int dir_y,int I,int J,int *II,int *JJ)
{
  // (I,J)=feltet der forlades
  // (II,JJ)=feltet der entres

  if (dir_y==0) {
    if (dir_x==-1) {    // i tilfælde af bevægelse til venstre
      *II=I-1;
      *JJ=J;
    }
    if (dir_x==1) {    // i tilfælde af bevægelse til højre
      *II=I+1;
      *JJ=J;
    }
  }
  if (dir_x==0) {      // i tilfælde af bevægelse opad
    if (dir_y==-1) {
      *II=I;
      *JJ=J-1;
    }
    if (dir_y==1) {    // i tilfælde af bevægelse nedad
      *II=I;
      *JJ=J+1;
    }
  }
}

void ny_lady_retning(int i)
{
  int retning;
  retning=random(4)+1;
  switch (retning) {
    case 1: ldirx[i]=-1; ldiry[i]=0;  break;
    case 2: ldirx[i]=0;  ldiry[i]=-1; break;
    case 3: ldirx[i]=1;  ldiry[i]=0;  break;
    case 4: ldirx[i]=0;  ldiry[i]=1;  break;
  }
}

void ny_male_retning(int i)
{
  int retning;
  retning=random(4)+1;
  switch (retning) {
    case 1: mdirx[i]=-1; mdiry[i]=0;  break;
    case 2: mdirx[i]=0;  mdiry[i]=-1; break;
    case 3: mdirx[i]=1;  mdiry[i]=0;  break;
    case 4: mdirx[i]=0;  mdiry[i]=1;  break;
  }
}

void ny_uhyre_retning(int i)
{
  int retning;
  retning=random(4)+1;
  switch (retning) {
    case 1: udirx[i]=-1; udiry[i]=0;  break;
    case 2: udirx[i]=0;  udiry[i]=-1; break;
    case 3: udirx[i]=1;  udiry[i]=0;  break;
    case 4: udirx[i]=0;  udiry[i]=1;  break;
  }
}

BOOL blokeret(int i,int j)
{
  if (felt[i-1][j] < 0 AND
      felt[i+1][j] < 0 AND
      felt[i][j-1] < 0 AND
      felt[i][j+1] < 0 )  return TRUE; else return FALSE;
}

void manta_OnReset(HWND hwnd)
{
  HINSTANCE hinst;
  hinst=(HINSTANCE) GetWindowLong(hwnd,GWL_HINSTANCE);
  init(hinst,hwnd);
  GetClientRect(hwnd,&r);
  InvalidateRect(hwnd,&r,FALSE);
  return;
}

int hvilkenblock(int i,int j)
{
  int n,brik=0;
  for (n=1;n<=nblock;n++) {
    if (existblock[n]) {
        if (blockI[n]==i AND blockJ[n]==j) brik=n;
    }
  }
  return brik;
}

void drawladybug(int n)
{
  BitBlt(hMemDC,ladyx[n],ladyy[n],unit,unit,hMemDC2,0,unit+1,SRCCOPY);
  return;
}


void drawmalebug(int n)
{
  BitBlt(hMemDC,malex[n],maley[n],unit,unit,hMemDC2,0,2*unit+2,SRCCOPY);
  return;
}

void drawuhyre(int n)
{
  BitBlt(hMemDC,uhyrex[n],uhyrey[n],unit,unit,hMemDC2,0,3*unit+3,SRCCOPY);
  return;
}

void drawblock( int x, int y )
{
  BitBlt( hMemDC, x, y, unit, unit, hMemDC2, 5*unit+5, 0, SRCCOPY );
  return;
}

void drawborderpiece( int i, int j )
{
  int border;

  if (i==0) {
    if (j==0 OR j==dimj+1) border=0; else border=3*unit+3;
  }
  if (i==dimi+1) {
    if (j==0 OR j==dimj+1) border=0; else border=unit+1;
  }
  if (j==0) {
    if (i==0 OR i==dimi+1) border=0; else border=4*unit+4;
  }
  if (j==dimj+1) {
    if (i==0 OR i==dimi+1) border=0; else border=2*unit+2;
  }

  BitBlt( hMemDC, i*unit, j*unit, unit, unit, hMemDC2, border, 0, SRCCOPY );
  return;
}

void drawbackgroundpiece(int i,int j)
{
  BitBlt(hMemDC,i*unit,j*unit,unit,unit,hMemDC2,0,0,SRCCOPY);
  return;
}

void manta_OnPaint( HWND hwnd )
{
  int i,j;
  int x,y;
  PAINTSTRUCT pstruct;
  char streng[255];

  // der kan tilsyneladende sendes WM_PAINT messages, osse selv om
  // der ikke er nogen update-region.
  // GetUpdateRect() checker for den slags 'falske' messages
  if ( GetUpdateRect( hwnd, NULL, FALSE ) == 0 ) return;

  hdc = BeginPaint( hwnd, &pstruct );

  //--------------------------------------------------------------------------

  SelectObject( hMemDC, bkgr );    // baggrundsfarven
  Rectangle( hMemDC ,0 ,0 , windowwidth, windowheight );

  for (i=0;i<dimi+2;i++) {
    for (j=0;j<dimj+2;j++) {
      if (i==0 OR i==dimi+1 OR j==0 OR j==dimj+1) drawborderpiece(i,j);
    }
  }
  for (i=1;i<=nblock;i++) {
    if (existblock[i]) drawblock(blockX[i],blockY[i]);
  }
  for (i=1;i<=nlady;i++) {
    if (existlady[i]) drawladybug(i);
  }
  for (i=1;i<=nmale;i++) {
    if (existmale[i]) drawmalebug(i);
  }
  for (i=1;i<=nuhyre;i++) {
    if (existuhyre[i]) drawuhyre(i);
  }

  BitBlt( hdc, 0, 0, windowwidth, windowheight, hMemDC, 0, 0, SRCCOPY );

//------------------------------------------------------------------------

/*
  sprintf(streng,"%d",antal);
  TextOut(hdc,20,20,streng,strlen(streng));
*/

  EndPaint( hwnd, &pstruct );
  return;
}

void init( HINSTANCE hinst, HWND hwnd )
{
  int i,j;
  int I,J;

  randomize();

  bkgr = CreateSolidBrush( RGB( 230, 200, 170 ));

  HDC dc = GetDC( hwnd );
  hMemDC = CreateCompatibleDC( dc );
  bitmap = CreateCompatibleBitmap( hMemDC, windowwidth, windowheight );
  oldBM = SelectObject( hMemDC, bitmap );

  pieces = (HBITMAP)LoadImage( 0, "pieces.bmp", IMAGE_BITMAP, windowwidth, windowheight, LR_LOADFROMFILE);
  if( !pieces )
      MessageBox( hwnd, "NoBitmap", "---", 0);

  //pieces = LoadBitmap( hinst, MAKEINTRESOURCE( MANTA_PIECES ));
  hMemDC2 = CreateCompatibleDC( dc );
  oldBM2 = SelectObject( hMemDC2, pieces );

  ReleaseDC( hwnd, dc );

  //----------------------------------------------------------------
  for (i=0;i<=dimi+1;i++) {    // spillefladen samt en kant udenom
    for (j=0;j<=dimj+1;j++) {  // gøres utilgængelig
        felt[i][j]=-2;
    }
  }
  for (i=1;i<=dimi;i++) {      // spillefladen ryddes
    for (j=1;j<=dimj;j++) {
        felt[i][j]=0;
    }
  }
  //----------------------------------------------------------------

  // der placeres blokke tilfældigt, antallet er nblock
  i=1;
  nblock=100;
  while (i<=nblock) {
    I=random(dimi)+1;
    J=random(dimj)+1;
    if (felt[I][J]==0) {
      felt[I][J]=-1;
      blockI[i]=I;
      blockJ[i]=J;
      blockX[i]=I*unit;
      blockY[i]=J*unit;
      existblock[i]=TRUE;
      i++;
    }
  }

  //-------------------------------------------------------------------

  // der placeres ladybugs tilfældigt, antallet er nlady
  i=1;
  nlady=5;
  while (i<=nlady) {
    I=random(dimi)+1;
    J=random(dimj)+1;
    if (felt[I][J]==0) {
      felt[I][J]=1;        // feltet gøres midlertidigt utilgængeligt
      ladyx[i]=I*unit;
      ladyy[i]=J*unit;
      existlady[i]=TRUE;
      ny_lady_retning(i);
      i++;
    }
  }

  //-------------------------------------------------------------------

  // der placeres malebugs tilfældigt, antallet er nmale
  i=1;
  nmale=5;
  while (i<=nmale) {
    I=random(dimi)+1;
    J=random(dimj)+1;
    if (felt[I][J]==0) {
      felt[I][J]=2;        // feltet gøres midlertidigt utilgængeligt
      malex[i]=I*unit;
      maley[i]=J*unit;
      existmale[i]=TRUE;
      ny_male_retning(i);
      i++;
    }
  }

  //-------------------------------------------------------------------

  // der placeres uhyrer tilfældigt, antallet er nuhyre
  i=1;
  nuhyre=1;
  while (i<=nuhyre) {
    I=random(dimi)+1;
    J=random(dimj)+1;
    if (felt[I][J]==0) {
      felt[I][J]=3;        // feltet gøres midlertidigt utilgængeligt
      uhyrex[i]=I*unit;
      uhyrey[i]=J*unit;
      existuhyre[i]=TRUE;
      ny_uhyre_retning(i);
      i++;
    }
  }

  //-------------------------------------------------------------------

  // sæt felter med ladybugs, malebugs og uhyrer lig nul igen
  // og sæt hastighederne=1
  for (i=1;i<=nlady;i++) {
    I=ladyx[i] DIV unit;
    J=ladyy[i] DIV unit;
    felt[I][J]=0;
    lvelocity[i]=1;
  }
  for (i=1;i<=nmale;i++) {
    I=malex[i] DIV unit;
    J=maley[i] DIV unit;
    felt[I][J]=0;
    mvelocity[i]=1;
  }
  for (i=1;i<=nuhyre;i++) {
    I=uhyrex[i] DIV unit;
    J=uhyrey[i] DIV unit;
    felt[I][J]=0;
    uvelocity[i]=1;
  }

  InvalidateRect(hwnd,NULL,FALSE);
  PostMessage(hwnd,WM_PAINT,0,0);
  return;
}

void afslut(HWND hwnd)
{

  bitmap=SelectObject(hMemDC,oldBM);
  DeleteObject(bitmap);
  DeleteDC(hMemDC);

  pieces=SelectObject(hMemDC2,oldBM2);
  DeleteObject(pieces);
  DeleteDC(hMemDC2);
  DeleteObject(bkgr);

  return;
}

BOOL no_bugs_here(int I,int J)
{
  int i;
  BOOL result=TRUE;

  for (i=1;i<=nlady;i++) {
    if (ladyi[i][0]==I AND ladyj[i][0]==J) result=FALSE;
    if (ladyi[i][1]==I AND ladyj[i][1]==J) result=FALSE;
  }
  for (i=1;i<=nmale;i++) {
    if (malei[i][0]==I AND malej[i][0]==J) result=FALSE;
    if (malei[i][1]==I AND malej[i][1]==J) result=FALSE;
  }
  for (i=1;i<=nuhyre;i++) {
    if (uhyrei[i][0]==I AND uhyrej[i][0]==J) result=FALSE;
    if (uhyrei[i][1]==I AND uhyrej[i][1]==J) result=FALSE;
  }

  return result;
}

void manta_OnLButtondown(HWND hwnd,BOOL dblclk,int x,int y,UINT flags)
{
  int i,j,k,n;
  i=x DIV unit;
  j=y DIV unit;

  if (felt[i][j]==0 AND no_bugs_here(i,j)) {
    nblock=nblock+1;
    existblock[nblock]=TRUE;
    blockI[nblock]=i;
    blockJ[nblock]=j;
    blockX[nblock]=i*unit;
    blockY[nblock]=j*unit;
    felt[i][j]=-1;
  }
  else if (felt[i][j]==-1) {
    n=hvilkenblock(i,j);
    existblock[n]=FALSE;
    felt[i][j]=0;
  }

  InvalidateRect(hwnd,NULL,FALSE);
}


void manta_OnKeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
  if (wParam==VK_ESCAPE) PostQuitMessage(0);
}


static
void aboutDlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT codeNotify)
{
  switch (id) {
    case IDOK:                      // OK pushbutton/Enter keypress
    case IDCANCEL:                  // Esc keypress
        EndDialog(hwnd,TRUE);          // Dismiss the about dialog box
        break ;
  }
}


static BOOL
aboutDlg_OnInitDialog(HWND hwnd,HWND hwndFocus,LPARAM lParam)
{
  return TRUE;
}


BOOL CALLBACK
aboutDlgProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
  switch (message) {
    case WM_COMMAND:            // Notification from a control
        return HANDLE_WM_COMMAND(hwnd,wParam,lParam,aboutDlg_OnCommand);

    case WM_INITDIALOG:        // Initialization of controls complete
        return HANDLE_WM_INITDIALOG(hwnd,wParam,lParam,aboutDlg_OnInitDialog);
  }
  return FALSE ;
}


void doAbout(HWND hwnd)
{
HINSTANCE hinst = GetWindowInstance(hwnd);
DialogBox(hinst,MAKEINTRESOURCE(MANTA_ABOUTBOX),hwnd,(DLGPROC) aboutDlgProc) ;
}


static void manta_OnDestroy(HWND hwnd)
{
  PostQuitMessage(0);
}


static void
manta_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT codeNotify)
{
  switch (id) {

    case MANTA_RESET:  manta_OnReset(hwnd); return;

    case MANTA_ABOUT:  doAbout(hwnd);  return;

    case MANTA_EXIT:  DestroyWindow(hwnd) ;  return;

    default:
        FORWARD_WM_COMMAND(hwnd,id,hwndCtl,codeNotify,DefWindowProc);
  }
}

LRESULT CALLBACK
mantaWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{

  switch (message) {

      case WM_COMMAND:
          return HANDLE_WM_COMMAND(hwnd,wParam,lParam,manta_OnCommand);

          case WM_LBUTTONDOWN:
                  return HANDLE_WM_LBUTTONDOWN(hwnd,wParam,lParam,manta_OnLButtondown);

      case WM_KEYDOWN:
                  manta_OnKeyDown(hwnd,wParam,lParam);
                  return 0;

      case WM_PAINT:
          return HANDLE_WM_PAINT(hwnd,wParam,lParam,manta_OnPaint);

      case WM_DESTROY:
          return HANDLE_WM_DESTROY(hwnd,wParam,lParam,manta_OnDestroy);

      default:
          return DefWindowProc(hwnd,message,wParam,lParam);
  }
}

HWND createwindow(HINSTANCE hinst)
{
  HWND hwnd;
  hwnd =
    CreateWindowEx (                        0,                    // Extended window styles
                        "manta_program",      // Address of registered class name
                        "Manta",              // Address of window name
                                                0,                    // Window style
                        100,                    // Horizontal position of window
                        50,                    // Vertical position of window
                        windowwidth,          // Window width
                        windowheight,        // Window height
                        NULL,                // Handle of parent or owner window
                        NULL,                // Handle of menu for this window
                        hinst,                // Handle of application instance
                        NULL) ;              // Address of window-creation data

  if (!hwnd) return FALSE ;

  ShowWindow(hwnd,SW_SHOWNORMAL);
  UpdateWindow(hwnd);

  return hwnd;
}

BOOL registerInstance(HINSTANCE hinst)
{
  BOOL result=TRUE;
  WNDCLASS wc;

  wc.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
  wc.lpfnWndProc  = mantaWndProc;
  wc.cbClsExtra    = 0 ;
  wc.cbWndExtra    = 0 ;
  wc.hInstance    = hinst;
  wc.hIcon        = LoadIcon(hinst,MAKEINTRESOURCE(MANTA_ICON));
  wc.hCursor      = LoadCursor(NULL,IDC_ARROW);
  wc.hbrBackground = NULL;
  wc.lpszMenuName  = NULL;
  wc.lpszClassName = "manta_program";

  if (!RegisterClass(&wc)) result=FALSE;

  return result;
}

int
WINAPI WinMain(HINSTANCE hinst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
  MSG          msg;
  HACCEL    haccel;
  HWND      hwnd;
  int tid1,tid2;

  tid1=GetTickCount();
  if (!registerInstance(hinst)) return FALSE ;
  hwnd=createwindow(hinst);
  init(hinst,hwnd);

  // Main message loop:
  while (1) {
    PeekMessage(&msg,NULL,0,0,PM_REMOVE);
    if (msg.message==WM_QUIT) break;
    if (!TranslateAccelerator(msg.hwnd,haccel,&msg)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    tid2=GetTickCount();
    if (tid2-tid1>12) {
      calc_next_pos(hwnd);
      JUST_BEGINNING=FALSE;
      tid1=tid2;
    }
  }

  afslut(hwnd);
  return msg.wParam ;
}
Avatar billede bertelbrander Novice
29. april 2007 - 23:46 #13
Prøv at ændre:
  bitmap = CreateCompatibleBitmap( hMemDC, windowwidth, windowheight );
til
  bitmap = CreateCompatibleBitmap( dc, windowwidth, windowheight );
i init(). Det synes at gøre en forskel
Avatar billede sessa Nybegynder
30. april 2007 - 08:11 #14
Jeg skal da lige love for, at det gør en forskel - pludselig er farverne kommet tilbage! Jeg kan ikke påstå, at jeg forstår, hvorfor det er afgørende, men jeg har nok et lidt for tåget billede af alt det der med device contexts og den slags :)
Tusind tak for hjælpen!

Jeg ved jo, hvordan du ser på point, så jeg tager dem til mig igen :)
Avatar billede sessa Nybegynder
30. april 2007 - 08:12 #15
Nå, jeg glemte lige at klikke på "Svar"...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester