- Karácsonyfaként világíthat a Thermaltake új CPU-hűtője
- Az USA vizsgálja a RISC-V kínai terjedésének kockázatát
- Kicsit extrémre sikerült a Hyte belépője a készre szerelt vízhűtések világába
- Egészen nagy teljesítményspektrumon fedné le a mobil piacot az AMD
- Kihívás a középkategóriában: teszten a Radeon RX 7600 XT
- VR topik (Oculus Rift, stb.)
- Gaming notebook topik
- Apple notebookok
- NVIDIA GeForce RTX 3080 / 3090 / Ti (GA102)
- Az USA vizsgálja a RISC-V kínai terjedésének kockázatát
- Logitech Z906
- Vezetékes FEJhallgatók
- Milyen egeret válasszak?
- Kormányok / autós szimulátorok topicja
- Intel Core i5 / i7 / i9 "Alder Lake-Raptor Lake/Refresh" (LGA1700)
Hirdetés
-
Samsung Univerzum: Így ismerhető meg a Galaxy AI bármilyen telefonon
ma A Try Galaxy webalkalmazás kontrollált környezetben mutatja meg, mit tud a One UI 6.1-es rendszer és a mesterséges intelligencia.
-
Megjelenési dátumot kapott a Star Wars: Hunters
gp A tervek szerint június elején végre befut a teljes kiadás mobilokra/tabletekre és Nintendo Switch-re.
-
Toyota Corolla Touring Sport 2.0 teszt és az autóipar
lo Némi autóipari kitekintés után egy középkategóriás autót mutatok be, ami az észszerűség műhelyében készül.
Ú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 #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
Jupí, most már működik; lépegetnek az alakok a képernyő ablakában! Nagyon köszönöm nektek a segítséget, Mgoogyinak különösen!
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 mostaniegyalak *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:locks, 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
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! -
Tomi_78
tag
Sziasztok!
Code:locks 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.
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:locks, 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: locks-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 #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 .
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
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: locks-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: locks 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...
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
É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
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.
Új hozzászólás Aktív témák
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- VR topik (Oculus Rift, stb.)
- KERÉKPÁR / BRINGA / ALKATRÉSZ beárazás
- Poco X6 Pro - ötös alá
- Kerékpárosok, bringások ide!
- Szevam: Érzelmi magabiztosság/biztonság - miért megyünk sokan külföldre valójában?
- Alkalmazásbemutató: Keep
- Gaming notebook topik
- Súlyos adatvédelmi botrányba kerülhet a ChatGPT az EU-ban
- Debrecen és környéke adok-veszek-beszélgetek
- Futott egy Geekbench kört egy új HTC készülék
- További aktív témák...