Keresés

Hirdetés

Új hozzászólás Aktív témák

  • Tomi_78

    tag

    Sziasztok!
    Tudna segíteni valaki, hogy Borland C++ Builder 6-ban saját függvényt hogyan lehet hívni egy futásidőben létrehozott időzítő OnTimer eseményével?
    Így néz ki a függvényem fejléce (__fastcall-t nem írtam bele, mert - gondolom - nem muszáj, de vele is hibás):
    void alakmozgatas()
    {
    ...
    }

    így pedig az időzítő:
    alakmozgato=new TTimer(this); //Időzítő létrehozása
    alakmozgato->Interval=5; //Időtartam beállítása
    alakmozgato->OnTimer=alakmozgatas(); //Ez történjen, ha lefutott.

    és az utolsó sorra azt írja ki, hogy: Not an allowed type.
    Ha meg elhagyom a zárójeleit:
    [C++ Error] Unit1.cpp(90): E2034 Cannot convert 'void (_fastcall *)(TObject *)' to 'void (_fastcall * (_closure )(TObject *))(TObject *)'

    Teljesen tanácstalan kezdő vagyok.

  • Tomi_78

    tag

    válasz mgoogyi #4248 üzenetére

    Köszi, de sajnos nem jó ez sem. :(
    Azt írja ki a fordító most, hogy:
    [C++ Error] Unit1.cpp(90): E2031 Cannot cast from 'void (_fastcall *)(TComponent *)' to 'void (_fastcall * (_closure )(TObject *))(TObject *)'

  • Tomi_78

    tag

    válasz mgoogyi #4250 üzenetére

    Most ilyen a fejléce a függvényemnek:
    void __fastcall alakmozgatas(TObject *Sender)
    a hívása pedig:
    alakmozgato->OnTimer=(TNotifyEvent) &alakmozgatas;
    És mégis ezt a hibaüzenetet kapom:
    [C++ Error] Unit1.cpp(90): E2031 Cannot cast from 'void (_fastcall *)(TObject *)' to 'void (_fastcall * (_closure )(TObject *))(TObject *)'

    De majd próbálok utánanézni, hogy az OnTimer milyen típust fogadhat.

  • Tomi_78

    tag

    Sziasztok!
    Napok óta rágódom egy C++-os programrészleten, nevezetesen hogy van egy alak nevű osztály, aminek vannak egy tömbben tárolt alképei, és ezeket az alképeket kellene váltogatnia szabályos időközönként. De sajnos az alképek váltogatása valamiért nem működik. Talán már az alképek beolvasását és eltárolását sem jól oldottam meg? Valaki tud segíteni?
    Íme a kód:
    #include <vcl.h>
    #pragma hdrstop

    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------

    class egyalak
    {
    public:
    egyalak(int px, int py, Graphics::TBitmap* kep)
    { x=px; y=py; kepe=kep;}
    int x;
    int y;
    Graphics::TBitmap* kepe;
    char alkepvaltoido;
    char aktalkep;
    char alkepdb;
    };

    Graphics::TBitmap *AlakokKepe = new Graphics::TBitmap;
    egyalak *alakok[5];
    TTimer *alakmozgato;
    Graphics::TBitmap* kepei[4];

    void __fastcall TForm1::alakmozgatas(TObject *Sender)
    {
    int i;
    for (i=0; i<5; i++)
    {
    if (alakok[i]->alkepvaltoido>0)
    {
    alakok[i]->alkepvaltoido-=1;
    }
    else
    {
    if (alakok[i]->aktalkep+1<alakok[i]->alkepdb)
    {
    alakok[i]->aktalkep+=1;
    }
    else
    {
    alakok[i]->aktalkep=0;
    }
    if (alakok[i]->x+(AlakokKepe->Width)<Form1->Width)
    {
    alakok[i]->x+=8;
    }
    else
    {
    alakok[i]->x=-64;
    alakok[i]->y=random(Form1->Height-64);
    }
    alakok[i]->alkepvaltoido=5;
    }
    alakok[i]->kepe=kepei[alakok[i]->aktalkep];
    }
    Invalidate();
    }
    //Ezeket kéne váltogatnia, ahogy lépked az alak:
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    AlakokKepe->LoadFromFile("alak\\alak_all.bmp");
    kepei[0] = AlakokKepe;
    kepei[2] = AlakokKepe;
    AlakokKepe->LoadFromFile("alak\\alak_lep1.bmp");
    kepei[1] = AlakokKepe;
    AlakokKepe->LoadFromFile("alak\\alak_lep2.bmp");
    kepei[3] = AlakokKepe;

    int i;
    for (i=0; i<5; i++)
    {
    alakok[i]=new egyalak(4,i*AlakokKepe->Height+10,kepei[0]);
    alakok[i]->alkepvaltoido=5;
    alakok[i]->aktalkep=0;
    alakok[i]->alkepdb=3;
    }

    alakmozgato=new TTimer(this);
    alakmozgato->Interval=50;
    alakmozgato->Enabled=true;
    alakmozgato->OnTimer=alakmozgatas;
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::Kirajzol(TObject *Sender)
    {
    int i;
    for (i=0; i<5; i++)
    {
    Canvas->Draw(alakok[i]->x,alakok[i]->y,alakok[i]->kepe);
    }
    }

  • Tomi_78

    tag

    válasz mgoogyi #4253 üzenetére

    Köszönöm szépen a válaszodat; mindenképpen kipróbálom a programomban.
    Tudod, azt hittem, hogy az a pointer felülírható minden értékadásnál.
    Sajnos még kezdő C++ felhasználó vagyok és eddig csak változókat használtam más programnyelvekben a mutatók helyett.

  • Tomi_78

    tag

    válasz mgoogyi #4255 üzenetére

    Pedig a LoadFromFile-lal újabb képeket tettem bele, felülírva a régit. Legalábbis azt hittem. De csodálkoztam is azon, hogy mindig a 2. lépésképet mutatja minden alaknál.

  • Tomi_78

    tag

    Jupí, most már működik; lépegetnek az alakok a képernyő ablakában! :K Nagyon köszönöm nektek a segítséget, Mgoogyinak különösen! :C
    Akkor, ha jól értelmezem, a mutató olyasmihoz hasonlítható, mint egy házszám, ami egy adott épületre mutat, mint helyre, a változó pedig az abban lakó személyre? Tehát ha arra vagyok kíváncsi, hogy hol van, akkor a mutatót használom, ha pedig magára az értékre, akkor a változónevet?

    [ Szerkesztve ]

  • Tomi_78

    tag

    És a C++-ban léteznek dinamikus tömbök, vagy a vektorok használatosak erre?
    A kódomból a mostani
    egyalak *alakok[5];
    tömböt szeretném dinamikussá tenni, azaz hogy lehessen törölni belőle, illetve adott esetben hozzáadni újabb elemeket. De a mostani esetben ha az 5-öst egy változóra cserélném, akkor azt const típusúnak engedi a C++.

  • Tomi_78

    tag

    válasz Silεncε #4262 üzenetére

    Az nem baj, ha elem(ek) hozzáadása után több helyet foglal, hiszen ez természetes. Akkor tehát Dabadabbal a vector használatát javasoljátok? Úgy látom, ehhez vannak külön műveletek az elemek módosításához (törlés, hozzáadás, stb).
    Sima tömbnél meg gondolom nekem kellene egy ciklussal a törölt elem utáni elemeket eggyel lejjebb rakosgatni, hozzáadni meg nem is tudnék(?).

  • Tomi_78

    tag

    No még egy furcsa dolog, amibe beleütköztem C++ programozás közben: a saját függvény hívása.
    Miért nem lehet azt csinálni, mint a példafeladatokban és leírásokban a könyvekben és a világhálón, hogy:
    void függvénynév(paraméterek)
    vagy
    int függvénynév(paraméterek)
    vagy
    bool függvénynév(paraméterek)
    stb.
    és utána egyszerűen a függvénynév használatával hívni azt?
    Ugyanis előző programomból kiszerveztem az alakok létrehozását egy függvénybe, mivel több helyen is kellene ugyanez:
    void __fastcall TForm1::alakcsinalas(TObject *Sender)
    {
    int i;
    for (i=0; i<alakdb; i++)
    {
    alakok[i]=new egyalak(4,i*kepei[0]->Height*2,kepei[0]);
    alakok[i]->alkepvaltoido=5;
    alakok[i]->aktalkep=0;
    alakok[i]->alkepdb=3;
    alakok[i]->sebessege=as;
    }
    }

    aztán ha hívnám valahol ezt a függvényt a nevével:
    alakcsinalas;
    akkor ezt a hibát kapom:
    E2235 Member function must be called or its address taken
    Utánanéztem, hogy ez mit jelent, és azt láttam, hogy egy & jel hiányzik előle ([link]).
    Nosza, elé is raktam, így meg valami EAccesViolation hibát kaptam. Na most akkor valami baj van a függvényemmel? Az Unit1.h-ban is deklarálva van pedig.
    A másik, hogy miért van szükség egy saját függvénynél a TForm1:: és (TObject *Sender) kiegészítésekre? Ez a C++ Builder sajátossága, és egy olyan fejlesztőeszköznél, ami konzolos, mint pl. a Code::Blocks, ott erre nincs szükség, hanem simán a void név(paraméterek) alak a használatos?

  • Tomi_78

    tag

    válasz mgoogyi #4267 üzenetére

    Nem, a Unt1.h-ban ez a fejléc:
    void __fastcall alakcsinalas(TObject *Sender);
    De itt az egész kódom, talán még nem olyan nagy annyira, hogy ne tegyem itt közzé:
    #include <vcl.h>
    #pragma hdrstop

    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------

    class egyalak
    {
    public:
    egyalak(int px, int py, Graphics::TBitmap* kep)
    { x=px; y=py; kepe=kep;}
    int x;
    int y;
    Graphics::TBitmap* kepe;
    unsigned char alkepvaltoido; //0-255
    unsigned char aktalkep;
    unsigned char alkepdb;
    unsigned char sebessege;
    };

    const int maxalakdb = 5;
    egyalak *alakok[maxalakdb];
    int alakdb = maxalakdb;
    TTimer *alakmozgato;
    Graphics::TBitmap* kepei[4];
    int pontok = 0;
    unsigned char as = 32;
    unsigned char th = 1;

    void __fastcall TForm1::alakcsinalas(TObject *Sender)
    {
    int i;
    for (i=0; i<alakdb; i++)
    {
    alakok[i]=new egyalak(4,i*kepei[0]->Height*2,kepei[0]);
    alakok[i]->alkepvaltoido=5;
    alakok[i]->aktalkep=0;
    alakok[i]->alkepdb=3;
    alakok[i]->sebessege=as;
    }
    }

    void __fastcall TForm1::alakmozgatas(TObject *Sender)
    {
    int i;
    for (i=0; i<alakdb; i++)
    {
    if (alakok[i]->alkepvaltoido>0)
    {
    alakok[i]->alkepvaltoido-=1;
    }
    else
    {
    if (alakok[i]->aktalkep+1<=alakok[i]->alkepdb)
    {
    alakok[i]->aktalkep+=1;
    }
    else
    {
    alakok[i]->aktalkep=0;
    }
    if (alakok[i]->x+(kepei[0]->Width)<Form1->Width)
    {
    alakok[i]->x+=alakok[i]->sebessege;
    }
    else
    {
    delete alakok[i];
    if (i<alakdb)
    {
    int j;
    for (j=i+1; j<alakdb; j++)
    {
    alakok[i]=alakok[j];
    }
    };
    alakdb-=1;
    if (alakdb<1)
    {
    if (as+4<255)
    {
    as+=4;
    }
    &alakcsinalas;
    };
    }
    alakok[i]->alkepvaltoido=5;
    }
    alakok[i]->kepe=kepei[alakok[i]->aktalkep];
    }
    Invalidate();
    }

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    kepei[0] = new Graphics::TBitmap;
    kepei[0]->LoadFromFile("alak\\alak_all.bmp");
    kepei[0]->Transparent=true;
    kepei[2] = new Graphics::TBitmap;
    kepei[2]->LoadFromFile("alak\\alak_all.bmp");
    kepei[2]->Transparent=true;
    kepei[1] = new Graphics::TBitmap;
    kepei[1]->LoadFromFile("alak\\alak_lep1.bmp");
    kepei[1]->Transparent=true;
    kepei[3] = new Graphics::TBitmap;
    kepei[3]->LoadFromFile("alak\\alak_lep2.bmp");
    kepei[3]->Transparent=true;

    &alakcsinalas;

    alakmozgato=new TTimer(this); //Időzítő létrehozása
    alakmozgato->Interval=50; //Időtartam beállítása
    alakmozgato->Enabled=true;
    alakmozgato->OnTimer=alakmozgatas; //Ez történjen, ha lefutott.
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::Kirajzol(TObject *Sender)
    {
    TPoint p = Form1->ScreenToClient(Mouse->CursorPos);
    int i;
    for (i=0; i<alakdb; i++)
    {
    if (GetAsyncKeyState(VK_LBUTTON) && p.x>=alakok[i]->x && p.x<=alakok[i]->x+kepei[0]->Width && p.y>=alakok[i]->y && p.y<=alakok[i]->y+kepei[0]->Height)
    {
    pontok+=1;
    delete alakok[i];
    if (i<alakdb)
    {
    int j;
    for (j=i+1; j<alakdb; j++)
    {
    alakok[i]=alakok[j];
    }
    };
    alakdb-=1;
    }
    Canvas->Draw(alakok[i]->x,alakok[i]->y,alakok[i]->kepe);
    }
    Form1->Caption = "Alakok: "+IntToStr(alakdb)+" - Pontjaid: "+IntToStr(pontok)+" - Támadóhullám: "+IntToStr(th);
    }

  • Tomi_78

    tag

    válasz dabadab #4270 üzenetére

    Na szóval: a fejléc most már így néz ki, mivel nekem nem kell semmilyen paraméter:
    void __fastcall alakcsinalas()
    Ezek után ha nincs () a függvényhívás után, tehát sima alakcsinalas; akkor a hiba:
    [C++ Error] Unit1.cpp(95): E2235 Member function must be called or its address taken
    ha meg van () utána, tehát alakcsinalas();, akkor a hiba:
    [Linker Error] Unresolved external '__fastcall TForm1::alakcsinalas()' referenced from F:\PROGSETUP\BCB6\BCBPROGIJAIM\ALAKMEGY\UNIT1.OBJ

  • Tomi_78

    tag

    válasz dabadab #4272 üzenetére

    Én nem, úgy tudom, az csak valami sebességgyorsítás céljából van ott.

  • Tomi_78

    tag

    Némi haladás:
    függvény fejléce: void alakcsinalas()
    függvény hívása: alakcsinalas();
    függvény deklarációja az Unit1.h-ban: nincs.
    Eredmény: program elindul, alakok végigmasíroznak a képernyőn, de másodjára már nem fut le az őket létrehozó függvény, ami az alakmozgatas() függvényen belül van.
    Izgi! :D

  • Tomi_78

    tag

    válasz Tomi_78 #4274 üzenetére

    Megvan a megoldás! :DD Minden jó, csak az alakdb változó nullázódik le, és így a függvény másodszori hívásában a ciklusmag egyszer sem fut le.
    Hiába no, egy pihentető alvás csodákat tud művelni, ha megfárad az elménk a programozás során. :D

  • Tomi_78

    tag

    Sziasztok!
    Code::Blocks C++-ban az időzítővel (Timer) van egy problémám:
    Megadom a változóit:
    UINT idozito;
    UINT_PTR idozito1;

    majd az ablak WM_CREATE-jében létrehozom az időzítőt:
    idozito = SetTimer(hwnd,idozito1,100,(TIMERPROC)NULL);
    és itt futna le az időzítő:
    case WM_TIMER:
    switch (wParam)
    {
    case idozito1:
    //csinál valamit
    break;
    }
    break;

    Viszont ezt a hibaüzenetet kapom az idozito1-gyel kapcsolatban:
    error: 'idozito1' cannot appear in a constant-expression|
    És nem tudom, hogy ezzel az idozito1-gyel most mit kezdjek, ugyanis innen:
    [link] sem tudtam kihámozni semmi érdemlegeset, hogy az időzítő azonosítót, ami ez az idozito1 lenne, hol és milyen típusként kell megadni.
    Valaki tud nekem segíteni?

  • Tomi_78

    tag

    válasz dabadab #4277 üzenetére

    Köszönöm a választ; működött a módszered. :K
    Amúgy én is találtam egy másik megoldást (internetről puskázva), mégpedig hogy ezzel a sorral egészítettem ki a programomat az elején:
    #define idozito1 1001
    Bár nem értem, hogy ez miért jó? Egyenértékű lenne a tiéddel ( const unsigned int idozito1=0x12345; )?

  • Tomi_78

    tag

    Köszi nektek!
    Még egy kérdésem volna: egy képecskét szeretnék kirajzolni, áttetsző háttérrel, tehát hogy az a szín ne látszódjon. Ezt a következőképpen csinálnám:
    BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
    AlphaBlend(hdc, 0, 0, bitmapkep.bmWidth, bitmapkep.bmHeight, hdcMem, 0, 0, bitmapkep.bmWidth, bitmapkep.bmHeight, pixelblend);

    De erre azt írja ki a Code::Blocks, hogy:
    error: 'AlphaBlend' was not declared in this scope
    Ez miért van? Külön deklarálnom kéne még az AlphaBlend függvényt?

  • Tomi_78

    tag

    Sziasztok!
    Code: :Blocks-ban írogatok egy kis programot, amiben egy labda pattog. Ez meg is volna, de nem tudom ezt a bitmap képet áttetszővé tenni, ahol nem szükséges a háttér kirajzolása.
    Van erre valami függvény vagy ez csak maszk használatával oldható meg?
    Azért kérdezem, mert van, ahol az olvasható, hogy létezik erre a MakeTransparent függvény is, csak nem tudom használni. Itt:
    https://apireference.aspose.com/barcode/cpp/class/system.drawing.bitmap
    ez olvasható:
    "System::Drawing::Bitmap::MakeTransparent(Color transparent_color = Color::get_LightGray())"
    De C++-ban ha jól tudom, nincs olyan, hogy "System" névtér. Vagy ez mégis csak C#-ra vonatkozik?

  • Tomi_78

    tag

    válasz dabadab #4302 üzenetére

    Nem használok külső könyvtárat (SDL vagy hasonlóra gondolsz?); egyszerűen csak egy ablakos programot készítettem.

  • Tomi_78

    tag

    válasz dabadab #4305 üzenetére

    Pedig tényleg nem használok semmi extrát a programozáshoz. De inkább be is szúrom kis programomat (175 sor talán még belefér a fórumba; ha nem, hát szóljatok érte, hogy az ilyet mellőzzem legközelebb), hogy lássátok. Persze így azt is látni, hogy sokminden még nem világos benne nekem sem; ezeket megjegyzésbe írtam.

    #if defined(UNICODE) && !defined(_UNICODE)
        #define _UNICODE
    #elif defined(_UNICODE) && !defined(UNICODE)
        #define UNICODE
    #endif

    #include <tchar.h>
    #include <windows.h>

    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

    /*  Make the class name into a global variable  */
    TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

    int xhely=50,yhely=5,xseb=8,yseb=8;
    UINT idozito;
    RECT ablak;
    const unsigned int idozito1=1;

    int WINAPI WinMain (HINSTANCE hThisInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpszArgument,
                         int nCmdShow)
    {
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */

        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);

        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;

        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               _T("Jatekom"),       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );

        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);

        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }

        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }

    /*  This function is called by the Windows function DispatchMessage()  */

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HDC hdc; //handle to device context a jelentése, de mire is jó?
        hdc = GetDC(hwnd);
        static HBITMAP kep;
        BITMAP bitmapkep;
        HDC hdcMem;
        HGDIOBJ oldBitmap;
        PAINTSTRUCT ps; //előző helyről törléshez
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                kep = (HBITMAP) LoadImageW(NULL, L".\\kek_labda.bmp",
                            IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

                 if (kep == NULL) {
                     MessageBoxW(hwnd, L"Nem tudtam betolteni a kepet!", L"Error", MB_OK);
                 }/*
                 else {
                    System::Drawing::Bitmap::kep.MakeTransparent();
                 };*/
                 idozito = SetTimer(hwnd,idozito1,100,(TIMERPROC)NULL);
            break;
            case WM_KEYDOWN:
                switch (wParam) {
                    case VK_LEFT: xhely-=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_RIGHT: xhely+=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_UP: yhely-=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_DOWN: yhely+=4; InvalidateRect(hwnd, NULL, true); break;
                }
            break;
            case WM_PAINT:
                hdcMem = CreateCompatibleDC(hdc); //ez mire jó?
                oldBitmap = SelectObject(hdcMem, kep); //és ez?

                GetObject(kep, sizeof(bitmapkep), &bitmapkep); //beolvassa a kep változóba a bitmap adatait(?)
                BeginPaint(hwnd, &ps); //előző helyről törléshez
                BitBlt(hdc, xhely, yhely, bitmapkep.bmWidth, bitmapkep.bmHeight,
                     hdcMem, 0, 0, SRCCOPY); //ez rendben van: kirajzolás
                /*BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
                AlphaBlend(hdc, 0, 0, bitmapkep.bmWidth, bitmapkep.bmHeight, hdcMem, 0, 0, bitmapkep.bmWidth, bitmapkep.bmHeight, pixelblend);*/
                EndPaint(hwnd, &ps); //előző helyről törléshez
                SelectObject(hdcMem, oldBitmap); //ez is mit csinál?
                DeleteDC(hdcMem); //???
                TextOut(hdc, 10, 10, TEXT("Szia!"),5); //ez is oké: kiírok egy szöveget.
                GetWindowRect(hwnd, &ablak);
                char szoveg[30];
                itoa(ablak.right,szoveg,10);
                TextOut(hdc, 50, 10, szoveg,5);
                itoa(xhely+8+bitmapkep.bmWidth,szoveg,10);
                TextOut(hdc, 100, 10, szoveg,5);
                Rectangle(hdc, 50, 50, 200, 100); //meg ez is: téglalap rajzolása
                ReleaseDC(hwnd, hdc); //ez minek kell?
            break;
            case WM_TIMER:
                switch (wParam)
                {
                    case idozito1:
                        GetWindowRect(hwnd, &ablak);
                        xhely = xhely + xseb;
                        yhely = yhely + yseb;
                        if (xhely+xseb+bitmapkep.bmWidth>ablak.right-ablak.left-bitmapkep.bmWidth) {
                            xseb = -1*abs(xseb);
                        }
                        else
                        if (xhely<0) {
                            xseb = abs(xseb);
                        };
                        if (yhely+yseb+bitmapkep.bmHeight>ablak.bottom) {
                            yseb = -1*abs(yseb);
                        }
                        else
                        if (yhely<0) {
                            yseb = abs(yseb);
                        };
                        InvalidateRect(hwnd, NULL, true);
                    break;
                }
            break;
            case WM_DESTROY:
                KillTimer(hwnd,idozito1);
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }

        return 0;
    }

  • Tomi_78

    tag

    válasz dabadab #4307 üzenetére

    Aha. Hát... ezt nem tudtam. Akkor volt egy kis félreértés részemről :B .
    Most egyébként próbáltam leegyszerűsíteni a programomat, már ami a Device Context (DC) beállításokat illeti. Ahogy olvastam a "Borland C++ Builder 6 Developer's Guide" című könyvben, a DC az a grafikus eszközillesztőhöz való hozzáférést biztosító kezelő(?). Tehát ez mindenképpen kell a rajzolásokhoz (itt volt a félreértés, mert azt hittem, hogy te valami kívülről származó eljáráskönyvtárról írtál, amit állítólag használok a progimban, ez meg alapban benne van a C++-ban).
    Szóval, a következőképpen fest most egy kis programom, de valami nem jó benne, mert a default ágra mutatva a következő hibaüzenetet írja:
    F:\progsetup\codeblocks-17.12mingw-nosetup\sajatok\ablakosrajz\Rajz\main.cpp|103|error: jump to case label [-fpermissive]|
    Röviden el tudnátok mondani, hogy mi a baj vele, vagy hogy mi hiányzik belőle? Pedig a könyv alapján csináltam, de így sem jó.
    int kockax=50, kockay=5;
    (...)
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_KEYDOWN:
                switch (wParam) {
                    case VK_LEFT: kockax-=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_RIGHT: kockax+=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_UP: kockay-=4; InvalidateRect(hwnd, NULL, true); break;
                    case VK_DOWN: kockay+=4; InvalidateRect(hwnd, NULL, true); break;
                }
            break;
            case WM_PAINT:
                HDC grafikakezelo = GetDC(hwnd);
                Rectangle(grafikakezelo,kockax,kockay,40,40);
                ReleaseDC(hwnd,grafikakezelo);
            break;
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
    }

  • Tomi_78

    tag

    válasz dabadab #4309 üzenetére

    Köszönöm szépen a segítő választ! :K
    Ezek szerint nem is kell a DC létrehozását úgy szétszerveznem, ahogy a 175 sorosan beillesztett programkódomban tettem, hanem így is megoldható:
    HDC grafikakezelo = GetDC(hwnd);
    illetve a ReleaseDC párjával.

  • Tomi_78

    tag

    Tisztelt segítők!
    Jól használom én az időzítőt a programomban?

    1. Megadom a változót a kód elején:
    const unsigned int idozito=1;
    bool cselekedhet=true;

    2. Itt beállítom 10 másodpercre:
    case WM_CREATE:
    SetTimer(hwnd,idozito,10000,(TIMERPROC)NULL);
    break;

    3. Itt pedig használom a cselekedhet változó értékének beállítgatására:
    case WM_TIMER:
    switch (wParam)
    {
    case idozito: if (cselekedhet==false) {
    cselekedhet = true;}
    else {
    cselekedhet = false;
    };
    break;
    };
    break;

    A WM_PAINT-ban mozgatom a kockát, ha a cselekedhet értéke igaz. De bármennyire állítom a SetTimer-ben a számot, ugyanolyan gyors lesz. Ki is íratom a változó értékét:
    char szoveg[1];
    itoa(cselekedhet,szoveg,10);
    TextOut(grafikakezelo, 50, 10, szoveg,5);

    és mindig 1-et, azaz igaz-t mutat. Hol és mit rontottam el, hogy ez az érték nem változik 1 mp.-enként igaz és hamis között?

  • Tomi_78

    tag

    Az előző problémát sikerült megoldani, viszont a képkirajzolás nem megy nekem, illetve a programomnak Code: :Blocks-ban :
    #include <gdiplus.h>
    (...)
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HDC grafikakezelo;
    PAINTSTRUCT ps;
    switch (message) /* handle the messages */
    {
    case WM_PAINT:
    grafikakezelo = BeginPaint(hwnd, &ps);
    Gdiplus::Graphics rajz(grafikakezelo);
    Gdiplus::Image labdakep(L"kek_labda.bmp");
    rajz.DrawImage(&labdakep, 60, 10);

    És mégsem rajzol ki semmit, hanem azt írja hibaként:
    F:\progsetup\codeblocks-17.12mingw-nosetup\sajatok\ablakosrajz\Rajz\main.cpp|114|note: crosses initialization of 'Gdiplus::Image labdakep'|
    meg:
    F:\progsetup\codeblocks-17.12mingw-nosetup\sajatok\ablakosrajz\Rajz\main.cpp|113|note: crosses initialization of 'Gdiplus::Graphics rajz'|
    Mit rontottam el és hogyan hozható helyre?

    [ Szerkesztve ]

  • Tomi_78

    tag

    válasz dabadab #4313 üzenetére

    "a WM_PAINT ágban deklarálsz egy változót, amit csak ott inicializálsz, viszont mindenhol látható. A megoldás az, hogy a case WM_PAINT: utána részt kapcsos zárójelek közé rakod, mert az ott egy külön blokk."

    Kapcsos zárójelek közé raktam a WM_PAINT-on belüli részt, de megbolondult tőle a programom a futtatáskor; valami krikszkrakszokat ír ki...

    [ Szerkesztve ]

  • Tomi_78

    tag

    Most egy teljesen másféle kódot próbáltam ki képkirajzolásra, mint az előző, de mégsem rajzol ki semmit... :(
    Ezzel mi a baj? Megjegyzéseket is írtam hozzá, hogy - szerintem - mi mit csinál:
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HDC grafikakezelo;
        PAINTSTRUCT ps;
        static HBITMAP kep;
        BITMAP bitmapkep;
        HDC grafikakezelo2;
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                //A kép betöltése:
                kep = (HBITMAP) LoadImageW(NULL, L"kek_labda.bmp",
                            IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT);
            break;
            case WM_PAINT:
                grafikakezelo = BeginPaint(hwnd, &ps);
                //Készítek egy másik grafikakezelőt az első alapján:
                grafikakezelo2 = CreateCompatibleDC(grafikakezelo);
                //A kep-et betöltöm ebbe az új grafikakezelőbe:
                SelectObject(grafikakezelo2, kep);
              //Kiolvasom a kep méretét:
                GetObject(kep, sizeof(bitmapkep), &bitmapkep);
                //Végül a kép kirajzolása az 50-50 képernyőkoordinátára:
                BitBlt(grafikakezelo, 50, 50, bitmapkep.bmWidth, bitmapkep.bmHeight, grafikakezelo2, 0, 0, SRCCOPY);

  • Tomi_78

    tag

    Kedves szakértők, tudnátok némi információval szolgálni a SwapBuffers() paranccsal kapcsolatban? Ugyanis ezt használnám Code: Blocks Win32GUI programomban a WM_PAINT ágban, hogy kiküszöböljem a képernyő eddigi villódzását rajzoláskor. Ezt meg is akadályozza, de a program érezhetően sokat lassul a használatával. Akkor lehet, hogy nem is a SwapBuffers() való a kettős buffereléshez?
    Dióhéjban így néz ki most a program, kiragadva a lényeges elemeket:
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
      HDC grafikakezelo;
        PAINTSTRUCT ps;

    (...)
    case WM_PAINT:
    grafikakezelo = BeginPaint(hwnd, &ps);
    (...Rajzolások...)
    SwapBuffers(grafikakezelo);
    EndPaint(hwnd, &ps);

  • Tomi_78

    tag

    Sziasztok!

    Code: :Blocks segítségével C++-ban próbálok egy windowsos grafikus játékot készíteni. Tehát nem konzolos programot.
    Jó lenne kiíratnom a magyar ékezetes betűket is, ha lehet. De nem tudom, hogyan kell... :F
    Próbáltam ezzel a lehetőséggel:
    #include <locale>
    és utána:
    setlocale(LC_ALL, "hun");

    De rá se bagózik a program. Valaki tudna segíteni nekem ezügyben?

  • Tomi_78

    tag

    válasz sztanozs #4381 üzenetére

    Azt nem tudom, hogy támogatja-e és hogy egyáltalán milyen grafikus könyvtárat használok.
    Ezeket a header fájlokat illesztettem be eddig:
    #include <tchar.h>
    #include <windows.h>
    #include <vector>
    #include <locale>
    A képernyő alján az van többek között, hogy UTF-8 meg a jobb szélén egy amerikai zászló. De ezekre hiába kattintok, nem történik semmi, tehát máshol kellene beállítani ezt.

  • Tomi_78

    tag

    válasz dabadab #4383 üzenetére

    "Hogyan írod ki a szöveget?"

    Pl. így: TextOut(Memhdc, idex, idey, szoveg, strlen(szoveg));

  • Tomi_78

    tag

    És arra vannak utasítások C++-ban, amivel lekérdezhető a felhasználó monitorának mérete, hogy a program ablaka mindig kitöltse a képernyőt?
    Mert most én perpillanat csak konkrét számokat tudok megadni a hwnd-nek, de ez így nem jó.

  • Tomi_78

    tag

    válasz DrojDtroll #4389 üzenetére

    Ezt láttam már, de sajnos nem működik: a WM_RESIZE ágra ír ki valami hibát.
    De most próbálkoztam így is:
    HWND kijelzo=GetDesktopWindow();
    ablakszel=kijelzo.right;
    ablakmag=kijelzo.bottom;

    De ez sem jó: error: request for member 'right' in 'kijelzo', which is of pointer type 'HWND {aka HWND__*}' (maybe you meant to use '->' ?)|

  • Tomi_78

    tag

    válasz DrojDtroll #4391 üzenetére

    Igen, azt is.
    És ilyeneket ír ki: error: jump to case label [-fpermissive]
    erre:
    HWND kepernyo = GetDesktopWindow();
    RECT kijelzo;
    ablakszel = LOWORD(GetWindowRect ( kepernyo, &kijelzo ));
    ablakmag = HIWORD(GetWindowRect ( kepernyo, &kijelzo ));

  • Tomi_78

    tag

    válasz DrojDtroll #4393 üzenetére

    Már nagyjából sikerült megoldanom, mégpedig azzal, hogy a WM_CREATE-ből átraktam a program tetejére a változók létrehozását, illetve a képernyőméret lekérdezést az ablak létrehozása elé.
    De még valahogy el kéne tüntetnem az ablak tetejéről a címsort vagy letiltani a felhasználó általi átméretezhetőségét.
    Ebben tudtok segíteni nekem?

  • Tomi_78

    tag

    És még egy kérdésem/gondom van a fejlesztendő programommal kapcsolatban: a címképernyőjén egy olyan animációt szeretnék, hogy a képernyő közepéből jönnek ki a csillagok véletlen irányba, és ez a "csillagkirobbanás" ismétlődne.
    Egy ciklussal 22 csillagot hozok létre, de a hatás finoman szólva nem az, amit szeretnék, mert mindig csak 4 irányba mennek a csillagok, nem pedig véletlenszerűen.
    Ez a csillagok osztálya:

    class Csillag {
    public:
    Csillag(int xh, int yh) {
    xhely = xh;
    yhely = yh;
    fajta = rand()%2;
    szin = rand()%2;
    do {
    celx = rand()%ablakszel;
    } while (celx==xhely);
    if (celx < xhely)
    xseb = -8;
    else xseb = 8;
    do {
    cely = rand()%ablakmag;
    } while (cely==yhely);
    if (cely < yhely)
    yseb = -8;
    else yseb = 8;
    };
    void kirajzol(HDC grafkez) {
    if (fajta == 0) { //Csak egy pont:
    if (szin == 0)
    SetPixel(grafkez,xhely,yhely,RGB(255,255,255));
    else
    SetPixel(grafkez,xhely,yhely,RGB(255,255,0));
    } else { //+ alakú:
    if (szin == 0) {
    SetPixel(grafkez,xhely,yhely,RGB(255,255,255)); //Közepe
    SetPixel(grafkez,xhely-1,yhely,RGB(255,255,255)); //Közepétől balra
    SetPixel(grafkez,xhely+1,yhely,RGB(255,255,255)); //Közepétől jobbra
    SetPixel(grafkez,xhely,yhely-1,RGB(255,255,255)); //Közepe fölött
    SetPixel(grafkez,xhely,yhely+1,RGB(255,255,255)); //Közepe alatt
    }
    else {
    SetPixel(grafkez,xhely,yhely,RGB(255,255,0)); //Közepe
    SetPixel(grafkez,xhely-1,yhely,RGB(255,255,0)); //Közepétől balra
    SetPixel(grafkez,xhely+1,yhely,RGB(255,255,0)); //Közepétől jobbra
    SetPixel(grafkez,xhely,yhely-1,RGB(255,255,0)); //Közepe fölött
    SetPixel(grafkez,xhely,yhely+1,RGB(255,255,0)); //Közepe alatt
    };
    };
    };
    int xhely,yhely,celx,cely;
    unsigned char fajta,szin;
    char xseb,yseb;
    bool tulcelxen=false,tulcelyon=false;
    };

    std::vector<Csillag> csillagok;

    Ez pedig a kirajzolásuk a WM_PAINT-ben:

    for (int cs=0; cs<csillagok.size(); cs++) {
    if (csillagok[cs].tulcelxen == false) {
    csillagok[cs].xhely += csillagok[cs].xseb;
    if ((csillagok[cs].xhely >= csillagok[cs].celx && csillagok[cs].xseb == 8) || (csillagok[cs].xhely <= csillagok[cs].celx && csillagok[cs].xseb == -8))
    csillagok[cs].tulcelxen = true;
    } else csillagok[cs].xhely += csillagok[cs].xseb;
    if (csillagok[cs].tulcelyon == false) {
    csillagok[cs].yhely += csillagok[cs].yseb;
    if ((csillagok[cs].yhely >= csillagok[cs].cely && csillagok[cs].yseb == 8) || (csillagok[cs].yhely <= csillagok[cs].cely && csillagok[cs].yseb == -8))
    csillagok[cs].tulcelyon = true;
    } else csillagok[cs].yhely += csillagok[cs].yseb;

    if (csillagok[cs].xhely<0 || csillagok[cs].xhely>ablakszel || csillagok[cs].yhely<0 || csillagok[cs].yhely>ablakmag) {
    csillagok[cs].xhely = ablakszel/2;
    csillagok[cs].yhely = ablakmag/2;
    do {
    csillagok[cs].celx = rand()%ablakszel;
    } while (csillagok[cs].celx == csillagok[cs].xhely);
    if (csillagok[cs].celx < csillagok[cs].xhely)
    csillagok[cs].xseb = -8;
    else csillagok[cs].xseb = 8;
    do {
    csillagok[cs].cely = rand()%ablakmag;
    } while (csillagok[cs].cely == csillagok[cs].yhely);
    if (csillagok[cs].cely < csillagok[cs].yhely)
    csillagok[cs].yseb = -8;
    else csillagok[cs].yseb = 8;
    csillagok[cs].tulcelxen = false;
    csillagok[cs].tulcelyon = false;
    };
    csillagok[cs].kirajzol(Memhdc);
    };

    Gyanítom, valami akkor nem lesz jó, mikor a képernyőn kívülre kerülve visszahelyezem őket a közepére, és új célxy koordinátát kapnak véletlenszerűen, de akárhogy nézem, nem látok benne semmi logikai hibát.

  • Tomi_78

    tag

    Sziasztok ismét, szakértők!

    Felmerült még pár hiba kicsiny programom fejlesztése közben, amit segítség nélkül nem tudok megoldani.
    Az első, hogy így íratok ki szöveget:
    static const WCHAR pontszoveg[]= L"PONTJAID:";
    TextOut(Memhdc,80,4,pontszoveg,wcslen(pontszoveg));


    ami így jó is, viszont számokat már nem tudok kiíratni, mert pl. erre:
    char jatpontjai[3];
    itoa(jatekospontjai,jatpontjai,10);
    TextOut(Memhdc,80,4+28,jatpontjai,wcslen(jatpontjai));

    már ezt a hibaüzenetet kapom:
    |911|error: cannot convert 'char*' to 'const wchar_t*' for argument '1' to 'size_t wcslen(const wchar_t*)'|
    A második kérdésem, hogy meg lehet-e határozni és ha igen, akkor hogyan egy ilyen szöveg képpontokban mért szélességét, hogy a képernyő közepére lehessen kiírni:
    static const WCHAR cimszoveg[]= L"Játék címe";
    TextOut(Memhdc, ablakszel/2,4,cimszoveg,wcslen(cimszoveg));
    és végül, le lehet-e valahogy tiltani a játékablak átméretezhetőségének lehetőségét, hogy a felhasználó csak egy fix, teljesképernyős módban használhassa a programot?

  • Tomi_78

    tag

    válasz kispx #4402 üzenetére

    Hű, köszönöm szépen, Kispx!
    Így már működik a számváltozók kiíratása:
    WCHAR jateleteidb[3];
    _itow(jatekoseletei,jateleteidb,10);
    TextOut(Memhdc,4,4+28,jateleteidb,wcslen(jateleteidb));

    A másik kettőt még próbálom kibogozni... :K

  • Tomi_78

    tag

    Sziasztok!

    Van itt valaki, aki Code Blocks-t használ wxWidgets-szel C++ programozáshoz?
    Azért kérdezem, mert én megpróbáltam volna ezt, és ehhez fel is telepítettem mindkettőt a számítógépemre (CB 20.03 és wxWidgets 3.2.4-et), megcsináltam a beállításokat, indítás után be is jön a GUI, de amikor futtatnám a programomat, mindig az
    ld.exe cannot find -lwxmsw31ud
    hibaüzenetet mutatja.
    Mit jelent ez és hogyan javítható ki?

  • Tomi_78

    tag

    válasz dabadab #4444 üzenetére

    Az a baj, hogy indításkor csak a wx3.1.x-ig kínálja fel a változatot. Ennek ellenére megkérdezi mindig az elérési mappáját, annak pedig jól megadom a 3.2.4-est, és erre már a képen látható hibát dobja fel, mikor beállítom neki a Configuration options-ban a dolgokat indításkor:

  • Tomi_78

    tag

    válasz dabadab #4446 üzenetére

    Igen, 3.0.x.-essel már hiba nélkül működik; köszi a segítséget!
    Azt hittem, a verzió kiválasztása a varázslóban csak amolyan tájékoztató jellegű, és ami fontos az az a mappa, amit én megadok, amiben a wxWidgets van. De úgy látszik, nem így van. Meg az is bekavart, hogy a legújabb CodeBlocks a legújabb wxWidgetst még nem ismeri.

  • Tomi_78

    tag

    válasz cog777 #4448 üzenetére

    Valami ilyesmikre gondoltál, mint:
    [link]
    vagy:
    [link] ?
    Nem tudom, milyen szintűek, de többek között ezeket adta ki a Google a "c++ programozás teszt" keresőszavakra.

Új hozzászólás Aktív témák