Hirdetés
-
PlayStationre és Xbox-ra tart a Horizon Chase 2
gp A folytatás a tervek szerint május végén debütál az újabb platformokon.
-
Már a Patriot is jegyezhet MPOWER szériás DDR5 RAM-okat
ph Az MSI visszatérő termékcsaládjába illeszkedő készletek kétféle kapacitással érkeznek, három sebességszintre.
-
Az IMF szerint cunamiként csap le a munkaerőpiacra az AI
it Az IMF vezetője, Kristalina Georgieva szerint cunamiként söpör majd végig a globális munkaerőpiacon az AI.
Új hozzászólás Aktív témák
-
Tomi_78
tag
válasz Fire/SOUL/CD #2050 üzenetére
Próbálom univerzálisabbá tenni a kódodat, hogy bármilyen kiindulási PaintBox méretnél megfelelő legyen a méretezés, de még nem akar összejönni a megoldás. A div 2-nél a 2-t próbáltam lecserélni, de akkor össze-vissza méreteződött.
Nekem egyelőre jó így is, ahogy pont a fele, de azért még gondolkodom. -
félisten
válasz Tomi_78 #2051 üzenetére
1. A div 2 azért van, hogy a 2 objektum (esetedben PaintBox-ok (továbbiakban PB)) egyforma méretűek legyenek, szóval ezt nem kell módosítani.
2. Ha azt szeretnéd, hogy ne pont a Form1.ClientWidth fele legyen a PB-k szélessége (vízszintesen), akkor a Panel2RightGap értékét kell megnövelni, Én most 200-ra tettem (majd alább a képeken látszani fog)
3. A Form1.OnCreate eseményére nincs szükség, mert az OnResize is lefut a progi indításakor, az meg elintézi egyből a méretezést (ez is majd képen látszódik).
4. A 2. pontban leírtaknak akkor van értelme, ha a 2 PB mellett még van(nak) objektum(ok) és azok méretét fixen akarjuk tartani, csak a PB-k méreteződjenek át.
(Itt a példában egy balra igazítot Panel-n elhelyezett 8 gomb marad fix méreten)IDE-ben így néz ki, a PB-k össze-vissza, méretük sem egyforma
OnResize automatikusan elrendezi a PB-k helyzetét, méretét progi futtatásakor
Vízszintesen méretezve | Függőlegesen méretezve | Mindkét irányban méretezveSzóval ha esetleg dobnál egy képet a progidról, ahol látom, hogy milyen a Form felépítése (milyen objektumok vannak, hogy néz ki), akkor talán könnyebb lenne segíteni.
[ Szerkesztve ]
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
válasz Fire/SOUL/CD #2052 üzenetére
Várj csak, kezdem érteni: a Panel2RightGap ugye nálad a jobb oldali panel jobb szélének távolsága a főablak jobb szélétől?
Ez alapján:procedure TForm1.FormCreate(Sender: TObject);
begin
oldalsotav:=Form1.ClientWidth-(Alaprajz.left+Alaprajz.width); //Az Alaprajz jobb szegélyének távolsága a főablak jobb szegélyétől.
alsotav:=Form1.ClientHeight-(Kep3d.height+Kep3d.top);
end;procedure TForm1.FormResize(Sender: TObject);
begin
Kep3d.left:=8;
Kep3d.top:=8;
Kep3d.width:=(Form1.ClientWidth-(8+8+oldalsotav)) div 2;
Kep3d.height:=Form1.ClientHeight-(8+alsotav);
//
Alaprajz.left:=Kep3d.left+Kep3d.width+8;
Alaprajz.top:=Kep3d.top;
Alaprajz.width:=Kep3d.width;
Alaprajz.height:=Kep3d.height;
end;
És akkor így jó is lett az egész, mert ha az oldalsotav változóban az Alaprajz.width-et kisebbre állítom vagy kivonást írok a végéhez, akkor kisebb méretnél is megfelelő arányú lesz az átméretezés.
Nagyszerű; ezt akartam! Még egyszer, ezer köszönet érte neked! -
Tomi_78
tag
Sziasztok!
Azt hiszem, valami nem jól működik ezekkel a ciklusokkal vagy én értelmezem rosszul. Tehát, van egy 2-dimenziós tömböm:terkep: array [0..7,0..7] of byte=(
(0,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0),
(0,0,1,1,0,0,0,0),
(0,0,1,0,0,0,0,0),
(0,0,1,0,0,0,0,0),
(0,0,1,1,0,0,0,0),
(0,0,0,1,0,0,0,0)
);
egy így átméretezett TBitmap-em:palyakep.SetSize(Form1.width*2,Form1.height*2);
és egy talajképem, ami eredetileg 256*256-os méretű volt, de most:talajkep.SetSize(palyakep.width div 8,palyakep.height div 8);
Ebből a 2d-s tömbből rajzolnám ki a 0-s helyekre a talajképet, az 1-esekre pedig egy kék négyzetet (mert az egy folyó lenne mondjuk):for psz:=0 to 7 do
for pm:=0 to 7 do
begin
case terkep[pm,psz] of
0: begin
palyakep.canvas.draw(psz*talajkep.width,pm*talajkep.height,talajkep);end;
Egyrészt nem értem, hogy a
1: begin
palyakep.Canvas.Brush.Color:=clBlue;
palyakep.canvas.fillrect(psz*talajkep.width,pm*talajkep.height,psz*talajkep.width+talajkep.width,pm*talajkep.height+talajkep.height);
//palyakep.canvas.textout(iderakx,ideraky,'Sz.: '+inttostr(psz*talajkep.width+talajkep.width)+' M.: '+inttostr(pm*talajkep.height+talajkep.height));
end;
end;
end;case terkep[pm,psz] of
kifejezésben miért kell megcserélnem a pm-et a psz-szel, hogy ne fektetve rajzolja ki a dolgokat, másrészt miért vannak fekete helyközök a talajképek között? Mert ha jól számolom, akkor minden talajképnek szorosan egymás mellett kellene lennie: ha pl. 400 a szélessége, akkor psz=0 esetén 0 X helyre rakódik ki és 400 a szélessége, psz=1 esetén 400*1=400-zal arrébb, és 800-nál van a vége (+400), stb. tehát elvileg mindig egymás mellett. De ha futtatom, akkor az a helyzet, mint a képen:
Miért vannak ezek a fekete foghíjak? Rossz a ciklus? Vagy a mérete rossz a talajképnek? -
vz12
tag
válasz Tomi_78 #2054 üzenetére
Hello!
(1) pm-psz csere ("m" a magasság, "sz" a szélesség szeretne lenni (?))
A tömbben az ELSŐ index az a SOR, a grafikán az ELSŐ koordináta az X pozíció, tehát az OSZLOP.
A tömbben a MÁSODIK index az OSZLOP, a grafikán az MÁSODIK koordináta az Y pozíció, tehát az SOR.
Ezért kell felcserélni.
Továbbá, ha "pm"-et és "psz"-t jól értelmeztem fentebb, akkor a 2 db FOR ciklust szerintem fordítva értelmezted, bár a végeredmény szempontjából az mindegy, hogy balról jobbra + felülről lefelé haladva a SORokkal rajzolod ki, vagy felülről lefelé + balról jobbra haladva az OSZLOPokkal rajzolod ki.
>psz=1 esetén 400*1=400-zal arrébb, és 800-nál van a vége (+400), stb. tehát elvileg mindig egymás mellett
Mivel "psz" NÁLAD valójában NEM a "szélesség", hanem a "magasság", ezért a megfogalmazásodban a "mellett"-nek valójában "alatt"-nak kellene hogy legyen.(2) fekete csík
Úgy látom, hogy a képernyő szélessége NEM egyezik meg a magassággal (szélesebb, mint amilyen magas), de a rajz elvileg mind a kettőt arányosítja (nagyon helyesen). A kiinduló képed 256*256-os ("NÉGYZET" alakú). A SetSize az eredetinél kisebb méretet minden probléma nélkül ki tudja venni a képből (eredeti tartalommal), de mit kezdjen a "hozzátoldással"? Úgy tűnik, hogy a Delphi fekete színnel (=0) bővíti a képet, amennyiben a SetSize paramétere nagyobb az eredeti méretnél. Te pedig VÍZSZINTES irányban bővítetted a képet 256-ról 400-ra, ezért lett a "toldás" fekete színű. Úgy tűnik hogy FÜGGŐLEGESEN belefértél a 256-ba, a képernyő arány miatt, ezért "folytonos" a kép függőlegesen, nem kellett fekete színnel kiegészíteni.
A "SetSize" NEM nyújt, hanem kivág, legalábbis jelen esetben.
ENNYI.
Ja, és vettem a fáradságot, arányítottam a "zöld" sáv pixelben vett szélességét a "zöld+fekete" szélességhez, és kerekítéstől eltekintve egészen pontosan kijött a 256/400 arány.Az nagyon jó, hogy elegendő adatot írtál a problémához, kellett a megoldáshoz.
Egyébként miért kellett megszorozni 2-vel a "Form1.width" és a "Form1.height" értékét? Hogy "lelógjon" a képed a képernyőről, vagyis a form-ról?
[ Szerkesztve ]
-
Tomi_78
tag
Szia!
Igen, az m magasságot, az sz szélességet jelent (pályamagasság és pályaszélesség).
Akkor a SetSize csak kisebbíteni tud képet? Ez érdekes..."arányítottam a "zöld" sáv pixelben vett szélességét a "zöld+fekete" szélességhez, és kerekítéstől eltekintve egészen pontosan kijött a 256/400 arány."
Ezt hogyan csináltad? Azért kérdezem, mert változó pályamérethez kellene majd mindig igazítanom a zöld és kék sáv kiterjedését.
"Egyébként miért kellett megszorozni 2-vel a "Form1.width" és a "Form1.height" értékét? Hogy "lelógjon" a képed a képernyőről, vagyis a form-ról?"
Pontosan. A kép görgethető a nyíl gombokkal a képernyőn. A pályaméretnek ugyanis nagyobbnak kell lennie a felhasználó aktuális képernyőméreténél. Ehhez a pályamérethez kellene igazítanom a zöld és kék sávok értékeit, hogy mindig pontosan kitöltsék.
A mátrix tkp. egy kistérkép, amely nagyban vetül ki a palyakep képre. -
vz12
tag
válasz Tomi_78 #2056 üzenetére
Hello!
> Akkor a SetSize csak kisebbíteni tud képet?
Ahogyan írtam is, a "SetSize" nem nyújt sem össze, sem szét, nem vetít, nem projektál. Tehát NEM kicsinyíti/kisebbíti és NEM nagyítja/nagyobbítja a TELJES képet. Tegnap este nem volt és most sincs előttem Delphi, de az általad írtakból + a Google találatokból is azt látom, hogy a "SetSize" a képből VÁG, kimetszi a kép egy RÉSZÉT az eredeti méretben, ha tudja, de működik az eredeti képméretnél nagyobb értékekkel is (nem akad ki a program), csak ilyenkor információ hiányában alapértelmezetten fekete színnel tölti ki a plusz helyet. De működik. Biztosan van valami "stretch" lehetőség, csak be kell állítani, de ezt rád bízom. Egyszínű képeknél ez a nyújtás még nem is okoz problémát, "rendes" képeknél viszont akár nagyon csúnya is lehet az eredmény. Kísérletezgetni, "játszani" kell a dolgokkal, és rá fogsz jönni.>Ezt hogyan csináltad?
Semmi extra, a képet megnyitottam Paint-ben, ahol az egérmutató (X,Y) pozíciója látszódott a státusz sorban, ebből könnyen kiszámítható volt, itt csak az X érték kellett. Ha jól emlékszem, a zöld sáv szélessége 86 pixel volt, a zöld+fekete sáv szélessége 135, az arányuk 86/135=0.637 (kb.), ami nagyon hasonlít a 256/400=0.64-re, csak a "durvább felbontás" miatt mondjuk kerekítési eltérés tapasztalható.Megoldás1: a "stretch" lehetőség megtalálása (vagy van, vagy nincs, fejből nem tudom, nekem még nem kellett)
Megoldás2: 256*256-nál (lényegesen) nagyobb kép alkalmazása, hogy nagyobb form-on se jelenjenek meg a fekete sávok (egyébként "alul" is megjelenhetnek, ha olyanok a számok ...) -
Tomi_78
tag
Huhhh, sikerült megcsinálnom; a StretchDraw utasítás volt hozzá a megfelelő.
Nagyon szépen köszönöm, hogy felvilágosítottál ezekről a dolgokról ! Sajnos a leírások nem voltak túl informatívak, amiket a világhálón találtam, úgyhogy hála neked, megint tanultam valamit.
A kód egyébként most így néz ki:var psz,pm: byte;
iderakx,ideraky: word;
talajteglalap: TRect;
terkep: array [0..7,0..7] of byte=(
(0,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0),
(0,0,1,1,0,0,0,0),
(0,0,1,0,0,0,0,0),
(0,0,1,0,0,0,0,0),
(0,0,1,1,0,0,0,0),
(0,0,0,1,0,0,0,0)
);
begin
iderakx:=0;
ideraky:=0;
case mostpalya of
1: begin
palyakep.SetSize(Form1.width*2,Form1.height*2);
for psz:=0 to 7 do
for pm:=0 to 7 do
begin
case terkep[pm,psz] of
0: begin
talajteglalap:=rect(iderakx,ideraky,iderakx+palyakep.width div 8,ideraky+palyakep.height div 8);
palyakep.canvas.StretchDraw(talajteglalap,talajkep);
end;
1: begin
palyakep.Canvas.Brush.Color:=clBlue;
palyakep.canvas.fillrect(psz*palyakep.width div 8,pm*palyakep.height div 8,psz*palyakep.width div 8+palyakep.width div 8,pm*palyakep.height div 8+palyakep.height div 8);
end;
end;
if pm<7 then
ideraky:=ideraky+palyakep.height div 8
else
begin
ideraky:=0;
iderakx:=iderakx+palyakep.width div 8;
end;
end; -
Tomi_78
tag
Segítség ismét...! Most meg a képpont színének cseréje nem működik valamiért!
Egy cikluson belül szeretném váltogatni a fehér és kék színeket. Ez a kódom hozzá Lazarusban:if (random(100)=1) and (palyakep.canvas.GetPixel(vsz,vm)=TColor($FF0000)) then
palyakep.canvas.SetPixel(vsz,vm,TColor($000000))
else
palyakep.canvas.SetPixel(vsz,vm,TColor($FF0000));
de nem jó, mert ezeket a hibákat írja ki:
unit1.pas(98,64) Error: identifier idents no member "GetPixel"
unit1.pas(99,42) Error: identifier idents no member "SetPixel"
unit1.pas(101,42) Error: identifier idents no member "SetPixel" -
vz12
tag
válasz Tomi_78 #2060 üzenetére
Próbálj meg közvetlenül a "$" után írni 2 db "0"-t, tehát pl. TColor($00FF0000).
Arra figyelni kell, hogy a színek sorrendje a "00" után NEM a normális "R-G-B", hanem "B-G-R", tehát fordított, viszont úgy látom, hogy ezt jól csináltad, legalábbis a KÉK szín esetén, a fehér viszont szerintem $00FFFFFF.[ Szerkesztve ]
-
-
Tomi_78
tag
Na, ez érdekes: itt az olvasható, hogy a Windows unit kell a GetPixelhez és a SetPixelhez: [link]
Viszont ha a unitok felsorolásához hozzáírom a Windows-t is, akkor a Rect megadásakor (ez máshol szerepel a programomban) hibát kapok, ugyanis ha fölé viszem az egeret, akkor Windows unit nélkül azt írja ki, hogy a Classes-ba tartozik, a Windows unit megadásakor meg azt, hogy ebbe a Windows-ba és hibát kapok, mert nem téglalaprajzolásnak érzékeli, hanem record-nak.
Ki érti ezt...? -
Tomi_78
tag
No szóval, most így sikerült úgy-ahogy megoldanom:
if vizdb>0 then
De valamiért gyanúsan sok fehér képpontot tesz ki, úgyhogy még gondolkodom ezen az egészen...
begin
for i:=1 to vizdb-1 do
begin
if random(100)=1 then
begin
for vsz:=viztomb[i,0] to viztomb[i,0]+palyakep.width div 8 do
for vm:=viztomb[i,1] to viztomb[i,1]+palyakep.height div 8 do
begin
if (random(100)=1) and (palyakep.canvas.Pixels[vsz,vm]=clBlue) then
begin
palyakep.Canvas.Brush.Color:=clWhite;
palyakep.canvas.fillrect(vsz,vm,vsz+1,vm+1);
end
else if (random(100)=1) and (palyakep.canvas.Pixels[vsz,vm]=clWhite) then
begin
palyakep.Canvas.Brush.Color:=clBlue;
palyakep.canvas.fillrect(vsz,vm,vsz+1,vm+1);
end;
end;
end
else Continue;
end;
end; -
vz12
tag
válasz Tomi_78 #2064 üzenetére
> A színeket meg innen puskáztam ki: [link]
A fehér ott sem $000000 ...
De a "clWhite", "clBlue" az rendben van.Esetleg a
"palyakep.canvas.fillrect(vsz,vm,vsz+1,vm+1);
" helyett pl . a
"palyakep.canvas.Pixels[vsz,vm]:=clWhite;
" nem lenne szebb?A 3 db "
random(100)
"-at sokallom egy kicsit, de te látod az eredményt, ha jó, akkor jó.
Remélem, hogy "Randomize;
" van a program elején ...[ Szerkesztve ]
-
félisten
válasz Tomi_78 #2066 üzenetére
A Pixels a SetPixel és GetPixel függvényekre támaszkodik, a Graphics unit-ban találhatóak.
property Pixels[X, Y: Integer]: TColor read GetPixel write SetPixel;
[ Szerkesztve ]
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
Köszönöm mindkettőtöknek a választ; kipróbáltam és működött!
-
Tomi_78
tag
Sziasztok!
Elakadtam kis játékprogramomban a radarképernyő elkészítésével. Azt hittem, hogy ez egy egyszerű arányszámítás lesz a pálya és a radarképernyő adatainak összevetésével, de valahogy mégsem jön össze nekem. Nagyon frusztrált vagyok emiatt...
Tehát az a kérdésem, hogy játékpálya és annak nézete alapján hogyan lehet elkészíteni annak kicsinyített mását, egy radarképernyőt, amelyen a téglalap pontosan ott foglal helyet, ahol a játéktéren is a nézet.
Így próbálkoztam:radnezetszel:=((opanelkep.width-4)*form1.width) / palyakep.canvas.width;
radnezetmag:=((opanelkep.width-4)*form1.height) / palyakep.canvas.height;
radxtav:=((opanelkep.width-4)*radpalyakepx) / palyakep.canvas.width;//Az oldalpanelképen van a radartérkép, mely szélessége=a magasságával, ezért az Y-nál is ugyanaz:
radytav:=((opanelkep.width-4)*radpalyakepy) / palyakep.canvas.height;
radt:=rect(2+round(radxtav),kilepgomb.top+kilepgomb.height+8+round(radytav),2+round(radxtav)+round(radnezetszel),kilepgomb.top+kilepgomb.height+8+round(radytav)+round(radnezetmag));
canvas.drawfocusrect(radt);
Az eredmény(telenség) a mellékelt képen látható: van téglalap a radartérképen, de nem egészen ott, ahol lennie kéne (a kékség egy folyó lenne, a zöldes mezőn):
-
félisten
válasz Tomi_78 #2070 üzenetére
Így első nekifutásra az elv jónak néz ki, csak mégsem jó az arány, amit okozhat ennek a sornak a hibája:
radnezetmag:=((opanelkep.width-4)*form1.height) / palyakep.canvas.height;
opanelkep.width-4
helyettopanelkep.height-4
kellene...Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
félisten
válasz Fire/SOUL/CD #2071 üzenetére
Ehhh, egy "kicsit" régi hsz-ra válaszoltam...
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
Sziasztok ismét!
Egy olyan kérdésem van, ami sokatoknak biztosan egyszerűen megválaszolható lesz - remélhetőleg:
kirajzolok egy gombot Lazarus-ban a képernyőre, és erre bal gombbal kattintva meg kéne jelennie egy 2-3 elemből álló legördülő menünek. Ezt hogyan kell megcsinálni futásidőben, kóddal?
Innen: [link] puskázva eljutottam addig, hogy valószínűleg így kell létrehozni:
mnuMainMain = TMainMenu.Create(Form1);
de hogyan adhatom hozzá a menüpontokat és hogyan kezelhetem le a rájuk történő kattintást?
Tehát valami olyasmi kéne pl. hogy:
1. rákattintok a gombra, erre legördül egy 2-3 elemből álló menüsor,
2. ha valamelyikre kattintok, történjen valami, pl. kiírni, hogy melyikre kattintottam, és tűnjön el a menü,
3. akkor is záródjon be, ha a legördített menüpontokon kívülre kattintottam. -
vz12
tag
válasz Tomi_78 #2073 üzenetére
Hello!
Miért kell futásidőben létrehozni? Helyzettől függően változik a tartalma?
Amúgy szerintem neked TPopupMenu kell inkább.
Ennek van egy "items" property-je, ami tartalmazza az egyes menüpontok objektumait szépen sorban, és amelyikhez van "onclick", az végrehajtja az ottani kódot. Azt hiszem, hogy az egyes menüpontokat lehet "disabled/enabled" állapotba is tenni (valahogy), tehát én inkább tervezési időben rátenném a formra a popup menüt, meg az elemeit, meg az onclick-eket, futásidőben legfeljebb ki/bekapcsolgatnám a menüpontokat helyzettől függően.
Vagy TÖBB popup menüt is lehet csinálni, és mindig a megfelelőt kell aktiválni.Én sosem használtam Lazarust, csak régebben "rendes" Delphi-t, de szerintem ez nem nagyon különbözhet egymástól.
Találtam Lazarushoz linket:
[link] -
félisten
válasz Tomi_78 #2073 üzenetére
Azt tudom javasolni Én is, amit vz12 kolléga is, ne foglalkozz futásidejű létrehozással (már ami a popup-okat illeti), sokkal egyszerűbb IDE-ben, a TpopupMenu objektumot használni, ebből annyit dobhatsz a form-ra, amennyit csak szeretnél, duplaklikkel meg szerkesztheted őket a beépített editorral ( elem neve, felirata és minden egyes elem onclick eseményét is). Mindenféle programozás nélkül, ha hozzárendelsz egy pl. Button-hoz egy popup-t(egyszerre értelem szerűen csak 1-t, de a létrehozott popup menük közül bármelyiket futás időben is
Button1.PopupMenu:=TPopupMenu(PopupMenu2);
), akkor az úgy fog működni, hogy a gombon jobb egérrel kattintva fog megjelenni.
Le is lehet tiltani (futás időben is, ha ez az igény), hogy megjelenjen avagy sem jobb egérre, ehhez az AutoPopup tulajdonságot lehet használni, pl:Button1.PopupMenu.AutoPopup:=False;
, ez elrejti a Button1 popupját...[ Szerkesztve ]
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
Sziasztok és köszönöm a válaszokat! Átnézem a javasolt dolgokat mindjárt. Egyébként a program jellegéből fakad, hogy futásidőben van szükség a menüre, mert ez nem olyan, hogy a Form-ra vannak pakolva a dolgok.
A TpopupMenu mindenképpen csak jobb kattintással hozható elő? Mert nekem bal egérgombbal kéne... -
félisten
válasz Tomi_78 #2076 üzenetére
"A TpopupMenu mindenképpen csak jobb kattintással hozható elő? Mert nekem bal egérgombbal kéne..."
Akkor a (példánál maradva) Button1-nek a popup.autopopup tulajdonságát false-ra állítod (IDE-ben ) [kép] majd az onclikbe meg ez:procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.PopupMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;UI: A Tpopupmenu objektum(ok) futásidőben nem látszódik/látszódnak...
[ Szerkesztve ]
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
Na, próbálkoztam így:
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
epitmenu: TMainMenu;
menupont: TMenuItem;
begin
if epitesgomb.aktkepe<>epitesgomb.kepe0 then
begin
epitesgomb.aktkepe:=epitesgomb.kepe0;
epitmenu:=TMainMenu.Create(self);
menupont:=TMenuItem.Create(epitmenu);
menupont.Caption:='Felirat';
epitmenu.items.Add(menupont);
end;
end;
és erre a képernyő tetején létrehoz egy, a képernyő szélességével megegyező szélességű fehér téglalapot, benne a felirattal...
Hogyan lehet ezt a gomb koordinátáihoz igazítani és megfelelő szélességűre? -
vz12
tag
válasz Tomi_78 #2078 üzenetére
NEM "TMainMenu"-ről volt szó, hanem "TPopupMenu"-ről ...
A főmenü helye valóban az ablak tetején egy teljes szélességű "csík", nézz meg bármilyen "normális" alkalmazást, neked NEM ez kell.
Arról is volt szó, hogy TERVEZÉSI időben nyugodtan létre lehet hozni a popup menüt, alapból nem fog látszódni, csak egérkattintás utáni aktivizáláskor (kóddal), és automatikusan el is fog tűnni, vagy a menüpont kiválasztásakor (ilyenkor végrehajtja a mögé írt kódot is), vagy a menü területén kívüli kattintásra (ilyenkor nem csinál semmit). Az eltüntetés beépített feature, azt nem kell kódolni.
Tervezési időben a megfelelő elemet (TPopupMenu) oda kell tenni a formra, és a beépített szerkesztővel fel lehet venni az elemeket + az OnClick eseményre lehet kódot írni szintén előzetesen. Futásidőben CSAK aktiválni kell az előre elkészített popup menüt, ami megjelenik + a fent említett esetekben automatikusan eltűnik, semmilyen "téglalap" nem marad utána.
A korábban megadott linket érdemes tanulmányozni, vagy valamilyen hasonlót lehet keresni a neten, az meg fogja erősíteni az általunk írtakat.Ja , "mbRight" helyett neked "mbLeft" fog kelleni, így a BAL egérgomb kattintásra fog aktiválódni a popup menü.
[ Szerkesztve ]
-
félisten
-
Tomi_78
tag
Ja, értem már (legalábbis remélem): tehát a MainMenu az azt a menüt jelenti, amely egy alkalmazás ablakának tetején van, míg a PopupMenu a felbukkanó menüt, ami egérkattintásra előjön(?).
-
félisten
-
Tomi_78
tag
válasz Fire/SOUL/CD #2085 üzenetére
Az!
De még lenne egy apró kérdésem: az OnClick eseménnyel hívott függvény paraméterezhető vajon?
Mert valahogy így próbálkoztam, de nem tetszett a Lazarus-nak:
procedure epitvagyvesz(Sender: TObject; mit: string);
(...)
menupont.OnClick:=@epitvagyvesz('valami');
(...)
procedure TForm1.epitvagyvesz(Sender: TObject; mit: string);
begin
case mit of ...Tehát azt szeretném elérni, hogy a különböző menüpontok más paraméterrel hívják ugyanazt a függvényt az OnClick eseményükben. És most ezt egyéb lehetőség híján a Caption-jük segítségével oldom meg, mert az különböző:
case TMenuItem(Sender).Caption of
(...)
De nagyban megkönnyítené a helyzetemet a függvényparaméterezés lehetősége - ha ez lehetséges. -
vz12
tag
válasz Tomi_78 #2086 üzenetére
Szerintem az OnClick-nek csak "Sender" paramétere van, és nem lehet második paramétert használni. Az alul lévő megoldás egyébként megfelelő, de egy kicsit azért lehet javítani rajta.
Hasonló, de talán egy kicsit szebb a Sender.tag használata, amit a property beállításoknál akár tervezési időben is meg lehet adni, de dinamikusan, kódból is. A "tag" viszont egész szám típusú (talán Longint), amit én 1,2,3, stb-re állítanék be (indulhat 0-tól is, de tudni kell, hogy alaphelyzetben minden objektumnál tag=0), amit úgy lehet a leghatékonyabban string típussá alakítani, ha definiálsz egy string típusú elemekből álló TÖMBÖT a programban 1,2,3, stb. tömbindexekkel. Az OnClick-ben pedig már csak használni kell a Tomb[Sender.tag] string értéket.
Persze némi validáció (intervallumba tartozás vizsgálat) a tömbindexre (Sender.tag) nem árthat.Ja, természetesen a különböző elemek OnClickjébe ugyanazt a függvényt kell beállítani, a hívó objektum "tag" beállítása legyen csak különböző.
[ Szerkesztve ]
-
Tomi_78
tag
-
félisten
válasz Tomi_78 #2086 üzenetére
"Tehát azt szeretném elérni, hogy a különböző menüpontok más paraméterrel hívják ugyanazt a függvényt az OnClick eseményükben."
Ebben az esetben nem látom értelmét Caption avagy Tag alapján megkülönböztetni, hogy melyik menüelem volt a küldő, hisz mindegyik menüelem saját onclick eseményét hívod meg, az meg egyértelműen azonosítja a küldőt...
Ez esetben ennyi az egész.procedure WriteStrToForm1Caption (MyCaption:String);
begin
Form1.Caption:=MyCaption;
end;
procedure TForm1.M11Click(Sender: TObject);
begin
WriteStrToForm1Caption('Első menüelem');
end;
procedure TForm1.M12Click(Sender: TObject);
begin
WriteStrToForm1Caption('Második menüelem');
end;
procedure TForm1.M1S11Click(Sender: TObject);
begin
WriteStrToForm1Caption('Első menüelem első almenüelem');
end;A TAG-es megoldás jobb, mint a Caption-ös, de abba is bele lehet keveredni, hisz egy popupmenu a kód fejlesztése során módosulhat(hozzáadsz/törölsz menüelemeket) és ilyenkor aztán lehet végignézni az összes menüelemet, hogy akkor most mi is legyen a TAG új értéke (ami nincs még/már), hisz nem lehet 2 vagy több egyforma, arról meg már nem is beszélve, ha submenu-t is használsz majd a későbbiekben...
A submenu elemeinél is ott figyel a TAG tulajdonság, szóval onnantól már submenü TAG-jeit is figyelni kellene(a főmenüvel együtt), hogy ne legyen 2 vagy több egyforma...Aztán egy olyan hiba, amit sokan elkövetnek: Amennyiben van submenu (linkelt submenu-s képen az M1 menü ilyen), akkor az M1 onclick eseményét nem programozzuk fel, ugyanis ilyen esetben elég az egérkurzort az M1 menü fölé vinni és egyből, kattintás nélkül lefut az M1 onclick eseménye... (ez a hibás helyzet van a linkelt képen)
[ Szerkesztve ]
Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
vz12
tag
válasz Fire/SOUL/CD #2089 üzenetére
> valami módot keresek arra, hogy ne kelljen minden menüponthoz külön függvényt írni
Pontosan olyan megoldást javasoltál, amit el szeretett volna kerülni ...
Ha sok menüpontnál hasonló vagy gyakorlatilag ugyanaz a kód kell, akkor nagyon is célszerű ezt összevonni, a kódismétlést ott kell kerülni, ahol csak lehet.
Ha eltérőek a menüpontok kódjai (VAGY várható, hogy a jövőben el fognak térni ...), akkor persze érdemes külön-külön függvényeket/kódokat írni, ilyenkor a "tag"-ra nincs szükség.
A "tag"-nak egyébként nem kötelező egyesével növekedni, a Longint miatt megoldható "beszédes" érték is, pl. a 324 lehet a 3. menüpont 2. almenüjének a 4. al-almenü végpontja, feltételezve, hogy egy szinten nincs 9 menüpontnál több.
Ha több elem van 9-nél, akkor lehet 2 jegyből álló blokkokat is csinálni, pl. 1205 a 12. menüpont 5. almenüpontja, de a legfelső szinten a vezető nulla sajnos nem működik, ott lehet 3 jegyű blokk. pl. 90203 a 2. menüpont 3. almenüje (a kezdő 9-es figyelmen kívül hagyandó). Így 99 menüpont lehet szintenként, ami már elég kell, hogy legyen, legtöbbször a 9 is elegendő.
Az ilyen "tagolt taggal" jobban átlátható a rendszer, persze egy nagyobb menü átalakítás után rendet kell csinálni a kódban, de bővítésre meglehetősen rugalmas ez a megoldás.És igen, a menürendszernek csak a "végpontjait" kell OnClick-elni (a menüfa LEVELEIT).
[ Szerkesztve ]
-
félisten
"Pontosan olyan megoldást javasoltál, amit el szeretett volna kerülni ..."
Amelyik hsz-re Én válaszoltam (amiből idéztem is), abban meg pont az ellenkezője van...
(másikat meg nem olvastam figyelmesen...)Mindenki tudja, hogy bizonyos dolgokat nem lehet megvalósítani, mígnem jön valaki, aki erről nem tud, és megvalósítja. (Albert Einstein)
-
Tomi_78
tag
Egy gyors kérdés: Lazarus-ban van valami mód képcsíkból a képek kinyerésére?
Tehát van egy .BMP strip (esetleg .GIF, ha ez a formátum is használható), és abból valamilyen függvénnyel kiemelni az alképeket? Mert tudtommal Delphi-ben van olyan függvény erre, hogy CopyRect(), de Lazarus-ban ezt nem találom. Mi a használatának a módja? Vagy marad az a fáradtságos megoldás, hogy a képcsíkból egy képszerkesztővel egyesével külön alképeket veszek ki és azokat töltöm be a LoadFromFile-lal? -
vz12
tag
válasz Tomi_78 #2092 üzenetére
Én úgy látom, hogy Lazarusban is úgy működik a CopyRect(), mint a Delphiben.
Feltettem egy Lazarust, és kipróbáltam.
Egy üres formra rátettem egy "TImage" elemet, és gyorsan írtam egy példakódot. Rajzoltam egy kört, és "CopyRect"-tel klónoztam:procedure TForm1.FormCreate(Sender: TObject);
var r1,r2:TRect;
begin
Image1.left:=0;
Image1.top:=0;
Image1.width:=200;
Image1.height:=100;;
Image1.Canvas.pen.color:=clWhite;
Image1.Canvas.brush.color:=clWhite;
Image1.Canvas.Rectangle(0,0,200,100);
Image1.Canvas.pen.color:=clRed;
Image1.Canvas.brush.color:=clYellow;
Image1.Canvas.Ellipse(0,0,100,100);
r1.left:=0; r1.top:=0; r1.right:=100; r1.bottom:=100;
r2.left:=100; r2.top:=0; r2.right:=200; r2.bottom:=100;
Image1.Canvas.CopyRect(r2,Image1.Canvas,r1);
end;Az eredmény 2 db kör egymás mellett, tehát működik.
A CopyRect() szintaktikája talán egy kicsit furcsa, de meg lehet szokni, és pontosan olyan, mint Delphi-ben, nem látok különbséget. -
vz12
tag
válasz Tomi_78 #2094 üzenetére
Igen, a példában ugyanaz a "Canvas" volt a forrás és a cél is, de 2 db különböző "Canvas" között is működnie kell, amennyiben a méretük megfelelő.
> tudtommal Delphi-ben van olyan függvény erre, hogy CopyRect(), de Lazarus-ban ezt nem találom
> Mi a használatának a módja?Én csak "megtaláltam" neked, amit egy példával illusztráltam.
Így talán hanyagolni lehet a "külső" képszerkesztőt. -
Tomi_78
tag
-
Tomi_78
tag
A fenébe is, valami nem jó, mert ezt a géppuskáskatona képet nem jeleníti meg, és nem értem, hogy miért?
Ez a kód:gpkatallkcs:=TBitmap.Create;
gpkatallkcs.LoadFromFile('kepei/egysegek/gpkat/gpkatall.bmp');
kcsbal:=0;
for i:=0 to 7 do
begingpkatallkep[i]:=TBitmap.Create;
t1.left:=kcsbal; t1.top:=0; t1.right:=kcsbal+round(gpkatallkcs.width/8); t1.bottom:=gpkatallkcs.height;
t2.width:=t1.width; t2.height:=t1.height;
gpkatallkep[i].Canvas.CopyRect(t2,gpkatallkcs.Canvas,t1);
gpkatallkep[i].transparent:=true;
if i<7 then
kcsbal:=kcsbal+round(gpkatallkcs.width/8)
else
kcsbal:=0;
end;
gpkatallkcs.Free;[ Szerkesztve ]
-
Tomi_78
tag
válasz Tomi_78 #2097 üzenetére
Megvan a megoldás!
A gpkatallkep[i]:=TBitmap.Create; egy csupán 1x1 képpont méretű képet hoz létre, ezért ki kellett egészíteni ezzel a kóddarabbal:gpkatallkep[i].width:=t2.width;
gpkatallkep[i].height:=t2.height;
De most meg valamiért az átlátszóság veszett el, mert a transparent hiába true, így is kirajzolja a háttérszínét... Valaki tudja, miért van ez és hogyan orvosolható? -
vz12
tag
válasz Tomi_78 #2098 üzenetére
Szerintem a BMP nem tud átlátszó lenni, vagy igen?
Halványan régről emlékszem olyanra, hogy ha a ".bmp" fájl mellett van egy ugyanolyan nevű ".msk" fájl IS (maszk fájl), akkor HA a szoftver fel van rá készítve, akkor az ".msk" fájl segítségével működhet az átlátszóság a BMP-nél is. Nem tudom, hogy a Delphi ismeri-e ezt a módszert, illetve van-e neked ".msk" fájlod.Véleményem szerint a TImage jobb lenne neked, mint a TBitmap, mert annak a "Picture.LoadFromFile"-ja több formátumot is kezel, pl. a PNG-t, ami viszont alapból átlátszó. A "transparent" property-t persze biztos true-ra kell állítani ilyenkor is.
De ez csak egy ötlet volt.
Új hozzászólás Aktív témák
- Iphone 12 Pro 128 GB + Tok
- Nintendo Switch RP2040-tiny Picofly 2.74fw CFW chip készlet eladó!
- Nintendo Switch RP2040-tiny Picofly 2.74fw CFW chip készlet eladó!
- Xbox 360 Slim 500GB Rgh 3.0 azonnali bootolás! + játékok, 1+5 év gar. 22 éve működő üzletből!
- XBOX ONE S 500GB, dobozában, gyári tarozékaival és 6 hó garanciával, Bp-i üzletből!
Állásajánlatok
Cég: Ozeki Kft.
Város: Debrecen
Cég: Ozeki Kft.
Város: Debrecen